Skip to content

Commit

Permalink
version: Extend output to include ECE API Version (#53)
Browse files Browse the repository at this point in the history
Extends the `ecctl version` output to include a structured output and a
series of information which was missing:

```console
$ ./bin/ecctl version
Version:               1.0.0-rc1-dev
Client API Version:    2.4.2
Go version:            go1.13.4
Git commit:            8d72808
Built:                 Fri 15 Nov 09:24:14 2019
OS/Arch:               darwin / amd64
```

Signed-off-by: Marc Lopez <[email protected]>
  • Loading branch information
marclop authored Nov 18, 2019
1 parent 8d72808 commit 7d63ff8
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 36 deletions.
2 changes: 1 addition & 1 deletion build/Makefile.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ CURRENT_ARCH := $(shell uname -s | tr '[:upper:]' '[:lower:]')
export OWNER := elastic
export REPO := ecctl

DEFAULT_LDFLAGS ?= -X main.version=$(VERSION)-dev -X main.commit=$(shell git rev-parse HEAD) -X main.owner=$(OWNER) -X main.repo=$(REPO)
DEFAULT_LDFLAGS ?= -X main.version=$(VERSION)-dev -X main.commit=$(shell git rev-parse HEAD) -X main.owner=$(OWNER) -X main.repo=$(REPO) -X main.built=$(shell date -u +%a_%d_%b_%H:%M:%S_%Y)

REPORT_PATH ?= reports
TEST_UNIT_FLAGS ?= -timeout 10s -p 4 -race -cover -coverprofile=$(REPORT_PATH)/c.out
Expand Down
8 changes: 4 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ var (
)

var (
version, commit, owner, repo string
excludedApplicationCommands = []string{
versionInfo ecctl.VersionInfo
excludedApplicationCommands = []string{
"help", "version", "generate", "docs", "completions", "init",
}
messageErrHasNoPreRunCheck = "command %s/%s has no PreRunE check set"
Expand All @@ -81,11 +81,11 @@ var RootCmd = &cobra.Command{
// Execute adds all child commands to the root command sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
// It returns the statuscode to be used by os.Exit.
func Execute(v, c, o, r string) int {
func Execute(v ecctl.VersionInfo) int {
defer stopDebug(defaultViper)

populateValidArgs(RootCmd)
version, commit, owner, repo = v, c, o, r
versionInfo = v

if err := RootCmd.Execute(); err != nil {
fmt.Fprintln(RootCmd.OutOrStderr(), err)
Expand Down
62 changes: 35 additions & 27 deletions cmd/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ package cmd

import (
"fmt"
"io"
"os"
"runtime"

"github.com/elastic/uptd"
"github.com/pkg/errors"
"github.com/spf13/cobra"

"github.com/elastic/ecctl/pkg/ecctl"
)

const (
Expand All @@ -44,34 +47,9 @@ var versionCmd = &cobra.Command{
Short: "Shows ecctl version",
PreRunE: cobra.MaximumNArgs(0),
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Printf("%s %s (build %s)\n", RootCmd.Use, version, commit)

githubUpdateProvider, err := uptd.NewGithubProvider(owner, repo, githubToken())
if err != nil {
fmt.Fprintln(cmd.OutOrStdout(), errors.Wrap(err, errWrapError.Error()))
return nil
}
fmt.Fprint(cmd.OutOrStdout(), versionInfo)

uptodate, err := uptd.New(githubUpdateProvider, version)
if err != nil {
fmt.Fprintln(cmd.OutOrStdout(), errors.Wrap(err, errWrapError.Error()))
return nil
}

res, err := uptodate.Check()
if err != nil {
fmt.Fprintln(cmd.OutOrStdout(), errors.Wrap(err, errWrapError.Error()))
return nil
}

if res.NeedsUpdate {
var message = fmt.Sprintf(updateFmt, RootCmd.Name(),
res.Latest.Version.String(), res.Latest.URL,
)
fmt.Fprintln(cmd.OutOrStdout(), message)
}

return nil
return checkUpdate(versionInfo, cmd.OutOrStderr())
},
}

Expand All @@ -88,6 +66,36 @@ func githubToken() string {
return ""
}

func checkUpdate(version ecctl.VersionInfo, device io.Writer) error {
githubUpdateProvider, err := uptd.NewGithubProvider(
version.Organization, version.Repository, githubToken(),
)
if err != nil {
fmt.Fprintln(device, errors.Wrap(err, errWrapError.Error()))
return nil
}

uptodate, err := uptd.New(githubUpdateProvider, version.Version)
if err != nil {
fmt.Fprintln(device, errors.Wrap(err, errWrapError.Error()))
return nil
}

res, err := uptodate.Check()
if err != nil {
fmt.Fprintln(device, errors.Wrap(err, errWrapError.Error()))
return nil
}

if res.NeedsUpdate {
var message = fmt.Sprintf(updateFmt, RootCmd.Name(),
res.Latest.Version.String(), res.Latest.URL,
)
fmt.Fprintln(device, message)
}
return nil
}

func init() {
RootCmd.AddCommand(versionCmd)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/chzyer/logex v1.1.10 // indirect
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
github.com/davecgh/go-spew v1.1.1
github.com/elastic/cloud-sdk-go v1.0.0-bc4
github.com/elastic/cloud-sdk-go v1.0.0-bc5
github.com/elastic/uptd v1.0.0
github.com/ghodss/yaml v1.0.0
github.com/go-openapi/runtime v0.19.8
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/elastic/cloud-sdk-go v1.0.0-bc4 h1:8Gc/gFos+dJv992c8FQ06X9Mx080p2ceuiB1dUPWeUA=
github.com/elastic/cloud-sdk-go v1.0.0-bc4/go.mod h1:19tuRaJglGTECDJfiWEDMOVj23ZL+9+YYoIV1fZIGzc=
github.com/elastic/cloud-sdk-go v1.0.0-bc5 h1:POlV6bafKwT728xJy+did8Q1QlDweE0z/lVfgRY6ic4=
github.com/elastic/cloud-sdk-go v1.0.0-bc5/go.mod h1:19tuRaJglGTECDJfiWEDMOVj23ZL+9+YYoIV1fZIGzc=
github.com/elastic/uptd v1.0.0 h1:oUhbbTK6hjFYB5w5dwjo1HtbqrWyLiqj+6Sb05oawU8=
github.com/elastic/uptd v1.0.0/go.mod h1:2Pm07gLal/a/gTPq3el2QgOjoxu97pB2I17AprXxa48=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
Expand Down
13 changes: 12 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,29 @@ package main
import (
"os"

"github.com/elastic/cloud-sdk-go/pkg/api"

"github.com/elastic/ecctl/cmd"
"github.com/elastic/ecctl/pkg/ecctl"
)

var (
version string
commit string
owner string
repo string
built string
)

func main() {
os.Exit(
cmd.Execute(version, commit, owner, repo),
cmd.Execute(ecctl.VersionInfo{
Version: version,
Commit: commit,
APIVersion: api.Version,
Built: built,
Organization: owner,
Repository: repo,
}),
)
}
60 changes: 60 additions & 0 deletions pkg/ecctl/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package ecctl

import (
"bytes"
"fmt"
"runtime"
"strings"
"text/tabwriter"
)

// VersionInfo contains detailed information about the binary.
type VersionInfo struct {
Version string
APIVersion string
Commit string
Built string

// Non Displayed fields
Repository string
Organization string
}

func (v VersionInfo) String() string {
buf := new(bytes.Buffer)

w := tabwriter.NewWriter(buf, 2, 2, 3, ' ', 0)

var commit = v.Commit
if len(commit) >= 8 {
commit = commit[:8]
}

fmt.Fprintln(w, "Version:\t", v.Version)
fmt.Fprintln(w, "Client API Version:\t", v.APIVersion)
fmt.Fprintln(w, "Go version:\t", runtime.Version())
fmt.Fprintln(w, "Git commit:\t", commit)
fmt.Fprintln(w, "Built:\t", strings.ReplaceAll(v.Built, "_", " "))
fmt.Fprintln(w, "OS/Arch:\t", runtime.GOOS, "/", runtime.GOARCH)

w.Flush()

return buf.String()
}
59 changes: 59 additions & 0 deletions pkg/ecctl/version_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package ecctl

import (
"fmt"
"runtime"
"testing"
)

const vTemplate = `Version: 1.0.0
Client API Version: 2.4.2
Go version: %s
Git commit: 12345678
Built: Fri 15 Nov 09:24:14 2019
OS/Arch: %s / %s
`

func TestVersionInfo_String(t *testing.T) {
tests := []struct {
name string
fields VersionInfo
want string
}{
{
name: "Prints the version",
fields: VersionInfo{
Version: "1.0.0",
APIVersion: "2.4.2",
Commit: "12345678910",
Built: "Fri_15_Nov_09:24:14_2019",
},
want: fmt.Sprintf(vTemplate, runtime.Version(), runtime.GOOS, runtime.GOARCH),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
v := tt.fields
if got := v.String(); got != tt.want {
t.Errorf("VersionInfo.String() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit 7d63ff8

Please sign in to comment.