diff --git a/pkg/cmd/pr/create/create.go b/pkg/cmd/pr/create/create.go index 83421d88b..33a4f71fe 100644 --- a/pkg/cmd/pr/create/create.go +++ b/pkg/cmd/pr/create/create.go @@ -45,6 +45,7 @@ type CreateOptions struct { RepoOverride string Autofill bool + FillFirst bool WebMode bool RecoverFile string @@ -167,8 +168,8 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co return errors.New("`--template` is not supported when using `--body` or `--body-file`") } - if !opts.IO.CanPrompt() && !opts.WebMode && !opts.Autofill && (!opts.TitleProvided || !opts.BodyProvided) { - return cmdutil.FlagErrorf("must provide `--title` and `--body` (or `--fill`) when not running interactively") + if !opts.IO.CanPrompt() && !opts.WebMode && !(opts.Autofill || opts.FillFirst) && (!opts.TitleProvided || !opts.BodyProvided) { + return cmdutil.FlagErrorf("must provide `--title` and `--body` (or `--fill` or `fill-first`) when not running interactively") } if runF != nil { @@ -187,6 +188,7 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co fl.StringVarP(&opts.HeadBranch, "head", "H", "", "The `branch` that contains commits for your pull request (default: current branch)") fl.BoolVarP(&opts.WebMode, "web", "w", false, "Open the web browser to create a pull request") fl.BoolVarP(&opts.Autofill, "fill", "f", false, "Do not prompt for title/body and just use commit info") + fl.BoolVar(&opts.FillFirst, "fill-first", false, "Do not prompt for title/body and just use first commit info") fl.StringSliceVarP(&opts.Reviewers, "reviewer", "r", nil, "Request reviews from people or teams by their `handle`") fl.StringSliceVarP(&opts.Assignees, "assignee", "a", nil, "Assign people by their `login`. Use \"@me\" to self-assign.") fl.StringSliceVarP(&opts.Labels, "label", "l", nil, "Add labels by `name`") @@ -196,6 +198,8 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co fl.StringVar(&opts.RecoverFile, "recover", "", "Recover input from a failed run of create") fl.StringVarP(&opts.Template, "template", "T", "", "Template `file` to use as starting body text") + cmd.MarkFlagsMutuallyExclusive("fill", "fill-first") + _ = cmdutil.RegisterBranchCompletionFlags(f.GitClient, cmd, "base", "head") _ = cmd.RegisterFlagCompletionFunc("reviewer", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { @@ -392,7 +396,7 @@ func createRun(opts *CreateOptions) (err error) { return } -func initDefaultTitleBody(ctx CreateContext, state *shared.IssueMetadataState) error { +func initDefaultTitleBody(ctx CreateContext, state *shared.IssueMetadataState, opts *CreateOptions) error { baseRef := ctx.BaseTrackingBranch headRef := ctx.HeadBranch gitClient := ctx.GitClient @@ -402,7 +406,7 @@ func initDefaultTitleBody(ctx CreateContext, state *shared.IssueMetadataState) e return err } - if len(commits) == 1 { + if len(commits) == 1 || opts.FillFirst { state.Title = commits[0].Title body, err := gitClient.CommitBody(context.Background(), commits[0].Sha) if err != nil { @@ -485,8 +489,8 @@ func NewIssueState(ctx CreateContext, opts CreateOptions) (*shared.IssueMetadata Draft: opts.IsDraft, } - if opts.Autofill || !opts.TitleProvided || !opts.BodyProvided { - err := initDefaultTitleBody(ctx, state) + if opts.Autofill || opts.FillFirst || !opts.TitleProvided || !opts.BodyProvided { + err := initDefaultTitleBody(ctx, state, &opts) if err != nil && opts.Autofill { return nil, fmt.Errorf("could not compute title or body defaults: %w", err) } diff --git a/pkg/cmd/pr/create/create_test.go b/pkg/cmd/pr/create/create_test.go index 84b5cf6fa..b4282ad17 100644 --- a/pkg/cmd/pr/create/create_test.go +++ b/pkg/cmd/pr/create/create_test.go @@ -168,6 +168,32 @@ func TestNewCmdCreate(t *testing.T) { cli: "-t mytitle --template bug_fix.md --body-file body_file.md", wantsErr: true, }, + { + name: "with fill-first option", + tty: false, + cli: "--fill-first", + wantsErr: false, + wantsOpts: CreateOptions{ + Title: "", + TitleProvided: false, + Body: "", + BodyProvided: false, + Autofill: false, + FillFirst: true, + RecoverFile: "", + WebMode: false, + IsDraft: false, + BaseBranch: "", + HeadBranch: "", + MaintainerCanModify: true, + }, + }, + { + name: "fill and fill-first is mutually exclusive", + tty: false, + cli: "--fill --fill-first", + wantsErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -210,6 +236,7 @@ func TestNewCmdCreate(t *testing.T) { assert.Equal(t, tt.wantsOpts.Title, opts.Title) assert.Equal(t, tt.wantsOpts.TitleProvided, opts.TitleProvided) assert.Equal(t, tt.wantsOpts.Autofill, opts.Autofill) + assert.Equal(t, tt.wantsOpts.FillFirst, opts.FillFirst) assert.Equal(t, tt.wantsOpts.WebMode, opts.WebMode) assert.Equal(t, tt.wantsOpts.RecoverFile, opts.RecoverFile) assert.Equal(t, tt.wantsOpts.IsDraft, opts.IsDraft)