Skip to content

Commit

Permalink
cmd: Support optional use of GitHub personal access tokens
Browse files Browse the repository at this point in the history
With a personal access token, the API rate limit is increased from
60 requests per hour to 5000 requests per hour.
  • Loading branch information
jmooring committed Sep 11, 2023
1 parent 618521d commit 1d09e03
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 14 deletions.
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,16 +138,25 @@ Use "hvm [command] --help" for more information about a command.

## Configuration

### Number of releases to display

By default, the `hvm use` and `hvm install` commands display the 30 most recent releases. To change the number of releases displayed, you can do one of the following:

- Set the `numtagstodisplay` option in the hvm configuration file. You can find the path to the configuration file by running the `hvm config` command.
- Set the `HVM_NUMTAGSTODISPLAY` environment variable
- Set the `HVM_NUMTAGSTODISPLAY` environment variable.

To display all releases since v0.54.0, set the value to `-1`. Releases before v0.54.0 were not semantically versioned.

## Rate limiting
### GitHub personal access token

GitHub limits the number of requests that can be made to its API per hour to 60 for unauthenticated clients. If you exceed this limit, hvm will display a message indicating when the limit will be reset. This is typically within minutes.

If you regularly exceed this limit, you can create a GitHub personal access token with read-only public repository access. Then, you can do either of the following:

- Set the `githubtoken` option in the hvm configuration file. You can find the path to the configuration file by running the hvm config command.
- Set the `HVM_GITHUBTOKEN` environment variable.

GitHub limits the number of requests that can be made to its API per hour. Unauthenticated clients are limited to 60 requests per hour. If you exceed this limit, hvm will display a message indicating when the limit will be reset. This is typically within minutes.
With a personal access token, GitHub limits API requests to 5,000 per hour.

