diff --git a/cmd/root.go b/cmd/root.go index c166041f..aa870efb 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -18,6 +18,7 @@ import ( "github.com/gojektech/proctor/io" "github.com/spf13/cobra" + "github.com/gojektech/proctor/cmd/version/github" ) var ( @@ -28,8 +29,8 @@ var ( } ) -func Execute(printer io.Printer, proctorDClient daemon.Client) { - versionCmd := version.NewCmd(printer) +func Execute(printer io.Printer, proctorDClient daemon.Client, githubClient github.LatestReleaseFetcher) { + versionCmd := version.NewCmd(printer, githubClient) rootCmd.AddCommand(versionCmd) descriptionCmd := description.NewCmd(printer, proctorDClient) diff --git a/cmd/root_test.go b/cmd/root_test.go index b8ad5807..a0718286 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -7,10 +7,11 @@ import ( "github.com/gojektech/proctor/io" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" + "github.com/gojektech/proctor/cmd/version/github" ) func TestRootCmdUsage(t *testing.T) { - Execute(&io.MockPrinter{}, &daemon.MockClient{}) + Execute(&io.MockPrinter{}, &daemon.MockClient{}, &github.MockClient{}) assert.Equal(t, "proctor", rootCmd.Use) assert.Equal(t, "A command-line interface to run procs", rootCmd.Short) @@ -27,7 +28,7 @@ func contains(commands []*cobra.Command, commandName string) bool { } func TestRootCmdSubCommands(t *testing.T) { - Execute(&io.MockPrinter{}, &daemon.MockClient{}) + Execute(&io.MockPrinter{}, &daemon.MockClient{}, &github.MockClient{}) assert.True(t, contains(rootCmd.Commands(), "describe")) assert.True(t, contains(rootCmd.Commands(), "execute")) diff --git a/cmd/version/github/client.go b/cmd/version/github/client.go new file mode 100644 index 00000000..20ee8d51 --- /dev/null +++ b/cmd/version/github/client.go @@ -0,0 +1,23 @@ +package github + +import ( + "context" + "github.com/google/go-github/github" +) + +type LatestReleaseFetcher interface { + LatestRelease(owner, repository string) (string, error) +} + +type client struct { + client *github.Client +} + +func NewClient() *client { + return &client{github.NewClient(nil)} +} + +func (gc *client) LatestRelease(owner, repository string) (string, error) { + release, _, err := gc.client.Repositories.GetLatestRelease(context.Background(), owner, repository) + return *release.TagName, err +} diff --git a/cmd/version/github/client_mock.go b/cmd/version/github/client_mock.go new file mode 100644 index 00000000..45b641c1 --- /dev/null +++ b/cmd/version/github/client_mock.go @@ -0,0 +1,14 @@ +package github + +import ( + "github.com/stretchr/testify/mock" +) + +type MockClient struct { + mock.Mock +} + +func (m *MockClient) LatestRelease(owner, repository string) (release string, err error) { + args := m.Called(owner, repository) + return args.Get(0).(string), args.Error(1) +} diff --git a/cmd/version/version.go b/cmd/version/version.go index fd6474cb..4b48d73d 100644 --- a/cmd/version/version.go +++ b/cmd/version/version.go @@ -4,19 +4,24 @@ import ( "fmt" "github.com/fatih/color" + "github.com/gojektech/proctor/cmd/version/github" "github.com/gojektech/proctor/io" "github.com/spf13/cobra" ) const ClientVersion = "v0.6.0" -func NewCmd(printer io.Printer) *cobra.Command { +func NewCmd(printer io.Printer, fetcher github.LatestReleaseFetcher) *cobra.Command { return &cobra.Command{ Use: "version", Short: "Print version of Proctor command-line tool", Long: `Example: proctor version`, Run: func(cmd *cobra.Command, args []string) { printer.Println(fmt.Sprintf("Proctor: A Developer Friendly Automation Orchestrator %s", ClientVersion), color.Reset) + release, e := fetcher.LatestRelease("gojektech", "proctor") + if e == nil && release != ClientVersion { + printer.Println(fmt.Sprintf("Your version of Proctor client is out of date! The latest version is %s You can update by either running brew upgrade proctor or downloading a release for your OS here: https://github.com/gojektech/proctor/releases", release), color.Reset) + } }, } } diff --git a/cmd/version/version_test.go b/cmd/version/version_test.go index 41d5543b..3eb16bb7 100644 --- a/cmd/version/version_test.go +++ b/cmd/version/version_test.go @@ -5,25 +5,48 @@ import ( "testing" "github.com/fatih/color" + gh "github.com/gojektech/proctor/cmd/version/github" "github.com/gojektech/proctor/io" "github.com/spf13/cobra" "github.com/stretchr/testify/assert" ) func TestVersionCmdUsage(t *testing.T) { - versionCmd := NewCmd(&io.MockPrinter{}) + githubClient := &gh.MockClient{} + versionCmd := NewCmd(&io.MockPrinter{}, githubClient) assert.Equal(t, "version", versionCmd.Use) assert.Equal(t, "Print version of Proctor command-line tool", versionCmd.Short) assert.Equal(t, "Example: proctor version", versionCmd.Long) } -func TestVersionCmd(t *testing.T) { +func TestLatestVersionCmd(t *testing.T) { mockPrinter := &io.MockPrinter{} - versionCmd := NewCmd(mockPrinter) + githubClient := &gh.MockClient{} + versionCmd := NewCmd(mockPrinter, githubClient) + version := "v0.6.0" mockPrinter.On("Println", fmt.Sprintf("Proctor: A Developer Friendly Automation Orchestrator %s", ClientVersion), color.Reset).Once() + githubClient.On("LatestRelease", "gojektech", "proctor").Return(version, nil) versionCmd.Run(&cobra.Command{}, []string{}) mockPrinter.AssertExpectations(t) } + +func TestOldVersionCmd(t *testing.T) { + mockPrinter := &io.MockPrinter{} + githubClient := &gh.MockClient{} + version := "v1000.0.0" + versionCmd := NewCmd(mockPrinter, githubClient) + + mockPrinter.On("Println", fmt.Sprintf("Proctor: A Developer Friendly Automation Orchestrator %s", ClientVersion), color.Reset).Once() + mockPrinter.On("Println", fmt.Sprintf("Your version of Proctor client is out of date!"+ + " The latest version is %s You can update by either running brew upgrade proctor or downloading a release for your OS here:"+ + " https://github.com/gojektech/proctor/releases", version), color.Reset).Once() + githubClient.On("LatestRelease", "gojektech", "proctor").Return(version, nil) + + versionCmd.Run(&cobra.Command{}, []string{}) + + mockPrinter.AssertExpectations(t) + githubClient.AssertExpectations(t) +} diff --git a/glide.lock b/glide.lock index 6305865f..7dd48393 100644 --- a/glide.lock +++ b/glide.lock @@ -1,13 +1,17 @@ -hash: 99d5240e2827968d8fea8861618d19371699d856ce4634572dfab614345e80c7 -updated: 2018-11-21T15:16:40.295388+05:30 +hash: 19b9d4912ddf0523c6e59bb0df99744c09ffc76e9864340ad2c8764b11715583 +updated: 2019-02-18T11:00:01.471006+05:30 imports: - name: cloud.google.com/go version: 3b1ae45394a234c385be014e9a488f2bb6eef821 subpackages: - compute/metadata - internal +- name: github.com/badoux/checkmail + version: 9661bd69e9ad6fce1f7579022bdab0440807722a - name: github.com/briandowns/spinner version: 48dbb65d7bd5c74ab50d53d04c949f20e3d14944 +- name: github.com/certifi/gocertifi + version: 3fd9e1adb12b72d2f3f82191d49be9b93c69f67c - name: github.com/davecgh/go-spew version: 782f4967f2dc4564575ca782fe2d04090b5faca8 subpackages: @@ -21,6 +25,8 @@ imports: subpackages: - internal - redis +- name: github.com/getsentry/raven-go + version: 3f7439d3e74d88e21d196ba20eb61a5a958bc118 - name: github.com/ghodss/yaml version: 73d445a93680fa1a78ae23a5839bad48f32ba1ee - name: github.com/gogo/protobuf @@ -40,6 +46,14 @@ imports: - ptypes/timestamp - name: github.com/google/btree version: 7d79101e329e5a3adf994758c578dab82b90c017 +- name: github.com/google/go-github + version: 1c3f0aaee1ce742b655f1ba8f33740103e904c5c + subpackages: + - github +- name: github.com/google/go-querystring + version: 44c6ddd0a2342c386950e880b658017258da92fc + subpackages: + - query - name: github.com/google/gofuzz version: 44d81051d367757e1c7c6a5a86423ece9afcf63c - name: github.com/googleapis/gnostic @@ -123,9 +137,11 @@ imports: version: 792786c7400a136282c1664665ae0a8db921c6c2 subpackages: - difflib +- name: github.com/robfig/cron + version: b41be1df696709bb6395fe435af20370037c0b4c - name: github.com/satori/go.uuid version: f58768cc1a7a7e77a3bd49e98cdd21419399b6a3 -- name: github.com/Sirupsen/logrus +- name: github.com/sirupsen/logrus version: 44067abb194b1bc8b342e1f2120f8d3ea691b834 - name: github.com/spf13/afero version: d40851caa0d747393da1ffb28f7f9d8b4eeffebd diff --git a/glide.yaml b/glide.yaml index b93d0b40..d8a3ea13 100644 --- a/glide.yaml +++ b/glide.yaml @@ -16,3 +16,5 @@ import: version: v0.0.1 - package: github.com/thingful/httpmock version: 0.0.2 +- package: github.com/google/go-github + version: v24.0.0 diff --git a/main.go b/main.go index 2c377f31..1b34e926 100644 --- a/main.go +++ b/main.go @@ -5,12 +5,14 @@ import ( "github.com/gojektech/proctor/config" "github.com/gojektech/proctor/daemon" "github.com/gojektech/proctor/io" + "github.com/gojektech/proctor/cmd/version/github" ) func main() { printer := io.GetPrinter() proctorConfigLoader := config.NewLoader() proctorDClient := daemon.NewClient(printer, proctorConfigLoader) + githubClient := github.NewClient() - cmd.Execute(printer, proctorDClient) + cmd.Execute(printer, proctorDClient, githubClient) }