diff --git a/.bazel_fix_commands.json b/.bazel_fix_commands.json index 4104641ae994..494b0ef92980 100644 --- a/.bazel_fix_commands.json +++ b/.bazel_fix_commands.json @@ -2,16 +2,16 @@ { "regex": "^Check that imports in Go sources match importpath attributes in deps.$", "command": "sg", - "args": ["bazel", "configure"] + "args": ["--skip-auto-update", "bazel", "configure"] }, { "regex": "missing input file", "command": "sg", - "args": ["bazel", "configure"] + "args": ["--skip-auto-update", "bazel", "configure"] }, { "regex": ": undefined:", "command": "sg", - "args": ["bazel", "configure"] + "args": ["--skip-auto-update", "bazel", "configure"] } ] diff --git a/deps.bzl b/deps.bzl index 56adfa19a9d3..abd1f93d7728 100644 --- a/deps.bzl +++ b/deps.bzl @@ -5587,6 +5587,13 @@ def go_dependencies(): sum = "h1:igJgVw1JdKH+trcLWLeLwZjU9fEfPesQ+9/e4MQ44S8=", version = "v1.22.12", ) + go_repository( + name = "com_github_urfave_cli_altsrc_v3", + build_file_proto_mode = "disable_global", + importpath = "github.com/urfave/cli-altsrc/v3", + sum = "h1:j4SaBpPB8++L0c0KuTnz/Yus3UQoWJ54hQjhIMW8rCM=", + version = "v3.0.0-alpha2", + ) go_repository( name = "com_github_urfave_cli_v2", build_file_proto_mode = "disable_global", @@ -5594,6 +5601,13 @@ def go_dependencies(): sum = "h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=", version = "v2.25.7", ) + go_repository( + name = "com_github_urfave_cli_v3", + build_file_proto_mode = "disable_global", + importpath = "github.com/urfave/cli/v3", + sum = "h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo=", + version = "v3.0.0-alpha9", + ) go_repository( name = "com_github_urfave_negroni", build_file_proto_mode = "disable_global", diff --git a/dev/sg/BUILD.bazel b/dev/sg/BUILD.bazel index ef87528e932a..756596495581 100644 --- a/dev/sg/BUILD.bazel +++ b/dev/sg/BUILD.bazel @@ -114,7 +114,7 @@ go_library( "@com_github_sourcegraph_conc//pool", "@com_github_sourcegraph_log//:log", "@com_github_sourcegraph_run//:run", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", "@in_gopkg_yaml_v3//:yaml_v3", "@io_opentelemetry_go_otel//attribute", "@io_opentelemetry_go_otel_trace//:trace", @@ -160,6 +160,6 @@ go_test( "//lib/output/outputtest", "@com_github_google_go_cmp//cmp", "@com_github_stretchr_testify//assert", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", ], ) diff --git a/dev/sg/analytics.go b/dev/sg/analytics.go index e0dffe00b675..a8c3b944a923 100644 --- a/dev/sg/analytics.go +++ b/dev/sg/analytics.go @@ -1,11 +1,12 @@ package main import ( + "context" "fmt" "runtime" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" @@ -21,8 +22,8 @@ import ( func addAnalyticsHooks(commandPath []string, commands []*cli.Command) { for _, command := range commands { fullCommandPath := append(commandPath, command.Name) - if len(command.Subcommands) > 0 { - addAnalyticsHooks(fullCommandPath, command.Subcommands) + if len(command.Commands) > 0 { + addAnalyticsHooks(fullCommandPath, command.Commands) } // No action to perform analytics on @@ -35,9 +36,9 @@ func addAnalyticsHooks(commandPath []string, commands []*cli.Command) { // Wrap action with analytics wrappedAction := command.Action - command.Action = func(cmd *cli.Context) (actionErr error) { + command.Action = func(ctx context.Context, cmd *cli.Command) (actionErr error) { var span *analytics.Span - cmd.Context, span = analytics.StartSpan(cmd.Context, fullCommand, "action", + ctx, span = analytics.StartSpan(ctx, fullCommand, "action", trace.WithAttributes( attribute.StringSlice("flags", cmd.FlagNames()), attribute.Int("args", cmd.NArg()), @@ -63,7 +64,7 @@ func addAnalyticsHooks(commandPath []string, commands []*cli.Command) { }) // Call the underlying action - actionErr = wrappedAction(cmd) + actionErr = wrappedAction(ctx, cmd) // Capture analytics post-run if actionErr != nil { diff --git a/dev/sg/ci/BUILD.bazel b/dev/sg/ci/BUILD.bazel index f663fadad3d6..9838f84db4f9 100644 --- a/dev/sg/ci/BUILD.bazel +++ b/dev/sg/ci/BUILD.bazel @@ -29,6 +29,6 @@ go_library( "@com_github_google_uuid//:uuid", "@com_github_grafana_regexp//:regexp", "@com_github_sourcegraph_run//:run", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", ], ) diff --git a/dev/sg/ci/buildkite.go b/dev/sg/ci/buildkite.go index f5a5c330a047..171d50c77012 100644 --- a/dev/sg/ci/buildkite.go +++ b/dev/sg/ci/buildkite.go @@ -10,7 +10,7 @@ import ( "github.com/buildkite/go-buildkite/v3/buildkite" "github.com/gen2brain/beeep" sgrun "github.com/sourcegraph/run" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/ci/runtype" "github.com/sourcegraph/sourcegraph/dev/sg/internal/bk" @@ -50,7 +50,7 @@ type targetBuild struct { // Buildkite build. // // Requires ciBranchFlag and ciBuildFlag to be registered on the command. -func getBuildTarget(cmd *cli.Context) (target targetBuild, err error) { +func getBuildTarget(ctx context.Context, cmd *cli.Command) (target targetBuild, err error) { target.pipeline = ciPipelineFlag.Get(cmd) if target.pipeline == "" { target.pipeline = "sourcegraph" @@ -77,7 +77,7 @@ func getBuildTarget(cmd *cli.Context) (target targetBuild, err error) { case commit != "": // get the full commit - target.target, err = root.Run(sgrun.Cmd(cmd.Context, "git rev-parse", commit)).String() + target.target, err = root.Run(sgrun.Cmd(ctx, "git rev-parse", commit)).String() if err != nil { return } diff --git a/dev/sg/ci/command.go b/dev/sg/ci/command.go index 24e2da154e1f..7f893b042772 100644 --- a/dev/sg/ci/command.go +++ b/dev/sg/ci/command.go @@ -1,8 +1,9 @@ package ci import ( + "github.com/urfave/cli/v3" + "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" - "github.com/urfave/cli/v2" ) var ( @@ -24,7 +25,7 @@ var ( ciPipelineFlag = cli.StringFlag{ Name: "pipeline", Aliases: []string{"p"}, - EnvVars: []string{"SG_CI_PIPELINE"}, + Sources: cli.EnvVars("SG_CI_PIPELINE"), Usage: "Select a custom Buildkite `pipeline` in the Sourcegraph org", Value: "sourcegraph", } @@ -77,7 +78,7 @@ sg ci build --force --commit my-commit main-dry-run sg ci build --help `, Category: category.Dev, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ previewCommand, bazelCommand, statusCommand, diff --git a/dev/sg/ci/subcommands.go b/dev/sg/ci/subcommands.go index fe17427eb18b..ff52ec4e4fca 100644 --- a/dev/sg/ci/subcommands.go +++ b/dev/sg/ci/subcommands.go @@ -1,6 +1,7 @@ package ci import ( + "context" "encoding/json" "fmt" "net/url" @@ -14,7 +15,7 @@ import ( "github.com/google/uuid" "github.com/grafana/regexp" sgrun "github.com/sourcegraph/run" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/ci/runtype" "github.com/sourcegraph/sourcegraph/dev/sg/internal/bk" @@ -43,11 +44,11 @@ var previewCommand = &cli.Command{ Value: "markdown", }, }, - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { std.Out.WriteLine(output.Styled(output.StyleSuggestion, "If the current branch were to be pushed, the following pipeline would be run:")) - target, err := getBuildTarget(cmd) + target, err := getBuildTarget(ctx, cmd) if err != nil { return err } @@ -68,7 +69,7 @@ var previewCommand = &cli.Command{ } switch cmd.String("format") { case "markdown": - previewCmd = usershell.Command(cmd.Context, "go run ./dev/ci/gen-pipeline.go -preview"). + previewCmd = usershell.Command(ctx, "go run ./dev/ci/gen-pipeline.go -preview"). Env(env) out, err := root.Run(previewCmd).String() if err != nil { @@ -76,7 +77,7 @@ var previewCommand = &cli.Command{ } return std.Out.WriteMarkdown(out) case "json": - previewCmd = usershell.Command(cmd.Context, "go run ./dev/ci/gen-pipeline.go"). + previewCmd = usershell.Command(ctx, "go run ./dev/ci/gen-pipeline.go"). Env(env) out, err := root.Run(previewCmd).String() if err != nil { @@ -84,7 +85,7 @@ var previewCommand = &cli.Command{ } return std.Out.WriteCode("json", out) case "yaml": - previewCmd = usershell.Command(cmd.Context, "go run ./dev/ci/gen-pipeline.go -yaml"). + previewCmd = usershell.Command(ctx, "go run ./dev/ci/gen-pipeline.go -yaml"). Env(env) out, err := root.Run(previewCmd).String() if err != nil { @@ -118,7 +119,7 @@ var bazelCommand = &cli.Command{ Value: false, }, }, - Action: func(cmd *cli.Context) (err error) { + Action: func(ctx context.Context, cmd *cli.Command) (err error) { args := cmd.Args().Slice() if !cmd.Bool("staged") { @@ -170,11 +171,11 @@ var bazelCommand = &cli.Command{ // give buildkite some time to kick off the build so that we can find it later on time.Sleep(10 * time.Second) - client, err := bk.NewClient(cmd.Context, std.Out) + client, err := bk.NewClient(ctx, std.Out) if err != nil { return err } - build, err := client.TriggerBuild(cmd.Context, "sourcegraph", branch, commit, bk.WithEnvVar("DISABLE_ASPECT_WORKFLOWS", "true")) + build, err := client.TriggerBuild(ctx, "sourcegraph", branch, commit, bk.WithEnvVar("DISABLE_ASPECT_WORKFLOWS", "true")) if err != nil { return err } @@ -187,7 +188,7 @@ var bazelCommand = &cli.Command{ if cmd.Bool("wait") { pending := std.Out.Pending(output.Styledf(output.StylePending, "Waiting for %d jobs...", len(build.Jobs))) - err = statusTicker(cmd.Context, fetchJobs(cmd.Context, client, &build, pending)) + err = statusTicker(ctx, fetchJobs(ctx, client, &build, pending)) if err != nil { return err } @@ -196,7 +197,7 @@ var bazelCommand = &cli.Command{ options := bk.ExportLogsOpts{ JobStepKey: "bazel-do", } - logs, err := client.ExportLogs(cmd.Context, "sourcegraph", *build.Number, options) + logs, err := client.ExportLogs(ctx, "sourcegraph", *build.Number, options) if err != nil { return err } @@ -234,18 +235,18 @@ var statusCommand = &cli.Command{ Aliases: []string{"view", "w"}, Usage: "Open build page in web browser (--view is DEPRECATED and will be removed in the future)", }), - Action: func(cmd *cli.Context) error { - client, err := bk.NewClient(cmd.Context, std.Out) + Action: func(ctx context.Context, cmd *cli.Command) error { + client, err := bk.NewClient(ctx, std.Out) if err != nil { return err } - target, err := getBuildTarget(cmd) + target, err := getBuildTarget(ctx, cmd) if err != nil { return err } // Just support main pipeline for now - build, err := target.GetBuild(cmd.Context, client) + build, err := target.GetBuild(ctx, client) if err != nil { return err } @@ -265,7 +266,7 @@ var statusCommand = &cli.Command{ } pending := std.Out.Pending(output.Styledf(output.StylePending, "Waiting for %d jobs...", len(build.Jobs))) - err := statusTicker(cmd.Context, fetchJobs(cmd.Context, client, &build, pending)) + err := statusTicker(ctx, fetchJobs(ctx, client, &build, pending)) pending.Destroy() if err != nil { return err @@ -274,7 +275,7 @@ var statusCommand = &cli.Command{ // lets get annotations (if any) for the build var annotations bk.JobAnnotations - annotations, err = client.GetJobAnnotationsByBuildNumber(cmd.Context, "sourcegraph", strconv.Itoa(*build.Number)) + annotations, err = client.GetJobAnnotationsByBuildNumber(ctx, "sourcegraph", strconv.Itoa(*build.Number)) if err != nil { return errors.Newf("failed to get annotations for build %d: %w", *build.Number, err) } @@ -339,7 +340,7 @@ sg ci build docker-images-patch-notest prometheus # Publish all images without testing sg ci build docker-images-candidates-notest `, - BashComplete: completions.CompleteArgs(getAllowedBuildTypeArgs), + ShellComplete: completions.CompleteArgs(getAllowedBuildTypeArgs), Flags: []cli.Flag{ &ciPipelineFlag, &cli.StringFlag{ @@ -348,8 +349,7 @@ sg ci build docker-images-candidates-notest Usage: "`commit` from the current branch to build (defaults to current commit)", }, }, - Action: func(cmd *cli.Context) error { - ctx := cmd.Context + Action: func(ctx context.Context, cmd *cli.Command) error { client, err := bk.NewClient(ctx, std.Out) if err != nil { return err @@ -488,14 +488,13 @@ From there, you can start exploring logs with the Grafana explore panel. Usage: "`state` to overwrite the job state metadata", }, ), - Action: func(cmd *cli.Context) error { - ctx := cmd.Context + Action: func(ctx context.Context, cmd *cli.Command) error { client, err := bk.NewClient(ctx, std.Out) if err != nil { return err } - target, err := getBuildTarget(cmd) + target, err := getBuildTarget(ctx, cmd) if err != nil { return err } @@ -632,9 +631,9 @@ From there, you can start exploring logs with the Grafana explore panel. var docsCommand = &cli.Command{ Name: "docs", Usage: "Render reference documentation for build pipeline types", - Action: func(ctx *cli.Context) error { - cmd := exec.Command("go", "run", "./dev/ci/gen-pipeline.go", "-docs") - out, err := run.InRoot(cmd) + Action: func(ctx context.Context, cmd *cli.Command) error { + exe := exec.Command("go", "run", "./dev/ci/gen-pipeline.go", "-docs") + out, err := run.InRoot(exe) if err != nil { return err } @@ -646,9 +645,9 @@ var openCommand = &cli.Command{ Name: "open", ArgsUsage: "[pipeline]", Usage: "Open Sourcegraph's Buildkite page in browser", - Action: func(ctx *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { buildkiteURL := fmt.Sprintf("https://buildkite.com/%s", bk.BuildkiteOrg) - args := ctx.Args().Slice() + args := cmd.Args().Slice() if len(args) > 0 && args[0] != "" { pipeline := args[0] buildkiteURL += fmt.Sprintf("/%s", pipeline) diff --git a/dev/sg/internal/backport/BUILD.bazel b/dev/sg/internal/backport/BUILD.bazel index 6c6567e0544a..21f96da37fe1 100644 --- a/dev/sg/internal/backport/BUILD.bazel +++ b/dev/sg/internal/backport/BUILD.bazel @@ -12,6 +12,6 @@ go_library( "//dev/sg/internal/std", "//lib/errors", "//lib/output", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", ], ) diff --git a/dev/sg/internal/backport/backport.go b/dev/sg/internal/backport/backport.go index 8760d0d37112..50d1ef4e0017 100644 --- a/dev/sg/internal/backport/backport.go +++ b/dev/sg/internal/backport/backport.go @@ -1,18 +1,19 @@ package backport import ( + "context" "encoding/json" "fmt" "os/exec" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" "github.com/sourcegraph/sourcegraph/lib/errors" "github.com/sourcegraph/sourcegraph/lib/output" ) -func Run(cmd *cli.Context, prNumber int64, version string) error { +func Run(ctx context.Context, cmd *cli.Command, prNumber int64, version string) error { p := std.Out.Pending(output.Styled(output.StylePending, "Checking for GitHub CLI...")) ghPath, err := exec.LookPath("gh") if err != nil { @@ -22,7 +23,7 @@ func Run(cmd *cli.Context, prNumber int64, version string) error { p.Complete(output.Linef(output.EmojiSuccess, output.StyleSuccess, "Using GitHub CLI at %q", ghPath)) p = std.Out.Pending(output.Styled(output.StylePending, "Checking GH auth status...")) - _, err = ghExec(cmd.Context, "auth", "status") + _, err = ghExec(ctx, "auth", "status") if err != nil { p.Destroy() return errors.Wrap(err, "GitHub CLI is not authenticated. Please run 'gh auth login' to authenticate") @@ -30,7 +31,7 @@ func Run(cmd *cli.Context, prNumber int64, version string) error { p.Complete(output.Linef(output.EmojiSuccess, output.StyleSuccess, "GH auth is authenticated")) p = std.Out.Pending(output.Styledf(output.StylePending, "Checking the existence of %q in remote...", version)) - _, err = ghExec(cmd.Context, "api", fmt.Sprintf("/repos/sourcegraph/sourcegraph/branches/%s", version)) + _, err = ghExec(ctx, "api", fmt.Sprintf("/repos/sourcegraph/sourcegraph/branches/%s", version)) if err != nil { p.Destroy() return errors.Wrapf(err, "%q does not exist in sourcegraph/sourcegraph", version) @@ -38,7 +39,7 @@ func Run(cmd *cli.Context, prNumber int64, version string) error { p.Complete(output.Linef(output.EmojiSuccess, output.StyleSuccess, "Found %q in remote", version)) p = std.Out.Pending(output.Styled(output.StylePending, "Getting PR info ....")) - rawPrInfo, err := ghExec(cmd.Context, "pr", "view", fmt.Sprintf("%d", prNumber), "--json", "mergeCommit,state,body,title") + rawPrInfo, err := ghExec(ctx, "pr", "view", fmt.Sprintf("%d", prNumber), "--json", "mergeCommit,state,body,title") if err != nil { p.Destroy() return errors.Wrapf(err, "Unable to fetch information for pull request: %d", prNumber) @@ -57,7 +58,7 @@ func Run(cmd *cli.Context, prNumber int64, version string) error { // prefixed with "sg/backport-" to avoid conflicts with other branches backportBranch := fmt.Sprintf("sg/backport-%d-to-%s", prNumber, version) p = std.Out.Pending(output.Styledf(output.StylePending, "Creating backport branch %q...", backportBranch)) - if err := gitExec(cmd.Context, "checkout", "-b", backportBranch, fmt.Sprintf("origin/%s", version)); err != nil { + if err := gitExec(ctx, "checkout", "-b", backportBranch, fmt.Sprintf("origin/%s", version)); err != nil { p.Destroy() return errors.Wrapf(err, "Unable to create backport branch: %q", backportBranch) } @@ -65,29 +66,29 @@ func Run(cmd *cli.Context, prNumber int64, version string) error { // Fetch latest change from remote p = std.Out.Pending(output.Styled(output.StylePending, "Fetching latest changes from remote...")) - if err := gitExec(cmd.Context, "fetch", "-a"); err != nil { + if err := gitExec(ctx, "fetch", "-a"); err != nil { p.Destroy() return err } p.Complete(output.Linef(output.EmojiSuccess, output.StyleSuccess, "Fetched latest changes from remote")) p = std.Out.Pending(output.Styledf(output.StylePending, "Cherry-picking merge commit for PR %d into backport branch...", prNumber)) - if err := gitExec(cmd.Context, "cherry-pick", mergeCommit); err != nil { + if err := gitExec(ctx, "cherry-pick", mergeCommit); err != nil { p.Destroy() // If this fails looool, nothing we much we can do here lol. - _ = gitExec(cmd.Context, "cherry-pick", "--abort") + _ = gitExec(ctx, "cherry-pick", "--abort") // checkout the last branch you were on before we tried to cherry-pick - _ = gitExec(cmd.Context, "checkout", "-") + _ = gitExec(ctx, "checkout", "-") // delete the branch we created - _ = gitExec(cmd.Context, "branch", "-D", backportBranch) + _ = gitExec(ctx, "branch", "-D", backportBranch) return errors.Wrapf(err, "Unable to cherry-pick merge commit: %q. This might be the result of a merge conflict. Manually run `git cherry-pick %s` and fix on your machine.", mergeCommit, mergeCommit) } p.Complete(output.Linef(output.EmojiSuccess, output.StyleSuccess, "Cherry-picked merge commit for PR %d into backport branch", prNumber)) p = std.Out.Pending(output.Styledf(output.StylePending, "Pushing backport branch %q to remote...", backportBranch)) - if err := gitExec(cmd.Context, "push", "--set-upstream", "origin", backportBranch); err != nil { + if err := gitExec(ctx, "push", "--set-upstream", "origin", backportBranch); err != nil { p.Destroy() return errors.Wrapf(err, "Unable to push backport branch: %q", backportBranch) } @@ -97,7 +98,7 @@ func Run(cmd *cli.Context, prNumber int64, version string) error { prTitle := generatePRTitle(pr.Title, version) p = std.Out.Pending(output.Styledf(output.StylePending, "Creating pull request for backport branch %q...", backportBranch)) out, err := ghExec( - cmd.Context, + ctx, "pr", "create", "--fill", @@ -117,7 +118,7 @@ func Run(cmd *cli.Context, prNumber int64, version string) error { p.Complete(output.Linef(output.EmojiSuccess, output.StyleSuccess, "Pull request for backport branch %q created.\n%s", backportBranch, string(out))) // checkout the last branch you were on before we tried to cherry-pick - if err = gitExec(cmd.Context, "checkout", "-"); err != nil { + if err = gitExec(ctx, "checkout", "-"); err != nil { std.Out.WriteWarningf("Unable to checkout last branch: %q", backportBranch) } diff --git a/dev/sg/internal/release/BUILD.bazel b/dev/sg/internal/release/BUILD.bazel index 5141d9027a33..4e62a7148a3e 100644 --- a/dev/sg/internal/release/BUILD.bazel +++ b/dev/sg/internal/release/BUILD.bazel @@ -18,7 +18,7 @@ go_library( "//lib/output", "@com_github_grafana_regexp//:regexp", "@com_github_sourcegraph_run//:run", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", "@in_gopkg_yaml_v3//:yaml_v3", ], ) diff --git a/dev/sg/internal/release/cve.go b/dev/sg/internal/release/cve.go index 9cc8662a7649..481684db110f 100644 --- a/dev/sg/internal/release/cve.go +++ b/dev/sg/internal/release/cve.go @@ -8,7 +8,7 @@ import ( "strings" "github.com/grafana/regexp" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/bk" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" @@ -66,13 +66,13 @@ func downloadUrl(uri string, w io.Writer) (err error) { } return nil } -func cveCheck(cmd *cli.Context) error { +func cveCheck(ctx context.Context, cmd *cli.Command) error { std.Out.WriteLine(output.Styledf(output.StylePending, "Checking release for approved CVEs...")) referenceUrl := referenceUriFlag.Get(cmd) buildNumber := buildNumberFlag.Get(cmd) - return CveCheck(cmd.Context, buildNumber, referenceUrl, false) // TODO(@jhchabran) + return CveCheck(ctx, buildNumber, referenceUrl, false) // TODO(@jhchabran) } func CveCheck(ctx context.Context, buildNumber, referenceUrl string, verbose bool) error { diff --git a/dev/sg/internal/release/release.go b/dev/sg/internal/release/release.go index fe697ade716c..851632df839b 100644 --- a/dev/sg/internal/release/release.go +++ b/dev/sg/internal/release/release.go @@ -1,13 +1,15 @@ package release import ( + "context" "fmt" "strings" "github.com/sourcegraph/run" + "github.com/urfave/cli/v3" + "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/lib/errors" - "github.com/urfave/cli/v2" ) // releaseBaseFlags are the flags that are common to all subcommands of the release command. @@ -66,7 +68,7 @@ var Command = &cli.Command{ Name: "release", Usage: "Sourcegraph release utilities", Category: category.Util, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "cve-check", Usage: "Check all CVEs found in a buildkite build against a set of preapproved CVEs for a release", @@ -82,33 +84,33 @@ var Command = &cli.Command{ Name: "run", Usage: "Run steps defined in release manifest. Those are meant to be run in CI", Category: category.Util, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "test", Flags: releaseRunFlags, Usage: "Run test steps as defined in the release manifest", - Action: func(cctx *cli.Context) error { - r, err := newReleaseRunnerFromCliContext(cctx) + Action: func(ctx context.Context, cmd *cli.Command) error { + r, err := newReleaseRunnerFromCliContext(ctx, cmd) if err != nil { return err } - return r.Test(cctx.Context) + return r.Test(ctx) }, }, { Name: "internal", Usage: "Run manifest defined steps (internal releases)", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "finalize", Usage: "Run manifest defined finalize step for internal releases", Flags: releaseRunFlags, - Action: func(cctx *cli.Context) error { - r, err := newReleaseRunnerFromCliContext(cctx) + Action: func(ctx context.Context, cmd *cli.Command) error { + r, err := newReleaseRunnerFromCliContext(ctx, cmd) if err != nil { return err } - return r.InternalFinalize(cctx.Context) + return r.InternalFinalize(ctx) }, }, }, @@ -116,17 +118,17 @@ var Command = &cli.Command{ { Name: "promote-to-public", Usage: "Run manifest defined steps (public releases)", - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "finalize", Usage: "Run manifest defined finalize step for public releases", Flags: releaseRunFlags, - Action: func(cctx *cli.Context) error { - r, err := newReleaseRunnerFromCliContext(cctx) + Action: func(ctx context.Context, cmd *cli.Command) error { + r, err := newReleaseRunnerFromCliContext(ctx, cmd) if err != nil { return err } - return r.PromoteFinalize(cctx.Context) + return r.PromoteFinalize(ctx) }, }, }, @@ -140,12 +142,12 @@ var Command = &cli.Command{ UsageText: "sg release create --workdir [path-to-folder-with-manifest] --version vX.Y.Z", Category: category.Util, Flags: releaseCreatePromoteFlags, - Action: func(cctx *cli.Context) error { - r, err := newReleaseRunnerFromCliContext(cctx) + Action: func(ctx context.Context, cmd *cli.Command) error { + r, err := newReleaseRunnerFromCliContext(ctx, cmd) if err != nil { return err } - return r.CreateRelease(cctx.Context) + return r.CreateRelease(ctx) }, }, { @@ -154,37 +156,37 @@ var Command = &cli.Command{ UsageText: "sg release promote-to-public --workdir [path-to-folder-with-manifest] --version vX.Y.Z", Category: category.Util, Flags: releaseCreatePromoteFlags, - Action: func(cctx *cli.Context) error { - r, err := newReleaseRunnerFromCliContext(cctx) + Action: func(ctx context.Context, cmd *cli.Command) error { + r, err := newReleaseRunnerFromCliContext(ctx, cmd) if err != nil { return err } - return r.Promote(cctx.Context) + return r.Promote(ctx) }, }, }, } -func newReleaseRunnerFromCliContext(cctx *cli.Context) (*releaseRunner, error) { - if cctx.Bool("config-from-commit") && cctx.String("version") != "" { +func newReleaseRunnerFromCliContext(ctx context.Context, cmd *cli.Command) (*releaseRunner, error) { + if cmd.Bool("config-from-commit") && cmd.String("version") != "" { return nil, errors.New("You cannot use --config-from-commit and --version at the same time") } - if !cctx.Bool("config-from-commit") && cctx.String("version") == "" { + if !cmd.Bool("config-from-commit") && cmd.String("version") == "" { return nil, errors.New("You must provide a version by specifying either --version or --config-from-commit") } - workdir := cctx.String("workdir") - pretend := cctx.Bool("pretend") + workdir := cmd.String("workdir") + pretend := cmd.Bool("pretend") // Normalize the version string, to prevent issues where this was given with the wrong convention // which requires a full rebuild. - version := fmt.Sprintf("v%s", strings.TrimPrefix(cctx.String("version"), "v")) - typ := cctx.String("type") - inputs := cctx.String("inputs") - branch := cctx.String("branch") + version := fmt.Sprintf("v%s", strings.TrimPrefix(cmd.String("version"), "v")) + typ := cmd.String("type") + inputs := cmd.String("inputs") + branch := cmd.String("branch") - if cctx.Bool("config-from-commit") { - cmd := run.Cmd(cctx.Context, "git", "log", "-1") + if cmd.Bool("config-from-commit") { + cmd := run.Cmd(ctx, "git", "log", "-1") cmd.Dir(workdir) lines, err := cmd.Run().Lines() if err != nil { @@ -206,5 +208,5 @@ func newReleaseRunnerFromCliContext(cctx *cli.Context) (*releaseRunner, error) { inputs = rc.Inputs } - return NewReleaseRunner(cctx.Context, workdir, version, inputs, typ, branch, pretend) + return NewReleaseRunner(ctx, workdir, version, inputs, typ, branch, pretend) } diff --git a/dev/sg/internal/wolfi/BUILD.bazel b/dev/sg/internal/wolfi/BUILD.bazel index 195c65c090ac..eed0747fb1d2 100644 --- a/dev/sg/internal/wolfi/BUILD.bazel +++ b/dev/sg/internal/wolfi/BUILD.bazel @@ -16,6 +16,5 @@ go_library( "//lib/errors", "//lib/output", "@com_github_grafana_regexp//:regexp", - "@com_github_urfave_cli_v2//:cli", ], ) diff --git a/dev/sg/internal/wolfi/update_hashes.go b/dev/sg/internal/wolfi/update_hashes.go index 19fb09141579..12f87d8ef112 100644 --- a/dev/sg/internal/wolfi/update_hashes.go +++ b/dev/sg/internal/wolfi/update_hashes.go @@ -2,6 +2,7 @@ package wolfi import ( "bufio" + "context" "encoding/json" "fmt" "io" @@ -11,7 +12,6 @@ import ( "strings" "github.com/grafana/regexp" - "github.com/urfave/cli/v2" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" "github.com/sourcegraph/sourcegraph/dev/sg/root" @@ -102,7 +102,7 @@ func getImageManifest(image string, tag string) (string, error) { return digest, nil } -func UpdateHashes(_ *cli.Context, updateImageName string) error { +func UpdateHashes(_ context.Context, updateImageName string) error { if updateImageName != "" { updateImageName = strings.ReplaceAll(updateImageName, "-", "_") updateImageName = fmt.Sprintf("wolfi_%s_base", updateImageName) diff --git a/dev/sg/main.go b/dev/sg/main.go index f4875ba4e7ca..5a8cb93f230e 100644 --- a/dev/sg/main.go +++ b/dev/sg/main.go @@ -6,9 +6,8 @@ import ( "fmt" "os" "path/filepath" - "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/log" @@ -34,8 +33,7 @@ func main() { bashCompletionsMode = true } - if err := sg.RunContext(context.Background(), os.Args); err != nil { - // We want to prefer an already-initialized std.Out no matter what happens, + if err := sg.Run(context.Background(), os.Args); err != nil { // We want to prefer an already-initialized std.Out no matter what happens, // because that can be configured (e.g. with '--disable-output-detection'). Only // if something went horribly wrong and std.Out is not yet initialized should we // attempt an initialization here. @@ -71,7 +69,7 @@ var ( // // Commands can register postInitHooks in an 'init()' function that appends to this // slice. - postInitHooks []func(cmd *cli.Context) + postInitHooks []func(ctx context.Context, cmd *cli.Command) // bashCompletionsMode determines if we are in bash completion mode. In this mode, // sg should respond quickly, so most setup tasks (e.g. postInitHooks) are skipped. @@ -83,17 +81,17 @@ var ( const sgBugReportTemplate = "https://github.com/sourcegraph/sourcegraph/issues/new?template=sg_bug.md" // sg is the main sg CLI application. -var sg = &cli.App{ +var sg = &cli.Command{ Usage: "The Sourcegraph developer tool!", Description: "Learn more: https://sourcegraph.com/docs/dev/background-information/sg", Version: BuildCommit, - Compiled: time.Now(), + // Compiled: time.Now(), Flags: []cli.Flag{ &cli.BoolFlag{ Name: "verbose", Usage: "toggle verbose mode", Aliases: []string{"v"}, - EnvVars: []string{"SG_VERBOSE"}, + Sources: cli.EnvVars("SG_VERBOSE"), Value: false, Destination: &verbose, }, @@ -101,7 +99,7 @@ var sg = &cli.App{ Name: "config", Usage: "load sg configuration from `file`", Aliases: []string{"c"}, - EnvVars: []string{"SG_CONFIG"}, + Sources: cli.EnvVars("SG_CONFIG"), TakesFile: true, Value: sgconf.DefaultFile, Destination: &configFile, @@ -110,7 +108,7 @@ var sg = &cli.App{ Name: "overwrite", Usage: "load sg configuration from `file` that is gitignored and can be used to, for example, add credentials", Aliases: []string{"o"}, - EnvVars: []string{"SG_OVERWRITE"}, + Sources: cli.EnvVars("SG_OVERWRITE"), TakesFile: true, Value: sgconf.DefaultOverwriteFile, Destination: &configOverwriteFile, @@ -118,37 +116,37 @@ var sg = &cli.App{ &cli.BoolFlag{ Name: "disable-overwrite", Usage: "disable loading additional sg configuration from overwrite file (see -overwrite)", - EnvVars: []string{"SG_DISABLE_OVERWRITE"}, + Sources: cli.EnvVars("SG_DISABLE_OVERWRITE"), Value: false, Destination: &disableOverwrite, }, &cli.BoolFlag{ Name: "skip-auto-update", Usage: "prevent sg from automatically updating itself", - EnvVars: []string{"SG_SKIP_AUTO_UPDATE"}, + Sources: cli.EnvVars("SG_SKIP_AUTO_UPDATE"), Value: BuildCommit == "dev", // Default to skip in dev }, &cli.BoolFlag{ Name: "disable-analytics", Usage: "disable event logging (logged to '~/.sourcegraph/events')", - EnvVars: []string{"SG_DISABLE_ANALYTICS"}, + Sources: cli.EnvVars("SG_DISABLE_ANALYTICS"), Value: BuildCommit == "dev", // Default to skip in dev }, &cli.BoolFlag{ Name: "disable-output-detection", Usage: "use fixed output configuration instead of detecting terminal capabilities", - EnvVars: []string{"SG_DISABLE_OUTPUT_DETECTION"}, + Sources: cli.EnvVars("SG_DISABLE_OUTPUT_DETECTION"), Destination: &std.DisableOutputDetection, }, &cli.BoolFlag{ Name: "no-dev-private", Usage: "disable checking for dev-private - only useful for automation or ci", - EnvVars: []string{"SG_NO_DEV_PRIVATE"}, + Sources: cli.EnvVars("SG_NO_DEV_PRIVATE"), Value: false, Destination: &NoDevPrivateCheck, }, }, - Before: func(cmd *cli.Context) (err error) { + Before: func(ctx context.Context, cmd *cli.Command) (err error) { // All other setup pertains to running commands - to keep completions fast, // we skip all other setup when in bashCompletions mode. if bashCompletionsMode { @@ -170,30 +168,30 @@ var sg = &cli.App{ interrupt.Listen() // Configure global output - std.Out = std.NewOutput(cmd.App.Writer, verbose) + std.Out = std.NewOutput(cmd.Writer, verbose) // Set up analytics and hooks for each command - do this as the first context // setup if !cmd.Bool("disable-analytics") { - cmd.Context, err = analytics.WithContext(cmd.Context, cmd.App.Version) + ctx, err = analytics.WithContext(ctx, cmd.Version) if err != nil { std.Out.WriteWarningf("Failed to initialize analytics: " + err.Error()) } // Ensure analytics are persisted - interrupt.Register(func() { analytics.Persist(cmd.Context) }) + interrupt.Register(func() { analytics.Persist(ctx) }) // Add analytics to each command - addAnalyticsHooks([]string{"sg"}, cmd.App.Commands) + addAnalyticsHooks([]string{"sg"}, cmd.Commands) } // Initialize context after analytics are set up - cmd.Context, err = usershell.Context(cmd.Context) + ctx, err = usershell.Context(ctx) if err != nil { std.Out.WriteWarningf("Unable to infer user shell context: " + err.Error()) } - cmd.Context = background.Context(cmd.Context, verbose) - interrupt.Register(func() { background.Wait(cmd.Context, std.Out) }) + ctx = background.Context(ctx, verbose) + interrupt.Register(func() { background.Wait(ctx, std.Out) }) // Configure logger, for commands that use components that use loggers if _, set := os.LookupEnv(log.EnvDevelopment); !set { @@ -218,7 +216,7 @@ var sg = &cli.App{ if err != nil { std.Out.WriteWarningf("failed to open secrets: %s", err) } else { - cmd.Context = secrets.WithContext(cmd.Context, secretsStore) + ctx = secrets.WithContext(ctx, secretsStore) } // We always try to set this, since we often want to watch files, start commands, etc... @@ -234,7 +232,7 @@ var sg = &cli.App{ "teammate": {}, } if _, skipped := skipBackgroundTasks[cmd.Args().First()]; !skipped { - background.Run(cmd.Context, func(ctx context.Context, out *std.Output) { + background.Run(ctx, func(ctx context.Context, out *std.Output) { err := checkSgVersionAndUpdate(ctx, out, cmd.Bool("skip-auto-update")) if err != nil { out.WriteWarningf("update check: %s", err) @@ -244,67 +242,23 @@ var sg = &cli.App{ // Call registered hooks last for _, hook := range postInitHooks { - hook(cmd) + hook(ctx, cmd) } return nil }, - After: func(cmd *cli.Context) error { + After: func(ctx context.Context, cmd *cli.Command) error { if !bashCompletionsMode { // Wait for background jobs to finish up, iff not in autocomplete mode - background.Wait(cmd.Context, std.Out) + background.Wait(ctx, std.Out) // Persist analytics - analytics.Persist(cmd.Context) + analytics.Persist(ctx) } return nil }, - Commands: []*cli.Command{ - // Common dev tasks - startCommand, - runCommand, - ci.Command, - testCommand, - lintCommand, - generateCommand, - bazelCommand, - dbCommand, - migrationCommand, - insightsCommand, - telemetryCommand, - monitoringCommand, - contextCommand, - deployCommand, - wolfiCommand, - backportCommand, - - // Dev environment - secretCommand, - setupCommand, - srcCommand, - srcInstanceCommand, - - // Company - teammateCommand, - rfcCommand, - liveCommand, - opsCommand, - auditCommand, - pageCommand, - cloudCommand, - msp.Command, - - // Util - analyticsCommand, - doctorCommand, - funkyLogoCommand, - helpCommand, - installCommand, - release.Command, - updateCommand, - versionCommand, - }, - ExitErrHandler: func(cmd *cli.Context, err error) { + Commands: commands, + ExitErrHandler: func(ctx context.Context, cmd *cli.Command, err error) { if err == nil { return } @@ -330,13 +284,59 @@ var sg = &cli.App{ Suggest: true, - EnableBashCompletion: true, + EnableShellCompletion: true, UseShortOptionHandling: true, HideVersion: true, HideHelpCommand: true, } +var commands = []*cli.Command{ + // Common dev tasks + startCommand, + runCommand, + ci.Command, + testCommand, + lintCommand, + generateCommand, + bazelCommand, + dbCommand, + migrationCommand, + insightsCommand, + telemetryCommand, + monitoringCommand, + contextCommand, + deployCommand, + wolfiCommand, + backportCommand, + + // Dev environment + secretCommand, + setupCommand, + srcCommand, + srcInstanceCommand, + + // Company + teammateCommand, + rfcCommand, + liveCommand, + opsCommand, + auditCommand, + pageCommand, + cloudCommand, + msp.Command, + + // Util + analyticsCommand, + doctorCommand, + funkyLogoCommand, + helpCommand, + installCommand, + release.Command, + updateCommand, + versionCommand, +} + func loadSecrets() (*secrets.Store, error) { homePath, err := root.GetSGHomePath() if err != nil { diff --git a/dev/sg/main_test.go b/dev/sg/main_test.go index 1cb73f14b8e8..266b9877fc25 100644 --- a/dev/sg/main_test.go +++ b/dev/sg/main_test.go @@ -2,15 +2,16 @@ package main import ( "bytes" + "context" "strings" "testing" "github.com/stretchr/testify/assert" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // testSG creates a copy of the sg app for testing. -func testSG() *cli.App { +func testSG() *cli.Command { tsg := *sg return &tsg } @@ -23,7 +24,7 @@ func TestAppRun(t *testing.T) { sg.Writer = &out sg.ErrWriter = &err // Check app starts up correctly - assert.NoError(t, sg.Run([]string{ + assert.NoError(t, sg.Run(context.Background(), []string{ "help", // Use a fixed output configuration for consistency, and to avoid issues with // detection. @@ -52,12 +53,12 @@ func testCommandFormatting(t *testing.T, cmd *cli.Command) { assert.NotEmpty(t, cmd.Name, "Name should be set") assert.NotEmpty(t, cmd.Usage, "Usage should be set") assert.False(t, strings.HasSuffix(cmd.Usage, "."), "Usage should not end with period") - if len(cmd.Subcommands) == 0 { + if len(cmd.Commands) == 0 { assert.NotNil(t, cmd.Action, "Action must be provided for command without subcommands") } assert.Nil(t, cmd.After, "After should not be used for simplicity") - for _, subCmd := range cmd.Subcommands { + for _, subCmd := range cmd.Commands { testCommandFormatting(t, subCmd) } }) diff --git a/dev/sg/msp/BUILD.bazel b/dev/sg/msp/BUILD.bazel index 7dff7ae9f82f..1f727d47f3c9 100644 --- a/dev/sg/msp/BUILD.bazel +++ b/dev/sg/msp/BUILD.bazel @@ -32,7 +32,7 @@ go_library( "//lib/output", "//lib/pointers", "@com_github_sourcegraph_run//:run", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", "@org_golang_x_exp//maps", ], ) diff --git a/dev/sg/msp/helpers.go b/dev/sg/msp/helpers.go index 58feba837dcb..cf19170343b7 100644 --- a/dev/sg/msp/helpers.go +++ b/dev/sg/msp/helpers.go @@ -1,6 +1,7 @@ package msp import ( + "context" "encoding/json" "fmt" "os" @@ -8,7 +9,7 @@ import ( "slices" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/managedservicesplatform" "github.com/sourcegraph/sourcegraph/dev/managedservicesplatform/clouddeploy" @@ -24,8 +25,8 @@ import ( // useServiceArgument retrieves the service spec corresponding to the first // argument. -func useServiceArgument(c *cli.Context) (*spec.Spec, error) { - serviceID := c.Args().First() +func useServiceArgument(_ context.Context, cmd *cli.Command) (*spec.Spec, error) { + serviceID := cmd.Args().First() if serviceID == "" { return nil, errors.New("argument service is required") } @@ -41,13 +42,13 @@ func useServiceArgument(c *cli.Context) (*spec.Spec, error) { // useServiceAndEnvironmentArguments retrieves the service and environment specs // corresponding to the first and second arguments respectively. It should only // be used if both arguments are required. -func useServiceAndEnvironmentArguments(c *cli.Context) (*spec.Spec, *spec.EnvironmentSpec, error) { - svc, err := useServiceArgument(c) +func useServiceAndEnvironmentArguments(ctx context.Context, cmd *cli.Command) (*spec.Spec, *spec.EnvironmentSpec, error) { + svc, err := useServiceArgument(ctx, cmd) if err != nil { return nil, nil, err } - environmentID := c.Args().Get(1) + environmentID := cmd.Args().Get(1) if environmentID == "" { return svc, nil, errors.New("second argument is required") } @@ -61,8 +62,8 @@ func useServiceAndEnvironmentArguments(c *cli.Context) (*spec.Spec, *spec.Enviro return svc, env, nil } -func syncEnvironmentWorkspaces(c *cli.Context, tfc *terraformcloud.Client, service spec.ServiceSpec, env spec.EnvironmentSpec) error { - if c.Bool("delete") { +func syncEnvironmentWorkspaces(ctx context.Context, cmd *cli.Command, tfc *terraformcloud.Client, service spec.ServiceSpec, env spec.EnvironmentSpec) error { + if cmd.Bool("delete") { if !pointers.DerefZero(env.AllowDestroys) { return errors.Newf("environments[%s].allowDestroys must be 'true' to delete workspaces", env.ID) } @@ -83,7 +84,7 @@ func syncEnvironmentWorkspaces(c *cli.Context, tfc *terraformcloud.Client, servi // Destroy stacks in reverse order stacks := managedservicesplatform.StackNames() slices.Reverse(stacks) - if errs := tfc.DeleteWorkspaces(c.Context, service, env, stacks); len(errs) > 0 { + if errs := tfc.DeleteWorkspaces(ctx, service, env, stacks); len(errs) > 0 { for _, err := range errs { std.Out.WriteWarningf(err.Error()) } @@ -97,7 +98,7 @@ func syncEnvironmentWorkspaces(c *cli.Context, tfc *terraformcloud.Client, servi pending := std.Out.Pending(output.Styledf(output.StylePending, "[%s] Synchronizing Terraform Cloud workspaces for environment %q", service.ID, env.ID)) - workspaces, err := tfc.SyncWorkspaces(c.Context, service, env, managedservicesplatform.StackNames()) + workspaces, err := tfc.SyncWorkspaces(ctx, service, env, managedservicesplatform.StackNames()) if err != nil { return errors.Wrap(err, "sync Terraform Cloud workspace") } diff --git a/dev/sg/msp/repo/BUILD.bazel b/dev/sg/msp/repo/BUILD.bazel index 0a7a2cb47a10..6297f591a1d1 100644 --- a/dev/sg/msp/repo/BUILD.bazel +++ b/dev/sg/msp/repo/BUILD.bazel @@ -15,7 +15,7 @@ go_library( "//lib/cliutil/completions", "//lib/errors", "@com_github_sourcegraph_run//:run", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", "@dev_bobheadxi_go_streamline//pipeline", ], ) diff --git a/dev/sg/msp/repo/repo.go b/dev/sg/msp/repo/repo.go index d007123756cc..ab147a18f3f3 100644 --- a/dev/sg/msp/repo/repo.go +++ b/dev/sg/msp/repo/repo.go @@ -6,7 +6,7 @@ import ( "os" "path/filepath" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/run" @@ -18,7 +18,7 @@ import ( // UseManagedServicesRepo is a cli.BeforeFunc that enforces that we are in the // sourcegraph/managed-services repository by setting the current working // directory. -func UseManagedServicesRepo(*cli.Context) error { +func UseManagedServicesRepo(_ context.Context, _ *cli.Command) error { cwd, err := os.Getwd() if err != nil { return err @@ -67,7 +67,7 @@ func ListServices() ([]string, error) { // ServicesAndEnvironmentsCompletion provides completions capabilities for // commands that accept ' ' positional arguments. -func ServicesAndEnvironmentsCompletion(additionalArgs ...func(args cli.Args) (options []string)) cli.BashCompleteFunc { +func ServicesAndEnvironmentsCompletion(additionalArgs ...func(args cli.Args) (options []string)) cli.ShellCompleteFunc { cwd, err := os.Getwd() if err != nil { return nil diff --git a/dev/sg/msp/sg_msp.go b/dev/sg/msp/sg_msp.go index efa0a93b8aa0..15dda0993014 100644 --- a/dev/sg/msp/sg_msp.go +++ b/dev/sg/msp/sg_msp.go @@ -2,13 +2,14 @@ package msp import ( + "context" "fmt" "os" "path/filepath" "sort" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/exp/maps" "github.com/sourcegraph/run" @@ -53,7 +54,7 @@ sg msp tfc sync $SERVICE $ENVIRONMENT sg msp generate $SERVICE $ENVIRONMENT `, Category: category.Company, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "init", ArgsUsage: "", @@ -86,7 +87,7 @@ sg msp init -owner core-services -name "MSP Example Service" msp-example }, }, Before: msprepo.UseManagedServicesRepo, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { if c.Args().Len() != 1 { return errors.New("exactly 1 argument required: service ID") } @@ -97,7 +98,7 @@ sg msp init -owner core-services -name "MSP Example Service" msp-example Owner: c.String("owner"), Dev: c.Bool("dev"), - ProjectIDSuffixLength: c.Int("project-id-suffix-length"), + ProjectIDSuffixLength: int(c.Int("project-id-suffix-length")), } var exampleSpec []byte @@ -142,16 +143,16 @@ sg msp init -owner core-services -name "MSP Example Service" msp-example }, }, Before: msprepo.UseManagedServicesRepo, - BashComplete: completions.CompleteArgs(func() (options []string) { + ShellComplete: completions.CompleteArgs(func() (options []string) { ss, _ := msprepo.ListServices() return ss }), - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { if c.Args().Len() != 2 { return errors.Newf("exactly 2 arguments required, '' and '' - " + " this command is for adding an environment to an existing service, did you mean to use 'sg msp init' instead?") } - svc, err := useServiceArgument(c) + svc, err := useServiceArgument(ctx, c) if err != nil { return err } @@ -163,7 +164,7 @@ sg msp init -owner core-services -name "MSP Example Service" msp-example envNode, err := example.NewEnvironment(example.EnvironmentTemplate{ ServiceID: svc.Service.ID, EnvironmentID: envID, - ProjectIDSuffixLength: c.Int("project-id-suffix-length"), + ProjectIDSuffixLength: int(c.Int("project-id-suffix-length")), }) if err != nil { return errors.Wrap(err, "example.NewEnvironment") @@ -218,8 +219,8 @@ sg msp generate -all Value: true, }, }, - BashComplete: msprepo.ServicesAndEnvironmentsCompletion(), - Action: func(c *cli.Context) error { + ShellComplete: msprepo.ServicesAndEnvironmentsCompletion(), + Action: func(ctx context.Context, c *cli.Command) error { var ( generateAll = c.Bool("all") stableGenerate = c.Bool("stable") @@ -267,7 +268,7 @@ sg msp generate -all Aliases: []string{"ops"}, Usage: "Generate operational reference for a service", Before: msprepo.UseManagedServicesRepo, - BashComplete: completions.CompleteArgs(func() (options []string) { + ShellComplete: completions.CompleteArgs(func() (options []string) { ss, _ := msprepo.ListServices() return ss }), @@ -278,13 +279,13 @@ sg msp generate -all Value: true, }, }, - Action: func(c *cli.Context) error { - svc, err := useServiceArgument(c) + Action: func(ctx context.Context, c *cli.Command) error { + svc, err := useServiceArgument(ctx, c) if err != nil { return err } - repoRev, err := msprepo.GitRevision(c.Context) + repoRev, err := msprepo.GitRevision(ctx) if err != nil { return errors.Wrap(err, "msprepo.GitRevision") } @@ -301,7 +302,7 @@ sg msp generate -all std.Out.Write(doc) return nil }, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "generate-handbook-pages", Usage: "Generate operations handbook pages for all services", @@ -318,7 +319,7 @@ The '-handbook-path' flag can also be used to specify where sourcegraph/handbook Name: "handbook-path", Usage: "Path to the directory in which sourcegraph/handbook is cloned", Value: "../handbook", - Action: func(_ *cli.Context, v string) error { + Action: func(_ context.Context, _ *cli.Command, v string) error { // 'Required: true' will error out even if a default // value is set, so do our own validation here. if v == "" { @@ -328,7 +329,7 @@ The '-handbook-path' flag can also be used to specify where sourcegraph/handbook }, }, }, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { handbookPath := c.String("handbook-path") if err := isHandbookRepo(handbookPath); err != nil { return errors.Wrapf(err, "expecting github.com/sourcegraph/handbook at %q", handbookPath) @@ -339,7 +340,7 @@ The '-handbook-path' flag can also be used to specify where sourcegraph/handbook return err } - repoRev, err := msprepo.GitRevision(c.Context) + repoRev, err := msprepo.GitRevision(ctx) if err != nil { return errors.Wrap(err, "msprepo.GitRevision") } @@ -403,9 +404,9 @@ The '-handbook-path' flag can also be used to specify where sourcegraph/handbook Value: "service", }, }, - BashComplete: msprepo.ServicesAndEnvironmentsCompletion(), - Action: func(c *cli.Context) error { - svc, env, err := useServiceAndEnvironmentArguments(c) + ShellComplete: msprepo.ServicesAndEnvironmentsCompletion(), + Action: func(ctx context.Context, c *cli.Command) error { + svc, env, err := useServiceAndEnvironmentArguments(ctx, c) if err != nil { return err } @@ -425,7 +426,7 @@ The '-handbook-path' flag can also be used to specify where sourcegraph/handbook Aliases: []string{"pg"}, Usage: "Interact with PostgreSQL instances provisioned by MSP", Before: msprepo.UseManagedServicesRepo, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "connect", Usage: "Connect to the PostgreSQL instance", @@ -463,9 +464,9 @@ full access, use the '-write-access' flag. Value: 300, }, }, - BashComplete: msprepo.ServicesAndEnvironmentsCompletion(), - Action: func(c *cli.Context) error { - _, env, err := useServiceAndEnvironmentArguments(c) + ShellComplete: msprepo.ServicesAndEnvironmentsCompletion(), + Action: func(ctx context.Context, c *cli.Command) error { + _, env, err := useServiceAndEnvironmentArguments(ctx, c) if err != nil { return err } @@ -478,7 +479,7 @@ full access, use the '-write-access' flag. return err } - secretStore, err := secrets.FromContext(c.Context) + secretStore, err := secrets.FromContext(ctx) if err != nil { return err } @@ -486,7 +487,7 @@ full access, use the '-write-access' flag. var serviceAccountEmail string if c.Bool("write-access") { // Use the workload identity if all access is requested - serviceAccountEmail, err = secretStore.GetExternal(c.Context, secrets.ExternalSecret{ + serviceAccountEmail, err = secretStore.GetExternal(ctx, secrets.ExternalSecret{ Name: stacks.OutputSecretID(iam.StackName, iam.OutputCloudRunServiceAccount), Project: env.ProjectID, }) @@ -497,7 +498,7 @@ full access, use the '-write-access' flag. } else { // Otherwise, use the operator access account which // is a bit more limited. - serviceAccountEmail, err = secretStore.GetExternal(c.Context, secrets.ExternalSecret{ + serviceAccountEmail, err = secretStore.GetExternal(ctx, secrets.ExternalSecret{ Name: stacks.OutputSecretID(iam.StackName, iam.OutputOperatorServiceAccount), Project: env.ProjectID, }) @@ -507,7 +508,7 @@ full access, use the '-write-access' flag. std.Out.WriteSuggestionf("Preparing a connection with read-only access - for write access, use the '-write-access' flag.") } - connectionName, err := secretStore.GetExternal(c.Context, secrets.ExternalSecret{ + connectionName, err := secretStore.GetExternal(ctx, secrets.ExternalSecret{ Name: stacks.OutputSecretID(cloudrun.StackName, cloudrun.OutputCloudSQLConnectionName), Project: env.ProjectID, }) @@ -515,7 +516,7 @@ full access, use the '-write-access' flag. return errors.Wrap(err, "find Cloud Run output") } - proxyPort := c.Int("port") + proxyPort := int(c.Int("port")) proxy, err := cloudsqlproxy.NewCloudSQLProxy( connectionName, serviceAccountEmail, @@ -539,7 +540,7 @@ full access, use the '-write-access' flag. } // Run proxy until stopped - return proxy.Start(c.Context, c.Int("session.timeout")) + return proxy.Start(ctx, int(c.Int("session.timeout"))) }, }, }, @@ -549,7 +550,7 @@ full access, use the '-write-access' flag. Aliases: []string{"tfc"}, Usage: "Manage Terraform Cloud workspaces for a service", Before: msprepo.UseManagedServicesRepo, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "view", Usage: "View MSP Terraform Cloud workspaces", @@ -564,16 +565,16 @@ sg msp tfc view # View all workspaces for a specific MSP service environment sg msp tfc view `, - ArgsUsage: "[service ID] [environment ID]", - BashComplete: msprepo.ServicesAndEnvironmentsCompletion(), - Action: func(c *cli.Context) error { + ArgsUsage: "[service ID] [environment ID]", + ShellComplete: msprepo.ServicesAndEnvironmentsCompletion(), + Action: func(ctx context.Context, c *cli.Command) error { if c.Args().Len() == 0 { std.Out.WriteNoticef("Opening link to all MSP Terraform Cloud workspaces in browser...") return open.URL(fmt.Sprintf("https://app.terraform.io/app/sourcegraph/workspaces?tag=%s", terraformcloud.MSPWorkspaceTag)) } - service, err := useServiceArgument(c) + service, err := useServiceArgument(ctx, c) if err != nil { return err } @@ -616,25 +617,25 @@ Supports completions on services and environments.`, Value: false, }, }, - BashComplete: msprepo.ServicesAndEnvironmentsCompletion(), - Action: func(c *cli.Context) error { - service, err := useServiceArgument(c) + ShellComplete: msprepo.ServicesAndEnvironmentsCompletion(), + Action: func(ctx context.Context, c *cli.Command) error { + service, err := useServiceArgument(ctx, c) if err != nil { return err } - secretStore, err := secrets.FromContext(c.Context) + secretStore, err := secrets.FromContext(ctx) if err != nil { return err } - tfcAccessToken, err := secretStore.GetExternal(c.Context, secrets.ExternalSecret{ + tfcAccessToken, err := secretStore.GetExternal(ctx, secrets.ExternalSecret{ Name: googlesecretsmanager.SecretTFCOrgToken, Project: googlesecretsmanager.SharedSecretsProjectID, }) if err != nil { return errors.Wrap(err, "get AccessToken") } - tfcOAuthClient, err := secretStore.GetExternal(c.Context, secrets.ExternalSecret{ + tfcOAuthClient, err := secretStore.GetExternal(ctx, secrets.ExternalSecret{ Name: googlesecretsmanager.SecretTFCOAuthClientID, Project: googlesecretsmanager.SharedSecretsProjectID, }) @@ -656,7 +657,7 @@ Supports completions on services and environments.`, return errors.Newf("environment %q not found in service spec", targetEnv) } - if err := syncEnvironmentWorkspaces(c, tfcClient, service.Service, *env); err != nil { + if err := syncEnvironmentWorkspaces(ctx, c, tfcClient, service.Service, *env); err != nil { return errors.Wrapf(err, "sync env %q", env.ID) } } else { @@ -664,7 +665,7 @@ Supports completions on services and environments.`, return errors.New("second argument environment ID is required without the '-all' flag") } for _, env := range service.Environments { - if err := syncEnvironmentWorkspaces(c, tfcClient, service.Service, env); err != nil { + if err := syncEnvironmentWorkspaces(ctx, c, tfcClient, service.Service, env); err != nil { return errors.Wrapf(err, "sync env %q", env.ID) } } @@ -683,13 +684,13 @@ Supports completions on services and environments.`, Usage: "Dump dot graph configuration instead of rendering the image with 'dot'", }, }, - BashComplete: msprepo.ServicesAndEnvironmentsCompletion( + ShellComplete: msprepo.ServicesAndEnvironmentsCompletion( func(cli.Args) (options []string) { return managedservicesplatform.StackNames() }, ), - Action: func(c *cli.Context) error { - service, env, err := useServiceAndEnvironmentArguments(c) + Action: func(ctx context.Context, c *cli.Command) error { + service, env, err := useServiceAndEnvironmentArguments(ctx, c) if err != nil { return err } @@ -699,7 +700,7 @@ Supports completions on services and environments.`, return errors.New("third argument is required") } - dotgraph, err := msprepo.TerraformGraph(c.Context, service.Service.ID, env.ID, stack) + dotgraph, err := msprepo.TerraformGraph(ctx, service.Service.ID, env.ID, stack) if err != nil { return err } @@ -715,7 +716,7 @@ Supports completions on services and environments.`, return errors.Wrapf(err, "open %q", output) } defer f.Close() - if err := run.Cmd(c.Context, "dot -Tpng"). + if err := run.Cmd(ctx, "dot -Tpng"). Input(strings.NewReader(dotgraph + "\n")). Environ(os.Environ()). Run(). @@ -732,7 +733,7 @@ Supports completions on services and environments.`, Name: "fleet", Usage: "Summarize aspects of the MSP fleet", Before: msprepo.UseManagedServicesRepo, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { services, err := msprepo.ListServices() if err != nil { return err @@ -779,7 +780,7 @@ Supports completions on services and environments.`, Usage: "Output path for generated schema", }, }, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { jsonSchema, err := schema.Render() if err != nil { return err diff --git a/dev/sg/sg_analytics.go b/dev/sg/sg_analytics.go index e6262e7bf2ad..f54694e8e28a 100644 --- a/dev/sg/sg_analytics.go +++ b/dev/sg/sg_analytics.go @@ -1,12 +1,13 @@ package main import ( + "context" "encoding/json" "fmt" "strings" "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/analytics" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" @@ -20,14 +21,14 @@ var analyticsCommand = &cli.Command{ Name: "analytics", Usage: "Manage analytics collected by sg", Category: category.Util, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "submit", ArgsUsage: " ", Usage: "Make sg better by submitting all analytics stored locally!", Description: "Requires HONEYCOMB_ENV_TOKEN or OTEL_EXPORTER_OTLP_ENDPOINT to be set.", - Action: func(cmd *cli.Context) error { - sec, err := secrets.FromContext(cmd.Context) + Action: func(ctx context.Context, cmd *cli.Command) error { + sec, err := secrets.FromContext(ctx) if err != nil { return err } @@ -35,7 +36,7 @@ var analyticsCommand = &cli.Command{ // we leave OTEL_EXPORTER_OTLP_ENDPOINT configuration a bit of a // hidden thing, most users will want to just send to Honeycomb // - honeyToken, err := sec.GetExternal(cmd.Context, secrets.ExternalSecret{ + honeyToken, err := sec.GetExternal(ctx, secrets.ExternalSecret{ Project: "sourcegraph-local-dev", Name: "SG_ANALYTICS_HONEYCOMB_TOKEN", }) @@ -44,7 +45,7 @@ var analyticsCommand = &cli.Command{ } pending := std.Out.Pending(output.Line(output.EmojiHourglass, output.StylePending, "Hang tight! We're submitting your analytics")) - if err := analytics.Submit(cmd.Context, honeyToken); err != nil { + if err := analytics.Submit(ctx, honeyToken); err != nil { pending.Destroy() return err } @@ -55,7 +56,7 @@ var analyticsCommand = &cli.Command{ { Name: "reset", Usage: "Delete all analytics stored locally", - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { if err := analytics.Reset(); err != nil { return err } @@ -72,7 +73,7 @@ var analyticsCommand = &cli.Command{ Usage: "view raw data", }, }, - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { spans, err := analytics.Load() if err != nil { std.Out.Writef("No analytics found: %s", err.Error()) diff --git a/dev/sg/sg_audit.go b/dev/sg/sg_audit.go index b0d4421e67cc..12e8023f2e96 100644 --- a/dev/sg/sg_audit.go +++ b/dev/sg/sg_audit.go @@ -12,7 +12,7 @@ import ( "github.com/google/go-github/v55/github" "github.com/slack-go/slack" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/oauth2" "github.com/sourcegraph/log" @@ -33,7 +33,7 @@ var auditCommand = &cli.Command{ ArgsUsage: "[target]", Hidden: true, Category: category.Company, - Subcommands: []*cli.Command{{ + Commands: []*cli.Command{{ Name: "pr", Usage: "Display audit trail for pull requests", Flags: []cli.Flag{ @@ -51,23 +51,23 @@ var auditCommand = &cli.Command{ Value: os.Getenv("GITHUB_TOKEN"), }, }, - Action: func(ctx *cli.Context) error { - ghc := github.NewClient(oauth2.NewClient(ctx.Context, oauth2.StaticTokenSource( + Action: func(ctx context.Context, cmd *cli.Command) error { + ghc := github.NewClient(oauth2.NewClient(ctx, oauth2.StaticTokenSource( &oauth2.Token{AccessToken: auditPRGitHubToken}, ))) logger := log.Scoped("auditPR") logger.Debug("fetching issues") - issues, err := fetchIssues(ctx.Context, logger, ghc) + issues, err := fetchIssues(ctx, logger, ghc) if err != nil { return err } - slack, err := sgslack.NewClient(ctx.Context, std.Out) + slack, err := sgslack.NewClient(ctx, std.Out) if err != nil { return err } logger.Debug("formatting results") - prAuditIssues, err := presentIssues(ctx.Context, ghc, slack, issues) + prAuditIssues, err := presentIssues(ctx, ghc, slack, issues) if err != nil { return err } diff --git a/dev/sg/sg_backport.go b/dev/sg/sg_backport.go index 93cd23fb9ef7..0a1cd50db8c6 100644 --- a/dev/sg/sg_backport.go +++ b/dev/sg/sg_backport.go @@ -1,8 +1,10 @@ package main import ( + "context" + "github.com/Masterminds/semver" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/backport" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" @@ -11,7 +13,7 @@ import ( "github.com/sourcegraph/sourcegraph/lib/output" ) -var pullRequestIDFlag = cli.Int64Flag{ +var pullRequestIDFlag = cli.IntFlag{ Name: "pullRequestID", Usage: "The pull request ID to backport into the release branch", Required: true, @@ -29,7 +31,7 @@ var backportCommand = &cli.Command{ Name: "backport", Category: category.Dev, Usage: "Backport commits from main to release branches.\nsg backport -r 5.3 -p 60932", - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { prNumber := pullRequestIDFlag.Get(cmd) releaseBranch := releaseBranchFlag.Get(cmd) @@ -43,7 +45,7 @@ var backportCommand = &cli.Command{ return errors.New("invalid release branch name") } std.Out.WriteLine(output.Styledf(output.StylePending, "Backporting commits from main to release branch %q for PR %d...", releaseBranch, prNumber)) - return backport.Run(cmd, prNumber, releaseBranch) + return backport.Run(ctx, cmd, prNumber, releaseBranch) }, Flags: []cli.Flag{&pullRequestIDFlag, &releaseBranchFlag}, } diff --git a/dev/sg/sg_bazel.go b/dev/sg/sg_bazel.go index 88d345b8207d..34cd88942c65 100644 --- a/dev/sg/sg_bazel.go +++ b/dev/sg/sg_bazel.go @@ -2,13 +2,14 @@ package main import ( "cmp" + "context" "fmt" "os" "os/exec" "slices" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/exp/maps" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" @@ -51,19 +52,19 @@ var bazelCommand = &cli.Command{ HideHelpCommand: true, Usage: "Proxies the bazel CLI with custom commands for local dev convenience", Category: category.Dev, - Action: func(ctx *cli.Context) error { - if slices.Equal(ctx.Args().Slice(), []string{"help"}) || slices.Equal(ctx.Args().Slice(), []string{"--help"}) || slices.Equal(ctx.Args().Slice(), []string{"-h"}) { + Action: func(ctx context.Context, cmd *cli.Command) error { + if slices.Equal(cmd.Args().Slice(), []string{"help"}) || slices.Equal(cmd.Args().Slice(), []string{"--help"}) || slices.Equal(cmd.Args().Slice(), []string{"-h"}) { fmt.Println("Additional commands from sg:") fmt.Println(" configure Wrappers around some commands to generate various files required by Bazel") } - cmd := exec.CommandContext(ctx.Context, "bazel", ctx.Args().Slice()...) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - cmd.Stdin = os.Stdin - return cmd.Run() + exe := exec.CommandContext(ctx, "bazel", cmd.Args().Slice()...) + exe.Stdout = os.Stdout + exe.Stderr = os.Stderr + exe.Stdin = os.Stdin + return exe.Run() }, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "configure", Usage: "Wrappers around some commands to generate various files required by Bazel", @@ -76,32 +77,32 @@ Available categories: - all: catch-all for all of the above If no categories are referenced, then 'builds' is assumed as the default.`, - BashComplete: completions.CompleteArgs(func() (options []string) { + ShellComplete: completions.CompleteArgs(func() (options []string) { return append(maps.Keys(bzlgenTargets), "all") }), - Before: func(ctx *cli.Context) error { - for _, arg := range ctx.Args().Slice() { + Before: func(ctx context.Context, cmd *cli.Command) error { + for _, arg := range cmd.Args().Slice() { if _, ok := bzlgenTargets[arg]; !ok && arg != "all" { cli.HandleExitCoder(errors.Errorf("category doesn't exist %q, run `sg bazel configure --help` for full info.", arg)) - cli.ShowSubcommandHelpAndExit(ctx, 1) + cli.ShowSubcommandHelpAndExit(cmd, 1) return nil } } return nil }, - Action: func(ctx *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { var categories []bzlgenTarget var categoryNames []string - if slices.Contains(ctx.Args().Slice(), "all") { + if slices.Contains(cmd.Args().Slice(), "all") { categories = maps.Values(bzlgenTargets) categoryNames = maps.Keys(bzlgenTargets) - } else if ctx.NArg() == 0 { + } else if cmd.NArg() == 0 { categories = []bzlgenTarget{bzlgenTargets["builds"]} categoryNames = []string{"builds"} } else { - for i := range ctx.NArg() { - categories = append(categories, bzlgenTargets[ctx.Args().Get(i)]) - categoryNames = append(categoryNames, ctx.Args().Get(i)) + for i := range cmd.NArg() { + categories = append(categories, bzlgenTargets[cmd.Args().Get(i)]) + categoryNames = append(categoryNames, cmd.Args().Get(i)) } } @@ -118,7 +119,7 @@ If no categories are referenced, then 'builds' is assumed as the default.`, } args := append([]string{c.cmd, "--noshow_progress"}, c.args...) - cmd := exec.CommandContext(ctx.Context, "bazel", args...) + cmd := exec.CommandContext(ctx, "bazel", args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Env = c.env diff --git a/dev/sg/sg_cloud.go b/dev/sg/sg_cloud.go index 778ee37a28d5..40b3e30fd01d 100644 --- a/dev/sg/sg_cloud.go +++ b/dev/sg/sg_cloud.go @@ -11,7 +11,7 @@ import ( "time" "github.com/sourcegraph/run" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" @@ -28,13 +28,13 @@ var cloudCommand = &cli.Command{ - Handbook: https://handbook.sourcegraph.com/departments/cloud/ `, Category: category.Company, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "install", Usage: "Install or upgrade local `mi2` CLI (for Cloud V2)", Description: "To learn more about Cloud V2, see https://handbook.sourcegraph.com/departments/cloud/technical-docs/v2.0/", - Action: func(c *cli.Context) error { - if err := installCloudCLI(c.Context); err != nil { + Action: func(ctx context.Context, cmd *cli.Command) error { + if err := installCloudCLI(ctx); err != nil { return err } if err := checkGKEAuthPlugin(); err != nil { diff --git a/dev/sg/sg_db.go b/dev/sg/sg_db.go index 6f31d4437d48..534a3332739e 100644 --- a/dev/sg/sg_db.go +++ b/dev/sg/sg_db.go @@ -12,7 +12,7 @@ import ( "github.com/gomodule/redigo/redis" "github.com/google/go-github/v55/github" "github.com/jackc/pgx/v4" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/oauth2" "github.com/sourcegraph/log" @@ -67,7 +67,7 @@ sg db add-user -username=foo sg db add-access-token -username=foo `, Category: category.Dev, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "delete-test-dbs", Usage: "Drops all databases that have the prefix `sourcegraph-test-`", @@ -184,8 +184,7 @@ sg db add-access-token -username=foo } ) -func dbAddUserAction(cmd *cli.Context) error { - ctx := cmd.Context +func dbAddUserAction(ctx context.Context, cmd *cli.Command) error { logger := log.Scoped("dbAddUserAction") // Read the configuration. @@ -239,8 +238,7 @@ func dbAddUserAction(cmd *cli.Context) error { }) } -func dbAddAccessTokenAction(cmd *cli.Context) error { - ctx := cmd.Context +func dbAddAccessTokenAction(ctx context.Context, cmd *cli.Command) error { logger := log.Scoped("dbAddAccessTokenAction") // Read the configuration. @@ -284,9 +282,8 @@ func dbAddAccessTokenAction(cmd *cli.Context) error { }) } -func dbUpdateUserExternalAccount(cmd *cli.Context) error { +func dbUpdateUserExternalAccount(ctx context.Context, cmd *cli.Command) error { logger := log.Scoped("dbUpdateUserExternalAccount") - ctx := cmd.Context username := cmd.String("sg.username") serviceName := cmd.String("extsvc.display-name") ghUsername := cmd.String("github.username") @@ -420,7 +417,7 @@ func githubClient(ctx context.Context, baseurl string, token string) (*github.Cl return gh, nil } -func dbResetRedisExec(ctx *cli.Context) error { +func dbResetRedisExec(ctx context.Context, cmd *cli.Command) error { // Read the configuration. config, _ := getConfig() if config == nil { @@ -443,7 +440,7 @@ func dbResetRedisExec(ctx *cli.Context) error { return nil } -func deleteTestDBsExec(ctx *cli.Context) error { +func deleteTestDBsExec(ctx context.Context, cmd *cli.Command) error { config, err := dbtest.GetDSN() if err != nil { return err @@ -462,13 +459,13 @@ func deleteTestDBsExec(ctx *cli.Context) error { } }() - names, err := basestore.ScanStrings(db.QueryContext(ctx.Context, `SELECT datname FROM pg_database WHERE datname LIKE 'sourcegraph-test-%'`)) + names, err := basestore.ScanStrings(db.QueryContext(ctx, `SELECT datname FROM pg_database WHERE datname LIKE 'sourcegraph-test-%'`)) if err != nil { return err } for _, name := range names { - _, err := db.ExecContext(ctx.Context, fmt.Sprintf(`DROP DATABASE %q`, name)) + _, err := db.ExecContext(ctx, fmt.Sprintf(`DROP DATABASE %q`, name)) if err != nil { return err } @@ -480,7 +477,7 @@ func deleteTestDBsExec(ctx *cli.Context) error { return nil } -func dbResetPGExec(ctx *cli.Context) error { +func dbResetPGExec(ctx context.Context, cmd *cli.Command) error { // Read the configuration. config, _ := getConfig() if config == nil { @@ -518,18 +515,18 @@ func dbResetPGExec(ctx *cli.Context) error { err error ) - db, err = pgx.Connect(ctx.Context, dsn) + db, err = pgx.Connect(ctx, dsn) if err != nil { return errors.Wrap(err, "failed to connect to Postgres database") } - _, err = db.Exec(ctx.Context, "DROP SCHEMA public CASCADE; CREATE SCHEMA public;") + _, err = db.Exec(ctx, "DROP SCHEMA public CASCADE; CREATE SCHEMA public;") if err != nil { std.Out.WriteFailuref("Failed to drop schema 'public': %s", err) return err } - if err := db.Close(ctx.Context); err != nil { + if err := db.Close(ctx); err != nil { return err } } @@ -550,7 +547,7 @@ func dbResetPGExec(ctx *cli.Context) error { }) } - if err := r.Run(ctx.Context, runner.Options{ + if err := r.Run(ctx, runner.Options{ Operations: operations, }); err != nil { return err diff --git a/dev/sg/sg_deploy.go b/dev/sg/sg_deploy.go index cab8e98b0e04..6cb421374c16 100644 --- a/dev/sg/sg_deploy.go +++ b/dev/sg/sg_deploy.go @@ -1,12 +1,13 @@ package main import ( + "context" "fmt" "os" "path" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "gopkg.in/yaml.v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" @@ -67,14 +68,14 @@ dns: dave-app.sgdev.org Destination: &infraRepo, }, }, - Before: func(c *cli.Context) error { + Before: func(ctx context.Context, cmd *cli.Command) error { if dryRun && infraRepo != "" { return errors.New("cannot specify both --infra-repo and --dry-run") } return nil }, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { err := generateConfig(valuesFile, dryRun, infraRepo) if err != nil { return errors.Wrap(err, "generate manifest") diff --git a/dev/sg/sg_doctor.go b/dev/sg/sg_doctor.go index a925b37c62d4..08d0de3faede 100644 --- a/dev/sg/sg_doctor.go +++ b/dev/sg/sg_doctor.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/text/cases" "golang.org/x/text/language" "gopkg.in/yaml.v3" @@ -66,7 +66,7 @@ func (r DiagnosticReport) Add(group string, result *DiagnosticResult) { } } -func runDoctorDiagnostics(cmd *cli.Context) error { +func runDoctorDiagnostics(ctx context.Context, cmd *cli.Command) error { diagnostics, err := readDiagnosticDefinitions(doctorYaml) if err != nil { return errors.Newf("failed to load diagnostics from embedded yaml:", err) @@ -81,7 +81,7 @@ func runDoctorDiagnostics(cmd *cli.Context) error { } diagOut.WriteLine(output.Emoji("🥼", "Gathering diagnostics")) - report := runner.Run(cmd.Context) + report := runner.Run(ctx) diagOut.WriteLine(output.Emoji("💉", "Gathering of diagnostics complete!")) markdown := buildMarkdownReport(report) diff --git a/dev/sg/sg_embeddings_qa.go b/dev/sg/sg_embeddings_qa.go index d3473430b245..91a8e9484b50 100644 --- a/dev/sg/sg_embeddings_qa.go +++ b/dev/sg/sg_embeddings_qa.go @@ -1,7 +1,9 @@ package main import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/cmd/embeddings/qa" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" @@ -21,8 +23,8 @@ var contextCommand = &cli.Command{ Usage: "Run the evaluation against this endpoint", }, }, - Action: func(ctx *cli.Context) error { - url := ctx.String("url") + Action: func(ctx context.Context, cmd *cli.Command) error { + url := cmd.String("url") if url == "" { return errors.New("url is empty") } diff --git a/dev/sg/sg_generate.go b/dev/sg/sg_generate.go index d22bf5acace2..970bdeca2246 100644 --- a/dev/sg/sg_generate.go +++ b/dev/sg/sg_generate.go @@ -7,7 +7,7 @@ import ( "os" "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/generate" @@ -40,7 +40,7 @@ sg --verbose generate ... # Enable verbose output Destination: &generateQuiet, }, }, - Before: func(cmd *cli.Context) error { + Before: func(ctx context.Context, cmd *cli.Command) error { if verbose && generateQuiet { return errors.Errorf("-q and --verbose flags are exclusive") } @@ -58,14 +58,14 @@ sg --verbose generate ... # Enable verbose output } return nil }, - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { if cmd.NArg() > 0 { std.Out.WriteFailuref("unrecognized command %q provided", cmd.Args().First()) return flag.ErrHelp } - return allGenerateTargets.RunAll(cmd.Context) + return allGenerateTargets.RunAll(ctx) }, - Subcommands: allGenerateTargets.Commands(), + Commands: allGenerateTargets.Commands(), } func runGenerateAndReport(ctx context.Context, t generate.Target, args []string) error { @@ -94,12 +94,12 @@ func (gt generateTargets) RunAll(ctx context.Context) error { // Commands converts all lint targets to CLI commands func (gt generateTargets) Commands() (cmds []*cli.Command) { actionFactory := func(c generate.Target) cli.ActionFunc { - return func(cmd *cli.Context) error { + return func(ctx context.Context, cmd *cli.Command) error { _, err := root.RepositoryRoot() if err != nil { return err } - report := c.Runner(cmd.Context, cmd.Args().Slice()) + report := c.Runner(ctx, cmd.Args().Slice()) if report.Err != nil { return report.Err } @@ -112,15 +112,15 @@ func (gt generateTargets) Commands() (cmds []*cli.Command) { } } for _, c := range gt { - var complete cli.BashCompleteFunc + var complete cli.ShellCompleteFunc if c.Completer != nil { complete = completions.CompleteArgs(c.Completer) } cmds = append(cmds, &cli.Command{ - Name: c.Name, - Usage: c.Help, - Action: actionFactory(c), - BashComplete: complete, + Name: c.Name, + Usage: c.Help, + Action: actionFactory(c), + ShellComplete: complete, }) } return cmds diff --git a/dev/sg/sg_help.go b/dev/sg/sg_help.go index 09f4ccb9f813..3d954053bbf8 100644 --- a/dev/sg/sg_help.go +++ b/dev/sg/sg_help.go @@ -1,10 +1,11 @@ package main import ( + "context" "os" "path/filepath" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" @@ -33,7 +34,7 @@ var helpCommand = &cli.Command{ Usage: "write reference to `file`", }, }, - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { if cmd.NArg() != 0 { return errors.Newf("unexpected argument %s", cmd.Args().First()) } @@ -45,9 +46,9 @@ var helpCommand = &cli.Command{ var doc string var err error if cmd.Bool("full") { - doc, err = docgen.Markdown(cmd.App) + doc, err = docgen.Markdown(cmd) } else { - doc, err = docgen.Default(cmd.App) + doc, err = docgen.Default(cmd) } if err != nil { return err diff --git a/dev/sg/sg_insights.go b/dev/sg/sg_insights.go index f395ca904ff8..edd37a1dc52e 100644 --- a/dev/sg/sg_insights.go +++ b/dev/sg/sg_insights.go @@ -1,11 +1,12 @@ package main import ( + "context" "encoding/base64" "strings" "github.com/keegancsmith/sqlf" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/log" @@ -23,7 +24,7 @@ var insightsCommand = &cli.Command{ Name: "insights", Usage: "Tools to interact with Code Insights data", Category: category.Dev, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "decode-id", Usage: "Decodes an encoded insight ID found on the frontend into a view unique_id", @@ -39,7 +40,7 @@ var insightsCommand = &cli.Command{ }, } -func decodeInsightIDAction(cmd *cli.Context) error { +func decodeInsightIDAction(ctx context.Context, cmd *cli.Command) error { ids := cmd.Args().Slice() if len(ids) == 0 { return errors.New("expected at least 1 id to decode") @@ -55,14 +56,13 @@ func decodeInsightIDAction(cmd *cli.Context) error { return nil } -func getInsightSeriesIDsAction(cmd *cli.Context) error { +func getInsightSeriesIDsAction(ctx context.Context, cmd *cli.Command) error { ids := cmd.Args().Slice() if len(ids) != 1 { return errors.New("expected 1 id to decode") } std.Out.WriteNoticef("Finding the Series IDs for %s", ids[0]) - ctx := cmd.Context logger := log.Scoped("getInsightSeriesIDsAction") // Read the configuration. diff --git a/dev/sg/sg_install.go b/dev/sg/sg_install.go index c0461139feec..cd1202915beb 100644 --- a/dev/sg/sg_install.go +++ b/dev/sg/sg_install.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "context" "fmt" "io" "os" @@ -10,7 +11,7 @@ import ( "runtime" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" @@ -45,9 +46,7 @@ Can also be used to install a custom build of 'sg' globally, for example: Action: installAction, } -func installAction(cmd *cli.Context) error { - ctx := cmd.Context - +func installAction(ctx context.Context, cmd *cli.Command) error { probeCmdOut, err := exec.CommandContext(ctx, "sg", "help").CombinedOutput() if err == nil && outputLooksLikeSG(string(probeCmdOut)) { path, err := exec.LookPath("sg") diff --git a/dev/sg/sg_lint.go b/dev/sg/sg_lint.go index 312b1f726c8e..800d49997253 100644 --- a/dev/sg/sg_lint.go +++ b/dev/sg/sg_lint.go @@ -1,10 +1,11 @@ package main import ( + "context" "flag" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/repo" @@ -67,15 +68,15 @@ sg lint --help lintFailFast, lintSkipFormatCheck, }, - Before: func(cmd *cli.Context) error { + Before: func(ctx context.Context, cmd *cli.Command) error { // If more than 1 target is requested, hijack subcommands by setting it to nil // so that the main lint command can handle it the run. if cmd.Args().Len() > 1 { - cmd.Command.Subcommands = nil + cmd.Commands = nil } return nil }, - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { var lintTargets []linters.Target targets := cmd.Args().Slice() @@ -118,7 +119,7 @@ sg lint --help } } - repoState, err := repo.GetState(cmd.Context) + repoState, err := repo.GetState(ctx) if err != nil { return errors.Wrap(err, "repo.GetState") } @@ -126,13 +127,13 @@ sg lint --help runner := linters.NewRunner(std.Out, generateAnnotations.Get(cmd), lintTargets...) if cmd.Bool("fix") { std.Out.WriteNoticef("Fixing checks from targets: %s", strings.Join(targets, ", ")) - return runner.Fix(cmd.Context, repoState) + return runner.Fix(ctx, repoState) } runner.FailFast = lintFailFast.Get(cmd) std.Out.WriteNoticef("Running checks from targets: %s", strings.Join(targets, ", ")) - return runner.Check(cmd.Context, repoState) + return runner.Check(ctx, repoState) }, - Subcommands: lintTargets(append(linters.Targets, linters.Formatting)).Commands(), + Commands: lintTargets(append(linters.Targets, linters.Formatting)).Commands(), } type lintTargets []linters.Target @@ -144,13 +145,13 @@ func (lt lintTargets) Commands() (cmds []*cli.Command) { cmds = append(cmds, &cli.Command{ Name: target.Name, Usage: target.Description, - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { if cmd.NArg() > 0 { std.Out.WriteFailuref("unrecognized argument %q provided", cmd.Args().First()) return flag.ErrHelp } - repoState, err := repo.GetState(cmd.Context) + repoState, err := repo.GetState(ctx) if err != nil { return errors.Wrap(err, "repo.GetState") } @@ -167,14 +168,14 @@ func (lt lintTargets) Commands() (cmds []*cli.Command) { runner := linters.NewRunner(std.Out, generateAnnotations.Get(cmd), lintTargets...) if lintFix.Get(cmd) { std.Out.WriteNoticef("Fixing checks from target: %s", strings.Join(targets, ", ")) - return runner.Fix(cmd.Context, repoState) + return runner.Fix(ctx, repoState) } runner.FailFast = lintFailFast.Get(cmd) std.Out.WriteNoticef("Running checks from target: %s", strings.Join(targets, ", ")) - return runner.Check(cmd.Context, repoState) + return runner.Check(ctx, repoState) }, // Completions to chain multiple commands - BashComplete: completions.CompleteArgs(func() (options []string) { + ShellComplete: completions.CompleteArgs(func() (options []string) { for _, c := range lt { options = append(options, c.Name) } diff --git a/dev/sg/sg_live.go b/dev/sg/sg_live.go index bfac5a5d9b9c..e57a73fcd9b2 100644 --- a/dev/sg/sg_live.go +++ b/dev/sg/sg_live.go @@ -1,11 +1,12 @@ package main import ( + "context" "fmt" "net/url" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" @@ -45,7 +46,7 @@ sg live -n 50 s2 Usage: "Number of commits to check for live version", }, }, - BashComplete: completions.CompleteArgs(func() (options []string) { + ShellComplete: completions.CompleteArgs(func() (options []string) { return append(environmentNames(), `https\://...`) }), } @@ -68,8 +69,8 @@ func constructLiveCmdLongHelp() string { return out.String() } -func liveExec(ctx *cli.Context) error { - args := ctx.Args().Slice() +func liveExec(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() if len(args) == 0 { std.Out.WriteLine(output.Styled(output.StyleWarning, "ERROR: No environment specified")) return exit.NewEmptyExitErr(1) @@ -89,5 +90,5 @@ func liveExec(ctx *cli.Context) error { } } - return printDeployedVersion(e, ctx.Int("commits")) + return printDeployedVersion(e, int(cmd.Int("commits"))) } diff --git a/dev/sg/sg_logo.go b/dev/sg/sg_logo.go index d4fb921ca7d7..38703e5d4c7c 100644 --- a/dev/sg/sg_logo.go +++ b/dev/sg/sg_logo.go @@ -2,12 +2,13 @@ package main import ( "bytes" + "context" "fmt" "io" "math/rand" "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" @@ -69,8 +70,8 @@ func printLogo(out io.Writer) { fmt.Fprintf(out, "%s", output.StyleReset) } -func logoExec(ctx *cli.Context) error { - args := ctx.Args().Slice() +func logoExec(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() if len(args) == 1 && args[0] == "classic" { var logoOut bytes.Buffer printLogo(&logoOut) diff --git a/dev/sg/sg_migration.go b/dev/sg/sg_migration.go index b0475b74dc78..8f5cf81c55e7 100644 --- a/dev/sg/sg_migration.go +++ b/dev/sg/sg_migration.go @@ -8,7 +8,7 @@ import ( "os" "github.com/Masterminds/semver" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/run" @@ -39,7 +39,7 @@ var ( Value: db.DefaultDatabase.Name, Destination: &migrateTargetDatabase, Aliases: []string{"db"}, - Action: func(ctx *cli.Context, val string) error { + Action: func(ctx context.Context, cmd *cli.Command, val string) error { migrateTargetDatabase = cliutil.TranslateSchemaNames(val, std.Out.Output) return nil }, @@ -191,7 +191,7 @@ sg migration add --db codeintel 'add missing index' sg migration squash `, Category: category.Dev, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ addCommand, revertCommand, upCommand, @@ -319,8 +319,8 @@ func resolveSchema(name string) (*schemas.Schema, error) { return schema, nil } -func addExec(ctx *cli.Context) error { - args := ctx.Args().Slice() +func addExec(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() if len(args) == 0 { return cli.Exit("no migration name specified", 1) } @@ -339,8 +339,8 @@ func addExec(ctx *cli.Context) error { return migration.Add(database, args[0]) } -func revertExec(ctx *cli.Context) error { - args := ctx.Args().Slice() +func revertExec(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() if len(args) == 0 { return cli.Exit("no commit specified", 1) } @@ -351,8 +351,8 @@ func revertExec(ctx *cli.Context) error { return migration.Revert(db.Databases(), args[0]) } -func squashExec(ctx *cli.Context) (err error) { - args := ctx.Args().Slice() +func squashExec(ctx context.Context, cmd *cli.Command) (err error) { + args := cmd.Args().Slice() if len(args) == 0 { return cli.Exit("no current-version specified", 1) } @@ -378,8 +378,8 @@ func squashExec(ctx *cli.Context) (err error) { return migration.Squash(database, commit, squashInContainer || squashInTimescaleDBContainer, squashInTimescaleDBContainer, skipTeardown, skipSquashData) } -func visualizeExec(ctx *cli.Context) (err error) { - args := ctx.Args().Slice() +func visualizeExec(ctx context.Context, cmd *cli.Command) (err error) { + args := cmd.Args().Slice() if len(args) != 0 { return cli.Exit("too many arguments", 1) } @@ -400,8 +400,8 @@ func visualizeExec(ctx *cli.Context) (err error) { return migration.Visualize(database, outputFilepath) } -func rewriteExec(ctx *cli.Context) (err error) { - args := ctx.Args().Slice() +func rewriteExec(ctx context.Context, cmd *cli.Command) (err error) { + args := cmd.Args().Slice() if len(args) != 0 { return cli.Exit("too many arguments", 1) } @@ -422,8 +422,8 @@ func rewriteExec(ctx *cli.Context) (err error) { return migration.Rewrite(database, targetRevision) } -func squashAllExec(ctx *cli.Context) (err error) { - args := ctx.Args().Slice() +func squashAllExec(ctx context.Context, cmd *cli.Command) (err error) { + args := cmd.Args().Slice() if len(args) != 0 { return cli.Exit("too many arguments", 1) } @@ -444,8 +444,8 @@ func squashAllExec(ctx *cli.Context) (err error) { return migration.SquashAll(database, squashInContainer || squashInTimescaleDBContainer, squashInTimescaleDBContainer, skipTeardown, skipSquashData, outputFilepath) } -func leavesExec(ctx *cli.Context) (err error) { - args := ctx.Args().Slice() +func leavesExec(ctx context.Context, cmd *cli.Command) (err error) { + args := cmd.Args().Slice() if len(args) == 0 { return cli.Exit("no commit specified", 1) } diff --git a/dev/sg/sg_monitoring.go b/dev/sg/sg_monitoring.go index d588e4983074..83c01d3f2aa9 100644 --- a/dev/sg/sg_monitoring.go +++ b/dev/sg/sg_monitoring.go @@ -1,11 +1,12 @@ package main import ( + "context" "fmt" "strings" "github.com/grafana/regexp" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" @@ -27,7 +28,7 @@ Also refer to the generated reference documentation available for site admins: - https://docs.sourcegraph.com/admin/observability/alerts `, Category: category.Dev, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ monitoringcmd.Generate("sg monitoring", func() string { root, _ := root.RepositoryRoot() return root @@ -46,14 +47,14 @@ Also refer to the generated reference documentation available for site admins: Usage: "Show row groups", }, }, - Action: func(c *cli.Context) error { - dashboards, err := dashboardsFromArgs(c.Args()) + Action: func(ctx context.Context, cmd *cli.Command) error { + dashboards, err := dashboardsFromArgs(cmd.Args()) if err != nil { return err } metrics := make(map[*monitoring.Dashboard][]string) - if c.Bool("metrics") { + if cmd.Bool("metrics") { var err error metrics, err = monitoring.ListMetrics(dashboards...) if err != nil { @@ -66,14 +67,14 @@ Also refer to the generated reference documentation available for site admins: summary.WriteString(fmt.Sprintf("* **%s** (`%s`): %s\n", d.Title, d.Name, d.Description)) - if c.Bool("metrics") { + if cmd.Bool("metrics") { summary.WriteString(" * Metrics used:\n") for _, m := range metrics[d] { summary.WriteString(fmt.Sprintf(" * `%s`\n", m)) } } - if c.Bool("groups") { + if cmd.Bool("groups") { for _, g := range d.Groups { summary.WriteString(fmt.Sprintf(" * %s (%d rows)\n", g.Title, len(g.Rows))) @@ -96,8 +97,8 @@ Also refer to the generated reference documentation available for site admins: Value: "markdown", }, }, - Action: func(c *cli.Context) error { - dashboards, err := dashboardsFromArgs(c.Args()) + Action: func(ctx context.Context, cmd *cli.Command) error { + dashboards, err := dashboardsFromArgs(cmd.Args()) if err != nil { return err } @@ -118,7 +119,7 @@ Also refer to the generated reference documentation available for site admins: } } - switch format := c.String("format"); format { + switch format := cmd.String("format"); format { case "markdown": var md strings.Builder for _, m := range uniqueMetrics { diff --git a/dev/sg/sg_ops.go b/dev/sg/sg_ops.go index b3763a8a2597..c18cfceeefc4 100644 --- a/dev/sg/sg_ops.go +++ b/dev/sg/sg_ops.go @@ -7,7 +7,7 @@ import ( "strconv" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/images" @@ -21,7 +21,7 @@ var opsCommand = &cli.Command{ Usage: "Commands used by operations teams to perform common tasks", Description: "Supports internal deploy-sourcegraph repos (non-customer facing)", Category: category.Company, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ opsTagDetailsCommand, OpsUpdateImagesCommand, }, @@ -72,9 +72,9 @@ var OpsUpdateImagesCommand = &cli.Command{ Usage: "List of comma separated images to update, ex: --only 'gitserver,indexed-server'. If not specified, all images will be updated. Cannot be combined with --skip", }, }, - Action: func(ctx *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { // Ensure args are correct. - args := ctx.Args().Slice() + args := cmd.Args().Slice() if len(args) == 0 { std.Out.WriteLine(output.Styled(output.StyleWarning, "No path provided")) return flag.ErrHelp @@ -85,11 +85,11 @@ var OpsUpdateImagesCommand = &cli.Command{ } var skip, only []string - if s := ctx.String("skip"); s != "" { - skip = strings.Split(ctx.String("skip"), ",") + if s := cmd.String("skip"); s != "" { + skip = strings.Split(cmd.String("skip"), ",") } - if s := ctx.String("only"); s != "" { - only = strings.Split(ctx.String("only"), ",") + if s := cmd.String("only"); s != "" { + only = strings.Split(cmd.String("only"), ",") } if len(skip) != 0 && len(only) != 0 { @@ -98,13 +98,13 @@ var OpsUpdateImagesCommand = &cli.Command{ } return opsUpdateImages( - ctx.Context, + ctx, args[0], - ctx.String("registry"), - ctx.String("kind"), - ctx.String("pin-tag"), - ctx.String("docker-username"), - ctx.String("docker-password"), + cmd.String("registry"), + cmd.String("kind"), + cmd.String("pin-tag"), + cmd.String("docker-username"), + cmd.String("docker-password"), skip, only, ) @@ -132,7 +132,7 @@ sg ops inspect-tag -p build 159625_2022-07-11_225c8ae162cc Usage: "only output a specific `property` (one of: 'build', 'date', 'commit')", }, }, - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { input := cmd.Args().First() // trim out leading image parts := strings.SplitN(input, ":", 2) diff --git a/dev/sg/sg_page.go b/dev/sg/sg_page.go index e108ce04600b..1a721b5c112f 100644 --- a/dev/sg/sg_page.go +++ b/dev/sg/sg_page.go @@ -1,7 +1,9 @@ package main import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "github.com/sourcegraph/log" @@ -25,7 +27,7 @@ var pageCommand = &cli.Command{ Name: "opsgenie.token", Usage: "OpsGenie token", Required: true, - EnvVars: []string{"SG_OPSGENIE_TOKEN"}, + Sources: cli.EnvVars("SG_OPSGENIE_TOKEN"), }, &cli.StringFlag{ Name: "message", @@ -55,7 +57,7 @@ var pageCommand = &cli.Command{ }, } -func pageExec(cmd *cli.Context) error { +func pageExec(ctx context.Context, cmd *cli.Command) error { logger := log.Scoped("pager") priority, err := parseOpsGeniePriority(cmd.String("priority")) @@ -102,7 +104,7 @@ func pageExec(cmd *cli.Context) error { req.Responders = append(req.Responders, opsgeniealert.Responder{Type: opsgeniealert.EscalationResponder, Name: schedule}) } - createResult, err := alertClient.Create(cmd.Context, req) + createResult, err := alertClient.Create(ctx, req) if err != nil { if createResult != nil { logger.Error("got error result from posting alert to opsgenie", log.Error(err), log.String("result", createResult.Result)) diff --git a/dev/sg/sg_rfc.go b/dev/sg/sg_rfc.go index cb16fb677bf5..f769a91073d9 100644 --- a/dev/sg/sg_rfc.go +++ b/dev/sg/sg_rfc.go @@ -1,10 +1,11 @@ package main import ( + "context" "fmt" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/rfc" @@ -55,47 +56,47 @@ sg rfc --private create --type "title" Value: false, }, }, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "list", ArgsUsage: " ", Usage: "List Sourcegraph RFCs", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { driveSpec := rfc.PublicDrive - if c.Bool("private") { + if cmd.Bool("private") { driveSpec = rfc.PrivateDrive } - return rfc.List(c.Context, driveSpec, std.Out) + return rfc.List(ctx, driveSpec, std.Out) }, }, { Name: "search", ArgsUsage: "[query]", Usage: "Search Sourcegraph RFCs", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { driveSpec := rfc.PublicDrive - if c.Bool("private") { + if cmd.Bool("private") { driveSpec = rfc.PrivateDrive } - if c.Args().Len() == 0 { + if cmd.Args().Len() == 0 { return errors.New("no search query given") } - return rfc.Search(c.Context, strings.Join(c.Args().Slice(), " "), driveSpec, std.Out) + return rfc.Search(ctx, strings.Join(cmd.Args().Slice(), " "), driveSpec, std.Out) }, }, { Name: "open", ArgsUsage: "[number]", Usage: "Open a Sourcegraph RFC - find and list RFC numbers with 'sg rfc list' or 'sg rfc search'", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { driveSpec := rfc.PublicDrive - if c.Bool("private") { + if cmd.Bool("private") { driveSpec = rfc.PrivateDrive } - if c.Args().Len() == 0 { + if cmd.Args().Len() == 0 { return errors.New("no RFC given") } - return rfc.Open(c.Context, c.Args().First(), driveSpec, std.Out) + return rfc.Open(ctx, cmd.Args().First(), driveSpec, std.Out) }, }, { @@ -109,13 +110,13 @@ sg rfc --private create --type "title" }, }, Usage: "Create Sourcegraph RFCs", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { driveSpec := rfc.PublicDrive - if c.Bool("private") { + if cmd.Bool("private") { driveSpec = rfc.PrivateDrive } - rfcType := c.String("type") + rfcType := cmd.String("type") var template rfc.Template // Search for the rfcType and assign it to template @@ -129,10 +130,10 @@ sg rfc --private create --type "title" return errors.New(fmt.Sprintf("Unknown RFC type: %s", rfcType)) } - if c.Args().Len() == 0 { + if cmd.Args().Len() == 0 { return errors.New("no title given") } - return rfc.Create(c.Context, template, strings.Join(c.Args().Slice(), " "), + return rfc.Create(ctx, template, strings.Join(cmd.Args().Slice(), " "), driveSpec, std.Out) }, }, diff --git a/dev/sg/sg_run.go b/dev/sg/sg_run.go index 6aac3abce65d..49b0dcf8b010 100644 --- a/dev/sg/sg_run.go +++ b/dev/sg/sg_run.go @@ -7,7 +7,7 @@ import ( "sort" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "gopkg.in/yaml.v3" "github.com/sourcegraph/conc/pool" @@ -22,16 +22,15 @@ import ( func init() { postInitHooks = append(postInitHooks, - func(cmd *cli.Context) { + func(ctx context.Context, cmd *cli.Command) { // Create 'sg run' help text after flag (and config) initialization runCommand.Description = constructRunCmdLongHelp() }, - func(cmd *cli.Context) { - ctx, cancel := context.WithCancel(cmd.Context) + func(ctx context.Context, cmd *cli.Command) { + _, cancel := context.WithCancel(ctx) interrupt.Register(func() { cancel() }) - cmd.Context = ctx }, ) @@ -67,7 +66,7 @@ sg run -describe jaeger }, }, Action: runExec, - BashComplete: completions.CompleteArgs(func() (options []string) { + ShellComplete: completions.CompleteArgs(func() (options []string) { config, _ := getConfig() if config == nil { return @@ -79,14 +78,14 @@ sg run -describe jaeger }), } -func runExec(ctx *cli.Context) error { +func runExec(ctx context.Context, cmd *cli.Command) error { config, err := getConfig() if err != nil { return err } - legacy := ctx.Bool("legacy") + legacy := cmd.Bool("legacy") - args := ctx.Args().Slice() + args := cmd.Args().Slice() if len(args) == 0 { std.Out.WriteLine(output.Styled(output.StyleWarning, "No command specified")) return flag.ErrHelp @@ -104,7 +103,7 @@ func runExec(ctx *cli.Context) error { } } - if ctx.Bool("describe") { + if cmd.Bool("describe") { for _, cmd := range cmds { out, err := yaml.Marshal(cmd) if err != nil { @@ -118,7 +117,7 @@ func runExec(ctx *cli.Context) error { return nil } - p := pool.New().WithContext(ctx.Context).WithCancelOnError() + p := pool.New().WithContext(ctx).WithCancelOnError() p.Go(func(ctx context.Context) error { return run.Commands(ctx, config.Env, verbose, cmds...) }) diff --git a/dev/sg/sg_secret.go b/dev/sg/sg_secret.go index 85948c74a1ec..56ed9768b9b6 100644 --- a/dev/sg/sg_secret.go +++ b/dev/sg/sg_secret.go @@ -1,10 +1,11 @@ package main import ( + "context" "encoding/json" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/secrets" @@ -29,13 +30,13 @@ sg secret list sg secret reset buildkite `, Category: category.Env, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { - Name: "reset", - ArgsUsage: "<...key>", - Usage: "Remove a specific secret from secrets file", - Action: resetSecretExec, - BashComplete: completions.CompleteArgs(bashCompleteSecrets), + Name: "reset", + ArgsUsage: "<...key>", + Usage: "Remove a specific secret from secrets file", + Action: resetSecretExec, + ShellComplete: completions.CompleteArgs(bashCompleteSecrets), }, { Name: "list", @@ -55,13 +56,13 @@ sg secret reset buildkite } ) -func resetSecretExec(ctx *cli.Context) error { - args := ctx.Args().Slice() +func resetSecretExec(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() if len(args) == 0 { return errors.New("no key provided to reset") } - secretsStore, err := secrets.FromContext(ctx.Context) + secretsStore, err := secrets.FromContext(ctx) if err != nil { return err } @@ -79,8 +80,8 @@ func resetSecretExec(ctx *cli.Context) error { return nil } -func listSecretExec(ctx *cli.Context) error { - secretsStore, err := secrets.FromContext(ctx.Context) +func listSecretExec(ctx context.Context, cmd *cli.Command) error { + secretsStore, err := secrets.FromContext(ctx) if err != nil { return err } diff --git a/dev/sg/sg_setup.go b/dev/sg/sg_setup.go index 1e477b8b86ee..94626019c28a 100644 --- a/dev/sg/sg_setup.go +++ b/dev/sg/sg_setup.go @@ -1,13 +1,15 @@ package main import ( + "context" "fmt" "os" "runtime" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/run" + "github.com/sourcegraph/sourcegraph/dev/sg/dependencies" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" @@ -36,14 +38,14 @@ var setupCommand = &cli.Command{ Usage: "Skip overwriting pre-commit.com installation", }, }, - Subcommands: []*cli.Command{{ + Commands: []*cli.Command{{ Name: "disable-pre-commit", Usage: "Disable pre-commit hooks", - Action: func(cmd *cli.Context) error { - return root.Run(run.Bash(cmd.Context, "rm .git/hooks/pre-commit || echo \"no pre-commit hook was found.\"")).Stream(os.Stdout) + Action: func(ctx context.Context, cmd *cli.Command) error { + return root.Run(run.Bash(ctx, "rm .git/hooks/pre-commit || echo \"no pre-commit hook was found.\"")).Stream(os.Stdout) }, }}, - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { if runtime.GOOS != "linux" && runtime.GOOS != "darwin" { std.Out.WriteLine(output.Styled(output.StyleWarning, "'sg setup' currently only supports macOS and Linux")) return exit.NewEmptyExitErr(1) @@ -54,7 +56,7 @@ var setupCommand = &cli.Command{ currentOS = overridesOS } - setup := dependencies.Setup(cmd.App.Reader, std.Out, dependencies.OS(currentOS)) + setup := dependencies.Setup(cmd.Reader, std.Out, dependencies.OS(currentOS)) setup.AnalyticsCategory = "setup" setup.RenderDescription = func(out *std.Output) { printSgSetupWelcomeScreen(out) @@ -71,17 +73,17 @@ var setupCommand = &cli.Command{ switch { case cmd.Bool("check"): - err := setup.Check(cmd.Context, args) + err := setup.Check(ctx, args) if err != nil { std.Out.WriteSuggestionf("Run 'sg setup -fix' to try and automatically fix issues!") } return err case cmd.Bool("fix"): - return setup.Fix(cmd.Context, args) + return setup.Fix(ctx, args) default: - return setup.Interactive(cmd.Context, args) + return setup.Interactive(ctx, args) } }, } diff --git a/dev/sg/sg_src.go b/dev/sg/sg_src.go index 82a5ad3ac75a..1929b2d3a3ef 100644 --- a/dev/sg/sg_src.go +++ b/dev/sg/sg_src.go @@ -6,7 +6,7 @@ import ( "os" "os/exec" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/secrets" @@ -30,13 +30,13 @@ var srcInstanceCommand = &cli.Command{ UsageText: "sg src-instance [command]", Usage: "Interact with Sourcegraph instances that 'sg src' will use", Category: category.Dev, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "register", Usage: "Register (or edit an existing) Sourcegraph instance to target with src-cli", UsageText: "sg src instance register [name] [endpoint]", - Action: func(cmd *cli.Context) error { - store, sc, err := getSrcInstances(cmd.Context) + Action: func(ctx context.Context, cmd *cli.Command) error { + store, sc, err := getSrcInstances(ctx) if err != nil { return errors.Wrap(err, "failed to read existing instances") } @@ -79,8 +79,8 @@ var srcInstanceCommand = &cli.Command{ { Name: "use", Usage: "Set current src-cli instance to use with 'sg src'", - Action: func(cmd *cli.Context) error { - store, sc, err := getSrcInstances(cmd.Context) + Action: func(ctx context.Context, cmd *cli.Command) error { + store, sc, err := getSrcInstances(ctx) if err != nil { return err } @@ -101,8 +101,8 @@ var srcInstanceCommand = &cli.Command{ { Name: "list", Usage: "List registered instances for src-cli", - Action: func(cmd *cli.Context) error { - _, sc, err := getSrcInstances(cmd.Context) + Action: func(ctx context.Context, cmd *cli.Command) error { + _, sc, err := getSrcInstances(ctx) if err != nil { return err } @@ -125,8 +125,8 @@ var srcCommand = &cli.Command{ UsageText: "sg src [src-cli args]\nsg src help # get src-cli help", Usage: "Run src-cli on a given instance defined with 'sg src-instance'", Category: category.Dev, - Action: func(cmd *cli.Context) error { - _, sc, err := getSrcInstances(cmd.Context) + Action: func(ctx context.Context, cmd *cli.Command) error { + _, sc, err := getSrcInstances(ctx) if err != nil { return err } @@ -141,7 +141,7 @@ var srcCommand = &cli.Command{ return errors.New("instance not found") } - c := exec.CommandContext(cmd.Context, "src", cmd.Args().Slice()...) + c := exec.CommandContext(ctx, "src", cmd.Args().Slice()...) c.Env = append(c.Environ(), "SRC_ACCESS_TOKEN="+instance.AccessToken, "SRC_ENDPOINT="+instance.Endpoint) c.Stdout = os.Stdout c.Stderr = os.Stderr diff --git a/dev/sg/sg_start.go b/dev/sg/sg_start.go index 0bb5b2421524..908aa84cf1ab 100644 --- a/dev/sg/sg_start.go +++ b/dev/sg/sg_start.go @@ -13,7 +13,7 @@ import ( "time" sgrun "github.com/sourcegraph/run" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "gopkg.in/yaml.v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" @@ -30,18 +30,17 @@ import ( func init() { postInitHooks = append(postInitHooks, - func(cmd *cli.Context) { + func(ctx context.Context, cmd *cli.Command) { // Create 'sg start' help text after flag (and config) initialization startCommand.Description = constructStartCmdLongHelp() }, - func(cmd *cli.Context) { - ctx, cancel := context.WithCancel(cmd.Context) + func(ctx context.Context, cmd *cli.Command) { + _, cancel := context.WithCancel(ctx) interrupt.Register(func() { cancel() // TODO wait for stuff properly. time.Sleep(1 * time.Second) }) - cmd.Context = ctx }, ) } @@ -49,13 +48,13 @@ func init() { const devPrivateDefaultBranch = "master" var ( - debugStartServices cli.StringSlice - infoStartServices cli.StringSlice - warnStartServices cli.StringSlice - errorStartServices cli.StringSlice - critStartServices cli.StringSlice - exceptServices cli.StringSlice - onlyServices cli.StringSlice + debugStartServices []string + infoStartServices []string + warnStartServices []string + errorStartServices []string + critStartServices []string + exceptServices []string + onlyServices []string startCommand = &cli.Command{ Name: "start", @@ -136,7 +135,7 @@ sg start -describe single-program Destination: &onlyServices, }, }, - BashComplete: completions.CompleteArgs(func() (options []string) { + ShellComplete: completions.CompleteArgs(func() (options []string) { config, _ := getConfig() if config == nil { return @@ -182,13 +181,13 @@ func constructStartCmdLongHelp() string { return out.String() } -func startExec(ctx *cli.Context) error { +func startExec(ctx context.Context, cmd *cli.Command) error { config, err := getConfig() if err != nil { return err } - args := ctx.Args().Slice() + args := cmd.Args().Slice() if len(args) > 2 { std.Out.WriteLine(output.Styled(output.StyleWarning, "ERROR: too many arguments")) return flag.ErrHelp @@ -213,7 +212,7 @@ func startExec(ctx *cli.Context) error { return errors.New("no concurrent sg start with same arguments allowed") } - if ctx.Bool("sgtail") { + if cmd.Bool("sgtail") { if err := run.OpenUnixSocket(); err != nil { return errors.Wrapf(err, "Did you forget to run sgtail first?") } @@ -226,7 +225,7 @@ func startExec(ctx *cli.Context) error { return flag.ErrHelp } - if ctx.Bool("describe") { + if cmd.Bool("describe") { out, err := yaml.Marshal(set) if err != nil { return err @@ -270,7 +269,7 @@ func startExec(ctx *cli.Context) error { // dev-private exists, let's see if there are any changes update := std.Out.Pending(output.Styled(output.StylePending, "Checking for dev-private changes...")) - shouldUpdate, err := shouldUpdateDevPrivate(ctx.Context, devPrivatePath, devPrivateDefaultBranch) + shouldUpdate, err := shouldUpdateDevPrivate(ctx, devPrivatePath, devPrivateDefaultBranch) if shouldUpdate { update.WriteLine(output.Line(output.EmojiInfo, output.StyleSuggestion, "We found some changes in dev-private that you're missing out on! If you want the new changes, 'cd ../dev-private' and then do a 'git stash' and a 'git pull'!")) } @@ -284,7 +283,7 @@ func startExec(ctx *cli.Context) error { update.Complete(output.Line(output.EmojiSuccess, output.StyleSuccess, "Done checking dev-private changes")) } } - if ctx.Bool("profile") { + if cmd.Bool("profile") { // start a pprof server go func() { err := http.ListenAndServe("127.0.0.1:6060", nil) @@ -306,7 +305,7 @@ go tool pprof -help `) } - return startCommandSet(ctx.Context, set, config) + return startCommandSet(ctx, set, config) } func shouldUpdateDevPrivate(ctx context.Context, path, branch string) (bool, error) { @@ -408,15 +407,13 @@ func startCommandSet(ctx context.Context, set *sgconf.Commandset, conf *sgconf.C } func getCommands[T run.SGConfigCommand](commands []string, set *sgconf.Commandset, conf map[string]T) ([]T, error) { - exceptList := exceptServices.Value() - exceptSet := make(map[string]interface{}, len(exceptList)) - for _, svc := range exceptList { + exceptSet := make(map[string]interface{}, len(exceptServices)) + for _, svc := range exceptServices { exceptSet[svc] = struct{}{} } - onlyList := onlyServices.Value() - onlySet := make(map[string]interface{}, len(onlyList)) - for _, svc := range onlyList { + onlySet := make(map[string]interface{}, len(onlyServices)) + for _, svc := range onlyServices { onlySet[svc] = struct{}{} } @@ -450,11 +447,11 @@ func getCommands[T run.SGConfigCommand](commands []string, set *sgconf.Commandse // logLevelOverrides builds a map of commands -> log level that should be overridden in the environment. func logLevelOverrides() map[string]string { levelServices := make(map[string][]string) - levelServices["debug"] = debugStartServices.Value() - levelServices["info"] = infoStartServices.Value() - levelServices["warn"] = warnStartServices.Value() - levelServices["error"] = errorStartServices.Value() - levelServices["crit"] = critStartServices.Value() + levelServices["debug"] = debugStartServices + levelServices["info"] = infoStartServices + levelServices["warn"] = warnStartServices + levelServices["error"] = errorStartServices + levelServices["crit"] = critStartServices overrides := make(map[string]string) for level, services := range levelServices { diff --git a/dev/sg/sg_teammate.go b/dev/sg/sg_teammate.go index decf313a4b60..d505885595ea 100644 --- a/dev/sg/sg_teammate.go +++ b/dev/sg/sg_teammate.go @@ -8,7 +8,7 @@ import ( "time" "github.com/google/go-github/v55/github" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/open" @@ -43,20 +43,20 @@ sg teammate time thorsten ball sg teammate handbook asdine `, Category: category.Company, - Subcommands: []*cli.Command{{ + Commands: []*cli.Command{{ Name: "time", ArgsUsage: "", Usage: "Get the current time of a Sourcegraph teammate", - Action: func(ctx *cli.Context) error { - args := ctx.Args().Slice() + Action: func(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() if len(args) == 0 { return errors.New("no nickname provided") } - resolver, err := getTeamResolver(ctx.Context) + resolver, err := getTeamResolver(ctx) if err != nil { return err } - teammate, err := resolver.ResolveByName(ctx.Context, strings.Join(args, " ")) + teammate, err := resolver.ResolveByName(ctx, strings.Join(args, " ")) if err != nil { return err } @@ -68,16 +68,16 @@ sg teammate handbook asdine Name: "handbook", ArgsUsage: "", Usage: "Open the handbook page of a Sourcegraph teammate", - Action: func(ctx *cli.Context) error { - args := ctx.Args().Slice() + Action: func(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() if len(args) == 0 { return errors.New("no nickname provided") } - resolver, err := getTeamResolver(ctx.Context) + resolver, err := getTeamResolver(ctx) if err != nil { return err } - teammate, err := resolver.ResolveByName(ctx.Context, strings.Join(args, " ")) + teammate, err := resolver.ResolveByName(ctx, strings.Join(args, " ")) if err != nil { return err } diff --git a/dev/sg/sg_telemetry.go b/dev/sg/sg_telemetry.go index 4fd49dcf0325..30db8c831594 100644 --- a/dev/sg/sg_telemetry.go +++ b/dev/sg/sg_telemetry.go @@ -1,6 +1,7 @@ package main import ( + "context" "fmt" "strings" @@ -11,7 +12,7 @@ import ( "github.com/sourcegraph/sourcegraph/dev/sg/internal/db" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/std" ) @@ -32,14 +33,14 @@ func renderTelemetryV1DeprecationWarning() { var telemetryCommand = &cli.Command{ Name: "telemetry", - Before: func(ctx *cli.Context) error { + Before: func(ctx context.Context, cmd *cli.Command) error { renderTelemetryV1DeprecationWarning() return nil }, Usage: "[DEPRECATED] Operations relating to Sourcegraph telemetry v1", Description: telemetryV1DeprecationWarning, Category: category.Dev, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ allowlistCommand, }, } @@ -67,7 +68,7 @@ sg telemetry allowlist add --migration EVENT_ONE EVENT_TWO # Provide a specific migration name for the migration files sg telemetry allowlist add --migration --name my_migration_name EVENT_ONE EVENT_TWO `, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ addAllowlistCommand, removeAllowlistCommand, }, @@ -132,26 +133,26 @@ var allowlistMigrationNameOverrideFlag = &cli.StringFlag{ Destination: &allowlistMigrationName, } -func addAllowList(ctx *cli.Context) (err error) { - events := ctx.Args().Slice() +func addAllowList(ctx context.Context, cmd *cli.Command) (err error) { + events := cmd.Args().Slice() if len(events) == 0 { return cli.Exit("no events provided", 1) } - return editAllowlist(ctx, events, false) + return editAllowlist(cmd, events, false) } -func removeAllowList(ctx *cli.Context) (err error) { - events := ctx.Args().Slice() +func removeAllowList(ctx context.Context, cmd *cli.Command) (err error) { + events := cmd.Args().Slice() if len(events) == 0 { return cli.Exit("no events provided", 1) } - return editAllowlist(ctx, events, true) + return editAllowlist(cmd, events, true) } -func editAllowlist(ctx *cli.Context, events []string, reverse bool) error { - header := fmt.Sprintf("-- This migration was generated by the command `sg telemetry %s`", ctx.Command.FullName()) +func editAllowlist(cmd *cli.Command, events []string, reverse bool) error { + header := fmt.Sprintf("-- This migration was generated by the command `sg telemetry %s`", cmd.FullName()) arrayStr := fmt.Sprintf(`'{%v}'`, strings.Join(events, ",")) upQuery := fmt.Sprintf("INSERT INTO event_logs_export_allowlist (event_name) VALUES (UNNEST(%s::TEXT[])) ON CONFLICT DO NOTHING;", arrayStr) downQuery := fmt.Sprintf("DELETE FROM event_logs_export_allowlist WHERE event_name IN (SELECT * FROM UNNEST(%s::TEXT[]));", arrayStr) diff --git a/dev/sg/sg_tests.go b/dev/sg/sg_tests.go index 519ce2eae631..57fcf7a555cf 100644 --- a/dev/sg/sg_tests.go +++ b/dev/sg/sg_tests.go @@ -8,7 +8,7 @@ import ( "sort" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/run" @@ -18,7 +18,7 @@ import ( ) func init() { - postInitHooks = append(postInitHooks, func(cmd *cli.Context) { + postInitHooks = append(postInitHooks, func(ctx context.Context, cmd *cli.Command) { // Create 'sg test' help text after flag (and config) initialization testCommand.Description = constructTestCmdLongHelp() }) @@ -42,7 +42,7 @@ sg test -help sg test backend-integration -run TestSearch `, Category: category.Dev, - BashComplete: completions.CompleteArgs(func() (options []string) { + ShellComplete: completions.CompleteArgs(func() (options []string) { config, _ := getConfig() if config == nil { return @@ -55,25 +55,25 @@ sg test backend-integration -run TestSearch Action: testExec, } -func testExec(ctx *cli.Context) error { +func testExec(ctx context.Context, cmd *cli.Command) error { config, err := getConfig() if err != nil { return err } - args := ctx.Args().Slice() + args := cmd.Args().Slice() if len(args) == 0 { std.Out.WriteLine(output.Styled(output.StyleWarning, "No test suite specified")) return flag.ErrHelp } - cmd, ok := config.Tests[args[0]] + test, ok := config.Tests[args[0]] if !ok { std.Out.WriteLine(output.Styledf(output.StyleWarning, "ERROR: test suite %q not found :(", args[0])) return flag.ErrHelp } - return run.Test(ctx.Context, newSGTestCommand(*cmd, args[1:]), config.Env) + return run.Test(ctx, newSGTestCommand(*test, args[1:]), config.Env) } func constructTestCmdLongHelp() string { diff --git a/dev/sg/sg_update.go b/dev/sg/sg_update.go index 0d9f140102ff..c69711c99cbf 100644 --- a/dev/sg/sg_update.go +++ b/dev/sg/sg_update.go @@ -8,7 +8,7 @@ import ( "runtime" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" @@ -30,9 +30,9 @@ var updateCommand = &cli.Command{ sg version changelog -next`, Category: category.Util, - Action: func(cmd *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { p := std.Out.Pending(output.Styled(output.StylePending, "Downloading latest sg release...")) - if _, err := updateToPrebuiltSG(cmd.Context); err != nil { + if _, err := updateToPrebuiltSG(ctx); err != nil { p.Destroy() return err } diff --git a/dev/sg/sg_version.go b/dev/sg/sg_version.go index 8af969290d7a..f25f2e41b8ce 100644 --- a/dev/sg/sg_version.go +++ b/dev/sg/sg_version.go @@ -1,12 +1,13 @@ package main import ( + "context" "fmt" "os" "os/exec" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/run" @@ -17,14 +18,14 @@ import ( var ( versionChangelogNext bool - versionChangelogEntries int + versionChangelogEntries int64 versionCommand = &cli.Command{ Name: "version", Usage: "View details for this installation of sg", Action: versionExec, Category: category.Util, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "changelog", Aliases: []string{"c"}, @@ -48,12 +49,12 @@ var ( } ) -func versionExec(ctx *cli.Context) error { +func versionExec(ctx context.Context, cmd *cli.Command) error { std.Out.Write(BuildCommit) return nil } -func changelogExec(ctx *cli.Context) error { +func changelogExec(ctx context.Context, cmd *cli.Command) error { if _, err := run.GitCmd("fetch", "origin", "main"); err != nil { return errors.Newf("failed to update main: %s", err) } diff --git a/dev/sg/sg_wolfi.go b/dev/sg/sg_wolfi.go index fb5ed74d0c44..e0527df79b03 100644 --- a/dev/sg/sg_wolfi.go +++ b/dev/sg/sg_wolfi.go @@ -1,7 +1,9 @@ package main import ( - "github.com/urfave/cli/v2" + "context" + + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/dev/sg/internal/category" "github.com/sourcegraph/sourcegraph/dev/sg/internal/wolfi" @@ -27,7 +29,7 @@ sg wolfi image gitserver sg wolfi image gitserver.yaml `, Category: category.Dev, - Subcommands: []*cli.Command{{ + Commands: []*cli.Command{{ Name: "package", ArgsUsage: "", Usage: "Build a package locally using a manifest from sourcegraph/wolfi-packages/", @@ -37,8 +39,8 @@ Build a Wolfi package locally by running Melange against a provided Melange mani This is convenient for testing package changes locally before pushing to the Wolfi registry. Base images containing locally-built packages can then be built using 'sg wolfi image'. `, - Action: func(ctx *cli.Context) error { - args := ctx.Args().Slice() + Action: func(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() if len(args) == 0 { return errors.New("no package manifest file provided") } @@ -77,8 +79,8 @@ This is convenient for testing package changes locally before publishing them. Once built, the base image is loaded into Docker and can be run locally. It can also be used for local development by updating its path and hash in the 'dev/oci_deps.bzl' file. `, - Action: func(ctx *cli.Context) error { - args := ctx.Args().Slice() + Action: func(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() if len(args) == 0 { return errors.New("no base image manifest file provided") } @@ -116,7 +118,7 @@ It can also be used for local development by updating its path and hash in the ' Usage: "Scan Wolfi base images for vulnerabilities", UsageText: ` Scans the Wolfi base images in the 'dev/oci_deps.bzl' file.`, - Action: func(ctx *cli.Context) error { + Action: func(ctx context.Context, cmd *cli.Command) error { wolfi.ScanImages() return nil @@ -131,8 +133,8 @@ By default all hashes will be updated; pass in a base image name to update a spe Hash references are updated by fetching the ':latest' tag for each base image from the registry, and updating the corresponding hash in 'dev/oci_deps.bzl'. `, - Action: func(ctx *cli.Context) error { - args := ctx.Args().Slice() + Action: func(ctx context.Context, cmd *cli.Command) error { + args := cmd.Args().Slice() var imageName string if len(args) == 1 { imageName = args[0] diff --git a/go.mod b/go.mod index d25bfe6abd30..e46282787f46 100644 --- a/go.mod +++ b/go.mod @@ -390,6 +390,7 @@ require ( github.com/skeema/knownhosts v1.2.1 // indirect github.com/smartystreets/assertions v1.13.0 // indirect github.com/tetratelabs/wazero v1.3.0 // indirect + github.com/urfave/cli/v3 v3.0.0-alpha9 // indirect github.com/vbatts/tar-split v0.11.3 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect diff --git a/go.sum b/go.sum index d51793da8f63..a63e2874eb01 100644 --- a/go.sum +++ b/go.sum @@ -1775,6 +1775,8 @@ github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo= +github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= diff --git a/internal/database/migration/cliutil/BUILD.bazel b/internal/database/migration/cliutil/BUILD.bazel index b975b1b693b6..28dc8a480d0f 100644 --- a/internal/database/migration/cliutil/BUILD.bazel +++ b/internal/database/migration/cliutil/BUILD.bazel @@ -40,6 +40,6 @@ go_library( "//lib/output", "@com_github_jackc_pgerrcode//:pgerrcode", "@com_github_sourcegraph_log//:log", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", ], ) diff --git a/internal/database/migration/cliutil/addlog.go b/internal/database/migration/cliutil/addlog.go index 5844faa0f31a..7d9f27a9bd29 100644 --- a/internal/database/migration/cliutil/addlog.go +++ b/internal/database/migration/cliutil/addlog.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/log" @@ -30,10 +30,10 @@ func AddLog(commandName string, factory RunnerFactory, outFactory OutputFactory) Value: true, } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { var ( schemaName = TranslateSchemaNames(schemaNameFlag.Get(cmd), out) - versionFlag = versionFlag.Get(cmd) + versionFlag = int(versionFlag.Get(cmd)) upFlag = upFlag.Get(cmd) logger = log.Scoped("up") ) diff --git a/internal/database/migration/cliutil/describe.go b/internal/database/migration/cliutil/describe.go index 229ac924526b..ba3ebdb37896 100644 --- a/internal/database/migration/cliutil/describe.go +++ b/internal/database/migration/cliutil/describe.go @@ -5,7 +5,7 @@ import ( "io" "strings" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/lib/output" ) @@ -38,7 +38,7 @@ func Describe(commandName string, factory RunnerFactory, outFactory OutputFactor Required: false, } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) (err error) { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) (err error) { w, shouldDecorate, err := getOutput(out, outFlag.Get(cmd), forceFlag.Get(cmd), noColorFlag.Get(cmd)) if err != nil { return err diff --git a/internal/database/migration/cliutil/downgrade.go b/internal/database/migration/cliutil/downgrade.go index fc6477cd7a57..022284fcbf43 100644 --- a/internal/database/migration/cliutil/downgrade.go +++ b/internal/database/migration/cliutil/downgrade.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database/migration/multiversion" "github.com/sourcegraph/sourcegraph/internal/database/migration/runner" @@ -74,7 +74,7 @@ func Downgrade( Required: false, } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { airgapped := isAirgapped(ctx) if airgapped != nil { out.WriteLine(output.Line(output.EmojiWarningSign, output.StyleYellow, airgapped.Error())) @@ -127,7 +127,7 @@ func Downgrade( return err } - privilegedMode, err := getPivilegedModeFromFlags(cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) + privilegedMode, err := getPivilegedModeFromFlags(ctx, cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) if err != nil { return err } diff --git a/internal/database/migration/cliutil/downto.go b/internal/database/migration/cliutil/downto.go index 512df4ccc6e0..09d167f3074c 100644 --- a/internal/database/migration/cliutil/downto.go +++ b/internal/database/migration/cliutil/downto.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database/migration/runner" "github.com/sourcegraph/sourcegraph/lib/output" @@ -48,8 +48,8 @@ func DownTo(commandName string, factory RunnerFactory, outFactory OutputFactory, Value: development, } - makeOptions := func(cmd *cli.Context, out *output.Output, versions []int) (runner.Options, error) { - privilegedMode, err := getPivilegedModeFromFlags(cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) + makeOptions := func(ctx context.Context, cmd *cli.Command, out *output.Output, versions []int) (runner.Options, error) { + privilegedMode, err := getPivilegedModeFromFlags(ctx, cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) if err != nil { return runner.Options{}, err } @@ -69,7 +69,7 @@ func DownTo(commandName string, factory RunnerFactory, outFactory OutputFactory, }, nil } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { versions, err := parseTargets(targetFlag.Get(cmd)) if err != nil { return err @@ -83,7 +83,7 @@ func DownTo(commandName string, factory RunnerFactory, outFactory OutputFactory, return err } - options, err := makeOptions(cmd, out, versions) + options, err := makeOptions(ctx, cmd, out, versions) if err != nil { return err } diff --git a/internal/database/migration/cliutil/drift.go b/internal/database/migration/cliutil/drift.go index c9b7ede78961..bc7f20d1c524 100644 --- a/internal/database/migration/cliutil/drift.go +++ b/internal/database/migration/cliutil/drift.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database/migration/drift" "github.com/sourcegraph/sourcegraph/internal/database/migration/multiversion" @@ -57,7 +57,7 @@ func Drift(commandName string, factory RunnerFactory, outFactory OutputFactory, Aliases: []string{"autofix"}, } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { airgapped := isAirgapped(ctx) if airgapped != nil { out.WriteLine(output.Line(output.EmojiWarningSign, output.StyleYellow, airgapped.Error())) diff --git a/internal/database/migration/cliutil/drift_autofix.go b/internal/database/migration/cliutil/drift_autofix.go index 9d149cf71795..6e18e3abb2f1 100644 --- a/internal/database/migration/cliutil/drift_autofix.go +++ b/internal/database/migration/cliutil/drift_autofix.go @@ -27,6 +27,7 @@ func attemptAutofix( summaries []drift.Summary, compareDescriptionAgainstTarget func(descriptions.SchemaDescription) []drift.Summary, ) (_ []drift.Summary, err error) { + var schemas map[string]descriptions.SchemaDescription for attempts := maxAutofixAttempts; attempts > 0 && len(summaries) > 0 && err == nil; attempts-- { if !runAutofix(ctx, out, store, summaries) { out.WriteLine(output.Linef(output.EmojiInfo, output.StyleReset, "No autofix to apply")) @@ -35,7 +36,7 @@ func attemptAutofix( out.WriteLine(output.Linef(output.EmojiInfo, output.StyleReset, "Re-checking drift")) - schemas, err := store.Describe(ctx) + schemas, err = store.Describe(ctx) if err != nil { return nil, err } diff --git a/internal/database/migration/cliutil/run_oobmigrations.go b/internal/database/migration/cliutil/run_oobmigrations.go index 8c3eacb90463..1485556ed893 100644 --- a/internal/database/migration/cliutil/run_oobmigrations.go +++ b/internal/database/migration/cliutil/run_oobmigrations.go @@ -3,7 +3,7 @@ package cliutil import ( "context" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database/migration/multiversion" "github.com/sourcegraph/sourcegraph/internal/database/migration/schemas" @@ -35,7 +35,7 @@ func RunOutOfBandMigrations( Required: false, } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { r, err := runnerFactory(schemas.SchemaNames) if err != nil { return err @@ -46,6 +46,10 @@ func RunOutOfBandMigrations( } registerMigrators := registerMigratorsWithStore(store.BasestoreExtractor{Runner: r}) + var ids []int + for _, id := range idsFlag.Get(cmd) { + ids = append(ids, int(id)) + } if err := multiversion.RunOutOfBandMigrations( ctx, db, @@ -54,7 +58,7 @@ func RunOutOfBandMigrations( !disableAnimation.Get(cmd), registerMigrators, out, - idsFlag.Get(cmd), + ids, ); err != nil { return err } diff --git a/internal/database/migration/cliutil/undo.go b/internal/database/migration/cliutil/undo.go index 8d7ba88ac3bb..419ed6f9fd0d 100644 --- a/internal/database/migration/cliutil/undo.go +++ b/internal/database/migration/cliutil/undo.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database/migration/runner" "github.com/sourcegraph/sourcegraph/lib/output" @@ -18,7 +18,7 @@ func Undo(commandName string, factory RunnerFactory, outFactory OutputFactory, d Aliases: []string{"db"}, } - makeOptions := func(cmd *cli.Context, out *output.Output) runner.Options { + makeOptions := func(_ context.Context, cmd *cli.Command, out *output.Output) runner.Options { return runner.Options{ Operations: []runner.MigrationOperation{ { @@ -31,13 +31,13 @@ func Undo(commandName string, factory RunnerFactory, outFactory OutputFactory, d } } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { r, err := setupRunner(factory, TranslateSchemaNames(schemaNameFlag.Get(cmd), out)) if err != nil { return err } - return r.Run(ctx, makeOptions(cmd, out)) + return r.Run(ctx, makeOptions(ctx, cmd, out)) }) return &cli.Command{ diff --git a/internal/database/migration/cliutil/up.go b/internal/database/migration/cliutil/up.go index 3540ad005116..9d62d6164453 100644 --- a/internal/database/migration/cliutil/up.go +++ b/internal/database/migration/cliutil/up.go @@ -6,7 +6,7 @@ import ( "fmt" "github.com/jackc/pgerrcode" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database/migration/multiversion" "github.com/sourcegraph/sourcegraph/internal/database/migration/runner" @@ -22,7 +22,7 @@ func Up(commandName string, factory RunnerFactory, outFactory OutputFactory, dev schemaNamesFlag := &cli.StringSliceFlag{ Name: "schema", Usage: "The target `schema(s)` to modify. Comma-separated values are accepted. Possible values are 'frontend', 'codeintel', 'codeinsights' and 'all'.", - Value: cli.NewStringSlice("all"), + Value: []string{"all"}, Aliases: []string{"db"}, } unprivilegedOnlyFlag := &cli.BoolFlag{ @@ -63,7 +63,7 @@ func Up(commandName string, factory RunnerFactory, outFactory OutputFactory, dev Value: development, } - makeOptions := func(cmd *cli.Context, out *output.Output, schemaNames []string) (runner.Options, error) { + makeOptions := func(ctx context.Context, cmd *cli.Command, out *output.Output, schemaNames []string) (runner.Options, error) { operations := make([]runner.MigrationOperation, 0, len(schemaNames)) for _, schemaName := range schemaNames { operations = append(operations, runner.MigrationOperation{ @@ -72,7 +72,7 @@ func Up(commandName string, factory RunnerFactory, outFactory OutputFactory, dev }) } - privilegedMode, err := getPivilegedModeFromFlags(cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) + privilegedMode, err := getPivilegedModeFromFlags(ctx, cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) if err != nil { return runner.Options{}, err } @@ -94,7 +94,7 @@ func Up(commandName string, factory RunnerFactory, outFactory OutputFactory, dev }, nil } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { schemaNames := sanitizeSchemaNames(schemaNamesFlag.Get(cmd), out) if len(schemaNames) == 0 { return flagHelp(out, "supply a schema via -db") @@ -105,7 +105,7 @@ func Up(commandName string, factory RunnerFactory, outFactory OutputFactory, dev return err } - options, err := makeOptions(cmd, out, schemaNames) + options, err := makeOptions(ctx, cmd, out, schemaNames) if err != nil { return err } diff --git a/internal/database/migration/cliutil/upgrade.go b/internal/database/migration/cliutil/upgrade.go index 14a153a507cd..acb11b64408e 100644 --- a/internal/database/migration/cliutil/upgrade.go +++ b/internal/database/migration/cliutil/upgrade.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database/migration/multiversion" "github.com/sourcegraph/sourcegraph/internal/database/migration/runner" @@ -76,7 +76,7 @@ func Upgrade( Required: false, } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { airgapped := isAirgapped(ctx) if airgapped != nil { out.WriteLine(output.Line(output.EmojiWarningSign, output.StyleYellow, airgapped.Error())) @@ -158,7 +158,7 @@ func Upgrade( return err } - privilegedMode, err := getPivilegedModeFromFlags(cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) + privilegedMode, err := getPivilegedModeFromFlags(ctx, cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) if err != nil { return err } diff --git a/internal/database/migration/cliutil/upto.go b/internal/database/migration/cliutil/upto.go index ed8a9204c5a5..d66903a1e8d9 100644 --- a/internal/database/migration/cliutil/upto.go +++ b/internal/database/migration/cliutil/upto.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database/migration/runner" "github.com/sourcegraph/sourcegraph/lib/output" @@ -48,8 +48,8 @@ func UpTo(commandName string, factory RunnerFactory, outFactory OutputFactory, d Value: development, } - makeOptions := func(cmd *cli.Context, out *output.Output, versions []int) (runner.Options, error) { - privilegedMode, err := getPivilegedModeFromFlags(cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) + makeOptions := func(ctx context.Context, cmd *cli.Command, out *output.Output, versions []int) (runner.Options, error) { + privilegedMode, err := getPivilegedModeFromFlags(ctx, cmd, out, unprivilegedOnlyFlag, noopPrivilegedFlag) if err != nil { return runner.Options{}, err } @@ -69,7 +69,7 @@ func UpTo(commandName string, factory RunnerFactory, outFactory OutputFactory, d }, nil } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { versions, err := parseTargets(targetFlag.Get(cmd)) if err != nil { return err @@ -83,7 +83,7 @@ func UpTo(commandName string, factory RunnerFactory, outFactory OutputFactory, d return err } - options, err := makeOptions(cmd, out, versions) + options, err := makeOptions(ctx, cmd, out, versions) if err != nil { return err } diff --git a/internal/database/migration/cliutil/util.go b/internal/database/migration/cliutil/util.go index 7c49000664d2..279de395e5c9 100644 --- a/internal/database/migration/cliutil/util.go +++ b/internal/database/migration/cliutil/util.go @@ -8,7 +8,7 @@ import ( "strings" "time" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database" "github.com/sourcegraph/sourcegraph/internal/database/migration/runner" @@ -20,17 +20,17 @@ import ( "github.com/sourcegraph/sourcegraph/lib/output" ) -type actionFunction func(ctx context.Context, cmd *cli.Context, out *output.Output) error +type actionFunction func(ctx context.Context, cmd *cli.Command, out *output.Output) error // makeAction creates a new migration action function. It is expected that these // commands accept zero arguments and define their own flags. -func makeAction(outFactory OutputFactory, f actionFunction) func(cmd *cli.Context) error { - return func(cmd *cli.Context) error { +func makeAction(outFactory OutputFactory, f actionFunction) func(ctx context.Context, cmd *cli.Command) error { + return func(ctx context.Context, cmd *cli.Command) error { if cmd.NArg() != 0 { return flagHelp(outFactory(), "too many arguments") } - return f(cmd.Context, cmd, outFactory()) + return f(ctx, cmd, outFactory()) } } @@ -122,7 +122,7 @@ func parseTargets(targets []string) ([]int, error) { // getPivilegedModeFromFlags transforms the given flags into an equivalent PrivilegedMode value. A user error is // returned if the supplied flags form an invalid state. -func getPivilegedModeFromFlags(cmd *cli.Context, out *output.Output, unprivilegedOnlyFlag, noopPrivilegedFlag *cli.BoolFlag) (runner.PrivilegedMode, error) { +func getPivilegedModeFromFlags(_ context.Context, cmd *cli.Command, out *output.Output, unprivilegedOnlyFlag, noopPrivilegedFlag *cli.BoolFlag) (runner.PrivilegedMode, error) { unprivilegedOnly := unprivilegedOnlyFlag.Get(cmd) noopPrivileged := noopPrivilegedFlag.Get(cmd) if unprivilegedOnly && noopPrivileged { diff --git a/internal/database/migration/cliutil/validate.go b/internal/database/migration/cliutil/validate.go index b1900e596ece..b07cc05f5785 100644 --- a/internal/database/migration/cliutil/validate.go +++ b/internal/database/migration/cliutil/validate.go @@ -3,7 +3,7 @@ package cliutil import ( "context" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/internal/database/migration/store" "github.com/sourcegraph/sourcegraph/internal/oobmigration" @@ -14,7 +14,7 @@ func Validate(commandName string, factory RunnerFactory, outFactory OutputFactor schemaNamesFlag := &cli.StringSliceFlag{ Name: "schema", Usage: "The target `schema(s)` to validate. Comma-separated values are accepted. Possible values are 'frontend', 'codeintel', 'codeinsights' and 'all'.", - Value: cli.NewStringSlice("all"), + Value: []string{"all"}, Aliases: []string{"db"}, } skipOutOfBandMigrationsFlag := &cli.BoolFlag{ @@ -23,7 +23,7 @@ func Validate(commandName string, factory RunnerFactory, outFactory OutputFactor Value: false, } - action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Context, out *output.Output) error { + action := makeAction(outFactory, func(ctx context.Context, cmd *cli.Command, out *output.Output) error { schemaNames := sanitizeSchemaNames(schemaNamesFlag.Get(cmd), out) if len(schemaNames) == 0 { return flagHelp(out, "supply a schema via -db") diff --git a/lib/cliutil/completions/BUILD.bazel b/lib/cliutil/completions/BUILD.bazel index 6026f22bb77f..03c5681dd899 100644 --- a/lib/cliutil/completions/BUILD.bazel +++ b/lib/cliutil/completions/BUILD.bazel @@ -5,5 +5,5 @@ go_library( srcs = ["options.go"], importpath = "github.com/sourcegraph/sourcegraph/lib/cliutil/completions", visibility = ["//visibility:public"], - deps = ["@com_github_urfave_cli_v2//:cli"], + deps = ["@com_github_urfave_cli_v3//:cli"], ) diff --git a/lib/cliutil/completions/options.go b/lib/cliutil/completions/options.go index 283d924421ec..183bddde8075 100644 --- a/lib/cliutil/completions/options.go +++ b/lib/cliutil/completions/options.go @@ -1,14 +1,15 @@ package completions import ( + "context" "fmt" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // defaultCompletions renders the default completions for a command. -func defaultCompletions() cli.BashCompleteFunc { - return func(c *cli.Context) { cli.DefaultCompleteWithFlags(c.Command)(c) } +func defaultCompletions() cli.ShellCompleteFunc { + return func(ctx context.Context, cmd *cli.Command) { cli.DefaultCompleteWithFlags(cmd)(ctx, cmd) } } // CompleteArgs provides autocompletions based on the options returned by @@ -16,11 +17,11 @@ func defaultCompletions() cli.BashCompleteFunc { // // generateOptions must not write to output, or reference any // resources that are initialized elsewhere. -func CompleteArgs(generateOptions func() (options []string)) cli.BashCompleteFunc { - return func(c *cli.Context) { +func CompleteArgs(generateOptions func() (options []string)) cli.ShellCompleteFunc { + return func(ctx context.Context, cmd *cli.Command) { CompletePositionalArgs(func(_ cli.Args) (options []string) { return generateOptions() - })(c) + })(ctx, cmd) } } @@ -30,39 +31,39 @@ func CompleteArgs(generateOptions func() (options []string)) cli.BashCompleteFun // // Each generator must not write to output, or reference any resources that are // initialized elsewhere. -func CompletePositionalArgs(generators ...func(args cli.Args) (options []string)) cli.BashCompleteFunc { - return func(c *cli.Context) { +func CompletePositionalArgs(generators ...func(args cli.Args) (options []string)) cli.ShellCompleteFunc { + return func(ctx context.Context, cmd *cli.Command) { // Let default handler deal with flag completions if the latest argument // looks like the start of a flag - if c.NArg() > 0 { - if f := c.Args().Get(c.NArg() - 1); f == "-" || f == "--" { - defaultCompletions()(c) + if cmd.NArg() > 0 { + if f := cmd.Args().Get(cmd.NArg() - 1); f == "-" || f == "--" { + defaultCompletions()(ctx, cmd) return } } // More arguments than positional options generators, we have no more // completions to offer - if len(generators) <= c.NArg() { + if len(generators) <= cmd.NArg() { return } // Generate the options for this posarg - opts := generators[c.NArg()](c.Args()) + opts := generators[cmd.NArg()](cmd.Args()) // If there are no options, render the previous options if we can, as // user may be typing the previous argument - if len(opts) == 0 && c.NArg() >= 1 { - opts = generators[c.NArg()-1](c.Args()) + if len(opts) == 0 && cmd.NArg() >= 1 { + opts = generators[cmd.NArg()-1](cmd.Args()) } // Render the options for _, opt := range opts { - fmt.Fprintf(c.App.Writer, "%s\n", opt) + fmt.Fprintf(cmd.Writer, "%s\n", opt) } // Also render default completions if there are no args yet - if c.Args().Len() == 0 { - defaultCompletions()(c) + if cmd.Args().Len() == 0 { + defaultCompletions()(ctx, cmd) } } } diff --git a/lib/cliutil/docgen/BUILD.bazel b/lib/cliutil/docgen/BUILD.bazel index c40a8153473e..da88c9c0d848 100644 --- a/lib/cliutil/docgen/BUILD.bazel +++ b/lib/cliutil/docgen/BUILD.bazel @@ -8,5 +8,5 @@ go_library( ], importpath = "github.com/sourcegraph/sourcegraph/lib/cliutil/docgen", visibility = ["//visibility:public"], - deps = ["@com_github_urfave_cli_v2//:cli"], + deps = ["@com_github_urfave_cli_v3//:cli"], ) diff --git a/lib/cliutil/docgen/default.go b/lib/cliutil/docgen/default.go index d275ad7f29f7..ec56502eb762 100644 --- a/lib/cliutil/docgen/default.go +++ b/lib/cliutil/docgen/default.go @@ -3,14 +3,14 @@ package docgen import ( "bytes" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // Default renders help text for the app using urfave/cli's default help format. -func Default(app *cli.App) (string, error) { - tpl := app.CustomAppHelpTemplate +func Default(app *cli.Command) (string, error) { + tpl := app.CustomRootCommandHelpTemplate if tpl == "" { - tpl = cli.AppHelpTemplate + tpl = cli.RootCommandHelpTemplate } var w bytes.Buffer diff --git a/lib/cliutil/docgen/markdown.go b/lib/cliutil/docgen/markdown.go index f31fea125f19..0768d2fbed5c 100644 --- a/lib/cliutil/docgen/markdown.go +++ b/lib/cliutil/docgen/markdown.go @@ -8,13 +8,13 @@ import ( "strings" "text/template" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) // Markdown renders a Markdown reference for the app. // // It is adapted from https://sourcegraph.com/github.com/urfave/cli@v2.4.0/-/blob/docs.go?L16 -func Markdown(app *cli.App) (string, error) { +func Markdown(app *cli.Command) (string, error) { var w bytes.Buffer if err := writeDocTemplate(app, &w); err != nil { return "", err @@ -23,12 +23,12 @@ func Markdown(app *cli.App) (string, error) { } type cliTemplate struct { - App *cli.App + App *cli.Command Commands []string GlobalArgs []string } -func writeDocTemplate(app *cli.App, w io.Writer) error { +func writeDocTemplate(app *cli.Command, w io.Writer) error { const name = "cli" t, err := template.New(name).Parse(markdownDocTemplate) if err != nil { @@ -73,10 +73,10 @@ func prepareCommands(lineage string, commands []*cli.Command, level int) []strin coms = append(coms, commandDoc.String()) // recursevly iterate subcommands - if len(command.Subcommands) > 0 { + if len(command.Commands) > 0 { coms = append( coms, - prepareCommands(lineage+" "+command.Name, command.Subcommands, level+1)..., + prepareCommands(lineage+" "+command.Name, command.Commands, level+1)..., ) } } @@ -88,6 +88,11 @@ func prepareArgsWithValues(flags []cli.Flag) []string { return prepareFlags(flags, ", ", "`", "`", `""`, true) } +type Flag interface { + cli.DocGenerationFlag + cli.Flag +} + func prepareFlags( flags []cli.Flag, sep, opener, closer, value string, @@ -95,7 +100,7 @@ func prepareFlags( ) []string { args := []string{} for _, f := range flags { - flag, ok := f.(cli.DocGenerationFlag) + flag, ok := f.(Flag) if !ok { continue } diff --git a/lib/go.mod b/lib/go.mod index 65c908e029e6..de5b2dc3202b 100644 --- a/lib/go.mod +++ b/lib/go.mod @@ -32,6 +32,7 @@ require ( github.com/sourcegraph/scip v0.3.1-0.20230627154934-45df7f6d33fc github.com/stretchr/testify v1.8.4 github.com/urfave/cli/v2 v2.23.7 + github.com/urfave/cli/v3 v3.0.0-alpha9 github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/sys v0.17.0 golang.org/x/term v0.17.0 diff --git a/lib/go.sum b/lib/go.sum index 67ec3adfba9b..e2d1d2ae9f37 100644 --- a/lib/go.sum +++ b/lib/go.sum @@ -338,6 +338,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/urfave/cli/v2 v2.23.7 h1:YHDQ46s3VghFHFf1DdF+Sh7H4RqhcM+t0TmZRJx4oJY= github.com/urfave/cli/v2 v2.23.7/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo= +github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= diff --git a/monitoring/BUILD.bazel b/monitoring/BUILD.bazel index e4eb1fdff1d7..549df302ced3 100644 --- a/monitoring/BUILD.bazel +++ b/monitoring/BUILD.bazel @@ -8,7 +8,7 @@ go_library( deps = [ "//monitoring/command", "@com_github_sourcegraph_log//:log", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", ], ) diff --git a/monitoring/command/BUILD.bazel b/monitoring/command/BUILD.bazel index f7a10ff53976..c9ac538a94ae 100644 --- a/monitoring/command/BUILD.bazel +++ b/monitoring/command/BUILD.bazel @@ -13,6 +13,6 @@ go_library( "@com_github_hashicorp_hcl//hcl/strconv", "@com_github_prometheus_prometheus//model/labels", "@com_github_sourcegraph_log//:log", - "@com_github_urfave_cli_v2//:cli", + "@com_github_urfave_cli_v3//:cli", ], ) diff --git a/monitoring/command/generate.go b/monitoring/command/generate.go index a859ad8dd077..21b50655f0a3 100644 --- a/monitoring/command/generate.go +++ b/monitoring/command/generate.go @@ -1,6 +1,7 @@ package command import ( + "context" "fmt" "os" "path/filepath" @@ -8,7 +9,7 @@ import ( "github.com/hashicorp/hcl/hcl/strconv" "github.com/prometheus/prometheus/model/labels" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/log" @@ -38,12 +39,12 @@ func Generate(cmdRoot string, sgRoot string) *cli.Command { Flags: []cli.Flag{ &cli.BoolFlag{ Name: "no-prune", - EnvVars: []string{"NO_PRUNE"}, + Sources: cli.EnvVars("NO_PRUNE"), Usage: "Toggles pruning of dangling generated assets through simple heuristic - should be disabled during builds.", }, &cli.BoolFlag{ Name: "reload", - EnvVars: []string{"RELOAD"}, + Sources: cli.EnvVars("RELOAD"), Usage: "Trigger reload of active Prometheus or Grafana instance (requires respective output directories)", }, @@ -54,7 +55,7 @@ func Generate(cmdRoot string, sgRoot string) *cli.Command { &cli.StringFlag{ Name: "grafana.dir", - EnvVars: []string{"GRAFANA_DIR"}, + Sources: cli.EnvVars("GRAFANA_DIR"), Value: "$SG_ROOT/docker-images/grafana/config/provisioning/dashboards/sourcegraph/", Usage: "Output directory for generated Grafana assets", }, @@ -70,7 +71,7 @@ func Generate(cmdRoot string, sgRoot string) *cli.Command { }, &cli.StringSliceFlag{ Name: "grafana.headers", - EnvVars: []string{"GRAFANA_HEADERS"}, + Sources: cli.EnvVars("GRAFANA_HEADERS"), Usage: "Additional headers for HTTP requests to the Grafana instance", }, &cli.StringFlag{ @@ -80,7 +81,7 @@ func Generate(cmdRoot string, sgRoot string) *cli.Command { &cli.StringFlag{ Name: "prometheus.dir", - EnvVars: []string{"PROMETHEUS_DIR"}, + Sources: cli.EnvVars("PROMETHEUS_DIR"), Value: "$SG_ROOT/docker-images/prometheus/config/", Usage: "Output directory for generated Prometheus assets", }, @@ -92,26 +93,26 @@ func Generate(cmdRoot string, sgRoot string) *cli.Command { &cli.StringFlag{ Name: "docs.dir", - EnvVars: []string{"DOCS_DIR"}, + Sources: cli.EnvVars("DOCS_DIR"), Value: "$SG_ROOT/doc/admin/observability/", Usage: "Output directory for generated documentation", }, &cli.StringSliceFlag{ Name: "inject-label-matcher", - EnvVars: []string{"INJECT_LABEL_MATCHERS"}, + Sources: cli.EnvVars("INJECT_LABEL_MATCHERS"), Usage: "Labels to inject into all selectors in Prometheus expressions: observable queries, dashboard template variables, etc.", }, &cli.StringSliceFlag{ Name: "multi-instance-groupings", - EnvVars: []string{"MULTI_INSTANCE_GROUPINGS"}, + Sources: cli.EnvVars("MULTI_INSTANCE_GROUPINGS"), Usage: "If non-empty, indicates whether or not to generate multi-instance assets with the provided labels to group on. The standard per-instance monitoring assets will NOT be generated.", }, }, - BashComplete: completions.CompleteArgs(func() (options []string) { + ShellComplete: completions.CompleteArgs(func() (options []string) { return definitions.Default().Names() }), - Action: func(c *cli.Context) error { - logger := log.Scoped(c.Command.Name) + Action: func(ctx context.Context, cmd *cli.Command) error { + logger := log.Scoped(cmd.Name) // expandErr is set from within expandWithSgRoot var expandErr error @@ -130,16 +131,16 @@ func Generate(cmdRoot string, sgRoot string) *cli.Command { } options := monitoring.GenerateOptions{ - DisablePrune: c.Bool("no-prune"), - Reload: c.Bool("reload"), + DisablePrune: cmd.Bool("no-prune"), + Reload: cmd.Bool("reload"), - GrafanaDir: os.Expand(c.String("grafana.dir"), expandWithSgRoot), - GrafanaURL: c.String("grafana.url"), - GrafanaCredentials: c.String("grafana.creds"), - GrafanaFolder: c.String("grafana.folder"), + GrafanaDir: os.Expand(cmd.String("grafana.dir"), expandWithSgRoot), + GrafanaURL: cmd.String("grafana.url"), + GrafanaCredentials: cmd.String("grafana.creds"), + GrafanaFolder: cmd.String("grafana.folder"), GrafanaHeaders: func() map[string]string { h := make(map[string]string) - for _, entry := range c.StringSlice("grafana.headers") { + for _, entry := range cmd.StringSlice("grafana.headers") { if len(entry) == 0 { continue } @@ -160,14 +161,14 @@ func Generate(cmdRoot string, sgRoot string) *cli.Command { return h }(), - PrometheusDir: os.Expand(c.String("prometheus.dir"), expandWithSgRoot), - PrometheusURL: c.String("prometheus.url"), + PrometheusDir: os.Expand(cmd.String("prometheus.dir"), expandWithSgRoot), + PrometheusURL: cmd.String("prometheus.url"), - DocsDir: os.Expand(c.String("docs.dir"), expandWithSgRoot), + DocsDir: os.Expand(cmd.String("docs.dir"), expandWithSgRoot), InjectLabelMatchers: func() []*labels.Matcher { var matchers []*labels.Matcher - for _, entry := range c.StringSlice("inject-label-matcher") { + for _, entry := range cmd.StringSlice("inject-label-matcher") { if len(entry) == 0 { continue } @@ -196,12 +197,12 @@ func Generate(cmdRoot string, sgRoot string) *cli.Command { return matchers }(), - MultiInstanceDashboardGroupings: c.StringSlice("multi-instance-groupings"), + MultiInstanceDashboardGroupings: cmd.StringSlice("multi-instance-groupings"), } // If 'all.dir' is set, override all other '*.dir' flags and ignore expansion // errors. - if allDir := c.String("all.dir"); allDir != "" { + if allDir := cmd.String("all.dir"); allDir != "" { logger.Info("overriding all directory flags with 'all.dir'", log.String("all.dir", allDir)) options.GrafanaDir = filepath.Join(allDir, "grafana") options.PrometheusDir = filepath.Join(allDir, "prometheus") @@ -212,11 +213,11 @@ func Generate(cmdRoot string, sgRoot string) *cli.Command { // Decide which dashboards to generate var dashboards definitions.Dashboards - if c.Args().Len() == 0 { + if cmd.Args().Len() == 0 { dashboards = definitions.Default() } else { - for _, arg := range c.Args().Slice() { - d := definitions.Default().GetByName(c.Args().First()) + for _, arg := range cmd.Args().Slice() { + d := definitions.Default().GetByName(cmd.Args().First()) if d == nil { return errors.Newf("Dashboard %q not found", arg) } diff --git a/monitoring/go.mod b/monitoring/go.mod index 47314b25a623..5ab798b72418 100644 --- a/monitoring/go.mod +++ b/monitoring/go.mod @@ -16,7 +16,7 @@ require ( github.com/sourcegraph/log v0.0.0-20231018134238-fbadff7458bb github.com/sourcegraph/sourcegraph/lib v0.0.0-20230613175844-f031949c72f5 github.com/stretchr/testify v1.8.4 - github.com/urfave/cli/v2 v2.23.7 + github.com/urfave/cli/v3 v3.0.0-alpha9 golang.org/x/text v0.14.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -35,7 +35,6 @@ require ( github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect github.com/cockroachdb/redact v1.1.5 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dennwc/varint v1.0.0 // indirect github.com/fatih/color v1.15.0 // indirect @@ -71,7 +70,6 @@ require ( github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect go.uber.org/atomic v1.11.0 // indirect diff --git a/monitoring/go.sum b/monitoring/go.sum index 88922a9561f3..f2b1d86dcf87 100644 --- a/monitoring/go.sum +++ b/monitoring/go.sum @@ -354,6 +354,8 @@ github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcU github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/urfave/cli/v2 v2.23.7 h1:YHDQ46s3VghFHFf1DdF+Sh7H4RqhcM+t0TmZRJx4oJY= github.com/urfave/cli/v2 v2.23.7/go.mod h1:GHupkWPMM0M/sj1a2b4wUrWBPzazNrIjouW6fmdJLxc= +github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo= +github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= diff --git a/monitoring/main.go b/monitoring/main.go index 619b3554a27d..8d3f26b2f1d5 100644 --- a/monitoring/main.go +++ b/monitoring/main.go @@ -7,10 +7,11 @@ package main import ( + "context" "os" "github.com/sourcegraph/log" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "github.com/sourcegraph/sourcegraph/monitoring/command" ) @@ -29,14 +30,14 @@ func main() { logger := log.Scoped("monitoring") // Create an app that only runs the generate command - app := &cli.App{ + app := &cli.Command{ Name: "monitoring-generator", Commands: []*cli.Command{ command.Generate("", "../"), }, DefaultCommand: "generate", } - if err := app.Run(os.Args); err != nil { + if err := app.Run(context.Background(), os.Args); err != nil { // Render in plain text for human readability println(err.Error()) logger.Fatal("error encountered")