Skip to content

Commit

Permalink
Support ~/.config/hub to acquire token
Browse files Browse the repository at this point in the history
Related:
- #114
  • Loading branch information
leoluk committed Dec 9, 2021
1 parent cf48807 commit af1225c
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 5 deletions.
79 changes: 74 additions & 5 deletions github/githubclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"bytes"
"context"
"fmt"
"gopkg.in/yaml.v3"
"net/url"
"os"
"path"
"regexp"
"strings"

Expand All @@ -17,13 +19,80 @@ import (
"golang.org/x/oauth2"
)

func NewGitHubClient(ctx context.Context, config *config.Config) *client {
type hubCLIConfig map[string][]struct {
User string `yaml:"user"`
OauthToken string `yaml:"oauth_token"`
Protocol string `yaml:"protocol"`
}

// readHubCLIConfig finds and deserialized the config file for
// Github's "hub" CLI (https://hub.github.com/).
func readHubCLIConfig(githubHost string) (hubCLIConfig, error) {
homeDir, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("failed to get user home directory: %w", err)
}

f, err := os.Open(path.Join(homeDir, ".config", "hub"))
if err != nil {
return nil, fmt.Errorf("failed to open hub config file: %w", err)
}

var cfg hubCLIConfig
if err := yaml.NewDecoder(f).Decode(&cfg); err != nil {
return nil, fmt.Errorf("failed to parse hub config file: %w", err)
}

return cfg, nil
}

func findToken(githubHost string) string {
// Try environment variable first
token := os.Getenv("GITHUB_TOKEN")
if token != "" {
return token
}

// Try ~/config/hub
cfg, err := readHubCLIConfig(githubHost)
if err != nil {
log.Warn().Err(err).Msg("failed to read hub config file")
return ""
}

if c, ok := cfg["github.com"]; ok {
if len(c) == 0 {
log.Warn().Msg("no token found in hub config file")
return ""
}
if len(c) > 1 {
log.Warn().Msgf("multiple tokens found in hub config file, using first one: %s", c[0].User)
}

return c[0].OauthToken
}

return ""
}

const tokenHelpText = `
No GitHub OAuth token found! You can either create one
at https://%s/settings/tokens and set the GITHUB_TOKEN environment variable,
or configure it in ~/.config/hub:
github.com:
- user: <your username>
oauth_token: <your token>
protocol: https
This configuration file is shared with GitHub's "hub" CLI (https://hub.github.com/),
so if you already use that, spr will automatically pick up your token.
`

func NewGitHubClient(ctx context.Context, config *config.Config) *client {
token := findToken(config.Repo.GitHubHost)
if token == "" {
fmt.Printf("GitHub OAuth Token Required\n")
fmt.Printf("Make one at: https://%s/settings/tokens\n", config.Repo.GitHubHost)
fmt.Printf("With repo scope selected.\n")
fmt.Printf("And set an env variable called GITHUB_TOKEN with it's value.\n")
fmt.Printf(tokenHelpText, config.Repo.GitHubHost)
os.Exit(3)
}
ts := oauth2.StaticTokenSource(
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ require (
github.com/urfave/cli/v2 v2.3.0
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
)

0 comments on commit af1225c

Please sign in to comment.