mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-15 02:01:43 +03:00
Merge pull request #200 from MichaelMure/bridge-token-stdin
bridge: support --token-stdin
This commit is contained in:
commit
16af70894c
@ -31,10 +31,11 @@ var bridgeImpl map[string]reflect.Type
|
|||||||
// BridgeParams holds parameters to simplify the bridge configuration without
|
// BridgeParams holds parameters to simplify the bridge configuration without
|
||||||
// having to make terminal prompts.
|
// having to make terminal prompts.
|
||||||
type BridgeParams struct {
|
type BridgeParams struct {
|
||||||
Owner string
|
Owner string
|
||||||
Project string
|
Project string
|
||||||
URL string
|
URL string
|
||||||
Token string
|
Token string
|
||||||
|
TokenStdin bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bridge is a wrapper around a BridgeImpl that will bind low-level
|
// Bridge is a wrapper around a BridgeImpl that will bind low-level
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
|
|
||||||
"github.com/MichaelMure/git-bug/bridge/core"
|
"github.com/MichaelMure/git-bug/bridge/core"
|
||||||
"github.com/MichaelMure/git-bug/repository"
|
"github.com/MichaelMure/git-bug/repository"
|
||||||
|
"github.com/MichaelMure/git-bug/util/interrupt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -37,13 +38,18 @@ var (
|
|||||||
ErrBadProjectURL = errors.New("bad project url")
|
ErrBadProjectURL = errors.New("bad project url")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (*Github) Configure(repo repository.RepoCommon, params core.BridgeParams) (core.Configuration, error) {
|
func (g *Github) Configure(repo repository.RepoCommon, params core.BridgeParams) (core.Configuration, error) {
|
||||||
conf := make(core.Configuration)
|
conf := make(core.Configuration)
|
||||||
var err error
|
var err error
|
||||||
var token string
|
var token string
|
||||||
var owner string
|
var owner string
|
||||||
var project string
|
var project string
|
||||||
|
|
||||||
|
if (params.Token != "" || params.TokenStdin) &&
|
||||||
|
(params.URL == "" && (params.Project == "" || params.Owner == "")) {
|
||||||
|
return nil, fmt.Errorf("you must provide a project URL or Owner/Name to configure this bridge with a token")
|
||||||
|
}
|
||||||
|
|
||||||
// getting owner and project name
|
// getting owner and project name
|
||||||
if params.Owner != "" && params.Project != "" {
|
if params.Owner != "" && params.Project != "" {
|
||||||
// first try to use params if both or project and owner are provided
|
// first try to use params if both or project and owner are provided
|
||||||
@ -85,6 +91,13 @@ func (*Github) Configure(repo repository.RepoCommon, params core.BridgeParams) (
|
|||||||
if params.Token != "" {
|
if params.Token != "" {
|
||||||
token = params.Token
|
token = params.Token
|
||||||
|
|
||||||
|
} else if params.TokenStdin {
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
token, err = reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("reading from stdin: %v", err)
|
||||||
|
}
|
||||||
|
token = strings.TrimSuffix(token, "\n")
|
||||||
} else {
|
} else {
|
||||||
token, err = promptTokenOptions(owner, project)
|
token, err = promptTokenOptions(owner, project)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -106,6 +119,11 @@ func (*Github) Configure(repo repository.RepoCommon, params core.BridgeParams) (
|
|||||||
conf[keyOwner] = owner
|
conf[keyOwner] = owner
|
||||||
conf[keyProject] = project
|
conf[keyProject] = project
|
||||||
|
|
||||||
|
err = g.ValidateConfig(conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,6 +523,16 @@ func validateProject(owner, project, token string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func promptPassword() (string, error) {
|
func promptPassword() (string, error) {
|
||||||
|
termState, err := terminal.GetState(int(syscall.Stdin))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel := interrupt.RegisterCleaner(func() error {
|
||||||
|
return terminal.Restore(int(syscall.Stdin), termState)
|
||||||
|
})
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
fmt.Print("password: ")
|
fmt.Print("password: ")
|
||||||
|
|
||||||
@ -526,6 +554,16 @@ func promptPassword() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func prompt2FA() (string, error) {
|
func prompt2FA() (string, error) {
|
||||||
|
termState, err := terminal.GetState(int(syscall.Stdin))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel := interrupt.RegisterCleaner(func() error {
|
||||||
|
return terminal.Restore(int(syscall.Stdin), termState)
|
||||||
|
})
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
fmt.Print("two-factor authentication code: ")
|
fmt.Print("two-factor authentication code: ")
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ var (
|
|||||||
ErrBadProjectURL = errors.New("bad project url")
|
ErrBadProjectURL = errors.New("bad project url")
|
||||||
)
|
)
|
||||||
|
|
||||||
func (*Gitlab) Configure(repo repository.RepoCommon, params core.BridgeParams) (core.Configuration, error) {
|
func (g *Gitlab) Configure(repo repository.RepoCommon, params core.BridgeParams) (core.Configuration, error) {
|
||||||
if params.Project != "" {
|
if params.Project != "" {
|
||||||
fmt.Println("warning: --project is ineffective for a gitlab bridge")
|
fmt.Println("warning: --project is ineffective for a gitlab bridge")
|
||||||
}
|
}
|
||||||
@ -33,6 +33,10 @@ func (*Gitlab) Configure(repo repository.RepoCommon, params core.BridgeParams) (
|
|||||||
var url string
|
var url string
|
||||||
var token string
|
var token string
|
||||||
|
|
||||||
|
if (params.Token != "" || params.TokenStdin) && params.URL == "" {
|
||||||
|
return nil, fmt.Errorf("you must provide a project URL to configure this bridge with a token")
|
||||||
|
}
|
||||||
|
|
||||||
// get project url
|
// get project url
|
||||||
if params.URL != "" {
|
if params.URL != "" {
|
||||||
url = params.URL
|
url = params.URL
|
||||||
@ -54,6 +58,13 @@ func (*Gitlab) Configure(repo repository.RepoCommon, params core.BridgeParams) (
|
|||||||
// get user token
|
// get user token
|
||||||
if params.Token != "" {
|
if params.Token != "" {
|
||||||
token = params.Token
|
token = params.Token
|
||||||
|
} else if params.TokenStdin {
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
token, err = reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("reading from stdin: %v", err)
|
||||||
|
}
|
||||||
|
token = strings.TrimSuffix(token, "\n")
|
||||||
} else {
|
} else {
|
||||||
token, err = promptToken()
|
token, err = promptToken()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -71,10 +82,15 @@ func (*Gitlab) Configure(repo repository.RepoCommon, params core.BridgeParams) (
|
|||||||
conf[keyToken] = token
|
conf[keyToken] = token
|
||||||
conf[core.KeyTarget] = target
|
conf[core.KeyTarget] = target
|
||||||
|
|
||||||
|
err = g.ValidateConfig(conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Gitlab) ValidateConfig(conf core.Configuration) error {
|
func (g *Gitlab) ValidateConfig(conf core.Configuration) error {
|
||||||
if v, ok := conf[core.KeyTarget]; !ok {
|
if v, ok := conf[core.KeyTarget]; !ok {
|
||||||
return fmt.Errorf("missing %s key", core.KeyTarget)
|
return fmt.Errorf("missing %s key", core.KeyTarget)
|
||||||
} else if v != target {
|
} else if v != target {
|
||||||
|
@ -22,7 +22,7 @@ const (
|
|||||||
defaultTimeout = 60 * time.Second
|
defaultTimeout = 60 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
func (*Launchpad) Configure(repo repository.RepoCommon, params core.BridgeParams) (core.Configuration, error) {
|
func (l *Launchpad) Configure(repo repository.RepoCommon, params core.BridgeParams) (core.Configuration, error) {
|
||||||
if params.Token != "" {
|
if params.Token != "" {
|
||||||
fmt.Println("warning: --token is ineffective for a Launchpad bridge")
|
fmt.Println("warning: --token is ineffective for a Launchpad bridge")
|
||||||
}
|
}
|
||||||
@ -63,6 +63,12 @@ func (*Launchpad) Configure(repo repository.RepoCommon, params core.BridgeParams
|
|||||||
|
|
||||||
conf[keyProject] = project
|
conf[keyProject] = project
|
||||||
conf[core.KeyTarget] = target
|
conf[core.KeyTarget] = target
|
||||||
|
|
||||||
|
err = l.ValidateConfig(conf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return conf, nil
|
return conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
|
||||||
|
|
||||||
"github.com/MichaelMure/git-bug/bridge"
|
"github.com/MichaelMure/git-bug/bridge"
|
||||||
"github.com/MichaelMure/git-bug/bridge/core"
|
"github.com/MichaelMure/git-bug/bridge/core"
|
||||||
@ -36,15 +34,10 @@ func runBridgeConfigure(cmd *cobra.Command, args []string) error {
|
|||||||
defer backend.Close()
|
defer backend.Close()
|
||||||
interrupt.RegisterCleaner(backend.Close)
|
interrupt.RegisterCleaner(backend.Close)
|
||||||
|
|
||||||
termState, err := terminal.GetState(int(syscall.Stdin))
|
if (bridgeParams.TokenStdin || bridgeParams.Token != "") && (bridgeConfigureName == "" || bridgeConfigureTarget == "") {
|
||||||
if err != nil {
|
return fmt.Errorf("you must provide a bridge name and target to configure a bridge with a token")
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interrupt.RegisterCleaner(func() error {
|
|
||||||
return terminal.Restore(int(syscall.Stdin), termState)
|
|
||||||
})
|
|
||||||
|
|
||||||
if bridgeConfigureTarget == "" {
|
if bridgeConfigureTarget == "" {
|
||||||
bridgeConfigureTarget, err = promptTarget()
|
bridgeConfigureTarget, err = promptTarget()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -192,6 +185,7 @@ func init() {
|
|||||||
bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.URL, "url", "u", "", "The URL of the target repository")
|
bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.URL, "url", "u", "", "The URL of the target repository")
|
||||||
bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.Owner, "owner", "o", "", "The owner of the target repository")
|
bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.Owner, "owner", "o", "", "The owner of the target repository")
|
||||||
bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.Token, "token", "T", "", "The authentication token for the API")
|
bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.Token, "token", "T", "", "The authentication token for the API")
|
||||||
|
bridgeConfigureCmd.Flags().BoolVar(&bridgeParams.TokenStdin, "token-stdin", false, "Will read the token from stdin and ignore --token")
|
||||||
bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.Project, "project", "p", "", "The name of the target repository")
|
bridgeConfigureCmd.Flags().StringVarP(&bridgeParams.Project, "project", "p", "", "The name of the target repository")
|
||||||
bridgeConfigureCmd.Flags().SortFlags = false
|
bridgeConfigureCmd.Flags().SortFlags = false
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,10 @@ Token configuration can be directly passed with the \-\-token flag or in the ter
|
|||||||
\fB\-T\fP, \fB\-\-token\fP=""
|
\fB\-T\fP, \fB\-\-token\fP=""
|
||||||
The authentication token for the API
|
The authentication token for the API
|
||||||
|
|
||||||
|
.PP
|
||||||
|
\fB\-\-token\-stdin\fP[=false]
|
||||||
|
Will read the token from stdin and ignore \-\-token
|
||||||
|
|
||||||
.PP
|
.PP
|
||||||
\fB\-p\fP, \fB\-\-project\fP=""
|
\fB\-p\fP, \fB\-\-project\fP=""
|
||||||
The name of the target repository
|
The name of the target repository
|
||||||
@ -91,7 +95,7 @@ Private:
|
|||||||
Enter token: 87cf5c03b64029f18ea5f9ca5679daa08ccbd700
|
Enter token: 87cf5c03b64029f18ea5f9ca5679daa08ccbd700
|
||||||
Successfully configured bridge: default
|
Successfully configured bridge: default
|
||||||
|
|
||||||
# For Github
|
# For GitHub
|
||||||
git bug bridge configure \\
|
git bug bridge configure \\
|
||||||
\-\-name=default \\
|
\-\-name=default \\
|
||||||
\-\-target=github \\
|
\-\-target=github \\
|
||||||
@ -103,7 +107,14 @@ git bug bridge configure \\
|
|||||||
git bug bridge configure \\
|
git bug bridge configure \\
|
||||||
\-\-name=default \\
|
\-\-name=default \\
|
||||||
\-\-target=launchpad\-preview \\
|
\-\-target=launchpad\-preview \\
|
||||||
\-\-url=https://bugs.launchpad.net/ubuntu/
|
\-\-url=https://bugs.launchpad.net/ubuntu/
|
||||||
|
|
||||||
|
# For Gitlab
|
||||||
|
git bug bridge configure \\
|
||||||
|
\-\-name=default \\
|
||||||
|
\-\-target=github \\
|
||||||
|
\-\-url=https://github.com/michaelmure/git\-bug \\
|
||||||
|
\-\-token=$(TOKEN)
|
||||||
|
|
||||||
.fi
|
.fi
|
||||||
.RE
|
.RE
|
||||||
|
@ -45,7 +45,7 @@ Private:
|
|||||||
Enter token: 87cf5c03b64029f18ea5f9ca5679daa08ccbd700
|
Enter token: 87cf5c03b64029f18ea5f9ca5679daa08ccbd700
|
||||||
Successfully configured bridge: default
|
Successfully configured bridge: default
|
||||||
|
|
||||||
# For Github
|
# For GitHub
|
||||||
git bug bridge configure \
|
git bug bridge configure \
|
||||||
--name=default \
|
--name=default \
|
||||||
--target=github \
|
--target=github \
|
||||||
@ -57,7 +57,14 @@ git bug bridge configure \
|
|||||||
git bug bridge configure \
|
git bug bridge configure \
|
||||||
--name=default \
|
--name=default \
|
||||||
--target=launchpad-preview \
|
--target=launchpad-preview \
|
||||||
--url=https://bugs.launchpad.net/ubuntu/
|
--url=https://bugs.launchpad.net/ubuntu/
|
||||||
|
|
||||||
|
# For Gitlab
|
||||||
|
git bug bridge configure \
|
||||||
|
--name=default \
|
||||||
|
--target=github \
|
||||||
|
--url=https://github.com/michaelmure/git-bug \
|
||||||
|
--token=$(TOKEN)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Options
|
### Options
|
||||||
@ -68,6 +75,7 @@ git bug bridge configure \
|
|||||||
-u, --url string The URL of the target repository
|
-u, --url string The URL of the target repository
|
||||||
-o, --owner string The owner of the target repository
|
-o, --owner string The owner of the target repository
|
||||||
-T, --token string The authentication token for the API
|
-T, --token string The authentication token for the API
|
||||||
|
--token-stdin Will read the token from stdin and ignore --token
|
||||||
-p, --project string The name of the target repository
|
-p, --project string The name of the target repository
|
||||||
-h, --help help for configure
|
-h, --help help for configure
|
||||||
```
|
```
|
||||||
|
@ -321,6 +321,8 @@ _git-bug_bridge_configure()
|
|||||||
two_word_flags+=("--token")
|
two_word_flags+=("--token")
|
||||||
two_word_flags+=("-T")
|
two_word_flags+=("-T")
|
||||||
local_nonpersistent_flags+=("--token=")
|
local_nonpersistent_flags+=("--token=")
|
||||||
|
flags+=("--token-stdin")
|
||||||
|
local_nonpersistent_flags+=("--token-stdin")
|
||||||
flags+=("--project=")
|
flags+=("--project=")
|
||||||
two_word_flags+=("--project")
|
two_word_flags+=("--project")
|
||||||
two_word_flags+=("-p")
|
two_word_flags+=("-p")
|
||||||
|
@ -65,6 +65,7 @@ Register-ArgumentCompleter -Native -CommandName 'git-bug' -ScriptBlock {
|
|||||||
[CompletionResult]::new('--owner', 'owner', [CompletionResultType]::ParameterName, 'The owner of the target repository')
|
[CompletionResult]::new('--owner', 'owner', [CompletionResultType]::ParameterName, 'The owner of the target repository')
|
||||||
[CompletionResult]::new('-T', 'T', [CompletionResultType]::ParameterName, 'The authentication token for the API')
|
[CompletionResult]::new('-T', 'T', [CompletionResultType]::ParameterName, 'The authentication token for the API')
|
||||||
[CompletionResult]::new('--token', 'token', [CompletionResultType]::ParameterName, 'The authentication token for the API')
|
[CompletionResult]::new('--token', 'token', [CompletionResultType]::ParameterName, 'The authentication token for the API')
|
||||||
|
[CompletionResult]::new('--token-stdin', 'token-stdin', [CompletionResultType]::ParameterName, 'Will read the token from stdin and ignore --token')
|
||||||
[CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'The name of the target repository')
|
[CompletionResult]::new('-p', 'p', [CompletionResultType]::ParameterName, 'The name of the target repository')
|
||||||
[CompletionResult]::new('--project', 'project', [CompletionResultType]::ParameterName, 'The name of the target repository')
|
[CompletionResult]::new('--project', 'project', [CompletionResultType]::ParameterName, 'The name of the target repository')
|
||||||
break
|
break
|
||||||
|
@ -146,6 +146,7 @@ function _git-bug_bridge_configure {
|
|||||||
'(-u --url)'{-u,--url}'[The URL of the target repository]:' \
|
'(-u --url)'{-u,--url}'[The URL of the target repository]:' \
|
||||||
'(-o --owner)'{-o,--owner}'[The owner of the target repository]:' \
|
'(-o --owner)'{-o,--owner}'[The owner of the target repository]:' \
|
||||||
'(-T --token)'{-T,--token}'[The authentication token for the API]:' \
|
'(-T --token)'{-T,--token}'[The authentication token for the API]:' \
|
||||||
|
'--token-stdin[Will read the token from stdin and ignore --token]' \
|
||||||
'(-p --project)'{-p,--project}'[The name of the target repository]:'
|
'(-p --project)'{-p,--project}'[The name of the target repository]:'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user