Brush all the lint off this code I wrote in a haze

This commit is contained in:
Erin Call 2019-12-09 10:52:41 -08:00
parent e3051ec72e
commit 8d66036252
No known key found for this signature in database
GPG key ID: 4071FF6C15B8DAD1
11 changed files with 47 additions and 21 deletions

View file

@ -5,6 +5,7 @@ TODO:
* [x] Make a `.drone.yml` that's sufficient for building an image * [x] Make a `.drone.yml` that's sufficient for building an image
* [x] Make a `Dockerfile` that's sufficient for launching the built image * [x] Make a `Dockerfile` that's sufficient for launching the built image
* [x] Make `cmd/drone-helm/main.go` actually invoke `helm` * [x] Make `cmd/drone-helm/main.go` actually invoke `helm`
* [x] Make `golint` part of the build process (and make it pass)
* [ ] Flesh out `helm upgrade` until it's capable of working * [ ] Flesh out `helm upgrade` until it's capable of working
* [ ] Implement `helm lint` * [ ] Implement `helm lint`
* [ ] Implement `helm delete` * [ ] Implement `helm delete`

2
go.mod
View file

@ -6,4 +6,6 @@ require (
github.com/golang/mock v1.3.1 github.com/golang/mock v1.3.1
github.com/kelseyhightower/envconfig v1.4.0 github.com/kelseyhightower/envconfig v1.4.0
github.com/stretchr/testify v1.4.0 github.com/stretchr/testify v1.4.0
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f // indirect
golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd // indirect
) )

8
go.sum
View file

@ -10,12 +10,20 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262 h1:qsl9y/CJx34tuA7QCPNp86JNJe4spst6Ff8MjvPUdPg= golang.org/x/tools v0.0.0-20190425150028-36563e24a262 h1:qsl9y/CJx34tuA7QCPNp86JNJe4spst6Ff8MjvPUdPg=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f h1:kDxGY2VmgABOe55qheT/TFqUMtcTHnomIPS1iv3G4Ms=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd h1:Zc7EU2PqpsNeIfOoVA7hvQX4cS3YDJEs5KlfatT3hLo=
golang.org/x/tools v0.0.0-20191206204035-259af5ff87bd/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=

View file

@ -5,9 +5,14 @@ import (
"strings" "strings"
) )
// The Config struct captures the `settings` and `environment` blocks inthe application's drone
// config. Configuration in drone's `settings` block arrives as uppercase env vars matching the
// config key, prefixed with `PLUGIN_`. Config from the `environment` block is *not* prefixed; any
// keys that are likely to be in that block (i.e. things that use `from_secret` need an explicit
// `envconfig:` tag so that envconfig will look for a non-prefixed env var.
type Config struct { type Config struct {
// Configuration for drone-helm itself // Configuration for drone-helm itself
Command HelmCommand `envconfig:"HELM_COMMAND"` // Helm command to run Command helmCommand `envconfig:"HELM_COMMAND"` // Helm command to run
DroneEvent string `envconfig:"DRONE_BUILD_EVENT"` // Drone event that invoked this plugin. DroneEvent string `envconfig:"DRONE_BUILD_EVENT"` // Drone event that invoked this plugin.
UpdateDependencies bool `split_words:"true"` // call `helm dependency update` before the main command UpdateDependencies bool `split_words:"true"` // call `helm dependency update` before the main command
Repos []string `envconfig:"HELM_REPOS"` // call `helm repo add` before the main command Repos []string `envconfig:"HELM_REPOS"` // call `helm repo add` before the main command
@ -37,14 +42,14 @@ type Config struct {
Force bool `` // Force bool `` //
} }
type HelmCommand string type helmCommand string
// HelmCommand.Decode checks the given value against the list of known commands and generates a helpful error if the command is unknown. // helmCommand.Decode checks the given value against the list of known commands and generates a helpful error if the command is unknown.
func (cmd *HelmCommand) Decode(value string) error { func (cmd *helmCommand) Decode(value string) error {
known := []string{"upgrade", "delete", "lint", "help"} known := []string{"upgrade", "delete", "lint", "help"}
for _, c := range known { for _, c := range known {
if value == c { if value == c {
*cmd = HelmCommand(value) *cmd = helmCommand(value)
return nil return nil
} }
} }
@ -53,6 +58,6 @@ func (cmd *HelmCommand) Decode(value string) error {
return nil return nil
} }
known[len(known)-1] = fmt.Sprintf("or %s", known[len(known)-1]) known[len(known)-1] = fmt.Sprintf("or %s", known[len(known)-1])
return fmt.Errorf("Unknown command '%s'. If specified, command must be %s.", return fmt.Errorf("unknown command '%s'. If specified, command must be %s",
value, strings.Join(known, ", ")) value, strings.Join(known, ", "))
} }

View file