[go]: https://go.dev/doc/install
[hugo]: https://github.com/gohugoio/hugo/#readme
Expand Down
15 changes: 10 additions & 5 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ import (
"os"
"path/filepath"
"runtime"
"strconv"

"github.com/jmooring/hvm/helpers"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

type config struct {
NumTagsToDisplay int `toml:"numtagstodisplay" comment:"The number of tags to display with the \"use\" and \"install\" commands."`
GithubToken string `toml:"githubToken,omitempty" comment:"GitHub personal access token"`
NumTagsToDisplay int `toml:"numTagsToDisplay" comment:"Number of tags to display with the \"use\" and \"install\" commands"`
}

var Config config
Expand Down Expand Up @@ -83,6 +84,7 @@ func init() {
func initConfig() {
// Set default values.
viper.SetDefault("numTagsToDisplay", 30)
viper.SetDefault("githubToken", "")

// Create config directory.
userConfigDir, err := os.UserConfigDir()
Expand Down Expand Up @@ -113,12 +115,15 @@ func initConfig() {

// Validate config values.
k := "numTagsToDisplay"
vs := viper.GetString(k)
vi := viper.GetInt(k)
if _, err = strconv.Atoi(vs); err != nil || vi == 0 {
if viper.GetInt(k) == 0 {
err = fmt.Errorf("configuration: %s must be a non-zero integer: see %s", k, viper.ConfigFileUsed())
cobra.CheckErr(err)
}
k = "githubToken"
if !helpers.IsString(viper.Get(k)) {
err = fmt.Errorf("configuration: %s must be a string: see %s", k, viper.ConfigFileUsed())
cobra.CheckErr(err)
}

// Unmarshal the config to the Config struct.
err = viper.Unmarshal(&Config)
Expand Down
4 changes: 2 additions & 2 deletions cmd/testscripts/hvm_config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

# Test
exec hvm config
stdout '# The number of tags to display with the "use" and "install" commands.\n'
stdout 'numtagstodisplay = 30\n'
stdout '# Number of tags to display with the "use" and "install" commands\n'
stdout 'numTagsToDisplay = 30\n'
stdout 'Configuration file: '
20 changes: 20 additions & 0 deletions cmd/testscripts/hvm_config_bad_value.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# User cache and config dirs (we use os.UserCacheDir and os.UserCongfigDir)
[darwin] env HOME=home
[darwin] mkdir "$HOME/Library/Caches"
[darwin] mkdir "$HOME/Library/Application Support"
[linux] env XDG_CACHE_HOME=cache
[linux] env XDG_CONFIG_HOME=config
[windows] env LocalAppData=cache
[windows] env AppData=config

# Test
! exec hvm config
stderr 'Error: configuration: numTagsToDisplay must be a non-zero integer'

# Files for darwin
-- home/Library/Application Support/hvm/config.toml --
numtagstodisplay = "x"

# Files for linux and windows
-- config/hvm/config.toml --
numtagstodisplay = "x"
19 changes: 19 additions & 0 deletions cmd/testscripts/hvm_config_with_env_vars.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# User cache and config dirs (we use os.UserCacheDir and os.UserCongfigDir)
[darwin] env HOME=home
[darwin] mkdir "$HOME/Library/Caches"
[darwin] mkdir "$HOME/Library/Application Support"
[linux] env XDG_CACHE_HOME=cache
[linux] env XDG_CONFIG_HOME=config
[windows] env LocalAppData=cache
[windows] env AppData=config

env HVM_NUMTAGSTODISPLAY=42
env HVM_GITHUBTOKEN=my-token

# Test
exec hvm config
stdout '# GitHub personal access token\n'
stdout 'githubToken = ''my-token''\n'
stdout '# Number of tags to display with the "use" and "install" commands\n'
stdout 'numTagsToDisplay = 42\n'
stdout 'Configuration file: '
8 changes: 6 additions & 2 deletions cmd/testscripts/hvm_config_with_file.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,18 @@

# Test
exec hvm config
stdout '# The number of tags to display with the "use" and "install" commands.\n'
stdout 'numtagstodisplay = 42\n'
stdout '# GitHub personal access token\n'
stdout 'githubToken = ''my-token''\n'
stdout '# Number of tags to display with the "use" and "install" commands\n'
stdout 'numTagsToDisplay = 42\n'
stdout 'Configuration file: '

# Files for darwin
-- home/Library/Application Support/hvm/config.toml --
githubtoken = "my-token"
numtagstodisplay = 42

# Files for linux and windows
-- config/hvm/config.toml --
githubtoken = "my-token"
numtagstodisplay = 42
1 change: 0 additions & 1 deletion cmd/testscripts/hvm_reset.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
[darwin] skip
[windows] skip


# Test
stdin input.txt
exec hvm reset
Expand Down
17 changes: 16 additions & 1 deletion cmd/use.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/jmooring/hvm/helpers"
"github.com/spf13/cobra"
"golang.org/x/mod/semver"
"golang.org/x/oauth2"
)

// useCmd represents the use command
Expand Down Expand Up @@ -141,10 +142,24 @@ func use() error {

// newRepository creates a new repository object, returning a pointer to same.
func newRepository(owner string, name string) *repository {
var client *github.Client

if Config.GithubToken == "" {
client = github.NewClient(nil)
} else {
ctx := context.Background()
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: Config.GithubToken},
)
tc := oauth2.NewClient(ctx, ts)

client = github.NewClient(tc)
}

r := repository{
owner: owner,
name: name,
client: github.NewClient(nil),
client: client,
}

return &r
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ require (
github.com/spf13/cobra v1.7.0
github.com/spf13/viper v1.16.0
golang.org/x/mod v0.12.0
golang.org/x/oauth2 v0.7.0
)

require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand All @@ -23,9 +25,12 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
golang.org/x/tools v0.6.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.30.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
13 changes: 13 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
Expand All @@ -99,6 +102,7 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
Expand Down Expand Up @@ -266,6 +270,8 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand All @@ -275,6 +281,8 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -415,6 +423,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
Expand Down Expand Up @@ -478,6 +487,10 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down

0 comments on commit 1d09e03

Please sign in to comment.