From 76a2402c00a7aebcb0f75cb97b42480b1a1fa48b Mon Sep 17 00:00:00 2001 From: Jarryd Tilbrook Date: Mon, 10 Jun 2024 11:01:43 +0800 Subject: [PATCH 1/6] Add pipeline flag and update docs --- pkg/cmd/build/view.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pkg/cmd/build/view.go b/pkg/cmd/build/view.go index a44503a..5579785 100644 --- a/pkg/cmd/build/view.go +++ b/pkg/cmd/build/view.go @@ -22,18 +22,16 @@ import ( func NewCmdBuildView(f *factory.Factory) *cobra.Command { var web bool + var pipeline string cmd := cobra.Command{ DisableFlagsInUseLine: true, - Use: "view [number [pipeline]] [flags]", + Use: "view [number] [flags]", Short: "View build information.", Long: heredoc.Doc(` View a build's information. - It accepts a build number and a pipeline slug as an argument. - If the build argument is be omitted, the most recent build on the current branch will be resolved. - The pipeline can be a {pipeline_slug} or in the format {org_slug}/{pipeline_slug}. - If the pipeline argument is omitted, it will be resolved using the current directory. + You can pass an optional build number to view. If omitted, the most recent build on the current branch will be resolved. `), RunE: func(cmd *cobra.Command, args []string) error { buildArtifacts := make([]buildkite.Artifact, 0) @@ -116,6 +114,9 @@ func NewCmdBuildView(f *factory.Factory) *cobra.Command { } cmd.Flags().BoolVarP(&web, "web", "w", false, "Open the build in a web browser.") + cmd.Flags().StringVarP(&pipeline, "pipeline", "p", "", "The pipeline to view. This can be a {pipeline slug} or in the format {org slug}/{pipeline slug}.\n"+ + "If omitted, it will be resolved using the current directory.", + ) return &cmd } From f7b740b9a364623de8f7babfca0fdd8fa7fa74df Mon Sep 17 00:00:00 2001 From: Jarryd Tilbrook Date: Mon, 10 Jun 2024 11:04:15 +0800 Subject: [PATCH 2/6] Update PickOne resolver to not prompt if only one option --- internal/pipeline/resolver/picker.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/pipeline/resolver/picker.go b/internal/pipeline/resolver/picker.go index 49a360d..15d0f66 100644 --- a/internal/pipeline/resolver/picker.go +++ b/internal/pipeline/resolver/picker.go @@ -22,6 +22,11 @@ func PickOne(pipelines []pipeline.Pipeline) *pipeline.Pipeline { return nil } + // no need to prompt for only one option + if len(pipelines) == 1 { + return &pipelines[0] + } + names := make([]string, len(pipelines)) for i, p := range pipelines { names[i] = p.Name From cb40ac3867fc17ca15925d2afb6732c2890b96fc Mon Sep 17 00:00:00 2001 From: Jarryd Tilbrook Date: Mon, 10 Jun 2024 11:08:14 +0800 Subject: [PATCH 3/6] Add pipeline flag resolver --- internal/pipeline/resolver/flag.go | 27 +++++++++++++++++++++++++++ pkg/cmd/build/view.go | 3 ++- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 internal/pipeline/resolver/flag.go diff --git a/internal/pipeline/resolver/flag.go b/internal/pipeline/resolver/flag.go new file mode 100644 index 0000000..7724395 --- /dev/null +++ b/internal/pipeline/resolver/flag.go @@ -0,0 +1,27 @@ +package resolver + +import ( + "context" + "fmt" + + "github.com/buildkite/cli/v3/internal/config" + "github.com/buildkite/cli/v3/internal/pipeline" +) + +func ResolveFromFlag(flag string, conf *config.Config) PipelineResolverFn { + return func(context.Context) (*pipeline.Pipeline, error) { + // if the flag is empty, pass through + if flag == "" { + return nil, nil + } + org, name := parsePipelineArg(flag, conf) + + // if we get here, we should be able to parse the value and return an error if not + // this is because a user has explicitly given an input value for us to use - we shoulnt ignore it on error + if org == "" || name == "" { + return nil, fmt.Errorf("unable to parse the input pipeline argument: \"%s\"", flag) + } + + return &pipeline.Pipeline{Name: name, Org: org}, nil + } +} diff --git a/pkg/cmd/build/view.go b/pkg/cmd/build/view.go index 5579785..b4c55cf 100644 --- a/pkg/cmd/build/view.go +++ b/pkg/cmd/build/view.go @@ -28,6 +28,7 @@ func NewCmdBuildView(f *factory.Factory) *cobra.Command { DisableFlagsInUseLine: true, Use: "view [number] [flags]", Short: "View build information.", + Args: cobra.MaximumNArgs(1), Long: heredoc.Doc(` View a build's information. @@ -38,7 +39,7 @@ func NewCmdBuildView(f *factory.Factory) *cobra.Command { buildAnnotations := make([]buildkite.Annotation, 0) pipelineRes := pipelineResolver.NewAggregateResolver( - pipelineResolver.ResolveFromPositionalArgument(args, 1, f.Config), + pipelineResolver.ResolveFromFlag(pipeline, f.Config), pipelineResolver.ResolveFromConfig(f.Config, pipelineResolver.PickOne), pipelineResolver.ResolveFromRepository(f, pipelineResolver.CachedPicker(f.Config, pipelineResolver.PickOne)), ) From 1ebf1a0ee6c89a8a4741567fa129b5d8e217b20f Mon Sep 17 00:00:00 2001 From: Jarryd Tilbrook Date: Mon, 10 Jun 2024 11:12:07 +0800 Subject: [PATCH 4/6] Update bk build cancel pipeline flag --- pkg/cmd/build/cancel.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/pkg/cmd/build/cancel.go b/pkg/cmd/build/cancel.go index 16e0266..4433c4e 100644 --- a/pkg/cmd/build/cancel.go +++ b/pkg/cmd/build/cancel.go @@ -14,28 +14,25 @@ import ( func NewCmdBuildCancel(f *factory.Factory) *cobra.Command { var web bool + var pipeline string cmd := cobra.Command{ DisableFlagsInUseLine: true, - Use: "cancel [number [pipeline]] [flags]", - Short: "Cancels a build.", + Use: "cancel [flags]", + Args: cobra.ExactArgs(1), + Short: "Cancel a build.", Long: heredoc.Doc(` - Cancels the specified build. - - It accepts a build number and a pipeline slug as an argument. - The pipeline can be a {pipeline_slug} or in the format {org_slug}/{pipeline_slug}. - If the pipeline argument is omitted, it will be resolved using the current directory. + Cancel the given build. `), RunE: func(cmd *cobra.Command, args []string) error { pipelineRes := pipelineResolver.NewAggregateResolver( - pipelineResolver.ResolveFromPositionalArgument(args, 1, f.Config), + pipelineResolver.ResolveFromFlag(pipeline, f.Config), pipelineResolver.ResolveFromConfig(f.Config, pipelineResolver.PickOne), pipelineResolver.ResolveFromRepository(f, pipelineResolver.CachedPicker(f.Config, pipelineResolver.PickOne)), ) buildRes := buildResolver.NewAggregateResolver( buildResolver.ResolveFromPositionalArgument(args, 0, pipelineRes.Resolve, f.Config), - buildResolver.ResolveBuildFromCurrentBranch(f.GitRepository, pipelineRes.Resolve, f), ) bld, err := buildRes.Resolve(cmd.Context()) @@ -51,7 +48,11 @@ func NewCmdBuildCancel(f *factory.Factory) *cobra.Command { } cmd.Flags().BoolVarP(&web, "web", "w", false, "Open the build in a web browser after it has been cancelled.") + cmd.Flags().StringVarP(&pipeline, "pipeline", "p", "", "The pipeline to cancel a build on. This can be a {pipeline slug} or in the format {org slug}/{pipeline slug}.\n"+ + "If omitted, it will be resolved using the current directory.", + ) cmd.Flags().SortFlags = false + return &cmd } From b72d126c80d0165dc30c695eeacc939833f41073 Mon Sep 17 00:00:00 2001 From: Jarryd Tilbrook Date: Mon, 10 Jun 2024 11:17:24 +0800 Subject: [PATCH 5/6] Update bk build new --- pkg/cmd/build/new.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/pkg/cmd/build/new.go b/pkg/cmd/build/new.go index d7c989c..56ac55b 100644 --- a/pkg/cmd/build/new.go +++ b/pkg/cmd/build/new.go @@ -14,25 +14,24 @@ import ( ) func NewCmdBuildNew(f *factory.Factory) *cobra.Command { - var message string - var commit string var branch string + var commit string + var message string + var pipeline string var web bool cmd := cobra.Command{ DisableFlagsInUseLine: true, - Use: "new [pipeline] [flags]", - Short: "Creates a new pipeline build", - Args: cobra.MaximumNArgs(1), + Use: "new [flags]", + Short: "Create a new build", + Args: cobra.NoArgs, Long: heredoc.Doc(` - Creates a new build for the specified pipeline and output the URL to the build. - - The pipeline can be a {pipeline_slug} or in the format {org_slug}/{pipeline_slug}. - If the pipeline argument is omitted, it will be resolved using the current directory. + Create a new build on a pipeline. + The web URL to the build will be printed to stdout. `), RunE: func(cmd *cobra.Command, args []string) error { resolvers := resolver.NewAggregateResolver( - resolver.ResolveFromPositionalArgument(args, 0, f.Config), + resolver.ResolveFromFlag(pipeline, f.Config), resolver.ResolveFromConfig(f.Config, resolver.PickOne), resolver.ResolveFromRepository(f, resolver.CachedPicker(f.Config, resolver.PickOne)), ) @@ -53,6 +52,9 @@ func NewCmdBuildNew(f *factory.Factory) *cobra.Command { cmd.Flags().StringVarP(&commit, "commit", "c", "HEAD", "The commit to build.") cmd.Flags().StringVarP(&branch, "branch", "b", "", "The branch to build. Defaults to the default branch of the pipeline.") cmd.Flags().BoolVarP(&web, "web", "w", false, "Open the build in a web browser after it has been created.") + cmd.Flags().StringVarP(&pipeline, "pipeline", "p", "", "The pipeline to build. This can be a {pipeline slug} or in the format {org slug}/{pipeline slug}.\n"+ + "If omitted, it will be resolved using the current directory.", + ) cmd.Flags().SortFlags = false return &cmd } From 220290c4ec951680263cce46d06a5b800c0c939d Mon Sep 17 00:00:00 2001 From: Jarryd Tilbrook Date: Mon, 10 Jun 2024 11:20:08 +0800 Subject: [PATCH 6/6] Update bk build rebuild --- pkg/cmd/build/rebuild.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/pkg/cmd/build/rebuild.go b/pkg/cmd/build/rebuild.go index 2cc46cf..73c4631 100644 --- a/pkg/cmd/build/rebuild.go +++ b/pkg/cmd/build/rebuild.go @@ -14,21 +14,20 @@ import ( func NewCmdBuildRebuild(f *factory.Factory) *cobra.Command { var web bool + var pipeline string cmd := cobra.Command{ DisableFlagsInUseLine: true, - Use: "rebuild [number [pipeline]] [flags]", - Short: "Reruns a build.", + Use: "rebuild [number] [flags]", + Short: "Rebuild a build.", + Args: cobra.MaximumNArgs(1), Long: heredoc.Doc(` - Runs a new build from the specified build number and pipeline and outputs the URL to the new build. - - It accepts a build number and a pipeline slug as an argument. - The pipeline can be a {pipeline_slug} or in the format {org_slug}/{pipeline_slug}. - If the pipeline argument is omitted, it will be resolved using the current directory. + Rebuild a build. + The web URL to the build will be printed to stdout. `), RunE: func(cmd *cobra.Command, args []string) error { pipelineRes := pipelineResolver.NewAggregateResolver( - pipelineResolver.ResolveFromPositionalArgument(args, 1, f.Config), + pipelineResolver.ResolveFromFlag(pipeline, f.Config), pipelineResolver.ResolveFromConfig(f.Config, pipelineResolver.PickOne), pipelineResolver.ResolveFromRepository(f, pipelineResolver.CachedPicker(f.Config, pipelineResolver.PickOne)), ) @@ -51,6 +50,9 @@ func NewCmdBuildRebuild(f *factory.Factory) *cobra.Command { } cmd.Flags().BoolVarP(&web, "web", "w", false, "Open the build in a web browser after it has been created.") + cmd.Flags().StringVarP(&pipeline, "pipeline", "p", "", "The pipeline to build. This can be a {pipeline slug} or in the format {org slug}/{pipeline slug}.\n"+ + "If omitted, it will be resolved using the current directory.", + ) cmd.Flags().SortFlags = false return &cmd }