X Tutup
Skip to content

Commit 7c8b686

Browse files
committed
Merge branch 'trunk' of https://github.com/cli/cli into feature/repo-with-gitignore-license
2 parents 5c96d5d + dd3aac7 commit 7c8b686

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+2533
-913
lines changed

.github/CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Run the new binary as:
3636

3737
Run tests with: `go test ./...`
3838

39-
See [project layout documentation](../project-layout.md) for information on where to find specific source files.
39+
See [project layout documentation](../docs/project-layout.md) for information on where to find specific source files.
4040

4141
## Submitting a pull request
4242

README.md

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@ GitHub CLI is available for repositories hosted on GitHub.com and GitHub Enterpr
1414

1515
If anything feels off, or if you feel that some functionality is missing, please check out the [contributing page][contributing]. There you will find instructions for sharing your feedback, building the tool locally, and submitting pull requests to the project.
1616

17-
1817
<!-- this anchor is linked to from elsewhere, so avoid renaming it -->
1918
## Installation
2019

2120
### macOS
2221

23-
`gh` is available via [Homebrew][], [MacPorts][], and as a downloadable binary from the [releases page][].
22+
`gh` is available via [Homebrew][], [MacPorts][], [Conda][], and as a downloadable binary from the [releases page][].
2423

2524
#### Homebrew
2625

@@ -34,24 +33,29 @@ If anything feels off, or if you feel that some functionality is missing, please
3433
| ---------------------- | ---------------------------------------------- |
3534
| `sudo port install gh` | `sudo port selfupdate && sudo port upgrade gh` |
3635

