X Tutup
Skip to content

Commit a325db3

Browse files
committed
new config infrastructure
- adds config get and config set commands - supports arbitrary k/v strings set at top and host level - supports writing an updated config, preserving comments - supports mostly lazy evaluation of yaml
1 parent 82bd7b9 commit a325db3

File tree

15 files changed

+856
-148
lines changed

15 files changed

+856
-148
lines changed

command/config.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package command
2+
3+
import (
4+
"fmt"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
func init() {
9+
RootCmd.AddCommand(configCmd)
10+
configCmd.AddCommand(configGetCmd)
11+
configCmd.AddCommand(configSetCmd)
12+
13+
configGetCmd.Flags().StringP("host", "h", "", "Get per-host setting")
14+
configSetCmd.Flags().StringP("host", "h", "", "Set per-host setting")
15+
16+
}
17+
18+
var configCmd = &cobra.Command{
19+
Use: "config",
20+
Short: "Set and get gh settings",
21+
Long: `Get and set key/value strings. They can be optionally scoped to a particular host.
22+
23+
Current respected settings:
24+
- git_protocol: https or ssh. Default is https.
25+
- editor: if unset, defaults to environment variables.
26+
`,
27+
}
28+
29+
var configGetCmd = &cobra.Command{
30+
Use: "get",
31+
Short: "Prints the value of a given configuration key.",
32+
Long: `Get the value for a given configuration key, optionally scoping by hostname.
33+
34+
Examples:
35+
gh config get git_protocol
36+
https
37+
gh config get --host example.com
38+
ssh
39+
`,
40+
Args: cobra.ExactArgs(1),
41+
RunE: configGet,
42+
}
43+
44+
var configSetCmd = &cobra.Command{
45+
Use: "set",
46+
Short: "Updates configuration with the value of a given key.",
47+
Long: `Update the configuration by setting a key to a value, optionally scoping by hostname.
48+
49+
Examples:
50+
gh config set editor vim
51+
gh config set --host example.com editor eclipse
52+
`,
53+
Args: cobra.ExactArgs(2),
54+
RunE: configSet,
55+
}
56+
57+
func configGet(cmd *cobra.Command, args []string) error {
58+
key := args[0]
59+
hostname, err := cmd.Flags().GetString("host")
60+
if err != nil {
61+
return err
62+
}
63+
64+
ctx := contextForCommand(cmd)
65+
66+
cfg, err := ctx.Config()
67+
if err != nil {
68+
return err
69+
}
70+
71+
val, err := cfg.Get(hostname, key)
72+
if err != nil {
73+
return err
74+
}
75+
76+
if val != "" {
77+
out := colorableOut(cmd)
78+
fmt.Fprintf(out, "%s\n", val)
79+
}
80+
81+
return nil
82+
}
83+
84+
func configSet(cmd *cobra.Command, args []string) error {
85+
key := args[0]
86+
value := args[1]
87+
88+
hostname, err := cmd.Flags().GetString("host")
89+
if err != nil {
90+
return err
91+
}
92+
93+
ctx := contextForCommand(cmd)
94+
95+
cfg, err := ctx.Config()
96+
if err != nil {
97+
return err
98+
}
99+
100+
err = cfg.Set(hostname, key, value)
101+
if err != nil {
102+
return fmt.Errorf("failed to set %q to %q: %s", key, value, err)
103+
}
104+
105+
err = cfg.Write()
106+
if err != nil {
107+
return fmt.Errorf("failed to write config to disk: %s", err)
108+
}
109+
110+
return nil
111+
}

command/config_test.go

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
package command
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/cli/cli/context"
8+
)
9+
10+
func TestConfigGet(t *testing.T) {
11+
cfg := `---
12+
hosts:
13+
github.com:
14+
user: OWNER
15+
oauth_token: MUSTBEHIGHCUZIMATOKEN
16+
editor: ed
17+
`
18+
initBlankContext(cfg, "OWNER/REPO", "master")
19+
20+
output, err := RunCommand(configGetCmd, "config get editor")
21+
if err != nil {
22+
t.Fatalf("error running command `config get editor`: %v", err)
23+
}
24+
25+
eq(t, output.String(), "ed\n")
26+
}
27+
28+
func TestConfigGet_default(t *testing.T) {
29+
initBlankContext("", "OWNER/REPO", "master")
30+
output, err := RunCommand(configGetCmd, "config get git_protocol")
31+
if err != nil {
32+
t.Fatalf("error running command `config get git_protocol`: %v", err)
33+
}
34+
35+
eq(t, output.String(), "https\n")
36+
}
37+
38+
func TestConfigGet_not_found(t *testing.T) {
39+
initBlankContext("", "OWNER/REPO", "master")
40+
41+
output, err := RunCommand(configGetCmd, "config get missing")
42+
if err != nil {
43+
t.Fatalf("error running command `config get missing`: %v", err)
44+
}
45+
46+
eq(t, output.String(), "")
47+
}
48+
49+
func TestConfigSet(t *testing.T) {
50+
initBlankContext("", "OWNER/REPO", "master")
51+
52+
buf := bytes.NewBufferString("")
53+
defer context.StubWriteConfig(buf)()
54+
output, err := RunCommand(configSetCmd, "config set editor ed")
55+
if err != nil {
56+
t.Fatalf("error running command `config set editor ed`: %v", err)
57+
}
58+
59+
eq(t, output.String(), "")
60+
61+
expected := `hosts:
62+
github.com:
63+
user: OWNER
64+
oauth_token: 1234567890
65+
editor: ed
66+
`
67+
68+
eq(t, buf.String(), expected)
69+
}
70+
71+
func TestConfigSet_update(t *testing.T) {
72+
cfg := `---
73+
hosts:
74+
github.com:
75+
user: OWNER
76+
oauth_token: MUSTBEHIGHCUZIMATOKEN
77+
editor: ed
78+
`
79+
80+
initBlankContext(cfg, "OWNER/REPO", "master")
81+
82+
buf := bytes.NewBufferString("")
83+
defer context.StubWriteConfig(buf)()
84+
85+
output, err := RunCommand(configSetCmd, "config set editor vim")
86+
if err != nil {
87+
t.Fatalf("error running command `config get editor`: %v", err)
88+
}
89+
90+
eq(t, output.String(), "")
91+
92+
expected := `hosts:
93+
github.com:
94+
user: OWNER
95+
oauth_token: MUSTBEHIGHCUZIMATOKEN
96+
editor: vim
97+
`
98+
eq(t, buf.String(), expected)
99+
}
100+
101+
func TestConfigGetHost(t *testing.T) {
102+
cfg := `---
103+
hosts:
104+
github.com:
105+
git_protocol: ssh
106+
user: OWNER
107+
oauth_token: MUSTBEHIGHCUZIMATOKEN
108+
editor: ed
109+
git_protocol: https
110+
`
111+
initBlankContext(cfg, "OWNER/REPO", "master")
112+
113+
output, err := RunCommand(configGetCmd, "config get -hgithub.com git_protocol")
114+
if err != nil {
115+
t.Fatalf("error running command `config get editor`: %v", err)
116+
}
117+
118+
eq(t, output.String(), "ssh\n")
119+
}
120+
121+
func TestConfigSetHost(t *testing.T) {
122+
initBlankContext("", "OWNER/REPO", "master")
123+
124+
buf := bytes.NewBufferString("")
125+
defer context.StubWriteConfig(buf)()
126+
output, err := RunCommand(configSetCmd, "config set -hgithub.com git_protocol ssh")
127+
if err != nil {
128+
t.Fatalf("error running command `config set editor ed`: %v", err)
129+
}
130+
131+
eq(t, output.String(), "")
132+
133+
expected := `hosts:
134+
github.com:
135+
user: OWNER
136+
oauth_token: 1234567890
137+
git_protocol: ssh
138+
`
139+
140+
eq(t, buf.String(), expected)
141+
}
142+
143+
func TestConfigSetHost_update(t *testing.T) {
144+
cfg := `---
145+
hosts:
146+
github.com:
147+
git_protocol: ssh
148+
user: OWNER
149+
oauth_token: MUSTBEHIGHCUZIMATOKEN
150+
`
151+
152+
initBlankContext(cfg, "OWNER/REPO", "master")
153+
154+
buf := bytes.NewBufferString("")
155+
defer context.StubWriteConfig(buf)()
156+
157+
output, err := RunCommand(configSetCmd, "config set -hgithub.com git_protocol https")
158+
if err != nil {
159+
t.Fatalf("error running command `config get editor`: %v", err)
160+
}
161+
162+
eq(t, output.String(), "")
163+
164+
expected := `hosts:
165+
github.com:
166+
git_protocol: https
167+
user: OWNER
168+
oauth_token: MUSTBEHIGHCUZIMATOKEN
169+
`
170+
eq(t, buf.String(), expected)
171+
}

0 commit comments

Comments
 (0)
X Tutup