Skip to content

dev/sg: migrate to urfave/cli

Administrator requested to merge sg-cli-framework/urfave-cli into main

Created by: bobheadxi

Spike migration to urfave/cli for https://github.com/sourcegraph/sourcegraph/issues/33383 . I am doing this because I have used Cobra rather extensively before, but not urfave/cli

Good stuff:

  1. I love how flags are defined in a structured manner
  2. Flags offer better types (slice type) and better customizations (multiple aliases)
  3. Categorization of commands
  4. Hiding of commands (hide sg install which is used by install script, sg audit which is only for the DevX team)
  5. Aliases for commands
  6. Light dependency, simpler API (cobra has grown quite convoluted)
  7. *cli.Context is quite powerful - possibly enabling for reducing reliance on global state (flags can be fetched from context), introspecting on what was run (https://github.com/sourcegraph/sourcegraph/issues/33447), etc.
  8. Before, After is very useful (maybe for collecting data for https://github.com/sourcegraph/sourcegraph/issues/32562)
  9. Less migration effort than Cobra (subcommands are defined in a similar manner to ffcli)
  10. Better docs generation (no long have to write usage: "sg command etc", can be detected automatically)
  11. app.Reader,app.Writer for testing? https://github.com/sourcegraph/sourcegraph/issues/33245 There is an example in main_test.go: https://github.com/sourcegraph/sourcegraph/pull/33758/files#diff-2acf46022d3ba8e2a3aec8c8f61fca60d03b93c1a32b01f4142fe00423d48297
  12. Completions => https://github.com/sourcegraph/sourcegraph/pull/33817
  13. Had to migrate migrator to urfave/cli as well, due to shared commands: https://github.com/sourcegraph/sourcegraph/pull/33758/commits/1950ec4edc3523883aa1fc04c645343595f453a3

Less good, but mostly minor:

  1. No out-of-the-box customization of command categories (Cobra does not have built-in categories) - for now, we can add numbers to categories to sort which works alright
  2. No out-of-the-box suggestions (Cobra has this) - this should be super easy to build with CommandNotFound
  3. Flags cannot be placed anywhere (Cobra has this). However, looking at our flags it might be beneficial to enforce the ordering since there seems to already be some overlapping flags

Not yet experimented:

  1. Docs generation (https://github.com/urfave/cli/pull/830) => follow-up!

Test plan

go build -o ./sg ./dev/sg     
./sg ...
NAME:
   sg - The Sourcegraph developer tool!

USAGE:
   sg [global options] command [command options] [arguments...]

DESCRIPTION:
   Learn more: https://docs.sourcegraph.com/dev/background-information/sg

COMMANDS:
   help, h  Shows a list of commands or help for one command
   1 - Development:
     start      🌟 Starts the given commandset. Without a commandset it starts the default Sourcegraph dev environment
     run        Run the given commands
     ci         Interact with Sourcegraph's continuous integration pipelines
     test       Run the given test suite
     lint       Run all or specified linter on the codebase
     generate   Run code and docs generation tasks
     db         Interact with local Sourcegraph databases for development
     migration  Modifies and runs database migrations
   2 - Company:
     teammate  Get information about Sourcegraph teammates
     rfc       Run the given RFC command to manage RFCs
     live      Reports which version of Sourcegraph is currently live in the given environment
     ops       Commands used by operations teams to perform common tasks
   3 - Environment:
     doctor  Run checks to test whether system is in correct state to run Sourcegraph
     secret  Manipulate secrets stored in memory and in file
     setup   Set up your local dev environment!
   4 - Utilities:
     version  View details for this installation of sg
     update   Update local sg installation
     logo     Print the sg logo

GLOBAL OPTIONS:
   --verbose, -v       toggle verbose mode (default: false) [$SG_VERBOSE]
   --config file       load sg configuration from file (default: "sg.config.yaml") [$SG_CONFIG]
   --overwrite file    load sg configuration from file that is gitignored and can be used to, for example, add credentials (default: "sg.config.overwrite.yaml") [$SG_OVERWRITE]
   --skip-auto-update  prevent sg from automatically updating itself (default: true) [$SG_SKIP_AUTO_UPDATE]
   --help, -h          show help (default: false)

Demo of specifying placeholder values in backticks of flag docstrings, and specifying required flags:

$ ./sg migration upto 
NAME:
   sg migration upto - Ensure a given migration has been applied - may apply dependency migrations

USAGE:
   sg migration upto -db=<schema> -target=<target>,<target>,...

DESCRIPTION:
   AVAILABLE SCHEMAS
     frontend
     codeintel
     codeinsights

OPTIONS:
   --db schema                The target schema to modify.
   --target migration         The migration to apply. Comma-separated values are accepted.
   --unprivileged-only        Do not apply privileged migrations. (default: false)
   --ignore-single-dirty-log  Ignore a previously failed attempt if it will be immediately retried by this operation. (default: true)
   --help, -h                 show help (default: false)
   
error: Required flags "db, target" not set

Merge request reports

Loading