Merge branch 'issue-839' into 'main'

feat[variable]: add get subCommand to variable

See merge request https://gitlab.com/gitlab-org/cli/-/merge_requests/1011

Merged-by: Gary Holtz <gholtz@gitlab.com>
Approved-by: Dmytro Makovey <dmakovey@gitlab.com>
Co-authored-by: LinaLinn <lina.cloud@outlook.de>
This commit is contained in:
Gary Holtz 2022-09-19 18:04:54 +00:00
commit 7a19cc7ce9
6 changed files with 305 additions and 0 deletions

View File

@ -30,6 +30,18 @@ var ListProjectVariables = func(client *gitlab.Client, projectID interface{}, op
return vars, nil
}
var GetProjectVariable = func(client *gitlab.Client, projectID interface{}, key string, opts *gitlab.RequestOptionFunc) (*gitlab.ProjectVariable, error) {
if client == nil {
client = apiClient.Lab()
}
vars, _, err := client.ProjectVariables.GetVariable(projectID, key)
if err != nil {
return nil, err
}
return vars, nil
}
var DeleteProjectVariable = func(client *gitlab.Client, projectID interface{}, key string, scope string) error {
if client == nil {
client = apiClient.Lab()
@ -99,6 +111,18 @@ var CreateGroupVariable = func(client *gitlab.Client, groupID interface{}, opts
return vars, nil
}
var GetGroupVariable = func(client *gitlab.Client, groupID interface{}, key string, opts *gitlab.RequestOptionFunc) (*gitlab.GroupVariable, error) {
if client == nil {
client = apiClient.Lab()
}
vars, _, err := client.GroupVariables.GetVariable(groupID, key)
if err != nil {
return nil, err
}
return vars, nil
}
var DeleteGroupVariable = func(client *gitlab.Client, groupID interface{}, key string) error {
if client == nil {
client = apiClient.Lab()

View File

@ -0,0 +1,91 @@
package get
import (
"fmt"
"github.com/MakeNowJust/heredoc"
"github.com/profclems/glab/api"
"github.com/profclems/glab/commands/cmdutils"
"github.com/profclems/glab/commands/variable/variableutils"
"github.com/profclems/glab/internal/glrepo"
"github.com/profclems/glab/pkg/iostreams"
"github.com/spf13/cobra"
"github.com/xanzy/go-gitlab"
)
type GetOps struct {
HTTPClient func() (*gitlab.Client, error)
IO *iostreams.IOStreams
BaseRepo func() (glrepo.Interface, error)
Key string
Group string
}
func NewCmdSet(f *cmdutils.Factory, runE func(opts *GetOps) error) *cobra.Command {
opts := &GetOps{
IO: f.IO,
}
cmd := &cobra.Command{
Use: "get <key>",
Short: "get a project or group variable",
Args: cobra.RangeArgs(1, 1),
Example: heredoc.Doc(`
$ glab variable get VAR_KEY
$ glab variable get -g GROUP VAR_KEY
`),
RunE: func(cmd *cobra.Command, args []string) (err error) {
opts.HTTPClient = f.HttpClient
opts.BaseRepo = f.BaseRepo
opts.Key = args[0]
if !variableutils.IsValidKey(opts.Key) {
err = cmdutils.FlagError{Err: fmt.Errorf("invalid key provided.\n%s", variableutils.ValidKeyMsg)}
return
}
if runE != nil {
err = runE(opts)
return
}
err = getRun(opts)
return
},
}
cmd.Flags().StringVarP(&opts.Group, "group", "g", "", "Get variable for a group")
return cmd
}
func getRun(opts *GetOps) error {
httpClient, err := opts.HTTPClient()
if err != nil {
return err
}
var variableValue string
if opts.Group != "" {
variable, err := api.GetGroupVariable(httpClient, opts.Group, opts.Key, nil)
if err != nil {
return err
}
variableValue = variable.Value
} else {
baseRepo, err := opts.BaseRepo()
if err != nil {
return err
}
variable, err := api.GetProjectVariable(httpClient, baseRepo.FullName(), opts.Key, nil)
if err != nil {
return err
}
variableValue = variable.Value
}
fmt.Fprint(opts.IO.StdOut, variableValue)
return nil
}

View File

@ -0,0 +1,146 @@
package get
import (
"bytes"
"github.com/alecthomas/assert"
"github.com/google/shlex"
"github.com/profclems/glab/api"
"github.com/profclems/glab/commands/cmdutils"
"github.com/profclems/glab/internal/glrepo"
"github.com/profclems/glab/pkg/httpmock"
"github.com/profclems/glab/pkg/iostreams"
"github.com/xanzy/go-gitlab"
"net/http"
"testing"
)
func Test_NewCmdSet(t *testing.T) {
tests := []struct {
name string
cli string
wants GetOps
wantsErr bool
}{
{
name: "good key",
cli: "good_key",
wantsErr: false,
wants: GetOps{
Key: "good_key",
},
},
{
name: "bad key",
cli: "bad-key",
wantsErr: true,
},
{
name: "no key",
cli: "",
wantsErr: true,
},
{
name: "good key",
cli: "-g group good_key",
wants: GetOps{
Key: "good_key",
Group: "group",
},
wantsErr: false,
},
{
name: "bad key",
cli: "-g group bad-key",
wants: GetOps{
Group: "group",
},
wantsErr: true,
},
{
name: "good key but no group",
cli: "good_key --group",
wantsErr: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
io, _, _, _ := iostreams.Test()
f := &cmdutils.Factory{
IO: io,
}
argv, err := shlex.Split(test.cli)
assert.NoError(t, err)
var gotOpts *GetOps
cmd := NewCmdSet(f, func(opts *GetOps) error {
gotOpts = opts
return nil
})
cmd.SetArgs(argv)
cmd.SetIn(&bytes.Buffer{})
cmd.SetOut(&bytes.Buffer{})
cmd.SetErr(&bytes.Buffer{})
_, err = cmd.ExecuteC()
if test.wantsErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)
assert.Equal(t, test.wants.Key, gotOpts.Key)
assert.Equal(t, test.wants.Group, gotOpts.Group)
})
}
}
func Test_getRun_project(t *testing.T) {
reg := &httpmock.Mocker{}
defer reg.Verify(t)
varContent := `
TEST variable\n
content
`
body := struct {
Key string `json:"key"`
VariableType string `json:"variable_type"`
Value string `json:"value"`
Protected bool `json:"protected"`
Masked bool `json:"masked"`
EnvironmentScope string `json:"environment_scope"`
}{
Key: "TEST_VAR",
VariableType: "env_var",
Value: varContent,
Protected: false,
Masked: false,
EnvironmentScope: "*",
}
reg.RegisterResponder("GET", "/projects/owner/repo/variables/TEST_VAR",
httpmock.NewJSONResponse(200, body),
)
io, _, stdout, _ := iostreams.Test()
opts := &GetOps{
HTTPClient: func() (*gitlab.Client, error) {
a, _ := api.TestClient(&http.Client{Transport: reg}, "", "gitlab.com", false)
return a.Lab(), nil
},
BaseRepo: func() (glrepo.Interface, error) {
return glrepo.FromFullName("owner/repo")
},
IO: io,
Key: "TEST_VAR",
}
_, _ = opts.HTTPClient()
err := getRun(opts)
assert.NoError(t, err)
assert.Equal(t, varContent, stdout.String())
}

View File

@ -3,6 +3,7 @@ package variable
import (
"github.com/profclems/glab/commands/cmdutils"
deleteCmd "github.com/profclems/glab/commands/variable/delete"
getCmd "github.com/profclems/glab/commands/variable/get"
listCmd "github.com/profclems/glab/commands/variable/list"
setCmd "github.com/profclems/glab/commands/variable/set"
updateCmd "github.com/profclems/glab/commands/variable/update"
@ -22,5 +23,6 @@ func NewVariableCmd(f *cmdutils.Factory) *cobra.Command {
cmd.AddCommand(listCmd.NewCmdSet(f, nil))
cmd.AddCommand(deleteCmd.NewCmdSet(f, nil))
cmd.AddCommand(updateCmd.NewCmdSet(f, nil))
cmd.AddCommand(getCmd.NewCmdSet(f, nil))
return cmd
}

View File

@ -0,0 +1,41 @@
.. _glab_variable_get:
glab variable get
-----------------
get a project or group variable
Synopsis
~~~~~~~~
get a project or group variable
::
glab variable get <key> [flags]
Examples
~~~~~~~~
::
$ glab variable get VAR_KEY
$ glab variable get -g GROUP VAR_KEY
Options
~~~~~~~
::
-g, --group string Get variable for a group
Options inherited from parent commands
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
::
--help Show help for command
-R, --repo OWNER/REPO Select another repository using the OWNER/REPO or `GROUP/NAMESPACE/REPO` format or full URL or git URL

View File

@ -32,6 +32,7 @@ Subcommands
:maxdepth: 0
delete <delete>
get <get>
list <list>
set <set>
update <update>