X Tutup
Skip to content

Commit f415245

Browse files
authored
Merge pull request cli#2472 from cristiand391/preserve-metadata-state
Prompt: avoid resetting PR/issue metadata
2 parents 8e1f736 + 8db2027 commit f415245

File tree

7 files changed

+280
-42
lines changed

7 files changed

+280
-42
lines changed

api/queries_repo.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,28 @@ func (m *RepoMetadataResult) MilestoneToID(title string) (string, error) {
464464
return "", errors.New("not found")
465465
}
466466

467+
func (m *RepoMetadataResult) Merge(m2 *RepoMetadataResult) {
468+
if len(m2.AssignableUsers) > 0 || len(m.AssignableUsers) == 0 {
469+
m.AssignableUsers = m2.AssignableUsers
470+
}
471+
472+
if len(m2.Teams) > 0 || len(m.Teams) == 0 {
473+
m.Teams = m2.Teams
474+
}
475+
476+
if len(m2.Labels) > 0 || len(m.Labels) == 0 {
477+
m.Labels = m2.Labels
478+
}
479+
480+
if len(m2.Projects) > 0 || len(m.Projects) == 0 {
481+
m.Projects = m2.Projects
482+
}
483+
484+
if len(m2.Milestones) > 0 || len(m.Milestones) == 0 {
485+
m.Milestones = m2.Milestones
486+
}
487+
}
488+
467489
type RepoMetadataInput struct {
468490
Assignees bool
469491
Reviewers bool

pkg/cmd/issue/create/create.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,13 @@ func createRun(opts *CreateOptions) (err error) {
206206
}
207207

208208
if action == prShared.MetadataAction {
209-
err = prShared.MetadataSurvey(opts.IO, apiClient, baseRepo, &tb)
209+
fetcher := &prShared.MetadataFetcher{
210+
IO: opts.IO,
211+
APIClient: apiClient,
212+
Repo: baseRepo,
213+
State: &tb,
214+
}
215+
err = prShared.MetadataSurvey(opts.IO, baseRepo, fetcher, &tb)
210216
if err != nil {
211217
return
212218
}

pkg/cmd/pr/create/create.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,13 @@ func createRun(opts *CreateOptions) (err error) {
259259
}
260260

261261
if action == shared.MetadataAction {
262-
err = shared.MetadataSurvey(opts.IO, client, ctx.BaseRepo, state)
262+
fetcher := &shared.MetadataFetcher{
263+
IO: opts.IO,
264+
APIClient: client,
265+
Repo: ctx.BaseRepo,
266+
State: state,
267+
}
268+
err = shared.MetadataSurvey(opts.IO, ctx.BaseRepo, fetcher, state)
263269
if err != nil {
264270
return
265271
}
@@ -380,7 +386,7 @@ func NewIssueState(ctx CreateContext, opts CreateOptions) (*shared.IssueMetadata
380386

381387
if opts.Autofill || !opts.TitleProvided || !opts.BodyProvided {
382388
err := initDefaultTitleBody(ctx, state)
383-
if err != nil {
389+
if err != nil && opts.Autofill {
384390
return nil, fmt.Errorf("could not compute title or body defaults: %w", err)
385391
}
386392
}

pkg/cmd/pr/shared/params.go

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,25 +37,53 @@ func WithPrAndIssueQueryParams(baseURL string, state IssueMetadataState) (string
3737
return u.String(), nil
3838
}
3939

40+
// Ensure that tb.MetadataResult object exists and contains enough pre-fetched API data to be able
41+
// to resolve all object listed in tb to GraphQL IDs.
42+
func fillMetadata(client *api.Client, baseRepo ghrepo.Interface, tb *IssueMetadataState) error {
43+
resolveInput := api.RepoResolveInput{}
44+
45+
if len(tb.Assignees) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.AssignableUsers) == 0) {
46+
resolveInput.Assignees = tb.Assignees
47+
}
48+
49+
if len(tb.Reviewers) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.AssignableUsers) == 0) {
50+
resolveInput.Reviewers = tb.Reviewers
51+
}
52+
53+
if len(tb.Labels) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.Labels) == 0) {
54+
resolveInput.Labels = tb.Labels
55+
}
56+
57+
if len(tb.Projects) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.Projects) == 0) {
58+
resolveInput.Projects = tb.Projects
59+
}
60+
61+
if len(tb.Milestones) > 0 && (tb.MetadataResult == nil || len(tb.MetadataResult.Milestones) == 0) {
62+
resolveInput.Milestones = tb.Milestones
63+
}
64+
65+
metadataResult, err := api.RepoResolveMetadataIDs(client, baseRepo, resolveInput)
66+
if err != nil {
67+
return err
68+
}
69+
70+
if tb.MetadataResult == nil {
71+
tb.MetadataResult = metadataResult
72+
} else {
73+
tb.MetadataResult.Merge(metadataResult)
74+
}
75+
76+
return nil
77+
}
78+
4079
func AddMetadataToIssueParams(client *api.Client, baseRepo ghrepo.Interface, params map[string]interface{}, tb *IssueMetadataState) error {
4180
if !tb.HasMetadata() {
4281
return nil
4382
}
4483

45-
if tb.MetadataResult == nil {
46-
resolveInput := api.RepoResolveInput{
47-
Reviewers: tb.Reviewers,
48-
Assignees: tb.Assignees,
49-
Labels: tb.Labels,
50-
Projects: tb.Projects,
51-
Milestones: tb.Milestones,
52-
}
53-
54-
var err error
55-
tb.MetadataResult, err = api.RepoResolveMetadataIDs(client, baseRepo, resolveInput)
56-
if err != nil {
57-
return err
58-
}
84+
err := fillMetadata(client, baseRepo, tb)
85+
if err != nil {
86+
return err
5987
}
6088

6189
assigneeIDs, err := tb.MetadataResult.MembersToIDs(tb.Assignees)

pkg/cmd/pr/shared/survey.go

Lines changed: 54 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"github.com/cli/cli/pkg/iostreams"
1313
"github.com/cli/cli/pkg/prompt"
1414
"github.com/cli/cli/pkg/surveyext"
15-
"github.com/cli/cli/utils"
1615
)
1716

1817
type Action int
@@ -196,7 +195,26 @@ func TitleSurvey(state *IssueMetadataState) error {
196195
return nil
197196
}
198197

199-
func MetadataSurvey(io *iostreams.IOStreams, client *api.Client, baseRepo ghrepo.Interface, state *IssueMetadataState) error {
198+
type MetadataFetcher struct {
199+
IO *iostreams.IOStreams
200+
APIClient *api.Client
201+
Repo ghrepo.Interface
202+
State *IssueMetadataState
203+
}
204+
205+
func (mf *MetadataFetcher) RepoMetadataFetch(input api.RepoMetadataInput) (*api.RepoMetadataResult, error) {
206+
mf.IO.StartProgressIndicator()
207+
metadataResult, err := api.RepoMetadata(mf.APIClient, mf.Repo, input)
208+
mf.IO.StopProgressIndicator()
209+
mf.State.MetadataResult = metadataResult
210+
return metadataResult, err
211+
}
212+
213+
type RepoMetadataFetcher interface {
214+
RepoMetadataFetch(api.RepoMetadataInput) (*api.RepoMetadataResult, error)
215+
}
216+
217+
func MetadataSurvey(io *iostreams.IOStreams, baseRepo ghrepo.Interface, fetcher RepoMetadataFetcher, state *IssueMetadataState) error {
200218
isChosen := func(m string) bool {
201219
for _, c := range state.Metadata {
202220
if m == c {
@@ -234,42 +252,32 @@ func MetadataSurvey(io *iostreams.IOStreams, client *api.Client, baseRepo ghrepo
234252
Projects: isChosen("Projects"),
235253
Milestones: isChosen("Milestone"),
236254
}
237-
s := utils.Spinner(io.ErrOut)
238-
utils.StartSpinner(s)
239-
state.MetadataResult, err = api.RepoMetadata(client, baseRepo, metadataInput)
240-
utils.StopSpinner(s)
255+
metadataResult, err := fetcher.RepoMetadataFetch(metadataInput)
241256
if err != nil {
242257
return fmt.Errorf("error fetching metadata options: %w", err)
243258
}
244259

245260
var users []string
246-
for _, u := range state.MetadataResult.AssignableUsers {
261+
for _, u := range metadataResult.AssignableUsers {
247262
users = append(users, u.Login)
248263
}
249264
var teams []string
250-
for _, t := range state.MetadataResult.Teams {
265+
for _, t := range metadataResult.Teams {
251266
teams = append(teams, fmt.Sprintf("%s/%s", baseRepo.RepoOwner(), t.Slug))
252267
}
253268
var labels []string
254-
for _, l := range state.MetadataResult.Labels {
269+
for _, l := range metadataResult.Labels {
255270
labels = append(labels, l.Name)
256271
}
257272
var projects []string
258-
for _, l := range state.MetadataResult.Projects {
273+
for _, l := range metadataResult.Projects {
259274
projects = append(projects, l.Name)
260275
}
261276
milestones := []string{noMilestone}
262-
for _, m := range state.MetadataResult.Milestones {
277+
for _, m := range metadataResult.Milestones {
263278
milestones = append(milestones, m.Title)
264279
}
265280

266-
type metadataValues struct {
267-
Reviewers []string
268-
Assignees []string
269-
Labels []string
270-
Projects []string
271-
Milestone string
272-
}
273281
var mqs []*survey.Question
274282
if isChosen("Reviewers") {
275283
if len(users) > 0 || len(teams) > 0 {
@@ -345,17 +353,38 @@ func MetadataSurvey(io *iostreams.IOStreams, client *api.Client, baseRepo ghrepo
345353
fmt.Fprintln(io.ErrOut, "warning: no milestones in the repository")
346354
}
347355
}
348-
values := metadataValues{}
356+
357+
values := struct {
358+
Reviewers []string
359+
Assignees []string
360+
Labels []string
361+
Projects []string
362+
Milestone string
363+
}{}
364+
349365
err = prompt.SurveyAsk(mqs, &values, survey.WithKeepFilter(true))
350366
if err != nil {
351367
return fmt.Errorf("could not prompt: %w", err)
352368
}
353-
state.Reviewers = values.Reviewers
354-
state.Assignees = values.Assignees
355-
state.Labels = values.Labels
356-
state.Projects = values.Projects
357-
if values.Milestone != "" && values.Milestone != noMilestone {
358-
state.Milestones = []string{values.Milestone}
369+
370+
if isChosen("Reviewers") {
371+
state.Reviewers = values.Reviewers
372+
}
373+
if isChosen("Assignees") {
374+
state.Assignees = values.Assignees
375+
}
376+
if isChosen("Labels") {
377+
state.Labels = values.Labels
378+
}
379+
if isChosen("Projects") {
380+
state.Projects = values.Projects
381+
}
382+
if isChosen("Milestone") {
383+
if values.Milestone != "" && values.Milestone != noMilestone {
384+
state.Milestones = []string{values.Milestone}
385+
} else {
386+
state.Milestones = []string{}
387+
}
359388
}
360389

361390
return nil

0 commit comments

Comments
 (0)
X Tutup