Merge pull request #4729 from cli/config-list

Add `gh config list`
This commit is contained in:
Nate Smith 2021-12-01 17:34:59 -06:00 committed by GitHub
commit 7e7735d450
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 185 additions and 0 deletions

View file

@ -6,6 +6,7 @@ import (
"github.com/cli/cli/v2/internal/config"
cmdGet "github.com/cli/cli/v2/pkg/cmd/config/get"
cmdList "github.com/cli/cli/v2/pkg/cmd/config/list"
cmdSet "github.com/cli/cli/v2/pkg/cmd/config/set"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/spf13/cobra"
@ -33,6 +34,7 @@ func NewCmdConfig(f *cmdutil.Factory) *cobra.Command {
cmd.AddCommand(cmdGet.NewCmdConfigGet(f, nil))
cmd.AddCommand(cmdSet.NewCmdConfigSet(f, nil))
cmd.AddCommand(cmdList.NewCmdConfigList(f, nil))
return cmd
}

View file

@ -0,0 +1,70 @@
package list
import (
"fmt"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/spf13/cobra"
)
type ListOptions struct {
IO *iostreams.IOStreams
Config func() (config.Config, error)
Hostname string
}
func NewCmdConfigList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command {
opts := &ListOptions{
IO: f.IOStreams,
Config: f.Config,
}
cmd := &cobra.Command{
Use: "list",
Short: "Print a list of configuration keys and values",
Args: cobra.ExactArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
if runF != nil {
return runF(opts)
}
return listRun(opts)
},
}
cmd.Flags().StringVarP(&opts.Hostname, "host", "h", "", "Get per-host configuration")
return cmd
}
func listRun(opts *ListOptions) error {
cfg, err := opts.Config()
if err != nil {
return err
}
var host string
if opts.Hostname != "" {
host = opts.Hostname
} else {
host, err = cfg.DefaultHost()
if err != nil {
return err
}
}
configOptions := config.ConfigOptions()
for _, key := range configOptions {
val, err := cfg.Get(host, key.Key)
if err != nil {
return err
}
fmt.Fprintf(opts.IO.Out, "%s=%s\n", key.Key, val)
}
return nil
}

View file

@ -0,0 +1,113 @@
package list
import (
"bytes"
"testing"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
)
func TestNewCmdConfigList(t *testing.T) {
tests := []struct {
name string
input string
output ListOptions
wantsErr bool
}{
{
name: "no arguments",
input: "",
output: ListOptions{},
wantsErr: false,
},
{
name: "list with host",
input: "--host HOST.com",
output: ListOptions{Hostname: "HOST.com"},
wantsErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := &cmdutil.Factory{
Config: func() (config.Config, error) {
return config.ConfigStub{}, nil
},
}
argv, err := shlex.Split(tt.input)
assert.NoError(t, err)
var gotOpts *ListOptions
cmd := NewCmdConfigList(f, func(opts *ListOptions) error {
gotOpts = opts
return nil
})
cmd.Flags().BoolP("help", "x", false, "")
cmd.SetArgs(argv)
cmd.SetIn(&bytes.Buffer{})
cmd.SetOut(&bytes.Buffer{})
cmd.SetErr(&bytes.Buffer{})
_, err = cmd.ExecuteC()
if tt.wantsErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assert.Equal(t, tt.output.Hostname, gotOpts.Hostname)
})
}
}
func Test_listRun(t *testing.T) {
tests := []struct {
name string
input *ListOptions
config config.ConfigStub
stdout string
wantErr bool
}{
{
name: "list",
config: config.ConfigStub{
"HOST:git_protocol": "ssh",
"HOST:editor": "/usr/bin/vim",
"HOST:prompt": "disabled",
"HOST:pager": "less",
"HOST:http_unix_socket": "",
"HOST:browser": "brave",
},
input: &ListOptions{Hostname: "HOST"}, // ConfigStub gives empty DefaultHost
stdout: `git_protocol=ssh
editor=/usr/bin/vim
prompt=disabled
pager=less
http_unix_socket=
browser=brave
`,
},
}
for _, tt := range tests {
io, _, stdout, _ := iostreams.Test()
tt.input.IO = io
tt.input.Config = func() (config.Config, error) {
return tt.config, nil
}
t.Run(tt.name, func(t *testing.T) {
err := listRun(tt.input)
assert.NoError(t, err)
assert.Equal(t, tt.stdout, stdout.String())
//assert.Equal(t, tt.stderr, stderr.String())
})
}
}