X Tutup
Skip to content

Commit 28c2d04

Browse files
committed
Extend @me replacing behavior to issue list
1 parent 6ad0c57 commit 28c2d04

File tree

6 files changed

+104
-30
lines changed

6 files changed

+104
-30
lines changed

pkg/cmd/issue/create/create.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/cli/cli/api"
1010
"github.com/cli/cli/internal/config"
1111
"github.com/cli/cli/internal/ghrepo"
12+
"github.com/cli/cli/pkg/cmd/pr/shared"
1213
prShared "github.com/cli/cli/pkg/cmd/pr/shared"
1314
"github.com/cli/cli/pkg/cmdutil"
1415
"github.com/cli/cli/pkg/iostreams"
@@ -115,9 +116,15 @@ func createRun(opts *CreateOptions) (err error) {
115116
milestones = []string{opts.Milestone}
116117
}
117118

119+
meReplacer := shared.NewMeReplacer(apiClient, baseRepo.RepoHost())
120+
assignees, err := meReplacer.ReplaceSlice(opts.Assignees)
121+
if err != nil {
122+
return err
123+
}
124+
118125
tb := prShared.IssueMetadataState{
119126
Type: prShared.IssueMetadata,
120-
Assignees: opts.Assignees,
127+
Assignees: assignees,
121128
Labels: opts.Labels,
122129
Projects: opts.Projects,
123130
Milestones: milestones,
@@ -133,11 +140,6 @@ func createRun(opts *CreateOptions) (err error) {
133140
}
134141
}
135142