@ -14,7 +14,7 @@ func TestConfigTestSuite(t *testing.T) {
} }
func (suite *ConfigTestSuite) TestHelmCommandDecodeSuccess() { func (suite *ConfigTestSuite) TestHelmCommandDecodeSuccess() {
cmd := HelmCommand("") cmd := helmCommand("")
err := cmd.Decode("upgrade") err := cmd.Decode("upgrade")
suite.Require().Nil(err) suite.Require().Nil(err)
@ -22,7 +22,7 @@ func (suite *ConfigTestSuite) TestHelmCommandDecodeSuccess() {
} }
func (suite *ConfigTestSuite) TestHelmCommandDecodeFailure() { func (suite *ConfigTestSuite) TestHelmCommandDecodeFailure() {
cmd := HelmCommand("") cmd := helmCommand("")
err := cmd.Decode("execute order 66") err := cmd.Decode("execute order 66")
suite.EqualError(err, "Unknown command 'execute order 66'. If specified, command must be upgrade, delete, lint, or help.") suite.EqualError(err, "unknown command 'execute order 66'. If specified, command must be upgrade, delete, lint, or help")
} }

View file

@ -5,14 +5,17 @@ import (
"github.com/pelotech/drone-helm3/internal/run" "github.com/pelotech/drone-helm3/internal/run"
) )
// A Step is one step in the plan.
type Step interface { type Step interface {
Run() error Run() error
} }
// A Plan is a series of steps to perform.
type Plan struct { type Plan struct {
steps []Step steps []Step
} }
// NewPlan makes a plan for running a helm operation.
func NewPlan(cfg Config) (*Plan, error) { func NewPlan(cfg Config) (*Plan, error) {
p := Plan{} p := Plan{}
switch cfg.Command { switch cfg.Command {
@ -44,6 +47,7 @@ func NewPlan(cfg Config) (*Plan, error) {
return &p, nil return &p, nil
} }
// Execute runs each step in the plan, aborting and reporting on error
func (p *Plan) Execute() error { func (p *Plan) Execute() error {
for _, step := range p.steps { for _, step := range p.steps {
if err := step.Run(); err != nil { if err := step.Run(); err != nil {

View file

@ -7,7 +7,7 @@ import (
"syscall" "syscall"
) )
const HELM_BIN = "/usr/bin/helm" const helmBin = "/usr/bin/helm"
// The cmd interface provides a generic form of exec.Cmd so that it can be mocked out in tests. // The cmd interface provides a generic form of exec.Cmd so that it can be mocked out in tests.
type cmd interface { type cmd interface {
@ -43,7 +43,7 @@ type execCmd struct {
*exec.Cmd *exec.Cmd
} }
var Command = func(path string, args ...string) cmd { var command = func(path string, args ...string) cmd {
return &execCmd{ return &execCmd{
Cmd: exec.Command(path, args...), Cmd: exec.Command(path, args...),
} }

View file

@ -4,18 +4,21 @@ import (
"os" "os"
) )
// Help is a step in a helm Plan that calls `helm help`.
type Help struct { type Help struct {
cmd cmd cmd cmd
} }
// Run launches the command.
func (h *Help) Run() error { func (h *Help) Run() error {
return h.cmd.Run() return h.cmd.Run()
} }
// NewHelp returns a new Help.
func NewHelp() *Help { func NewHelp() *Help {
h := Help{} h := Help{}
h.cmd = Command(HELM_BIN, "help") h.cmd = command(helmBin, "help")
h.cmd.Stdout(os.Stdout) h.cmd.Stdout(os.Stdout)
h.cmd.Stderr(os.Stderr) h.cmd.Stderr(os.Stderr)

View file

@ -11,14 +11,14 @@ func TestHelp(t *testing.T) {
defer ctrl.Finish() defer ctrl.Finish()
mCmd := NewMockcmd(ctrl) mCmd := NewMockcmd(ctrl)
originalCommand := Command originalCommand := command
Command = func(path string, args ...string) cmd { command = func(path string, args ...string) cmd {
assert.Equal(t, HELM_BIN, path) assert.Equal(t, helmBin, path)
assert.Equal(t, []string{"help"}, args) assert.Equal(t, []string{"help"}, args)
return mCmd return mCmd
} }
defer func() { Command = originalCommand }() defer func() { command = originalCommand }()
mCmd.EXPECT(). mCmd.EXPECT().
Stdout(gomock.Any()) Stdout(gomock.Any())

View file

@ -4,21 +4,24 @@ import (
"os" "os"
) )
// Upgrade is a step in a helm Plan that calls `helm upgrade`.
type Upgrade struct { type Upgrade struct {
Chart string Chart string
Release string Release string
cmd cmd cmd cmd
} }
// Run launches the command.
func (u *Upgrade) Run() error { func (u *Upgrade) Run() error {
return u.cmd.Run() return u.cmd.Run()
} }
// NewUpgrade creates a new Upgrade.
func NewUpgrade(release, chart string) *Upgrade { func NewUpgrade(release, chart string) *Upgrade {
u := Upgrade{ u := Upgrade{
Chart: chart, Chart: chart,
Release: release, Release: release,
cmd: Command(HELM_BIN, "upgrade", "--install", release, chart), cmd: command(helmBin, "upgrade", "--install", release, chart),
} }
u.cmd.Stdout(os.Stdout) u.cmd.Stdout(os.Stdout)

View file

@ -11,15 +11,15 @@ func TestNewUpgrade(t *testing.T) {
defer ctrl.Finish() defer ctrl.Finish()
mCmd := NewMockcmd(ctrl) mCmd := NewMockcmd(ctrl)
originalCommand := Command originalCommand := command
Command = func(path string, args ...string) cmd { command = func(path string, args ...string) cmd {
assert.Equal(t, HELM_BIN, path) assert.Equal(t, helmBin, path)
assert.Equal(t, []string{"upgrade", "--install", "jonas_brothers_only_human", "at40"}, args) assert.Equal(t, []string{"upgrade", "--install", "jonas_brothers_only_human", "at40"}, args)
return mCmd return mCmd
} }
defer func() { Command = originalCommand }() defer func() { command = originalCommand }()
mCmd.EXPECT(). mCmd.EXPECT().
Stdout(gomock.Any()) Stdout(gomock.Any())