Skip to content

Commit 7e7735d

Browse files
author
Nate Smith
authored
Merge pull request cli#4729 from cli/config-list
Add `gh config list`
2 parents 8f9548f + 5b13dec commit 7e7735d

File tree

3 files changed

+185
-0
lines changed

3 files changed

+185
-0
lines changed

pkg/cmd/config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/cli/cli/v2/internal/config"
88
cmdGet "github.com/cli/cli/v2/pkg/cmd/config/get"
9+
cmdList "github.com/cli/cli/v2/pkg/cmd/config/list"
910
cmdSet "github.com/cli/cli/v2/pkg/cmd/config/set"
1011
"github.com/cli/cli/v2/pkg/cmdutil"
1112
"github.com/spf13/cobra"
@@ -33,6 +34,7 @@ func NewCmdConfig(f *cmdutil.Factory) *cobra.Command {
3334

3435
cmd.AddCommand(cmdGet.NewCmdConfigGet(f, nil))
3536
cmd.AddCommand(cmdSet.NewCmdConfigSet(f, nil))
37+
cmd.AddCommand(cmdList.NewCmdConfigList(f, nil))
3638

3739
return cmd
3840
}

pkg/cmd/config/list/list.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package list
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/cli/cli/v2/internal/config"
7+
"github.com/cli/cli/v2/pkg/cmdutil"
8+
"github.com/cli/cli/v2/pkg/iostreams"
9+
"github.com/spf13/cobra"
10+
)
11+
12+
type ListOptions struct {
13+
IO *iostreams.IOStreams
14+
Config func() (config.Config, error)
15+
16+
Hostname string
17+
}
18+
19+
func NewCmdConfigList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command {
20+
opts := &ListOptions{
21+
IO: f.IOStreams,
22+
Config: f.Config,
23+
}
24+
25+
cmd := &cobra.Command{
26+
Use: "list",
27+
Short: "Print a list of configuration keys and values",
28+
Args: cobra.ExactArgs(0),
29+
RunE: func(cmd *cobra.Command, args []string) error {
30+
if runF != nil {
31+
return runF(opts)
32+
}
33+
34+
return listRun(opts)
35+
},
36+
}
37+
38+
cmd.Flags().StringVarP(&opts.Hostname, "host", "h", "", "Get per-host configuration")
39+
40+
return cmd
41+
}
42+
43+
func listRun(opts *ListOptions) error {
44+
cfg, err := opts.Config()
45+
if err != nil {
46+
return err
47+
}
48+
49+
var host string
50+
if opts.Hostname != "" {
51+
host = opts.Hostname
52+
} else {
53+
host, err = cfg.DefaultHost()
54+
if err != nil {
55+
return err
56+
}
57+
}
58+
59+
configOptions := config.ConfigOptions()
60+
61+
for _, key := range configOptions {
62+
val, err := cfg.Get(host, key.Key)
63+
if err != nil {
64+
return err
65+
}
66+
fmt.Fprintf(opts.IO.Out, "%s=%s\n", key.Key, val)
67+
}
68+
69+
return nil
70+
}

pkg/cmd/config/list/list_test.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package list
2+
3+
import (
4+
"bytes"
5+
"testing"
6+
7+
"github.com/cli/cli/v2/internal/config"
8+
"github.com/cli/cli/v2/pkg/cmdutil"
9+
"github.com/cli/cli/v2/pkg/iostreams"
10+
"github.com/google/shlex"
11+
"github.com/stretchr/testify/assert"
12+
)
13+
14+
func TestNewCmdConfigList(t *testing.T) {
15+
tests := []struct {
16+
name string
17+
input string
18+
output ListOptions
19+
wantsErr bool
20+
}{
21+
{
22+
name: "no arguments",
23+
input: "",
24+
output: ListOptions{},
25+
wantsErr: false,
26+
},
27+
{
28+
name: "list with host",
29+
input: "--host HOST.com",
30+
output: ListOptions{Hostname: "HOST.com"},
31+
wantsErr: false,
32+
},
33+
}
34+
35+
for _, tt := range tests {
36+
t.Run(tt.name, func(t *testing.T) {
37+
f := &cmdutil.Factory{
38+
Config: func() (config.Config, error) {
39+
return config.ConfigStub{}, nil
40+
},
41+
}
42+
43+
argv, err := shlex.Split(tt.input)
44+
assert.NoError(t, err)
45+
46+
var gotOpts *ListOptions
47+
cmd := NewCmdConfigList(f, func(opts *ListOptions) error {
48+
gotOpts = opts
49+
return nil
50+
})
51+
cmd.Flags().BoolP("help", "x", false, "")
52+
53+
cmd.SetArgs(argv)
54+
cmd.SetIn(&bytes.Buffer{})
55+
cmd.SetOut(&bytes.Buffer{})
56+
cmd.SetErr(&bytes.Buffer{})
57+
58+
_, err = cmd.ExecuteC()
59+
if tt.wantsErr {
60+
assert.Error(t, err)
61+
return
62+
}
63+
64+
assert.NoError(t, err)
65+
assert.Equal(t, tt.output.Hostname, gotOpts.Hostname)
66+
})
67+
}
68+
}
69+
70+
func Test_listRun(t *testing.T) {
71+
tests := []struct {
72+
name string
73+
input *ListOptions
74+
config config.ConfigStub
75+
stdout string
76+
wantErr bool
77+
}{
78+
{
79+
name: "list",
80+
config: config.ConfigStub{
81+
"HOST:git_protocol": "ssh",
82+
"HOST:editor": "/usr/bin/vim",
83+
"HOST:prompt": "disabled",
84+
"HOST:pager": "less",
85+
"HOST:http_unix_socket": "",
86+
"HOST:browser": "brave",
87+
},
88+
input: &ListOptions{Hostname: "HOST"}, // ConfigStub gives empty DefaultHost
89+
stdout: `git_protocol=ssh
90+
editor=/usr/bin/vim
91+
prompt=disabled
92+
pager=less
93+
http_unix_socket=
94+
browser=brave
95+
`,
96+
},
97+
}
98+
99+
for _, tt := range tests {
100+
io, _, stdout, _ := iostreams.Test()
101+
tt.input.IO = io
102+
tt.input.Config = func() (config.Config, error) {
103+
return tt.config, nil
104+
}
105+
106+
t.Run(tt.name, func(t *testing.T) {
107+
err := listRun(tt.input)
108+
assert.NoError(t, err)
109+
assert.Equal(t, tt.stdout, stdout.String())
110+
//assert.Equal(t, tt.stderr, stderr.String())
111+
})
112+
}
113+
}

0 commit comments

Comments
 (0)