ref: version refactored into action pattern

This adds an action implementation of 'helm version'. I'm testing out @adamreese's suggested function argument method of flexibly encapsulating logic in 'action' via function arguments.

Signed-off-by: Matt Butcher <matt.butcher@microsoft.com>
pull/5116/head
Matt Butcher 7 years ago
parent d880e200f9
commit 9b589f6e8d
No known key found for this signature in database
GPG Key ID: DCD5F5E5EF32C345

@ -19,12 +19,11 @@ package main
import ( import (
"fmt" "fmt"
"io" "io"
"text/template"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/helm/cmd/helm/require" "k8s.io/helm/cmd/helm/require"
"k8s.io/helm/pkg/version" "k8s.io/helm/pkg/action"
) )
const versionDesc = ` const versionDesc = `
@ -66,21 +65,19 @@ func newVersionCmd(out io.Writer) *cobra.Command {
} }
func (o *versionOptions) run(out io.Writer) error { func (o *versionOptions) run(out io.Writer) error {
ver := &action.Version{}
if o.short {
ver.Formatter = action.ShortVersion()
}
if o.template != "" { if o.template != "" {
tt, err := template.New("_").Parse(o.template) ver.Formatter = action.TemplateVersion(o.template)
if err != nil {
return err
}
return tt.Execute(out, version.GetBuildInfo())
} }
fmt.Fprintln(out, formatVersion(o.short))
return nil
}
func formatVersion(short bool) string { result, err := ver.Run()
v := version.GetBuildInfo() if err != nil {
if short { return err
return fmt.Sprintf("%s+g%s", v.Version, v.GitCommit[:7])
} }
return fmt.Sprintf("%#v", v) fmt.Fprintln(out, result)
return nil
} }

@ -0,0 +1,73 @@
/*
Copyright The Helm Authors.
Licensed 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 action
import (
"bytes"
"fmt"
"text/template"
"k8s.io/helm/pkg/version"
)
// Version represents a Helm version action.
type Version struct {
Formatter VersionFormatter
}
// VersionFormatter takes a version.BuildInfo and returns a printable string.
type VersionFormatter func(info version.BuildInfo) (string, error)
// Run retrieves the Helm version.
func (v *Version) Run() (string, error) {
bi := version.GetBuildInfo()
if v.Formatter == nil {
v.Formatter = DefaultVersion()
}
return v.Formatter(bi)
}
// ShortVersion returns a VersionFormatter capable of generating a SemVer representation of the Helm version
func ShortVersion() VersionFormatter {
return func(v version.BuildInfo) (string, error) {
commit := v.GitCommit
if len(commit) >= 7 {
commit = commit[:7]
}
return fmt.Sprintf("%s+g%s", v.Version, commit), nil
}
}
// TemplateVersion returns a VersionFormatter that uses a template to render the version
func TemplateVersion(tpl string) VersionFormatter {
return func(v version.BuildInfo) (string, error) {
renderer, err := template.New("_").Parse(tpl)
if err != nil {
return "", err
}
var buf bytes.Buffer
err = renderer.Execute(&buf, v)
return buf.String(), err
}
}
// DefaultVersion returns a version formatted like kubectl formats its version.
func DefaultVersion() VersionFormatter {
return func(v version.BuildInfo) (string, error) {
return fmt.Sprintf("%#v", v), nil
}
}

@ -0,0 +1,98 @@
/*
Copyright The Helm Authors.
Licensed 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 action
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
"k8s.io/helm/pkg/version"
)
func TestVersionFormatter(t *testing.T) {
var _ VersionFormatter = DefaultVersion()
var _ VersionFormatter = ShortVersion()
var _ VersionFormatter = TemplateVersion("")
}
func TestDefaultVersion(t *testing.T) {
golden := version.GetBuildInfo()
is := assert.New(t)
expect := fmt.Sprintf("%#v", golden)
result, err := DefaultVersion()(golden)
is.NoError(err)
is.Equal(expect, result)
}
func TestShortVersion(t *testing.T) {
v := version.GetBuildInfo()
v.GitCommit = "aaaaaaaaaaaaaaaa"
expect := fmt.Sprintf("%s+g%s", v.Version, v.GitCommit[:7])
is := assert.New(t)
got, err := ShortVersion()(v)
is.NoError(err)
is.Equal(expect, got)
// Make sure it handles the case where it can't get commit info
v.GitCommit = "test"
expect = fmt.Sprintf("%s+g%s", v.Version, v.GitCommit)
got, err = ShortVersion()(v)
is.NoError(err)
is.Equal(expect, got)
}
func TestTemplateVersion(t *testing.T) {
v := version.GetBuildInfo()
is := assert.New(t)
expect := fmt.Sprintf("foo-%s", v.GitCommit)
got, err := TemplateVersion("foo-{{.GitCommit}}")(v)
is.NoError(err)
is.Equal(expect, got)
// Test a broken template, too
_, err = TemplateVersion("foo-{{.GitCommit")(v)
is.Error(err)
}
func TestVersion(t *testing.T) {
// This test ensures that the default formatter works when none is specified
golden := version.GetBuildInfo()
is := assert.New(t)
expect := fmt.Sprintf("%#v", golden)
ver := new(Version)
got, err := ver.Run()
is.NoError(err)
is.Equal(expect, got)
}
func TestVersion_TemplateVersion(t *testing.T) {
// The purpose of this test is to ensure that we can override the formatter
v := version.GetBuildInfo()
is := assert.New(t)
expect := fmt.Sprintf("foo-%s", v.GitCommit)
ver := &Version{
Formatter: TemplateVersion("foo-{{.GitCommit}}"),
}
got, err := ver.Run()
is.NoError(err)
is.Equal(expect, got)
}
Loading…
Cancel
Save