X Tutup
Skip to content

Commit 8d05448

Browse files
committed
Merge remote-tracking branch 'origin' into jan25/issue-2042
2 parents 62e4c53 + fa86743 commit 8d05448

Some content is hidden

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

71 files changed

+2127
-747
lines changed

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ site-docs: site
4444
git -C site pull
4545
git -C site rm 'manual/gh*.md' 2>/dev/null || true
4646
go run ./cmd/gen-docs --website --doc-path site/manual
47-
for f in site/manual/gh*.md; do sed -i.bak -e '/^### SEE ALSO/,$$d' "$$f"; done
4847
rm -f site/manual/*.bak
4948
git -C site add 'manual/gh*.md'
5049
git -C site commit -m 'update help docs' || true

cmd/gen-docs/main.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@ import (
55
"os"
66
"strings"
77

8+
"github.com/cli/cli/internal/docs"
89
"github.com/cli/cli/pkg/cmd/root"
910
"github.com/cli/cli/pkg/cmdutil"
1011
"github.com/cli/cli/pkg/iostreams"
11-
"github.com/spf13/cobra/doc"
1212
"github.com/spf13/pflag"
1313
)
1414

1515
func main() {
16-
1716
var flagError pflag.ErrorHandling
1817
docCmd := pflag.NewFlagSet("", flagError)
1918
manPage := docCmd.BoolP("man-page", "", false, "Generate manual pages")
@@ -39,27 +38,28 @@ func main() {
3938

4039
io, _, _, _ := iostreams.Test()
4140
rootCmd := root.NewCmdRoot(&cmdutil.Factory{IOStreams: io}, "", "")
41+
rootCmd.InitDefaultHelpCmd()
4242

4343
err := os.MkdirAll(*dir, 0755)
4444
if err != nil {
4545
fatal(err)
4646
}
4747

4848
if *website {
49-
err = doc.GenMarkdownTreeCustom(rootCmd, *dir, filePrepender, linkHandler)
49+
err = docs.GenMarkdownTreeCustom(rootCmd, *dir, filePrepender, linkHandler)
5050
if err != nil {
5151
fatal(err)
5252
}
5353
}
5454

5555
if *manPage {
56-
header := &doc.GenManHeader{
56+
header := &docs.GenManHeader{
5757
Title: "gh",
5858
Section: "1",
59-
Source: "", //source and manual are just put at the top of the manpage, before name
60-
Manual: "", //if source is an empty string, it's set to "Auto generated by spf13/cobra"
59+
Source: "",
60+
Manual: "",
6161
}
62-
err = doc.GenManTree(rootCmd, header, *dir)
62+
err = docs.GenManTree(rootCmd, header, *dir)
6363
if err != nil {
6464
fatal(err)
6565
}

cmd/gh/main.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/cli/cli/pkg/cmdutil"
2323
"github.com/cli/cli/update"
2424
"github.com/cli/cli/utils"
25+
"github.com/mattn/go-colorable"
2526
"github.com/mgutz/ansi"
2627
"github.com/spf13/cobra"
2728
)
@@ -63,6 +64,12 @@ func main() {
6364
}
6465
}
6566

67+
// Enable running gh from Windows File Explorer's address bar. Without this, the user is told to stop and run from a
68+
// terminal. With this, a user can clone a repo (or take other actions) directly from explorer.
69+
if len(os.Args) > 1 && os.Args[1] != "" {
70+
cobra.MousetrapHelpText = ""
71+
}
72+
6673
rootCmd := root.NewCmdRoot(cmdFactory, buildVersion, buildDate)
6774

6875
cfg, err := cmdFactory.Config()
@@ -120,12 +127,14 @@ func main() {
120127
}
121128
}
122129

130+
cs := cmdFactory.IOStreams.ColorScheme()
131+
123132
authCheckEnabled := os.Getenv("GITHUB_TOKEN") == "" &&
124133
os.Getenv("GITHUB_ENTERPRISE_TOKEN") == "" &&
125134
cmd != nil && cmdutil.IsAuthCheckEnabled(cmd)
126135
if authCheckEnabled {
127136
if !cmdutil.CheckAuth(cfg) {
128-
fmt.Fprintln(stderr, utils.Bold("Welcome to GitHub CLI!"))
137+
fmt.Fprintln(stderr, cs.Bold("Welcome to GitHub CLI!"))
129138
fmt.Fprintln(stderr)
130139
fmt.Fprintln(stderr, "To authenticate, please run `gh auth login`.")
131140
fmt.Fprintln(stderr, "You can also set the GITHUB_TOKEN environment variable, if preferred.")
@@ -247,5 +256,5 @@ func basicClient(currentVersion string) (*api.Client, error) {
247256
func apiVerboseLog() api.ClientOption {
248257
logTraffic := strings.Contains(os.Getenv("DEBUG"), "api")
249258
colorize := utils.IsTerminal(os.Stderr)
250-
return api.VerboseLog(utils.NewColorable(os.Stderr), logTraffic, colorize)
259+
return api.VerboseLog(colorable.NewColorable(os.Stderr), logTraffic, colorize)
251260
}

docs/install_linux.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ Install and upgrade:
8181
1. Download the `.rpm` file from the [releases page][];
8282
2. Install the downloaded file: `sudo zypper in gh_*_linux_amd64.rpm`
8383

84-
## Community-supported methods
84+
## Unofficial, Community-supported methods
8585

86-
Our team does not directly maintain the following packages or repositories. They are unofficial and we are unable to provide support or guarantees for them.
86+
The core GitHub CLI team does not maintain the following packages or repositories. They are unofficial and we are unable to provide support or guarantees for them. They are linked here as a convenience and their presence does not imply continued oversight from the CLI core team. Users who choose to use them do so at their own risk.
8787

8888
### Arch Linux
8989

@@ -101,6 +101,21 @@ Android users can install via Termux:
101101
pkg install gh
102102
```
103103

104+
### Gentoo
105+
106+
Gentoo Linux users can install from the [main portage tree](https://packages.gentoo.org/packages/dev-util/github-cli):
107+
108+
``` bash
109+
emerge -av github-cli
110+
```
111+
112+
Upgrading can be done by updating the portage tree and then requesting an upgrade:
113+
114+
``` bash
115+
emerge --sync
116+
emerge -u github-cli
117+
```
118+
104119
### Kiss Linux
105120

106121
Kiss Linux users can install from the [community repos](https://github.com/kisslinux/community):
@@ -117,6 +132,17 @@ Nix/NixOS users can install from [nixpkgs](https://search.nixos.org/packages?sho
117132
nix-env -iA nixos.gitAndTools.gh
118133
```
119134

135+
### Snaps
136+
137+
Many Linux distro users can install using Snapd from the [Snap Store](https://snapcraft.io/gh) or the associated [repo](https://github.com/casperdcl/cli/tree/snap)
138+
139+
```bash
140+
sudo snap install --edge gh && snap connect gh:ssh-keys
141+
```
142+
> Snaps are auto-updated every 6 hours. `Snapd` is required and is available on a wide range of Linux distros.
143+
> Find out which distros have Snapd pre-installed and how to install it in the [Snapcraft Installation Docs](https://snapcraft.io/docs/installing-snapd)
144+
>
145+
> **Note:** `snap connect gh:ssh-keys` is needed for all authentication and SSH needs.
120146
121147
[releases page]: https://github.com/cli/cli/releases/latest
122148
[arch linux repo]: https://www.archlinux.org/packages/community/x86_64/github-cli

git/git.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"errors"
66
"fmt"
7+
"io"
78
"net/url"
89
"os"
910
"os/exec"
@@ -162,10 +163,10 @@ func CommitBody(sha string) (string, error) {
162163
}
163164

164165
// Push publishes a git ref to a remote and sets up upstream configuration
165-
func Push(remote string, ref string) error {
166+
func Push(remote string, ref string, cmdOut, cmdErr io.Writer) error {
166167
pushCmd := GitCommand("push", "--set-upstream", remote, ref)
167-
pushCmd.Stdout = os.Stdout
168-
pushCmd.Stderr = os.Stderr
168+
pushCmd.Stdout = cmdOut
169+
pushCmd.Stderr = cmdErr
169170
return run.PrepareCmd(pushCmd).Run()
170171
}
171172

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ require (
77
github.com/MakeNowJust/heredoc v1.0.0
88
github.com/briandowns/spinner v1.11.1
99
github.com/charmbracelet/glamour v0.2.1-0.20200724174618-1246d13c1684
10+
github.com/cpuguy83/go-md2man/v2 v2.0.0
1011
github.com/enescakir/emoji v1.0.0
1112
github.com/google/go-cmp v0.5.2
1213
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510

internal/authflow/flow.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ import (
1212
"github.com/cli/cli/auth"
1313
"github.com/cli/cli/internal/config"
1414
"github.com/cli/cli/pkg/browser"
15-
"github.com/cli/cli/utils"
16-
"github.com/mattn/go-colorable"
15+
"github.com/cli/cli/pkg/iostreams"
1716
)
1817

1918
var (
@@ -23,12 +22,13 @@ var (
2322
oauthClientSecret = "34ddeff2b558a23d38fba8a6de74f086ede1cc0b"
2423
)
2524

26-
func AuthFlowWithConfig(cfg config.Config, hostname, notice string, additionalScopes []string) (string, error) {
25+
func AuthFlowWithConfig(cfg config.Config, IO *iostreams.IOStreams, hostname, notice string, additionalScopes []string) (string, error) {
2726
// TODO this probably shouldn't live in this package. It should probably be in a new package that
2827
// depends on both iostreams and config.
29-
stderr := colorable.NewColorableStderr()
28+
stderr := IO.ErrOut
29+
cs := IO.ColorScheme()
3030

31-
token, userLogin, err := authFlow(hostname, stderr, notice, additionalScopes)
31+
token, userLogin, err := authFlow(hostname, IO, notice, additionalScopes)
3232
if err != nil {
3333
return "", err
3434
}
@@ -48,13 +48,16 @@ func AuthFlowWithConfig(cfg config.Config, hostname, notice string, additionalSc
4848
}
4949

5050
fmt.Fprintf(stderr, "%s Authentication complete. %s to continue...\n",
51-
utils.GreenCheck(), utils.Bold("Press Enter"))
52-
_ = waitForEnter(os.Stdin)
51+
cs.SuccessIcon(), cs.Bold("Press Enter"))
52+
_ = waitForEnter(IO.In)
5353

5454
return token, nil
5555
}
5656

57-
func authFlow(oauthHost string, w io.Writer, notice string, additionalScopes []string) (string, string, error) {
57+
func authFlow(oauthHost string, IO *iostreams.IOStreams, notice string, additionalScopes []string) (string, string, error) {
58+
w := IO.ErrOut
59+
cs := IO.ColorScheme()
60+
5861
var verboseStream io.Writer
5962
if strings.Contains(os.Getenv("DEBUG"), "oauth") {
6063
verboseStream = w
@@ -75,18 +78,18 @@ func authFlow(oauthHost string, w io.Writer, notice string, additionalScopes []s
7578
HTTPClient: http.DefaultClient,
7679
OpenInBrowser: func(url, code string) error {
7780
if code != "" {
78-
fmt.Fprintf(w, "%s First copy your one-time code: %s\n", utils.Yellow("!"), utils.Bold(code))
81+
fmt.Fprintf(w, "%s First copy your one-time code: %s\n", cs.Yellow("!"), cs.Bold(code))
7982
}
80-
fmt.Fprintf(w, "- %s to open %s in your browser... ", utils.Bold("Press Enter"), oauthHost)
81-
_ = waitForEnter(os.Stdin)
83+
fmt.Fprintf(w, "- %s to open %s in your browser... ", cs.Bold("Press Enter"), oauthHost)
84+
_ = waitForEnter(IO.In)
8285

8386
browseCmd, err := browser.Command(url)
8487
if err != nil {
8588
return err
8689
}
8790
err = browseCmd.Run()
8891
if err != nil {
89-
fmt.Fprintf(w, "%s Failed opening a web browser at %s\n", utils.Red("!"), url)
92+
fmt.Fprintf(w, "%s Failed opening a web browser at %s\n", cs.Red("!"), url)
9093
fmt.Fprintf(w, " %s\n", err)
9194
fmt.Fprint(w, " Please try entering the URL in your browser manually\n")
9295
}

internal/config/config_type.go

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,45 @@ func ConfigOptions() []ConfigOption {
4646
return configOptions
4747
}
4848

49-
var configValues = map[string][]string{
50-
"git_protocol": {"ssh", "https"},
51-
"prompt": {"enabled", "disabled"},
49+
func ValidateKey(key string) error {
50+
for _, configKey := range configOptions {
51+
if key == configKey.Key {
52+
return nil
53+
}
54+
}
55+
56+
return fmt.Errorf("invalid key")
57+
}
58+
59+
type InvalidValueError struct {
60+
ValidValues []string
61+
}
62+
63+
func (e InvalidValueError) Error() string {
64+
return "invalid value"
65+
}
66+
67+
func ValidateValue(key, value string) error {
68+
var validValues []string
69+
70+
for _, v := range configOptions {
71+
if v.Key == key {
72+
validValues = v.AllowedValues
73+
break
74+
}
75+
}
76+
77+
if validValues == nil {
78+
return nil
79+
}
80+
81+
for _, v := range validValues {
82+
if v == value {
83+
return nil
84+
}
85+
}
86+
87+
return &InvalidValueError{ValidValues: validValues}
5288
}
5389

5490
// This interface describes interacting with some persistent configuration for gh.
@@ -306,33 +342,7 @@ func (c *fileConfig) GetWithSource(hostname, key string) (string, string, error)
306342
return value, defaultSource, nil
307343
}
308344

309-
type InvalidValueError struct {
310-
ValidValues []string
311-
}
312-
313-
func (e InvalidValueError) Error() string {
314-
return "invalid value"
315-
}
316-
317-
func validateConfigEntry(key, value string) error {
318-
validValues, found := configValues[key]
319-
if !found {
320-
return nil
321-
}
322-
323-
for _, v := range validValues {
324-
if v == value {
325-
return nil
326-
}
327-
}
328-
329-
return &InvalidValueError{ValidValues: validValues}
330-
}
331-
332345
func (c *fileConfig) Set(hostname, key, value string) error {
333-
if err := validateConfigEntry(key, value); err != nil {
334-
return err
335-
}
336346
if hostname == "" {
337347
return c.SetStringValue(key, value)
338348
} else {

internal/config/config_type_test.go

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ func Test_fileConfig_Set(t *testing.T) {
2828
example.com:
2929
editor: vim
3030
`, hostsBuf.String())
31-
assert.EqualError(t, c.Set("github.com", "git_protocol", "sshpps"), "invalid value")
3231
}
3332

3433
func Test_defaultConfig(t *testing.T) {
@@ -70,16 +69,33 @@ func Test_defaultConfig(t *testing.T) {
7069
assert.Equal(t, expansion, "pr checkout")
7170
}
7271

73-
func Test_validateConfigEntry(t *testing.T) {
74-
err := validateConfigEntry("git_protocol", "sshpps")
72+
func Test_ValidateValue(t *testing.T) {
73+
err := ValidateValue("git_protocol", "sshpps")
7574
assert.EqualError(t, err, "invalid value")
7675

77-
err = validateConfigEntry("git_protocol", "ssh")
76+
err = ValidateValue("git_protocol", "ssh")
7877
assert.Nil(t, err)
7978

80-
err = validateConfigEntry("editor", "vim")
79+
err = ValidateValue("editor", "vim")
8180
assert.Nil(t, err)
8281

83-
err = validateConfigEntry("got", "123")
82+
err = ValidateValue("got", "123")
8483
assert.Nil(t, err)
8584
}
85+
86+
func Test_ValidateKey(t *testing.T) {
87+
err := ValidateKey("invalid")
88+
assert.EqualError(t, err, "invalid key")
89+
90+
err = ValidateKey("git_protocol")
91+
assert.NoError(t, err)
92+
93+
err = ValidateKey("editor")
94+
assert.NoError(t, err)
95+
96+
err = ValidateKey("prompt")
97+
assert.NoError(t, err)
98+
99+
err = ValidateKey("pager")
100+
assert.NoError(t, err)
101+
}

0 commit comments

Comments
 (0)
X Tutup