Skip to content

Commit

Permalink
Get the latest release version from GitHub Release
Browse files Browse the repository at this point in the history
  • Loading branch information
minamijoyo committed Oct 16, 2019
1 parent f30ba8a commit 2a04fa2
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 0 deletions.
65 changes: 65 additions & 0 deletions command/release.go
@@ -0,0 +1,65 @@
package command

import (
"fmt"
"strings"

"github.com/minamijoyo/tfupdate/release"
flag "github.com/spf13/pflag"
)

// ReleaseCommand is a command which gets the latest release version.
type ReleaseCommand struct {
Meta
url string
}

// Run runs the procedure of this command.
func (c *ReleaseCommand) Run(args []string) int {
cmdFlags := flag.NewFlagSet("release", flag.ContinueOnError)

if err := cmdFlags.Parse(args); err != nil {
c.UI.Error(fmt.Sprintf("failed to parse arguments: %s", err))
return 1
}

if len(cmdFlags.Args()) != 1 {
c.UI.Error(fmt.Sprintf("The command expects 1 argument, but got %#v", cmdFlags.Args()))
c.UI.Error(c.Help())
return 1
}

c.url = cmdFlags.Arg(0)

r, err := release.NewRelease("github", c.url)
if err != nil {
c.UI.Error(err.Error())
return 1
}

v, err := release.ResolveVersionAlias(r, "latest")
if err != nil {
c.UI.Error(err.Error())
return 1
}

c.UI.Output(v)
return 0
}

// Help returns long-form help text.
func (c *ReleaseCommand) Help() string {
helpText := `
Usage: tfupdate release [options] <URL>
Arguments
URL A URL of the release repository
(e.g. https://github.com/terraform-providers/terraform-provider-aws)
`
return strings.TrimSpace(helpText)
}

// Synopsis returns one-line help text.
func (c *ReleaseCommand) Synopsis() string {
return "Get the latest release version"
}
1 change: 1 addition & 0 deletions go.mod
Expand Up @@ -3,6 +3,7 @@ module github.com/minamijoyo/tfupdate
go 1.12

require (
github.com/google/go-github/v28 v28.1.1
github.com/hashicorp/hcl/v2 v2.0.0
github.com/hashicorp/logutils v1.0.0
github.com/mitchellh/cli v1.0.0
Expand Down
9 changes: 9 additions & 0 deletions go.sum
Expand Up @@ -14,8 +14,13 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-github/v28 v28.1.1 h1:kORf5ekX5qwXO2mGzXXOjMe/g6ap8ahVe0sBEulhSxo=
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
Expand Down Expand Up @@ -59,10 +64,14 @@ github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6Ac
github.com/zclconf/go-cty v1.1.0 h1:uJwc9HiBOCpoKIObTQaLR+tsEXx1HBHnOsOOpcdhZgw=
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734 h1:p/H982KKEjUnLJkM3tt/LemDnOc1GiZL5FCVlORJ5zo=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
5 changes: 5 additions & 0 deletions main.go
Expand Up @@ -88,6 +88,11 @@ func initCommands() map[string]cli.CommandFactory {
Meta: meta,
}, nil
},
"release": func() (cli.Command, error) {
return &command.ReleaseCommand{
Meta: meta,
}, nil
},
}

return commands
Expand Down
52 changes: 52 additions & 0 deletions release/github.go
@@ -0,0 +1,52 @@
package release

import (
"context"
"fmt"
"regexp"

"github.com/google/go-github/v28/github"
"github.com/pkg/errors"
)

// GitHubRelease is a release implementation which provides version information with GitHub Release.
type GitHubRelease struct {
client *github.Client
owner string
repo string
}

// NewGitHubRelease is a factory method which returns an GitHubRelease instance.
func NewGitHubRelease(url string) (Release, error) {
re := regexp.MustCompile(`https://github.com/(.+)/(.+)`)
matched := re.FindStringSubmatch(url)
if len(matched) != 3 {
return nil, errors.Errorf("failed to parse url: %s, matched: %#v", url, matched)
}
owner := matched[1]
repo := matched[2]

return &GitHubRelease{
client: github.NewClient(nil),
owner: owner,
repo: repo,
}, nil
}

// Latest returns a latest version.
func (r *GitHubRelease) Latest() (string, error) {
release, _, err := r.client.Repositories.GetLatestRelease(context.Background(), r.owner, r.repo)

if err != nil {
return "", fmt.Errorf("failed to get the latest release from github.com/%s/%s: %s", r.owner, r.repo, err)
}

name := *release.Name

// if a name starts with `v`, remove it.
if name[0] == 'v' {
return name[1:], nil
}

return name, nil
}
32 changes: 32 additions & 0 deletions release/release.go
@@ -0,0 +1,32 @@
package release

import (
"github.com/pkg/errors"
)

// Release is an interface which provides version information.
type Release interface {
// Latest returns a latest version.
Latest() (string, error)
}

// NewRelease is a factory method which returns a Release implementation.
func NewRelease(releaseType string, url string) (Release, error) {
switch releaseType {
case "github":
return NewGitHubRelease(url)
default:
return nil, errors.Errorf("failed to new release. unknown type: %s", releaseType)
}
}

// ResolveVersionAlias resolves a version alias.
func ResolveVersionAlias(r Release, alias string) (string, error) {
switch alias {
case "latest":
return r.Latest()
default:
// if an alias does not match keywords, just return alias as a version.
return alias, nil
}
}

0 comments on commit 2a04fa2

Please sign in to comment.