136-
opts.Assignees, err = prShared.ReplaceAtMeLogin(opts.Assignees, apiClient, baseRepo)
137-
if err != nil {
138-
return err
139-
}
140-
141143
if opts.WebMode {
142144
openURL := ghrepo.GenerateRepoURL(baseRepo, "issues/new")
143145
if opts.Title != "" || opts.Body != "" || len(opts.Assignees) > 0 {

pkg/cmd/issue/list/list.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/cli/cli/internal/config"
1010
"github.com/cli/cli/internal/ghrepo"
1111
issueShared "github.com/cli/cli/pkg/cmd/issue/shared"
12+
"github.com/cli/cli/pkg/cmd/pr/shared"
1213
prShared "github.com/cli/cli/pkg/cmd/pr/shared"
1314
"github.com/cli/cli/pkg/cmdutil"
1415
"github.com/cli/cli/pkg/iostreams"
@@ -91,15 +92,29 @@ func listRun(opts *ListOptions) error {
9192

9293
isTerminal := opts.IO.IsStdoutTTY()
9394

95+
meReplacer := shared.NewMeReplacer(apiClient, baseRepo.RepoHost())
96+
filterAssignee, err := meReplacer.Replace(opts.Assignee)
97+
if err != nil {
98+
return err
99+
}
100+
filterAuthor, err := meReplacer.Replace(opts.Author)
101+
if err != nil {
102+
return err
103+
}
104+
filterMention, err := meReplacer.Replace(opts.Mention)
105+
if err != nil {
106+
return err
107+
}
108+
94109
if opts.WebMode {
95110
issueListURL := ghrepo.GenerateRepoURL(baseRepo, "issues")
96111
openURL, err := prShared.ListURLWithQuery(issueListURL, prShared.FilterOptions{
97112
Entity: "issue",
98113
State: opts.State,
99-
Assignee: opts.Assignee,
114+
Assignee: filterAssignee,
100115
Labels: opts.Labels,
101-
Author: opts.Author,
102-
Mention: opts.Mention,
116+
Author: filterAuthor,
117+
Mention: filterMention,
103118
Milestone: opts.Milestone,
104119
})
105120
if err != nil {
@@ -111,7 +126,7 @@ func listRun(opts *ListOptions) error {
111126
return utils.OpenInBrowser(openURL)
112127
}
113128

114-
listResult, err := api.IssueList(apiClient, baseRepo, opts.State, opts.Labels, opts.Assignee, opts.LimitResults, opts.Author, opts.Mention, opts.Milestone)
129+
listResult, err := api.IssueList(apiClient, baseRepo, opts.State, opts.Labels, filterAssignee, opts.LimitResults, filterAuthor, filterMention, opts.Milestone)
115130
if err != nil {
116131
return err
117132
}

pkg/cmd/issue/list/list_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,31 @@ No issues match your search in OWNER/REPO
147147
`, output.String())
148148
}
149149

150+
func TestIssueList_atMe(t *testing.T) {
151+
http := &httpmock.Registry{}
152+
defer http.Verify(t)
153+
154+
http.Register(
155+
httpmock.GraphQL(`query UserCurrent\b`),
156+
httpmock.StringResponse(`{"data": {"viewer": {"login": "monalisa"} } }`))
157+
http.Register(
158+
httpmock.GraphQL(`query IssueList\b`),
159+
httpmock.GraphQLQuery(`
160+
{ "data": { "repository": {
161+
"hasIssuesEnabled": true,
162+
"issues": { "nodes": [] }
163+
} } }`, func(_ string, params map[string]interface{}) {
164+
assert.Equal(t, "monalisa", params["assignee"].(string))
165+
assert.Equal(t, "monalisa", params["author"].(string))
166+
assert.Equal(t, "monalisa", params["mention"].(string))
167+
}))
168+
169+
_, err := runCommand(http, true, "-a @me -A @me --mention @me")
170+
if err != nil {
171+
t.Errorf("error running command `issue list`: %v", err)
172+
}
173+
}
174+
150175
func TestIssueList_withInvalidLimitFlag(t *testing.T) {
151176
http := &httpmock.Registry{}
152177
defer http.Verify(t)

pkg/cmd/pr/create/create.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,10 +386,16 @@ func NewIssueState(ctx CreateContext, opts CreateOptions) (*shared.IssueMetadata
386386
milestoneTitles = []string{opts.Milestone}
387387
}
388388

389+
meReplacer := shared.NewMeReplacer(ctx.Client, ctx.BaseRepo.RepoHost())
390+
assignees, err := meReplacer.ReplaceSlice(opts.Assignees)
391+
if err != nil {
392+
return nil, err
393+
}
394+
389395
state := &shared.IssueMetadataState{
390396
Type: shared.PRMetadata,
391397
Reviewers: opts.Reviewers,
392-
Assignees: opts.Assignees,
398+
Assignees: assignees,
393399
Labels: opts.Labels,
394400
Projects: opts.Projects,
395401
Milestones: milestoneTitles,

pkg/cmd/pr/shared/params.go

Lines changed: 41 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,6 @@ func AddMetadataToIssueParams(client *api.Client, baseRepo ghrepo.Interface, par
8181
return nil
8282
}
8383

84-
var err error
85-
if tb.Assignees, err = ReplaceAtMeLogin(tb.Assignees, client, baseRepo); err != nil {
86-
return err
87-
}
88-
8984
if err := fillMetadata(client, baseRepo, tb); err != nil {
9085
return err
9186
}
@@ -196,17 +191,47 @@ func quoteValueForQuery(v string) string {
196191
return v
197192
}
198193

199-
// ReplaceAtMeLogin iterates over the list of specified login names, replacing
200-
// any "@me" mentions with the current user LoginName.
201-
func ReplaceAtMeLogin(logins []string, client *api.Client, repo ghrepo.Interface) ([]string, error) {
202-
for i, u := range logins {
203-
if strings.EqualFold(u, "@me") {
204-
login, err := api.CurrentLoginName(client, repo.RepoHost())
205-
if err != nil {
206-
return logins, fmt.Errorf("@me resolve: failed obtaining user id: %w", err)
207-
}
208-
logins[i] = login
194+
// MeReplacer resolves usages of `@me` to the handle of the currently logged in user.
195+
type MeReplacer struct {
196+
apiClient *api.Client
197+
hostname string
198+
login string
199+
}
200+
201+
func NewMeReplacer(apiClient *api.Client, hostname string) *MeReplacer {
202+
return &MeReplacer{
203+
apiClient: apiClient,
204+
hostname: hostname,
205+
}
206+
}
207+
208+
func (r *MeReplacer) currentLogin() (string, error) {
209+
if r.login != "" {
210+
return r.login, nil
211+
}
212+
login, err := api.CurrentLoginName(r.apiClient, r.hostname)
213+
if err != nil {
214+
return "", fmt.Errorf("failed resolving `@me` to your user handle: %w", err)
215+
}
216+
r.login = login
217+
return login, nil
218+
}
219+
220+
func (r *MeReplacer) Replace(handle string) (string, error) {
221+
if handle == "@me" {
222+
return r.currentLogin()
223+
}
224+
return handle, nil
225+
}
226+
227+
func (r *MeReplacer) ReplaceSlice(handles []string) ([]string, error) {
228+
res := make([]string, len(handles))
229+
for i, h := range handles {
230+
var err error
231+
res[i], err = r.Replace(h)
232+
if err != nil {
233+
return nil, err
209234
}
210235
}
211-
return logins, nil
236+
return res, nil
212237
}

pkg/cmd/pr/shared/params_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func Test_listURLWithQuery(t *testing.T) {
7878
}
7979
}
8080

81-
func TestReplaceAtMeLogin(t *testing.T) {
81+
func TestMeReplacer_Replace(t *testing.T) {
8282
rtSuccess := &httpmock.Registry{}
8383
rtSuccess.Register(
8484
httpmock.GraphQL(`query UserCurrent\b`),
@@ -129,13 +129,14 @@ func TestReplaceAtMeLogin(t *testing.T) {
129129
logins: []string{"some", "@me", "other"},
130130
},
131131
verify: rtFailure.Verify,
132-
want: []string{"some", "@me", "other"},
132+
want: []string(nil),
133133
wantErr: true,
134134
},
135135
}
136136
for _, tt := range tests {
137137
t.Run(tt.name, func(t *testing.T) {
138-
got, err := ReplaceAtMeLogin(tt.args.logins, tt.args.client, tt.args.repo)
138+
me := NewMeReplacer(tt.args.client, tt.args.repo.RepoHost())
139+
got, err := me.ReplaceSlice(tt.args.logins)
139140
if (err != nil) != tt.wantErr {
140141
t.Errorf("ReplaceAtMeLogin() error = %v, wantErr %v", err, tt.wantErr)
141142
return

0 commit comments

Comments
 (0)
X Tutup