aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bridge/core/auth/credential.go2
-rw-r--r--bridge/core/bridge.go4
-rw-r--r--bridge/core/config.go5
-rw-r--r--bridge/github/config.go35
-rw-r--r--bridge/github/github.go6
-rw-r--r--bridge/gitlab/config.go14
-rw-r--r--input/prompt.go88
7 files changed, 54 insertions, 100 deletions
diff --git a/bridge/core/auth/credential.go b/bridge/core/auth/credential.go
index 86cf737e..2814e94c 100644
--- a/bridge/core/auth/credential.go
+++ b/bridge/core/auth/credential.go
@@ -123,7 +123,7 @@ func loadFromConfig(rawConfigs map[string]string, id entity.Id) (Credential, err
case KindLoginPassword:
cred, err = NewLoginPasswordFromConfig(configs)
default:
- return nil, fmt.Errorf("unknown credential type %s", configs[configKeyKind])
+ return nil, fmt.Errorf("unknown credential type \"%s\"", configs[configKeyKind])
}
if err != nil {
diff --git a/bridge/core/bridge.go b/bridge/core/bridge.go
index 62fd70f6..c72ff6b4 100644
--- a/bridge/core/bridge.go
+++ b/bridge/core/bridge.go
@@ -52,7 +52,7 @@ func Register(impl BridgeImpl) {
if bridgeLoginMetaKey == nil {
bridgeLoginMetaKey = make(map[string]string)
}
- bridgeImpl[impl.Target()] = reflect.TypeOf(impl)
+ bridgeImpl[impl.Target()] = reflect.TypeOf(impl).Elem()
bridgeLoginMetaKey[impl.Target()] = impl.LoginMetaKey()
}
@@ -94,7 +94,7 @@ func NewBridge(repo *cache.RepoCache, target string, name string) (*Bridge, erro
return nil, fmt.Errorf("unknown bridge target %v", target)
}
- impl := reflect.New(implType).Elem().Interface().(BridgeImpl)
+ impl := reflect.New(implType).Interface().(BridgeImpl)
bridge := &Bridge{
Name: name,
diff --git a/bridge/core/config.go b/bridge/core/config.go
index afcda560..7f8d7e13 100644
--- a/bridge/core/config.go
+++ b/bridge/core/config.go
@@ -1,6 +1,8 @@
package core
import (
+ "fmt"
+
"github.com/MichaelMure/git-bug/cache"
"github.com/MichaelMure/git-bug/identity"
)
@@ -24,6 +26,7 @@ func FinishConfig(repo *cache.RepoCache, metaKey string, login string) error {
return err
}
if err == nil {
+ fmt.Printf("Current identity %v tagged with login %v\n", user.Id().Human(), login)
// found one
user.SetMetadata(metaKey, login)
return user.CommitAsNeeded()
@@ -42,5 +45,7 @@ func FinishConfig(repo *cache.RepoCache, metaKey string, login string) error {
return err
}
+ fmt.Printf("Identity %v created, set as current\n", i.Id().Human())
+
return nil
}
diff --git a/bridge/github/config.go b/bridge/github/config.go
index 9167ac26..269c6144 100644
--- a/bridge/github/config.go
+++ b/bridge/github/config.go
@@ -143,7 +143,7 @@ func (g *Github) Configure(repo *cache.RepoCache, params core.BridgeParams) (cor
return conf, core.FinishConfig(repo, metaKeyGithubLogin, login)
}
-func (Github) ValidateConfig(conf core.Configuration) error {
+func (*Github) ValidateConfig(conf core.Configuration) error {
if v, ok := conf[core.ConfigKeyTarget]; !ok {
return fmt.Errorf("missing %s key", core.ConfigKeyTarget)
} else if v != target {
@@ -252,13 +252,18 @@ func promptTokenOptions(repo repository.RepoConfig, login, owner, project string
return nil, err
}
- cred, err := input.PromptCredentialWithInteractive(target, "token", creds)
- switch err {
- case nil:
+ cred, index, err := input.PromptCredential(target, "token", creds, []string{
+ "enter my token",
+ "interactive token creation",
+ })
+ switch {
+ case err != nil:
+ return nil, err
+ case cred != nil:
return cred, nil
- case input.ErrDirectPrompt:
+ case index == 0:
return promptToken()
- case input.ErrInteractiveCreation:
+ case index == 1:
value, err := loginAndRequestToken(login, owner, project)
if err != nil {
return nil, err
@@ -267,7 +272,7 @@ func promptTokenOptions(repo repository.RepoConfig, login, owner, project string
token.SetMetadata(auth.MetaKeyLogin, login)
return token, nil
default:
- return nil, err
+ panic("missed case")
}
}
@@ -322,31 +327,19 @@ func loginAndRequestToken(login, owner, project string) (string, error) {
fmt.Println()
// prompt project visibility to know the token scope needed for the repository
- i, err := input.PromptChoice("repository visibility", []string{"public", "private"})
+ index, err := input.PromptChoice("repository visibility", []string{"public", "private"})
if err != nil {
return "", err
}
- isPublic := i == 0
+ scope := []string{"public_repo", "repo"}[index]
password, err := input.PromptPassword("Password", "password", input.Required)
if err != nil {
return "", err
}
- var scope string
- if isPublic {
- // public_repo is requested to be able to read public repositories
- scope = "public_repo"
- } else {
- // 'repo' is request to be able to read private repositories
- // /!\ token will have read/write rights on every private repository you have access to
- scope = "repo"
- }
-
// Attempt to authenticate and create a token
-
note := fmt.Sprintf("git-bug - %s/%s", owner, project)
-
resp, err := requestToken(note, login, password, scope)
if err != nil {
return "", err
diff --git a/bridge/github/github.go b/bridge/github/github.go
index a02d9460..3a99cec7 100644
--- a/bridge/github/github.go
+++ b/bridge/github/github.go
@@ -30,7 +30,7 @@ var _ core.BridgeImpl = &Github{}
type Github struct{}
-func (Github) Target() string {
+func (*Github) Target() string {
return target
}
@@ -38,11 +38,11 @@ func (g *Github) LoginMetaKey() string {
return metaKeyGithubLogin
}
-func (Github) NewImporter() core.Importer {
+func (*Github) NewImporter() core.Importer {
return &githubImporter{}
}
-func (Github) NewExporter() core.Exporter {
+func (*Github) NewExporter() core.Exporter {
return &githubExporter{}
}
diff --git a/bridge/gitlab/config.go b/bridge/gitlab/config.go
index 94026635..b730a365 100644
--- a/bridge/gitlab/config.go
+++ b/bridge/gitlab/config.go
@@ -161,14 +161,18 @@ func promptTokenOptions(repo repository.RepoConfig, login, baseUrl string) (auth
return nil, err
}
- cred, err := input.PromptCredential(target, "token", creds)
- switch err {
- case nil:
+ cred, index, err := input.PromptCredential(target, "token", creds, []string{
+ "enter my token",
+ })
+ switch {
+ case err != nil:
+ return nil, err
+ case cred != nil:
return cred, nil
- case input.ErrDirectPrompt:
+ case index == 0:
return promptToken(baseUrl)
default:
- return nil, err
+ panic("missed case")
}
}
diff --git a/input/prompt.go b/input/prompt.go
index 2093695f..b5ca9a17 100644
--- a/input/prompt.go
+++ b/input/prompt.go
@@ -2,7 +2,6 @@ package input
import (
"bufio"
- "errors"
"fmt"
"net/url"
"os"
@@ -47,6 +46,8 @@ func IsURL(name string, value string) (string, error) {
return "", nil
}
+// Prompts
+
func Prompt(prompt, name string, validators ...PromptValidator) (string, error) {
return PromptDefault(prompt, name, "", validators...)
}
@@ -148,7 +149,7 @@ func PromptChoice(prompt string, choices []string) (int, error) {
continue
}
- return index, nil
+ return index - 1, nil
}
}
@@ -193,69 +194,22 @@ func PromptURLWithRemote(prompt, name string, validRemotes []string, validators
return Prompt(prompt, name, validators...)
}
-var ErrDirectPrompt = errors.New("direct prompt selected")
-var ErrInteractiveCreation = errors.New("interactive creation selected")
-
-func PromptCredential(target, name string, credentials []auth.Credential) (auth.Credential, error) {
- if len(credentials) == 0 {
- return nil, nil
+func PromptCredential(target, name string, credentials []auth.Credential, choices []string) (auth.Credential, int, error) {
+ if len(credentials) == 0 && len(choices) == 0 {
+ return nil, 0, fmt.Errorf("no possible choice")
}
-
- sort.Sort(auth.ById(credentials))
-
- for {
- _, _ = fmt.Fprintf(os.Stderr, "[1]: enter my %s\n", name)
-
- _, _ = fmt.Fprintln(os.Stderr)
- _, _ = fmt.Fprintf(os.Stderr, "Existing %s for %s:", name, target)
-
- for i, cred := range credentials {
- meta := make([]string, 0, len(cred.Metadata()))
- for k, v := range cred.Metadata() {
- meta = append(meta, k+":"+v)
- }
- sort.Strings(meta)
- metaFmt := strings.Join(meta, ",")
-
- fmt.Printf("[%d]: %s => (%s) (%s)\n",
- i+2,
- colors.Cyan(cred.ID().Human()),
- metaFmt,
- cred.CreateTime().Format(time.RFC822),
- )
- }
-
- _, _ = fmt.Fprintln(os.Stderr)
- _, _ = fmt.Fprintf(os.Stderr, "Select option: ")
-
- line, err := bufio.NewReader(os.Stdin).ReadString('\n')
- _, _ = fmt.Fprintln(os.Stderr)
- if err != nil {
- return nil, err
- }
-
- line = strings.TrimSpace(line)
- index, err := strconv.Atoi(line)
- if err != nil || index < 1 || index > len(credentials)+1 {
- _, _ = fmt.Fprintln(os.Stderr, "invalid input")
- continue
- }
-
- switch index {
- case 1:
- return nil, ErrDirectPrompt
- default:
- return credentials[index-2], nil
- }
+ if len(credentials) == 0 && len(choices) == 1 {
+ return nil, 0, nil
}
-}
-func PromptCredentialWithInteractive(target, name string, credentials []auth.Credential) (auth.Credential, error) {
sort.Sort(auth.ById(credentials))
for {
- _, _ = fmt.Fprintf(os.Stderr, "[1]: enter my %s\n", name)
- _, _ = fmt.Fprintf(os.Stderr, "[2]: interactive %s creation\n", name)
+ offset := 0
+ for i, choice := range choices {
+ _, _ = fmt.Fprintf(os.Stderr, "[%d]: %s\n", i+1, choice)
+ offset++
+ }
if len(credentials) > 0 {
_, _ = fmt.Fprintln(os.Stderr)
@@ -270,7 +224,7 @@ func PromptCredentialWithInteractive(target, name string, credentials []auth.Cre
metaFmt := strings.Join(meta, ",")
fmt.Printf("[%d]: %s => (%s) (%s)\n",
- i+2,
+ i+1+offset,
colors.Cyan(cred.ID().Human()),
metaFmt,
cred.CreateTime().Format(time.RFC822),
@@ -284,23 +238,21 @@ func PromptCredentialWithInteractive(target, name string, credentials []auth.Cre
line, err := bufio.NewReader(os.Stdin).ReadString('\n')
_, _ = fmt.Fprintln(os.Stderr)
if err != nil {
- return nil, err
+ return nil, 0, err
}
line = strings.TrimSpace(line)
index, err := strconv.Atoi(line)
- if err != nil || index < 1 || index > len(credentials)+1 {
+ if err != nil || index < 1 || index > len(choices)+len(credentials) {
_, _ = fmt.Fprintln(os.Stderr, "invalid input")
continue
}
- switch index {
- case 1:
- return nil, ErrDirectPrompt
- case 2:
- return nil, ErrInteractiveCreation
+ switch {
+ case index < len(choices):
+ return nil, index - 1, nil
default:
- return credentials[index-3], nil
+ return credentials[index-len(choices)-1], 0, nil
}
}
}