-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
337 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package api | ||
|
||
import ( | ||
"context" | ||
"net/url" | ||
) | ||
|
||
// Packages returns the details of the package listing | ||
func (c *Client) GitConfig(cc context.Context, repo string) ([]GitConfigPair, error) { | ||
path := "/git/repos/{acct}/" + url.PathEscape(repo) + "/config-vars" | ||
req := c.newRequest(cc, "GET", path, false) | ||
|
||
resp := gitConfigJSON{} | ||
if err := req.doJSON(&resp); err != nil { | ||
return nil, err | ||
} | ||
|
||
out := make([]GitConfigPair, 0, len(resp.ConfigVars)) | ||
for k, v := range resp.ConfigVars { | ||
out = append(out, GitConfigPair{k, v}) | ||
} | ||
|
||
return out, nil | ||
} | ||
|
||
// Git Config request/response | ||
type gitConfigJSON struct { | ||
ConfigVars map[string]string `json:"config_vars"` | ||
} | ||
|
||
// Repo represents Git Config KV pair | ||
type GitConfigPair struct { | ||
Key string | ||
Value string | ||
} | ||
|
||
// GitConfigSet updates Git Config with passed-in map of new variables | ||
func (c *Client) GitConfigSet(cc context.Context, repo string, vars map[string]string) error { | ||
path := "/git/repos/{acct}/" + url.PathEscape(repo) + "/config-vars" | ||
req := c.newRequest(cc, "PATCH", path, false) | ||
c.prepareJSONBody(req, &gitConfigJSON{vars}) | ||
return req.doJSON(nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package cli | ||
|
||
import ( | ||
"github.com/gemfury/cli/api" | ||
"github.com/gemfury/cli/internal/ctx" | ||
"github.com/spf13/cobra" | ||
"sort" | ||
"strings" | ||
"text/tabwriter" | ||
|
||
"fmt" | ||
) | ||
|
||
// NewCmdGitConfig is the root for Git Config | ||
func NewCmdGitConfig() *cobra.Command { | ||
gitConfigCmd := &cobra.Command{ | ||
Use: "config", | ||
Short: "Configure Git build", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return filteredGitConfig(cmd, args, false) | ||
}, | ||
} | ||
|
||
gitConfigCmd.AddCommand(NewCmdGitConfigSet()) | ||
gitConfigCmd.AddCommand(NewCmdGitConfigGet()) | ||
|
||
return gitConfigCmd | ||
} | ||
|
||
// NewCmdGitConfigGet updates one or more configuration keys | ||
func NewCmdGitConfigGet() *cobra.Command { | ||
gitConfigGetCmd := &cobra.Command{ | ||
Use: "get KEY", | ||
Short: "Get Git build environment key", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return filteredGitConfig(cmd, args, true) | ||
}, | ||
} | ||
|
||
return gitConfigGetCmd | ||
} | ||
|
||
// Filtered/unfiltered retrieval of Git Config for commands above | ||
func filteredGitConfig(cmd *cobra.Command, args []string, filter bool) error { | ||
if filter && len(args) < 2 { | ||
return fmt.Errorf("Please specify a repository and a key") | ||
} else if !filter && len(args) != 1 { | ||
return fmt.Errorf("Command requires only a repository") | ||
} | ||
|
||
cc := cmd.Context() | ||
term := ctx.Terminal(cc) | ||
c, err := newAPIClient(cc) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
config, err := c.GitConfig(cc, args[0]) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
filteredConfig := config | ||
if keys := args[1:]; filter && len(keys) > 0 { | ||
filteredConfig = make([]api.GitConfigPair, 0, len(keys)) | ||
for _, c := range config { | ||
for _, k := range keys { | ||
if c.Key == k { | ||
filteredConfig = append(filteredConfig, c) | ||
break | ||
} | ||
} | ||
} | ||
} | ||
|
||
if len(filteredConfig) > 0 { | ||
sort.Slice(filteredConfig, func(i, j int) bool { | ||
return filteredConfig[i].Key < filteredConfig[j].Key | ||
}) | ||
} | ||
|
||
term.Printf("\n*** GIT CONFIG ***\n\n") | ||
w := tabwriter.NewWriter(term.IOOut(), 0, 0, 2, ' ', 0) | ||
|
||
for _, c := range filteredConfig { | ||
fmt.Fprintf(w, "%s:\t%s\n", c.Key, c.Value) | ||
} | ||
|
||
w.Flush() | ||
return nil | ||
} | ||
|
||
// NewCmdGitConfigSet updates one or more configuration keys | ||
func NewCmdGitConfigSet() *cobra.Command { | ||
gitConfigSetCmd := &cobra.Command{ | ||
Use: "set KEY=VAL", | ||
Short: "Set Git build environment key", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if len(args) < 2 { | ||
return fmt.Errorf("Please specify a repository and a KEY=VALUE") | ||
} | ||
|
||
cc := cmd.Context() | ||
term := ctx.Terminal(cc) | ||
c, err := newAPIClient(cc) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
vars := map[string]string{} | ||
for _, pairStr := range args[1:] { | ||
pair := strings.SplitN(pairStr, "=", 2) | ||
if len(pair) != 2 { | ||
return fmt.Errorf("Argument has no value: %s", pairStr) | ||
} | ||
vars[pair[0]] = pair[1] | ||
} | ||
|
||
err = c.GitConfigSet(cc, args[0], vars) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
term.Printf("Updated %s repository config\n", args[0]) | ||
return nil | ||
}, | ||
} | ||
|
||
return gitConfigSetCmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package cli_test | ||
|
||
import ( | ||
"github.com/gemfury/cli/cli" | ||
"github.com/gemfury/cli/internal/ctx" | ||
"github.com/gemfury/cli/internal/testutil" | ||
"github.com/gemfury/cli/pkg/terminal" | ||
"strings" | ||
"testing" | ||
) | ||
|
||
const ( | ||
gitConfigResponse = `{ "config_vars": { | ||
"KEY1": "VALUE1", | ||
"KEY2": "VALUE2" | ||
}} | ||
` | ||
) | ||
|
||
// ==== GIT CONFIG ==== | ||
|
||
func TestGitConfigCommandSuccess(t *testing.T) { | ||
auth := terminal.TestAuther("user", "abc123", nil) | ||
term := terminal.NewForTest() | ||
|
||
// Fire up test server | ||
path := "/git/repos/me/repo-name/config-vars" | ||
server := testutil.APIServer(t, "GET", path, gitConfigResponse, 200) | ||
defer server.Close() | ||
|
||
cc := cli.TestContext(term, auth) | ||
flags := ctx.GlobalFlags(cc) | ||
flags.Endpoint = server.URL | ||
|
||
err := runCommandNoErr(cc, []string{"git", "config", "repo-name"}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
exp := "KEY1: VALUE1 KEY2: VALUE2" | ||
if outStr := compactString(term.OutBytes()); !strings.HasSuffix(outStr, exp) { | ||
t.Errorf("Expected output to include %q, got %q", exp, outStr) | ||
} | ||
} | ||
|
||
func TestGitConfigCommandUnauthorized(t *testing.T) { | ||
path := "/git/repos/me/repo-name/config-vars" | ||
server := testutil.APIServer(t, "GET", path, "{}", 200) | ||
testCommandLoginPreCheck(t, []string{"git", "config", "repo-name"}, server) | ||
server.Close() | ||
} | ||
|
||
func TestGitConfigCommandForbidden(t *testing.T) { | ||
path := "/git/repos/me/repo-name/config-vars" | ||
server := testutil.APIServer(t, "GET", path, "", 403) | ||
testCommandForbiddenResponse(t, []string{"git", "config", "repo-name"}, server) | ||
server.Close() | ||
} | ||
|
||
// ==== GIT CONFIG GET ==== | ||
|
||
func TestGitConfigGetCommandSuccess(t *testing.T) { | ||
auth := terminal.TestAuther("user", "abc123", nil) | ||
term := terminal.NewForTest() | ||
|
||
// Fire up test server | ||
path := "/git/repos/me/repo-name/config-vars" | ||
server := testutil.APIServer(t, "GET", path, gitConfigResponse, 200) | ||
defer server.Close() | ||
|
||
cc := cli.TestContext(term, auth) | ||
flags := ctx.GlobalFlags(cc) | ||
flags.Endpoint = server.URL | ||
|
||
err := runCommandNoErr(cc, []string{"git", "config", "get", "repo-name", "KEY2"}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
exp := "KEY2: VALUE2" | ||
if outStr := compactString(term.OutBytes()); !strings.HasSuffix(outStr, exp) { | ||
t.Errorf("Expected output to include %q, got %q", exp, outStr) | ||
} else if strings.Contains(outStr, "KEY1") { | ||
t.Errorf("Expected output to be filtered, got %q", outStr) | ||
} | ||
} | ||
|
||
func TestGitConfigGetCommandUnauthorized(t *testing.T) { | ||
path := "/git/repos/me/repo-name/config-vars" | ||
server := testutil.APIServer(t, "GET", path, "{}", 200) | ||
testCommandLoginPreCheck(t, []string{"git", "config", "get", "repo-name", "KEY2"}, server) | ||
server.Close() | ||
} | ||
|
||
func TestGitConfigGetCommandForbidden(t *testing.T) { | ||
path := "/git/repos/me/repo-name/config-vars" | ||
server := testutil.APIServer(t, "GET", path, "", 403) | ||
testCommandForbiddenResponse(t, []string{"git", "config", "get", "repo-name", "KEY2"}, server) | ||
server.Close() | ||
} | ||
|
||
// ==== GIT CONFIG SET ==== | ||
|
||
func TestGitConfigSetCommandSuccess(t *testing.T) { | ||
auth := terminal.TestAuther("user", "abc123", nil) | ||
term := terminal.NewForTest() | ||
|
||
// Fire up test server | ||
path := "/git/repos/me/repo-name/config-vars" | ||
server := testutil.APIServer(t, "PATCH", path, gitConfigResponse, 200) | ||
defer server.Close() | ||
|
||
cc := cli.TestContext(term, auth) | ||
flags := ctx.GlobalFlags(cc) | ||
flags.Endpoint = server.URL | ||
|
||
err := runCommandNoErr(cc, []string{"git", "config", "set", "repo-name", "KEY2=VALUE2"}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
exp := "Updated repo-name repository config" | ||
if outStr := compactString(term.OutBytes()); outStr != exp { | ||
t.Errorf("Expected output to include %q, got %q", exp, outStr) | ||
} | ||
} | ||
|
||
func TestGitConfigSetCommandUnauthorized(t *testing.T) { | ||
path := "/git/repos/me/repo-name/config-vars" | ||
server := testutil.APIServer(t, "PATCH", path, "{}", 200) | ||
testCommandLoginPreCheck(t, []string{"git", "config", "set", "repo-name", "KEY2=VALUE2"}, server) | ||
server.Close() | ||
} | ||
|
||
func TestGitConfigSetCommandForbidden(t *testing.T) { | ||
path := "/git/repos/me/repo-name/config-vars" | ||
server := testutil.APIServer(t, "PATCH", path, "", 403) | ||
testCommandForbiddenResponse(t, []string{"git", "config", "set", "repo-name", "KEY2=VALUE2"}, server) | ||
server.Close() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.