From 75ba4f14d8d7317a8a02a2645892c3cb4bb49c67 Mon Sep 17 00:00:00 2001 From: Kyoichiro Yamada Date: Tue, 23 Jun 2020 15:39:13 +0900 Subject: [PATCH] Create new "setup" wizard --- go.mod | 2 ++ go.sum | 2 ++ internal/command/bin.go | 11 +++++++++++ internal/command/config.go | 7 ++----- internal/command/initialize.go | 11 +++++++++++ internal/command/setup.go | 29 ++++++++++++++++++++++++++--- internal/env/validation.go | 3 +-- internal/gordon/github_token.go | 31 +++++++++++++++++++++++++++++++ internal/hub/client.go | 18 +----------------- main.go | 25 +++++++++++++++++++++++-- 10 files changed, 110 insertions(+), 29 deletions(-) create mode 100644 internal/command/bin.go create mode 100644 internal/command/initialize.go create mode 100644 internal/gordon/github_token.go diff --git a/go.mod b/go.mod index 6b805a9..6ff28e6 100644 --- a/go.mod +++ b/go.mod @@ -8,8 +8,10 @@ require ( github.com/golang/mock v1.4.1 github.com/google/go-github/v29 v29.0.3 github.com/kyoh86/appenv v0.0.20 + github.com/kyoh86/ask v0.0.7 github.com/kyoh86/gogh v1.5.4 github.com/kyoh86/xdg v1.2.0 + github.com/morikuni/aec v1.0.0 github.com/pkg/errors v0.9.1 github.com/saracen/walker v0.0.0-20191201085201-324a081bae7e github.com/stoewer/go-strcase v1.2.0 diff --git a/go.sum b/go.sum index 72f1b4f..9dfe5a0 100644 --- a/go.sum +++ b/go.sum @@ -55,6 +55,8 @@ github.com/kyoh86/scopelint v0.2.0/go.mod h1:veFgnmDG8sPR5nFaXGX2mEIOXKHjWpGo79v github.com/kyoh86/xdg v1.2.0 h1:CERuT/ShdTDj+A2UaX3hQ3mOV369+Sj+wyn2nIRIIkI= github.com/kyoh86/xdg v1.2.0/go.mod h1:/mg8zwu1+qe76oTFUBnyS7rJzk7LLC0VGEzJyJ19DHs= github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/internal/command/bin.go b/internal/command/bin.go new file mode 100644 index 0000000..196d978 --- /dev/null +++ b/internal/command/bin.go @@ -0,0 +1,11 @@ +package command + +import ( + "context" + "fmt" +) + +func Bin(_ context.Context, ev Env) error { + fmt.Println(ev.Bin()) + return nil +} diff --git a/internal/command/config.go b/internal/command/config.go index 5c4b502..3d658af 100644 --- a/internal/command/config.go +++ b/internal/command/config.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/kyoh86/gordon/internal/env" + "github.com/kyoh86/gordon/internal/gordon" keyring "github.com/zalando/go-keyring" ) @@ -42,11 +43,7 @@ func ConfigGet(cfg *env.Config, optionName string) error { func ConfigSet(ev Env, cfg *env.Config, optionName, optionValue string) error { if optionName == "github.token" { - host, user := ev.GithubHost(), ev.GithubUser() - if err := keyring.Set(strings.Join([]string{host, env.KeyringService}, "."), user, optionValue); err != nil { - return err - } - return nil + return gordon.SetGitHubToken(ev.GithubHost(), ev.GithubUser(), optionValue) } opt, err := cfg.Property(optionName) diff --git a/internal/command/initialize.go b/internal/command/initialize.go new file mode 100644 index 0000000..679f691 --- /dev/null +++ b/internal/command/initialize.go @@ -0,0 +1,11 @@ +package command + +import ( + "context" + "fmt" +) + +func Initialize(_ context.Context, ev Env) error { + fmt.Printf(`export PATH="%s:${PATH}"%s`, ev.Bin(), "\n") + return nil +} diff --git a/internal/command/setup.go b/internal/command/setup.go index 32a86a7..65d7fb3 100644 --- a/internal/command/setup.go +++ b/internal/command/setup.go @@ -3,9 +3,32 @@ package command import ( "context" "fmt" + + "github.com/kyoh86/ask" + "github.com/kyoh86/gordon/internal/gordon" + "github.com/morikuni/aec" ) -func Setup(_ context.Context, ev Env) error { - fmt.Printf(`export PATH="%s:${PATH}"%s`, ev.Bin(), "\n") - return nil +func q(text string) string { + return aec.GreenF.With(aec.Bold).Apply("?") + " " + aec.Bold.Apply(text) +} + +func Setup(_ context.Context, ev Env, force bool) error { + user := ev.GithubUser() + if user == "" || force { + if err := ask.Default(ev.GithubUser()).Message(q("Enter your GitHub user ID")).StringVar(&user).Do(); err != nil { + return fmt.Errorf("asking GitHub user ID: %w", err) + } + } + token, err := gordon.GetGitHubToken(ev.GithubHost(), user) + if err != nil { + return fmt.Errorf("getting token: %w", err) + } + if token == "" || force { + if err := ask.Default(token).Hidden(true).Message(q("Enter your GitHub Private Access Token")).StringVar(&token).Do(); err != nil { + return fmt.Errorf("asking GitHub Private Access Token: %w", err) + } + } + + return gordon.SetGitHubToken(ev.GithubHost(), ev.GithubUser(), token) } diff --git a/internal/env/validation.go b/internal/env/validation.go index 03b05d4..732ec6e 100644 --- a/internal/env/validation.go +++ b/internal/env/validation.go @@ -1,12 +1,11 @@ package env import ( + "errors" "fmt" "os" "path/filepath" "regexp" - - "github.com/pkg/errors" ) var validOwnerRegexp = regexp.MustCompile(`^[a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*$`) diff --git a/internal/gordon/github_token.go b/internal/gordon/github_token.go new file mode 100644 index 0000000..18e8f00 --- /dev/null +++ b/internal/gordon/github_token.go @@ -0,0 +1,31 @@ +package gordon + +import ( + "errors" + "os" + "strings" + + "github.com/kyoh86/gordon/internal/env" + "github.com/zalando/go-keyring" +) + +func SetGitHubToken(host, user, token string) error { + if host == "" { + return errors.New("host is empty") + } + if user == "" { + return errors.New("user is empty") + } + return keyring.Set(strings.Join([]string{host, env.KeyringService}, "."), user, token) +} + +func GetGitHubToken(host, user string) (string, error) { + if user == "" { + return "", errors.New("user is empty") + } + envar := os.Getenv("GORDON_GITHUB_TOKEN") + if envar != "" { + return envar, nil + } + return keyring.Get(strings.Join([]string{host, env.KeyringService}, "."), user) +} diff --git a/internal/hub/client.go b/internal/hub/client.go index 274068c..ed879bd 100644 --- a/internal/hub/client.go +++ b/internal/hub/client.go @@ -2,16 +2,11 @@ package hub import ( "context" - "errors" "fmt" "net/http" - "os" - "strings" "github.com/google/go-github/v29/github" - "github.com/kyoh86/gordon/internal/env" "github.com/kyoh86/gordon/internal/gordon" - keyring "github.com/zalando/go-keyring" "golang.org/x/oauth2" ) @@ -41,22 +36,11 @@ func New(authContext context.Context, ev gordon.Env) (*Client, error) { return &Client{client}, nil } -func getToken(ev gordon.Env) (string, error) { - if ev.GithubUser() == "" { - return "", errors.New("github.user is empty") - } - envar := os.Getenv("GORDON_GITHUB_TOKEN") - if envar != "" { - return envar, nil - } - return keyring.Get(strings.Join([]string{ev.GithubHost(), env.KeyringService}, "."), ev.GithubUser()) -} - func oauth2Client(authContext context.Context, ev gordon.Env) (*http.Client, error) { if ev.GithubUser() == "" { return http.DefaultClient, nil } - token, err := getToken(ev) + token, err := gordon.GetGitHubToken(ev.GithubHost(), ev.GithubUser()) if err != nil { return nil, err } diff --git a/main.go b/main.go index e517640..f85a453 100644 --- a/main.go +++ b/main.go @@ -47,7 +47,10 @@ func main() { dump, restore, + setup, + bin, + initialize, } { key, run := f(app) cmds[key] = run @@ -174,8 +177,26 @@ func update(app *kingpin.Application) (string, func() error) { } func setup(app *kingpin.Application) (string, func() error) { - cmd := app.Command("setup", "Setup shell to support gordon") + var ( + force bool + ) + cmd := app.Command("setup", "Setup gordon with wizards") + cmd.Flag("force", "Ask even though that the option has already set").BoolVar(&force) + return mainutil.WrapCommand(cmd, func(ev command.Env) error { + return command.Setup(context.Background(), ev, force) + }) +} + +func bin(app *kingpin.Application) (string, func() error) { + cmd := app.Command("bin", "Print directory to store downloaded binaries") + return mainutil.WrapCommand(cmd, func(ev command.Env) error { + return command.Bin(context.Background(), ev) + }) +} + +func initialize(app *kingpin.Application) (string, func() error) { + cmd := app.Command("init", "Initialize shell to support gordon") return mainutil.WrapCommand(cmd, func(ev command.Env) error { - return command.Setup(context.Background(), ev) + return command.Initialize(context.Background(), ev) }) }