36+
#### Conda
37+
38+
| Install: | Upgrade: |
39+
|------------------------------------------|-----------------------------------------|
40+
| `conda install gh --channel conda-forge` | `conda update gh --channel conda-forge` |
41+
42+
Additional Conda installation options available on the [gh-feedstock page](https://github.com/conda-forge/gh-feedstock#installing-gh).
43+
3744
### Linux
3845

39-
`gh` is available via [Homebrew](#homebrew), and as downloadable binaries from the [releases page][].
46+
`gh` is available via [Homebrew](#homebrew), [Conda](#Conda), and as downloadable binaries from the [releases page][].
4047

4148
For more information and distro-specific instructions, see the [Linux installation docs](./docs/install_linux.md).
4249

4350
### Windows
4451

45-
`gh` is available via [WinGet][], [scoop][], [Chocolatey][], and as downloadable MSI.
46-
52+
`gh` is available via [WinGet][], [scoop][], [Chocolatey][], [Conda](#Conda), and as downloadable MSI.
4753

4854
#### WinGet
4955

5056
| Install: | Upgrade: |
5157
| ------------------- | --------------------|
52-
| `winget install gh` | `winget install gh` |
53-
54-
<i>WinGet does not have a specialized `upgrade` command yet, but the `install` command should work for upgrading to a newer version of GitHub CLI.</i>
58+
| `winget install gh` | `winget upgrade gh` |
5559

5660
#### scoop
5761

@@ -88,13 +92,13 @@ what an official GitHub CLI tool can look like with a fundamentally different de
8892
tools bring GitHub to the terminal, `hub` behaves as a proxy to `git`, and `gh` is a standalone
8993
tool. Check out our [more detailed explanation][gh-vs-hub] to learn more.
9094

91-
9295
[manual]: https://cli.github.com/manual/
9396
[Homebrew]: https://brew.sh
9497
[MacPorts]: https://www.macports.org
9598
[winget]: https://github.com/microsoft/winget-cli
9699
[scoop]: https://scoop.sh
97100
[Chocolatey]: https://chocolatey.org
101+
[Conda]: https://docs.conda.io/en/latest/
98102
[releases page]: https://github.com/cli/cli/releases/latest
99103
[hub]: https://github.com/github/hub
100104
[contributing]: ./.github/CONTRIBUTING.md

api/export_pr.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,20 @@ func (pr *PullRequest) ExportData(fields []string) *map[string]interface{} {
8080
case "reviewRequests":
8181
requests := make([]interface{}, 0, len(pr.ReviewRequests.Nodes))
8282
for _, req := range pr.ReviewRequests.Nodes {
83-
if req.RequestedReviewer.TypeName == "" {
84-
continue
83+
r := req.RequestedReviewer
84+
switch r.TypeName {
85+
case "User":
86+
requests = append(requests, map[string]string{
87+
"__typename": r.TypeName,
88+
"login": r.Login,
89+
})
90+
case "Team":
91+
requests = append(requests, map[string]string{
92+
"__typename": r.TypeName,
93+
"name": r.Name,
94+
"slug": r.LoginOrSlug(),
95+
})
8596
}
86-
requests = append(requests, req.RequestedReviewer)
8797
}
8898
data[f] = &requests
8999
default:

api/queries_pr.go

Lines changed: 31 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -150,28 +150,33 @@ type PullRequestFile struct {
150150

151151
type ReviewRequests struct {
152152
Nodes []struct {
153-
RequestedReviewer struct {
154-
TypeName string `json:"__typename"`
155-
Login string `json:"login"`
156-
Name string `json:"name"`
157-
Slug string `json:"slug"`
158-
Organization struct {
159-
Login string `json:"login"`
160-
}
161-
}
153+
RequestedReviewer RequestedReviewer
162154
}
163155
}
164156

157+
type RequestedReviewer struct {
158+
TypeName string `json:"__typename"`
159+
Login string `json:"login"`
160+
Name string `json:"name"`
161+
Slug string `json:"slug"`
162+
Organization struct {
163+
Login string `json:"login"`
164+
} `json:"organization"`
165+
}
166+
167+
func (r RequestedReviewer) LoginOrSlug() string {
168+
if r.TypeName == teamTypeName {
169+
return fmt.Sprintf("%s/%s", r.Organization.Login, r.Slug)
170+
}
171+
return r.Login
172+
}
173+
165174
const teamTypeName = "Team"
166175

167176
func (r ReviewRequests) Logins() []string {
168177
logins := make([]string, len(r.Nodes))
169-
for i, a := range r.Nodes {
170-
if a.RequestedReviewer.TypeName == teamTypeName {
171-
logins[i] = fmt.Sprintf("%s/%s", a.RequestedReviewer.Organization.Login, a.RequestedReviewer.Slug)
172-
} else {
173-
logins[i] = a.RequestedReviewer.Login
174-
}
178+
for i, r := range r.Nodes {
179+
logins[i] = r.RequestedReviewer.LoginOrSlug()
175180
}
176181
return logins
177182
}
@@ -391,7 +396,7 @@ func PullRequestStatus(client *Client, repo ghrepo.Interface, options StatusOpti
391396
// these are always necessary to find the PR for the current branch
392397
fields.AddValues([]string{"isCrossRepository", "headRepositoryOwner", "headRefName"})
393398
gr := PullRequestGraphQL(fields.ToSlice())
394-
fragments = fmt.Sprintf("fragment pr on PullRequest{%[1]s}fragment prWithReviews on PullRequest{%[1]s}", gr)
399+
fragments = fmt.Sprintf("fragment pr on PullRequest{%s}fragment prWithReviews on PullRequest{...pr}", gr)
395400
} else {
396401
var err error
397402
fragments, err = pullRequestFragment(client.http, repo.RepoHost())
@@ -526,67 +531,23 @@ func pullRequestFragment(httpClient *http.Client, hostname string) (string, erro
526531
return "", err
527532
}
528533

529-
var reviewsFragment string
530-
if prFeatures.HasReviewDecision {
531-
reviewsFragment = "reviewDecision"
534+
fields := []string{
535+
"number", "title", "state", "url", "isDraft", "isCrossRepository",
536+
"requiresStrictStatusChecks", "headRefName", "headRepositoryOwner", "mergeStateStatus",
532537
}
533-
534-
var statusesFragment string
535538
if prFeatures.HasStatusCheckRollup {
536-
statusesFragment = `
537-
commits(last: 1) {
538-
nodes {
539-
commit {
540-
statusCheckRollup {
541-
contexts(last: 100) {
542-
nodes {
543-
...on StatusContext {
544-
state
545-
}
546-
...on CheckRun {
547-
conclusion
548-
status
549-
}
550-
}
551-
}
552-
}
553-
}
554-
}
555-
}
556-
`
539+
fields = append(fields, "statusCheckRollup")
557540
}
558541

559-
var requiresStrictStatusChecks string
560-
if prFeatures.HasBranchProtectionRule {
561-
requiresStrictStatusChecks = `
562-
baseRef {
563-
branchProtectionRule {
564-
requiresStrictStatusChecks
565-
}
566-
}`
542+
var reviewFields []string
543+
if prFeatures.HasReviewDecision {
544+
reviewFields = append(reviewFields, "reviewDecision")
567545
}
568546

569547
fragments := fmt.Sprintf(`
570-
fragment pr on PullRequest {
571-
number
572-
title
573-
state
574-
url
575-
headRefName
576-
mergeStateStatus
577-
headRepositoryOwner {
578-
login
579-
}
580-
%s
581-
isCrossRepository
582-
isDraft
583-
%s
584-
}
585-
fragment prWithReviews on PullRequest {
586-
...pr
587-
%s
588-
}
589-
`, requiresStrictStatusChecks, statusesFragment, reviewsFragment)
548+
fragment pr on PullRequest {%s}
549+
fragment prWithReviews on PullRequest {...pr,%s}
550+
`, PullRequestGraphQL(fields), PullRequestGraphQL(reviewFields))
590551
return fragments, nil
591552
}
592553

api/query_builder.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ func PullRequestGraphQL(fields []string) string {
216216
q = append(q, `commits(last:1){nodes{commit{oid}}}`)
217217
case "commitsCount": // pseudo-field
218218
q = append(q, `commits{totalCount}`)
219+
case "requiresStrictStatusChecks": // pseudo-field
220+
q = append(q, `baseRef{branchProtectionRule{requiresStrictStatusChecks}}`)
219221
case "statusCheckRollup":
220222
q = append(q, StatusCheckRollupGraphQL(""))
221223
default:

cmd/gh/main.go

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/cli/cli/internal/run"
2222
"github.com/cli/cli/internal/update"
2323
"github.com/cli/cli/pkg/cmd/alias/expand"
24+
"github.com/cli/cli/pkg/cmd/extensions"
2425
"github.com/cli/cli/pkg/cmd/factory"
2526
"github.com/cli/cli/pkg/cmd/root"
2627
"github.com/cli/cli/pkg/cmdutil"
@@ -92,14 +93,6 @@ func mainRun() exitCode {
9293
return exitError
9394
}
9495

95-
if prompt, _ := cfg.Get("", "prompt"); prompt == "disabled" {
96-
cmdFactory.IOStreams.SetNeverPrompt(true)
97-
}
98-
99-
if pager, _ := cfg.Get("", "pager"); pager != "" {
100-
cmdFactory.IOStreams.SetPager(pager)
101-
}
102-
10396
// TODO: remove after FromFullName has been revisited
10497
if host, err := cfg.DefaultHost(); err == nil {
10598
ghrepo.SetDefaultHost(host)
@@ -140,15 +133,27 @@ func mainRun() exitCode {
140133

141134
err = preparedCmd.Run()
142135
if err != nil {
143-
if ee, ok := err.(*exec.ExitError); ok {
144-
return exitCode(ee.ExitCode())
136+
var execError *exec.ExitError
137+
if errors.As(err, &execError) {
138+
return exitCode(execError.ExitCode())
145139
}
146-
147140
fmt.Fprintf(stderr, "failed to run external command: %s", err)
148141
return exitError
149142
}
150143

151144
return exitOK
145+
} else if c, _, err := rootCmd.Traverse(expandedArgs); err == nil && c == rootCmd && len(expandedArgs) > 0 {
146+
extensionManager := extensions.NewManager()
147+
if found, err := extensionManager.Dispatch(expandedArgs, os.Stdin, os.Stdout, os.Stderr); err != nil {
148+
var execError *exec.ExitError
149+
if errors.As(err, &execError) {
150+
return exitCode(execError.ExitCode())
151+
}
152+
fmt.Fprintf(stderr, "failed to run extension: %s", err)
153+
return exitError
154+
} else if found {
155+
return exitOK
156+
}
152157
}
153158
}
154159

@@ -264,7 +269,7 @@ func checkForUpdate(currentVersion string) (*update.ReleaseInfo, error) {
264269
}
265270

266271
repo := updaterEnabled
267-
stateFilePath := filepath.Join(config.ConfigDir(), "state.yml")
272+
stateFilePath := filepath.Join(config.StateDir(), "state.yml")
268273
return update.CheckForUpdate(client, stateFilePath, repo, currentVersion)
269274
}
270275

docs/project-layout.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ and talk through which code gets run in order.
7575
This task might be tricky. Typically, gh commands do things like look up information from the git repository
7676
in the current directory, query the GitHub API, scan the user's `~/.ssh/config` file, clone or fetch git
7777
repositories, etc. Naturally, none of these things should ever happen for real when running tests, unless
78-
you are sure that any filesystem operations are stricly scoped to a location made for and maintained by the
78+
you are sure that any filesystem operations are strictly scoped to a location made for and maintained by the
7979
test itself. To avoid actually running things like making real API requests or shelling out to `git`
8080
commands, we stub them. You should look at how that's done within some existing tests.
8181

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ require (
1111
github.com/cli/oauth v0.8.0
1212
github.com/cli/safeexec v1.0.0
1313
github.com/cpuguy83/go-md2man/v2 v2.0.0
14+
github.com/creack/pty v1.1.13
1415
github.com/gabriel-vasile/mimetype v1.1.2
1516
github.com/google/go-cmp v0.5.2
1617
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
6262
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
6363
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
6464
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
65+
github.com/creack/pty v1.1.13 h1:rTPnd/xocYRjutMfqide2zle1u96upp1gm6eUHKi7us=
66+
github.com/creack/pty v1.1.13/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
6567
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
6668
github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
6769
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

0 commit comments

Comments
 (0)
X Tutup