Merge pull request #7398 from kousikmitra/feature/pr-fill-first
Feature: Add `fill-first` flag to `pr create` command
This commit is contained in:
commit
4c918e90a6
2 changed files with 89 additions and 9 deletions
|
|
@ -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) {
|
||||
|
|
@ -281,7 +285,7 @@ func createRun(opts *CreateOptions) (err error) {
|
|||
ghrepo.FullName(ctx.BaseRepo))
|
||||
}
|
||||
|
||||
if opts.Autofill || (opts.TitleProvided && opts.BodyProvided) {
|
||||
if opts.Autofill || opts.FillFirst || (opts.TitleProvided && opts.BodyProvided) {
|
||||
err = handlePush(*opts, *ctx)
|
||||
if err != nil {
|
||||
return
|
||||
|
|
@ -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
|
||||
|
|
@ -401,8 +405,15 @@ func initDefaultTitleBody(ctx CreateContext, state *shared.IssueMetadataState) e
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(commits) == 1 {
|
||||
if opts.FillFirst {
|
||||
firstCommitIndex := len(commits) - 1
|
||||
state.Title = commits[firstCommitIndex].Title
|
||||
body, err := gitClient.CommitBody(context.Background(), commits[firstCommitIndex].Sha)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
state.Body = body
|
||||
} else if len(commits) == 1 {
|
||||
state.Title = commits[0].Title
|
||||
body, err := gitClient.CommitBody(context.Background(), commits[0].Sha)
|
||||
if err != nil {
|
||||
|
|
@ -485,9 +496,9 @@ func NewIssueState(ctx CreateContext, opts CreateOptions) (*shared.IssueMetadata
|
|||
Draft: opts.IsDraft,
|
||||
}
|
||||
|
||||
if opts.Autofill || !opts.TitleProvided || !opts.BodyProvided {
|
||||
err := initDefaultTitleBody(ctx, state)
|
||||
if err != nil && opts.Autofill {
|
||||
if opts.Autofill || opts.FillFirst || !opts.TitleProvided || !opts.BodyProvided {
|
||||
err := initDefaultTitleBody(ctx, state, &opts)
|
||||
if err != nil && (opts.Autofill || opts.FillFirst) {
|
||||
return nil, fmt.Errorf("could not compute title or body defaults: %w", err)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -969,6 +996,48 @@ func Test_createRun(t *testing.T) {
|
|||
},
|
||||
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
|
||||
},
|
||||
{
|
||||
name: "fill-first flag provided",
|
||||
tty: true,
|
||||
setup: func(opts *CreateOptions, t *testing.T) func() {
|
||||
opts.TitleProvided = false
|
||||
opts.FillFirst = true
|
||||
opts.HeadBranch = "feature"
|
||||
return func() {}
|
||||
},
|
||||
cmdStubs: func(cs *run.CommandStubber) {
|
||||
cs.Register(
|
||||
"git -c log.ShowSignature=false log --pretty=format:%H,%s --cherry origin/master...feature",
|
||||
0,
|
||||
"56b6f8bb7c9e3a30093cd17e48934ce354148e80,second commit of pr\n"+
|
||||
"343jdfe47c9e3a30093cd17e48934ce354148e80,first commit of pr",
|
||||
)
|
||||
cs.Register(
|
||||
"git -c log.ShowSignature=false show -s --pretty=format:%b 343jdfe47c9e3a30093cd17e48934ce354148e80",
|
||||
0,
|
||||
"first commit description",
|
||||
)
|
||||
},
|
||||
httpStubs: func(reg *httpmock.Registry, t *testing.T) {
|
||||
reg.Register(
|
||||
httpmock.GraphQL(`mutation PullRequestCreate\b`),
|
||||
httpmock.GraphQLMutation(`
|
||||
{
|
||||
"data": { "createPullRequest": { "pullRequest": {
|
||||
"URL": "https://github.com/OWNER/REPO/pull/12"
|
||||
} } }
|
||||
}
|
||||
`,
|
||||
func(input map[string]interface{}) {
|
||||
assert.Equal(t, "first commit of pr", input["title"], "pr title should be first commit message")
|
||||
assert.Equal(t, "first commit description", input["body"], "pr body should be first commit description")
|
||||
},
|
||||
),
|
||||
)
|
||||
},
|
||||
expectedOut: "https://github.com/OWNER/REPO/pull/12\n",
|
||||
expectedErrOut: "\nCreating pull request for feature into master in OWNER/REPO\n\n",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue