Merge branch 'trunk' into bagtoad/cli-8946-list-licenses-and-gitignore-options
This commit is contained in:
commit
04ed1ed1a0
14 changed files with 202 additions and 44 deletions
20
.github/CONTRIBUTING.md
vendored
20
.github/CONTRIBUTING.md
vendored
|
|
@ -6,9 +6,10 @@ We accept pull requests for bug fixes and features where we've discussed the app
|
|||
|
||||
Please do:
|
||||
|
||||
* Check existing issues to verify that the [bug][bug issues] or [feature request][feature request issues] has not already been submitted.
|
||||
* Check existing issues to verify that an existing [bug][bug issues] or [feature request][feature request issues] issue does not already exist for the same problem or feature.
|
||||
* Open an issue if things aren't working as expected.
|
||||
* Open an issue to propose a significant change.
|
||||
* Open an issue to propose a design for an issue labelled [`needs-design` and `help wanted`][needs design and help wanted], following the [proposing a design guidelines](#proposing-a-design) instructions below.
|
||||
* Open a pull request to fix a bug.
|
||||
* Open a pull request to fix documentation about a command.
|
||||
* Open a pull request for any issue labelled [`help wanted`][hw] or [`good first issue`][gfi].
|
||||
|
|
@ -52,7 +53,21 @@ We generate manual pages from source on every release. You do not need to submit
|
|||
|
||||
## Design guidelines
|
||||
|
||||
You may reference the [CLI Design System][] when suggesting features, and are welcome to use our [Google Docs Template][] to suggest designs.
|
||||
### Proposing a design
|
||||
|
||||
You may propose a design to solve an open bug or feature request issue that has both [the `needs-design` and `help-wanted` labels][needs design and help wanted].
|
||||
|
||||
To propose a design:
|
||||
|
||||
- Open a new issue using the [design proposal issue template](./ISSUE_TEMPLATE/submit-a-design-proposal.md).
|
||||
- Include a link to the issue that the design is for.
|
||||
- Describe the design you are proposing to resolve the issue, leveraging the [CLI Design System][].
|
||||
- Mock up the design you are proposing using our [Google Docs Template][] or code blocks.
|
||||
- Mock ups should cleary illustrate the command(s) being run and the expected output(s).
|
||||
|
||||
### (core team only) Revewing a design
|
||||
|
||||
A member of the core team will [triage](../docs/triage.md) the design proposal. Once a member of the core team has reviewed the design, they may add the [`help wanted`][hw] label to the issue, so a PR can be opened to provide the implementation.
|
||||
|
||||
## Resources
|
||||
|
||||
|
|
@ -62,6 +77,7 @@ You may reference the [CLI Design System][] when suggesting features, and are we
|
|||
|
||||
|
||||
[bug issues]: https://github.com/cli/cli/issues?q=is%3Aopen+is%3Aissue+label%3Abug
|
||||
[needs design and help wanted]: https://github.com/cli/cli/issues?q=state%3Aclosed%20is%3Aissue%20label%3Aneeds-design%20label%3A%22help%20wanted%22
|
||||
[feature request issues]: https://github.com/cli/cli/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement
|
||||
[hw]: https://github.com/cli/cli/labels/help%20wanted
|
||||
[gfi]: https://github.com/cli/cli/labels/good%20first%20issue
|
||||
|
|
|
|||
58
.github/ISSUE_TEMPLATE/submit-a-design-proposal.md
vendored
Normal file
58
.github/ISSUE_TEMPLATE/submit-a-design-proposal.md
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
name: "🎨 Submit a design proposal"
|
||||
about: Submit a design to resolve an open issue that has both `needs-design` and `help-wanted` labels
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- See [CONTRIBUTING.md](../CONTRIBUTING.md#proposing-a-design) for more information.-->
|
||||
|
||||
### Link to issue for design submission
|
||||
|
||||
<!--
|
||||
Provide a link to the issue this design is for.
|
||||
|
||||
All design submissions must be linked to an open issue that
|
||||
has both the `needs-design` and `help-wanted` labels.
|
||||
-->
|
||||
|
||||
### Proposed Design
|
||||
|
||||
<!--
|
||||
Describe the design you are proposing to resolve the issue.
|
||||
|
||||
All CLI designs must adhere to the [Primer CLI design reference](https://primer.style/cli/).
|
||||
-->
|
||||
|
||||
### Mockup
|
||||
|
||||
<!--
|
||||
Provide a mockup of the design you are proposing. All mockups should clearly illustrate the command(s) being run and the expected output(s).
|
||||
|
||||
When color and formatting are important, consider using our [CLI design Google Docs Template](https://docs.google.com/document/d/1JIRErIUuJ6fTgabiFYfCH3x91pyHuytbfa0QLnTfXKM/edit#heading=h.or54sa47ylpg).
|
||||
|
||||
Code blocks can also be used to submit a design mockup - remember to include the command(s) being run. Example:
|
||||
|
||||
```shell
|
||||
$ gh issue list --json title -L 5
|
||||
[
|
||||
{
|
||||
"title": "`gh pr checks <pr> --required` should not fail when there are no required checks"
|
||||
},
|
||||
{
|
||||
"title": "gh pr view commits should include commit description"
|
||||
},
|
||||
{
|
||||
"title": "Adapt the color of the device code to the color used by the terminal"
|
||||
},
|
||||
{
|
||||
"title": "`gh pr create` does not default to fork when user has write access to upstream"
|
||||
},
|
||||
{
|
||||
"title": "First party discussions support"
|
||||
}
|
||||
]
|
||||
```
|
||||
-->
|
||||
5
.github/SECURITY.md
vendored
5
.github/SECURITY.md
vendored
|
|
@ -2,7 +2,10 @@ GitHub takes the security of our software products and services seriously, inclu
|
|||
|
||||
If you believe you have found a security vulnerability in GitHub CLI, you can report it to us in one of two ways:
|
||||
|
||||
* Report it to this repository directly using [private vulnerability reporting][]. Such reports are not eligible for a bounty reward.
|
||||
* Report it to this repository directly using [private vulnerability reporting][].
|
||||
* Include a description of your investigation of the GitHub CLI's codebase and why you believe an exploit is possible.
|
||||
* POCs and links to code are greatly encouraged.
|
||||
* Such reports are not eligible for a bounty reward.
|
||||
|
||||
* Submit the report through [HackerOne][] to be eligible for a bounty reward.
|
||||
|
||||
|
|
|
|||
|
|
@ -43,12 +43,29 @@ sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.re
|
|||
sudo dnf install gh --repo gh-cli
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Show dnf5 commands</summary>
|
||||
|
||||
If you're using `dnf5`, commands will vary slightly:
|
||||
|
||||
```bash
|
||||
sudo dnf5 install dnf5-plugins
|
||||
sudo dnf5 config-manager addrepo --from-repofile=https://cli.github.com/packages/rpm/gh-cli.repo
|
||||
sudo dnf5 install gh --repo gh-cli
|
||||
```
|
||||
|
||||
For more details, check out the [`dnf5 config-manager` documentation](https://dnf5.readthedocs.io/en/latest/dnf5_plugins/config-manager.8.html).
|
||||
</details>
|
||||
|
||||
Alternatively, install from the [community repository](https://packages.fedoraproject.org/pkgs/gh/gh/):
|
||||
|
||||
```bash
|
||||
sudo dnf install gh
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> If errors regarding GPG signatures occur, see [cli/cli#9569](https://github.com/cli/cli/issues/9569) for steps to fix this.
|
||||
|
||||
Upgrade:
|
||||
|
||||
```bash
|
||||
|
|
@ -91,6 +108,9 @@ sudo zypper ref
|
|||
sudo zypper update gh
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> If errors regarding GPG signatures occur, see [cli/cli#9569](https://github.com/cli/cli/issues/9569) for steps to fix this.
|
||||
|
||||
## Manual installation
|
||||
|
||||
* [Download release binaries][releases page] that match your platform; or
|
||||
|
|
|
|||
|
|
@ -33,27 +33,32 @@ the changeset is feasible and to allow the associated CI run for new contributor
|
|||
|
||||
- can this be closed outright?
|
||||
- e.g. spam/junk
|
||||
- add the `invalid` label
|
||||
- close without comment
|
||||
- do we not want to do it?
|
||||
- e.g. have already discussed not wanting to do or duplicate issue
|
||||
- e.g. we have already discussed not wanting to do or it's a duplicate issue
|
||||
- add the appropriate label (e.g. `duplicate`)
|
||||
- comment and close
|
||||
- are we ok with outside contribution for this?
|
||||
- e.g. the task is relatively straightforward, but no people on our team have the bandwidth to take it on at the moment
|
||||
- do we want external contribution for this?
|
||||
- e.g. the task is relatively straightforward, but the core team does not have the bandwidth to take it on
|
||||
- ensure that the thread contains all the context necessary for someone new to pick this up
|
||||
- add `help wanted` label
|
||||
- add the `help wanted` label
|
||||
- consider adding `good first issue` label
|
||||
- do we want external design contribution for this?
|
||||
- e.g. the task is worthwhile, but needs design work to flesh out the details before implementation and the core team does not have the bandwidth to take it on
|
||||
- ensure that the thread contains all the context necessary for someone new to pick this up
|
||||
- add both the `help wanted` and `needs-design` labels
|
||||
- do we want to do it?
|
||||
- add the `core` label
|
||||
- comment acknowledging that
|
||||
- add `core` label
|
||||
- add to the project “TODO” column if this is something that should ship soon
|
||||
- is it intriguing, but requires discussion?
|
||||
- label `discuss`
|
||||
- label `needs-investigation` if engineering research is required before action can be taken
|
||||
- Add the `discuss` label
|
||||
- Add the `needs-investigation` label if engineering research is required before action can be taken
|
||||
- does it need more info from the issue author?
|
||||
- ask the user for details
|
||||
- add `needs-user-input` label
|
||||
- add the `needs-user-input` label
|
||||
- is it a usage/support question?
|
||||
- consider converting the Issue to a Discussion
|
||||
- Convert the Issue to a Discussion
|
||||
|
||||
## Weekly PR audit
|
||||
|
||||
|
|
|
|||
4
go.mod
4
go.mod
|
|
@ -14,7 +14,7 @@ require (
|
|||
github.com/cli/go-gh/v2 v2.10.0
|
||||
github.com/cli/oauth v1.0.1
|
||||
github.com/cli/safeexec v1.0.1
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5
|
||||
github.com/creack/pty v1.1.23
|
||||
github.com/distribution/reference v0.5.0
|
||||
github.com/gabriel-vasile/mimetype v1.4.5
|
||||
|
|
@ -143,7 +143,7 @@ require (
|
|||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/theupdateframework/go-tuf v0.7.0 // indirect
|
||||
github.com/theupdateframework/go-tuf/v2 v2.0.0 // indirect
|
||||
github.com/theupdateframework/go-tuf/v2 v2.0.1 // indirect
|
||||
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e // indirect
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
|
||||
github.com/transparency-dev/merkle v0.0.2 // indirect
|
||||
|
|
|
|||
7
go.sum
7
go.sum
|
|
@ -109,8 +109,9 @@ github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AX
|
|||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
|
||||
github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
|
||||
|
|
@ -440,8 +441,8 @@ github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8
|
|||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI=
|
||||
github.com/theupdateframework/go-tuf v0.7.0/go.mod h1:uEB7WSY+7ZIugK6R1hiBMBjQftaFzn7ZCDJcp1tCUug=
|
||||
github.com/theupdateframework/go-tuf/v2 v2.0.0 h1:rD8d9RotYBprZVgC+9oyTZ5MmawepnTSTqoDuxjWgbs=
|
||||
github.com/theupdateframework/go-tuf/v2 v2.0.0/go.mod h1:baB22nBHeHBCeuGZcIlctNq4P61PcOdyARlplg5xmLA=
|
||||
github.com/theupdateframework/go-tuf/v2 v2.0.1 h1:11p9tXpq10KQEujxjcIjDSivMKCMLguls7erXHZnxJQ=
|
||||
github.com/theupdateframework/go-tuf/v2 v2.0.1/go.mod h1:baB22nBHeHBCeuGZcIlctNq4P61PcOdyARlplg5xmLA=
|
||||
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e h1:BuzhfgfWQbX0dWzYzT1zsORLnHRv3bcRcsaUk0VmXA8=
|
||||
github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e/go.mod h1:/Tnicc6m/lsJE0irFMA0LfIwTBo4QP7A8IfyIv4zZKI=
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 h1:e/5i7d4oYZ+C1wj2THlRK+oAhjeS/TRQwMfkIuet3w0=
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ func AuthFlow(oauthHost string, IO *iostreams.IOStreams, notice string, addition
|
|||
return nil
|
||||
}
|
||||
|
||||
fmt.Fprintf(w, "%s to open %s in your browser... ", cs.Bold("Press Enter"), oauthHost)
|
||||
fmt.Fprintf(w, "%s to open %s in your browser... ", cs.Bold("Press Enter"), authURL)
|
||||
_ = waitForEnter(IO.In)
|
||||
|
||||
if err := b.Browse(authURL); err != nil {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ func (p *surveyPrompter) InputHostname() (string, error) {
|
|||
var result string
|
||||
err := p.ask(
|
||||
&survey.Input{
|
||||
Message: "GHE hostname:",
|
||||
Message: "Hostname:",
|
||||
}, &result, survey.WithValidator(func(v interface{}) error {
|
||||
return ghinstance.HostnameValidator(v.(string))
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -126,6 +126,12 @@ func getTrustedRoot(makeTUF tufClientInstantiator, opts *Options) error {
|
|||
// Disable local caching, so we get up-to-date response from TUF repository
|
||||
tufOpt.CacheValidity = 0
|
||||
|
||||
// Target will be either the default trusted root, or the trust domain-qualified one
|
||||
ghTR := defaultTR
|
||||
if opts.TrustDomain != "" {
|
||||
ghTR = fmt.Sprintf("%s.%s", opts.TrustDomain, defaultTR)
|
||||
}
|
||||
|
||||
if opts.TufUrl != "" && opts.TufRootPath != "" {
|
||||
tufRoot, err := os.ReadFile(opts.TufRootPath)
|
||||
if err != nil {
|
||||
|
|
@ -136,7 +142,7 @@ func getTrustedRoot(makeTUF tufClientInstantiator, opts *Options) error {
|
|||
tufOpt.RepositoryBaseURL = opts.TufUrl
|
||||
tufOptions = append(tufOptions, tufConfig{
|
||||
tufOptions: tufOpt,
|
||||
targets: []string{defaultTR},
|
||||
targets: []string{ghTR},
|
||||
})
|
||||
} else {
|
||||
// Get from both Sigstore public good and GitHub private instance
|
||||
|
|
@ -147,14 +153,9 @@ func getTrustedRoot(makeTUF tufClientInstantiator, opts *Options) error {
|
|||
|
||||
tufOpt = verification.GitHubTUFOptions()
|
||||
tufOpt.CacheValidity = 0
|
||||
targets := []string{defaultTR}
|
||||
if opts.TrustDomain != "" {
|
||||
targets = append(targets, fmt.Sprintf("%s.%s",
|
||||
opts.TrustDomain, defaultTR))
|
||||
}
|
||||
tufOptions = append(tufOptions, tufConfig{
|
||||
tufOptions: tufOpt,
|
||||
targets: targets,
|
||||
targets: []string{ghTR},
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ func NewCmdLogin(f *cmdutil.Factory, runF func(*LoginOptions) error) *cobra.Comm
|
|||
Long: heredoc.Docf(`
|
||||
Authenticate with a GitHub host.
|
||||
|
||||
The default hostname is %[1]sgithub.com%[1]s. This can be overridden using the %[1]s--hostname%[1]s
|
||||
flag.
|
||||
|
||||
The default authentication mode is a web-based browser flow. After completion, an
|
||||
authentication token will be stored securely in the system credential store.
|
||||
If a credential store is not found or there is an issue using it gh will fallback
|
||||
|
|
@ -222,21 +225,19 @@ func loginRun(opts *LoginOptions) error {
|
|||
}
|
||||
|
||||
func promptForHostname(opts *LoginOptions) (string, error) {
|
||||
options := []string{"GitHub.com", "GitHub Enterprise Server"}
|
||||
options := []string{"GitHub.com", "Other"}
|
||||
hostType, err := opts.Prompter.Select(
|
||||
"What account do you want to log into?",
|
||||
"Where do you use GitHub?",
|
||||
options[0],
|
||||
options)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
isEnterprise := hostType == 1
|
||||
|
||||
hostname := ghinstance.Default()
|
||||
if isEnterprise {
|
||||
hostname, err = opts.Prompter.InputHostname()
|
||||
isGitHubDotCom := hostType == 0
|
||||
if isGitHubDotCom {
|
||||
return ghinstance.Default(), nil
|
||||
}
|
||||
|
||||
return hostname, err
|
||||
return opts.Prompter.InputHostname()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package login
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"runtime"
|
||||
|
|
@ -546,7 +547,7 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
wantErrOut: regexp.MustCompile("Tip: you can generate a Personal Access Token here https://rebecca.chambers/settings/tokens"),
|
||||
},
|
||||
{
|
||||
name: "choose enterprise",
|
||||
name: "choose Other",
|
||||
wantHosts: heredoc.Doc(`
|
||||
brad.vickers:
|
||||
users:
|
||||
|
|
@ -563,8 +564,8 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
prompterStubs: func(pm *prompter.PrompterMock) {
|
||||
pm.SelectFunc = func(prompt, _ string, opts []string) (int, error) {
|
||||
switch prompt {
|
||||
case "What account do you want to log into?":
|
||||
return prompter.IndexFor(opts, "GitHub Enterprise Server")
|
||||
case "Where do you use GitHub?":
|
||||
return prompter.IndexFor(opts, "Other")
|
||||
case "What is your preferred protocol for Git operations on this host?":
|
||||
return prompter.IndexFor(opts, "HTTPS")
|
||||
case "How would you like to authenticate GitHub CLI?":
|
||||
|
|
@ -606,7 +607,7 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
prompterStubs: func(pm *prompter.PrompterMock) {
|
||||
pm.SelectFunc = func(prompt, _ string, opts []string) (int, error) {
|
||||
switch prompt {
|
||||
case "What account do you want to log into?":
|
||||
case "Where do you use GitHub?":
|
||||
return prompter.IndexFor(opts, "GitHub.com")
|
||||
case "What is your preferred protocol for Git operations on this host?":
|
||||
return prompter.IndexFor(opts, "HTTPS")
|
||||
|
|
@ -640,7 +641,7 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
prompterStubs: func(pm *prompter.PrompterMock) {
|
||||
pm.SelectFunc = func(prompt, _ string, opts []string) (int, error) {
|
||||
switch prompt {
|
||||
case "What account do you want to log into?":
|
||||
case "Where do you use GitHub?":
|
||||
return prompter.IndexFor(opts, "GitHub.com")
|
||||
case "What is your preferred protocol for Git operations on this host?":
|
||||
return prompter.IndexFor(opts, "SSH")
|
||||
|
|
@ -803,3 +804,50 @@ func Test_loginRun_Survey(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_promptForHostname(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
options []string
|
||||
selectedIndex int
|
||||
// This is so we can test that the options in the function don't change
|
||||
expectedSelection string
|
||||
inputHostname string
|
||||
expect string
|
||||
}{
|
||||
{
|
||||
name: "select 'GitHub.com'",
|
||||
selectedIndex: 0,
|
||||
expectedSelection: "GitHub.com",
|
||||
expect: "github.com",
|
||||
},
|
||||
{
|
||||
name: "select 'Other'",
|
||||
selectedIndex: 1,
|
||||
expectedSelection: "Other",
|
||||
inputHostname: "github.enterprise.com",
|
||||
expect: "github.enterprise.com",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
promptMock := &prompter.PrompterMock{
|
||||
SelectFunc: func(_ string, _ string, options []string) (int, error) {
|
||||
if options[tt.selectedIndex] != tt.expectedSelection {
|
||||
return 0, fmt.Errorf("expected %s at index %d, but got %s", tt.expectedSelection, tt.selectedIndex, options[tt.selectedIndex])
|
||||
}
|
||||
return tt.selectedIndex, nil
|
||||
},
|
||||
InputHostnameFunc: func() (string, error) {
|
||||
return tt.inputHostname, nil
|
||||
},
|
||||
}
|
||||
opts := &LoginOptions{
|
||||
Prompter: promptMock,
|
||||
}
|
||||
hostname, err := promptForHostname(opts)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expect, hostname)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ import (
|
|||
// ErrInitialCommitFailed indicates the initial commit when making a new extension failed.
|
||||
var ErrInitialCommitFailed = errors.New("initial commit failed")
|
||||
|
||||
const darwinAmd64 = "darwin-amd64"
|
||||
|
||||
type Manager struct {
|
||||
dataDir func() string
|
||||
lookPath func(string) (string, error)
|
||||
|
|
@ -266,13 +268,16 @@ func (m *Manager) installBin(repo ghrepo.Interface, target string) error {
|
|||
// if using an ARM-based Mac and an arm64 binary is unavailable, fall back to amd64 if a relevant binary is available and Rosetta 2 is installed
|
||||
if asset == nil && isMacARM {
|
||||
for _, a := range r.Assets {
|
||||
if strings.HasSuffix(a.Name, "darwin-amd64") {
|
||||
if strings.HasSuffix(a.Name, darwinAmd64) {
|
||||
if !hasRosetta() {
|
||||
return fmt.Errorf(
|
||||
"%[1]s unsupported for %[2]s. Install Rosetta with `softwareupdate --install-rosetta` to use the available darwin-amd64 binary, or open an issue: `gh issue create -R %[3]s/%[1]s -t'Support %[2]s'`",
|
||||
repo.RepoName(), platform, repo.RepoOwner())
|
||||
"%[1]s unsupported for %[2]s. Install Rosetta with `softwareupdate --install-rosetta` to use the available %[3]s binary, or open an issue: `gh issue create -R %[4]s/%[1]s -t'Support %[2]s'`",
|
||||
repo.RepoName(), platform, darwinAmd64, repo.RepoOwner())
|
||||
}
|
||||
|
||||
fallbackMessage := fmt.Sprintf("%[1]s not available for %[2]s. Falling back to compatible %[3]s binary", repo.RepoName(), platform, darwinAmd64)
|
||||
fmt.Fprintln(m.io.Out, fallbackMessage)
|
||||
|
||||
asset = &a
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1098,7 +1098,7 @@ func TestManager_Install_amd64_when_supported(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Equal(t, "FAKE BINARY", string(fakeBin))
|
||||
|
||||
assert.Equal(t, "", stdout.String())
|
||||
assert.Equal(t, "gh-bin-ext not available for darwin-arm64. Falling back to compatible darwin-amd64 binary\n", stdout.String())
|
||||
assert.Equal(t, "", stderr.String())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue