X Tutup
Skip to content

Commit 59b4d5c

Browse files
rneatherwaymislav
authored andcommitted
Support standard path variable replacement syntax
Add support for the following synonyms: {owner} for :owner {repo} for :repo {branch} for :branch
1 parent d478a65 commit 59b4d5c

File tree

2 files changed

+72
-13
lines changed

2 files changed

+72
-13
lines changed

pkg/cmd/api/api.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func NewCmdApi(f *cmdutil.Factory, runF func(*ApiOptions) error) *cobra.Command
7171
The endpoint argument should either be a path of a GitHub API v3 endpoint, or
7272
"graphql" to access the GitHub API v4.
7373
74-
Placeholder values ":owner", ":repo", and ":branch" in the endpoint argument will
74+
Placeholder values "{owner}", "{repo}", and "{branch}" in the endpoint argument will
7575
get replaced with values from the repository of the current directory.
7676
7777
The default HTTP request method is "GET" normally and "POST" if any parameters
@@ -87,7 +87,7 @@ func NewCmdApi(f *cmdutil.Factory, runF func(*ApiOptions) error) *cobra.Command
8787
8888
- literal values "true", "false", "null", and integer numbers get converted to
8989
appropriate JSON types;
90-
- placeholder values ":owner", ":repo", and ":branch" get populated with values
90+
- placeholder values "{owner}", "{repo}", and "{branch}" get populated with values
9191
from the repository of the current directory;
9292
- if the value starts with "@", the rest of the value is interpreted as a
9393
filename to read the value from. Pass "-" to read from standard input.
@@ -106,10 +106,10 @@ func NewCmdApi(f *cmdutil.Factory, runF func(*ApiOptions) error) *cobra.Command
106106
`, "`"),
107107
Example: heredoc.Doc(`
108108
# list releases in the current repository
109-
$ gh api repos/:owner/:repo/releases
109+
$ gh api repos/{owner}/{repo}/releases
110110
111111
# post an issue comment
112-
$ gh api repos/:owner/:repo/issues/123/comments -f body='Hi from CLI'
112+
$ gh api repos/{owner}/{repo}/issues/123/comments -f body='Hi from CLI'
113113
114114
# add parameters to a GET request
115115
$ gh api -X GET search/issues -f q='repo:cli/cli is:open remote'
@@ -121,14 +121,14 @@ func NewCmdApi(f *cmdutil.Factory, runF func(*ApiOptions) error) *cobra.Command
121121
$ gh api --preview baptiste,nebula ...
122122
123123
# print only specific fields from the response
124-
$ gh api repos/:owner/:repo/issues --jq '.[].title'
124+
$ gh api repos/{owner}/{repo}/issues --jq '.[].title'
125125
126126
# use a template for the output
127-
$ gh api repos/:owner/:repo/issues --template \
127+
$ gh api repos/{owner}/{repo}/issues --template \
128128
'{{range .}}{{.title}} ({{.labels | pluck "name" | join ", " | color "yellow"}}){{"\n"}}{{end}}'
129129
130130
# list releases with GraphQL
131-
$ gh api graphql -F owner=':owner' -F name=':repo' -f query='
131+
$ gh api graphql -F owner='{owner}' -F name='{repo}' -f query='
132132
query($name: String!, $owner: String!) {
133133
repository(owner: $owner, name: $name) {
134134
releases(last: 3) {
@@ -397,9 +397,9 @@ func processResponse(resp *http.Response, opts *ApiOptions, headersOutputStream
397397
return
398398
}
399399

400-
var placeholderRE = regexp.MustCompile(`\:(owner|repo|branch)\b`)
400+
var placeholderRE = regexp.MustCompile(`(\:(owner|repo|branch)\b|\{(owner|repo|branch)\})`)
401401

402-
// fillPlaceholders populates `:owner` and `:repo` placeholders with values from the current repository
402+
// fillPlaceholders populates `{owner}` and `{repo}` placeholders with values from the current repository
403403
func fillPlaceholders(value string, opts *ApiOptions) (string, error) {
404404
if !placeholderRE.MatchString(value) {
405405
return value, nil
@@ -412,11 +412,11 @@ func fillPlaceholders(value string, opts *ApiOptions) (string, error) {
412412

413413
filled := placeholderRE.ReplaceAllStringFunc(value, func(m string) string {
414414
switch m {
415-
case ":owner":
415+
case ":owner", "{owner}":
416416
return baseRepo.RepoOwner()
417-
case ":repo":
417+
case ":repo", "{repo}":
418418
return baseRepo.RepoName()
419-
case ":branch":
419+
case ":branch", "{branch}":
420420
branch, e := opts.Branch()
421421
if e != nil {
422422
err = e

pkg/cmd/api/api_test.go

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ func Test_magicFieldValue(t *testing.T) {
870870
wantErr: false,
871871
},
872872
{
873-
name: "placeholder",
873+
name: "placeholder colon",
874874
args: args{
875875
v: ":owner",
876876
opts: &ApiOptions{
@@ -883,6 +883,20 @@ func Test_magicFieldValue(t *testing.T) {
883883
want: "hubot",
884884
wantErr: false,
885885
},
886+
{
887+
name: "placeholder braces",
888+
args: args{
889+
v: "{owner}",
890+
opts: &ApiOptions{
891+
IO: io,
892+
BaseRepo: func() (ghrepo.Interface, error) {
893+
return ghrepo.New("hubot", "robot-uprising"), nil
894+
},
895+
},
896+
},
897+
want: "hubot",
898+
wantErr: false,
899+
},
886900
{
887901
name: "file",
888902
args: args{
@@ -1008,6 +1022,51 @@ func Test_fillPlaceholders(t *testing.T) {
10081022
want: "repos/:owner/:repo/branches/:branch",
10091023
wantErr: true,
10101024
},
1025+
{
1026+
name: "has substitutes (braces)",
1027+
args: args{
1028+
value: "repos/{owner}/{repo}/releases",
1029+
opts: &ApiOptions{
1030+
BaseRepo: func() (ghrepo.Interface, error) {
1031+
return ghrepo.New("hubot", "robot-uprising"), nil
1032+
},
1033+
},
1034+
},
1035+
want: "repos/hubot/robot-uprising/releases",
1036+
wantErr: false,
1037+
},
1038+
{
1039+
name: "has branch placeholder (braces)",
1040+
args: args{
1041+
value: "repos/cli/cli/branches/{branch}/protection/required_status_checks",
1042+
opts: &ApiOptions{
1043+
BaseRepo: func() (ghrepo.Interface, error) {
1044+
return ghrepo.New("cli", "cli"), nil
1045+
},
1046+
Branch: func() (string, error) {
1047+
return "trunk", nil
1048+
},
1049+
},
1050+
},
1051+
want: "repos/cli/cli/branches/trunk/protection/required_status_checks",
1052+
wantErr: false,
1053+
},
1054+
{
1055+
name: "has branch placeholder and git is in detached head (braces)",
1056+
args: args{
1057+
value: "repos/{owner}/{repo}/branches/{branch}",
1058+
opts: &ApiOptions{
1059+
BaseRepo: func() (ghrepo.Interface, error) {
1060+
return ghrepo.New("cli", "cli"), nil
1061+
},
1062+
Branch: func() (string, error) {
1063+
return "", git.ErrNotOnAnyBranch
1064+
},
1065+
},
1066+
},
1067+
want: "repos/{owner}/{repo}/branches/{branch}",
1068+
wantErr: true,
1069+
},
10111070
{
10121071
name: "no greedy substitutes",
10131072
args: args{

0 commit comments

Comments
 (0)
X Tutup