Skip to content

Commit

Permalink
feat: refactor main.go to spf13/cobra (#1472)
Browse files Browse the repository at this point in the history
* feat: refactor cli

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* feat: refactor cli

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* feat: refactor cli

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* feat: refactor cli

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* feat: refactor cli

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: revert

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* feat: refactor cli

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* feat: refactor cli

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* feat: refactor cli

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: lint

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>

* fix: move

Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
  • Loading branch information
caarlos0 committed Apr 28, 2020
1 parent 20e3261 commit 9bd0033
Show file tree
Hide file tree
Showing 19 changed files with 879 additions and 450 deletions.
63 changes: 63 additions & 0 deletions cmd/check.go
@@ -0,0 +1,63 @@
package cmd

import (
"fmt"

"github.com/apex/log"
"github.com/caarlos0/ctrlc"
"github.com/fatih/color"
"github.com/goreleaser/goreleaser/internal/pipe/defaults"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/pkg/errors"
"github.com/spf13/cobra"
)

type checkCmd struct {
cmd *cobra.Command
config string
deprecated bool
}

func newCheckCmd() *checkCmd {
var root = &checkCmd{}
var cmd = &cobra.Command{
Use: "check",
Aliases: []string{"c"},
Short: "Checks if configuration is valid",
SilenceUsage: true,
SilenceErrors: true,
RunE: func(cmd *cobra.Command, args []string) error {
cfg, err := loadConfig(root.config)
if err != nil {
return err
}
var ctx = context.New(cfg)
ctx.Deprecated = root.deprecated

if err := ctrlc.Default.Run(ctx, func() error {
log.Info(color.New(color.Bold).Sprint("checking config:"))
return defaults.Pipe{}.Run(ctx)
}); err != nil {
log.WithError(err).Error(color.New(color.Bold).Sprintf("config is invalid"))
return errors.Wrap(err, "invalid config")
}

if ctx.Deprecated {
return wrapErrorWithCode(
fmt.Errorf("config is valid, but uses deprecated properties, check logs above for details"),
2,
"",
)
}
log.Infof(color.New(color.Bold).Sprintf("config is valid"))
return nil
},
}

cmd.Flags().StringVarP(&root.config, "config", "f", "", "Configuration file to check")
cmd.Flags().BoolVar(&root.deprecated, "deprecated", false, "Force print the deprecation message - tests only")
_ = cmd.Flags().MarkHidden("deprecated")

root.cmd = cmd
return root
}
37 changes: 37 additions & 0 deletions cmd/check_test.go
@@ -0,0 +1,37 @@
package cmd

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestCheckConfig(t *testing.T) {
var cmd = newCheckCmd()
cmd.cmd.SetArgs([]string{"-f", "testdata/good.yml"})
require.NoError(t, cmd.cmd.Execute())
}

func TestCheckConfigThatDoesNotExist(t *testing.T) {
var cmd = newCheckCmd()
cmd.cmd.SetArgs([]string{"-f", "testdata/nope.yml"})
require.EqualError(t, cmd.cmd.Execute(), "open testdata/nope.yml: no such file or directory")
}

func TestCheckConfigUnmarshalError(t *testing.T) {
var cmd = newCheckCmd()
cmd.cmd.SetArgs([]string{"-f", "testdata/unmarshal_error.yml"})
require.EqualError(t, cmd.cmd.Execute(), "yaml: unmarshal errors:\n line 1: field foo not found in type config.Project")
}

func TestCheckConfigInvalid(t *testing.T) {
var cmd = newCheckCmd()
cmd.cmd.SetArgs([]string{"-f", "testdata/invalid.yml"})
require.EqualError(t, cmd.cmd.Execute(), "invalid config: found 2 builds with the ID 'a', please fix your config")
}

func TestCheckConfigDeprecated(t *testing.T) {
var cmd = newCheckCmd()
cmd.cmd.SetArgs([]string{"-f", "testdata/good.yml", "--deprecated"})
require.EqualError(t, cmd.cmd.Execute(), "config is valid, but uses deprecated properties, check logs above for details")
}
30 changes: 30 additions & 0 deletions cmd/config.go
@@ -0,0 +1,30 @@
package cmd

import (
"os"

"github.com/apex/log"
"github.com/goreleaser/goreleaser/pkg/config"
)

func loadConfig(path string) (config.Project, error) {
if path != "" {
return config.Load(path)
}
for _, f := range [4]string{
".goreleaser.yml",
".goreleaser.yaml",
"goreleaser.yml",
"goreleaser.yaml",
} {
proj, err := config.Load(f)
if err != nil && os.IsNotExist(err) {
continue
}
return proj, err
}
// the user didn't specify a config file and the known possible file names
// don't exist, so, return an empty config and a nil err.
log.Warn("could not find a config file, using defaults...")
return config.Project{}, nil
}
41 changes: 41 additions & 0 deletions cmd/config_test.go
@@ -0,0 +1,41 @@
package cmd

import (
"os"
"path/filepath"
"testing"

"github.com/goreleaser/goreleaser/pkg/config"
"github.com/stretchr/testify/require"
)

func TestConfigFlagNotSetButExists(t *testing.T) {
for _, name := range []string{
".goreleaser.yml",
".goreleaser.yaml",
"goreleaser.yml",
"goreleaser.yaml",
} {
t.Run(name, func(t *testing.T) {
folder, back := setup(t)
defer back()
require.NoError(t, os.Rename(
filepath.Join(folder, "goreleaser.yml"),
filepath.Join(folder, name),
))
proj, err := loadConfig("")
require.NoError(t, err)
require.NotEqual(t, config.Project{}, proj)
})
}
}

func TestConfigFileDoesntExist(t *testing.T) {
folder, back := setup(t)
defer back()
err := os.Remove(filepath.Join(folder, "goreleaser.yml"))
require.NoError(t, err)
proj, err := loadConfig("")
require.NoError(t, err)
require.Equal(t, config.Project{}, proj)
}
23 changes: 23 additions & 0 deletions cmd/error.go
@@ -0,0 +1,23 @@
package cmd

type exitError struct {
err error
code int
details string
}

func wrapErrorWithCode(err error, code int, details string) *exitError {
return &exitError{
err: err,
code: code,
details: details,
}
}

func wrapError(err error, log string) *exitError {
return wrapErrorWithCode(err, 1, log)
}

func (e *exitError) Error() string {
return e.err.Error()
}
46 changes: 46 additions & 0 deletions cmd/init.go
@@ -0,0 +1,46 @@
package cmd

import (
"os"

"github.com/apex/log"
"github.com/fatih/color"
"github.com/goreleaser/goreleaser/internal/static"
"github.com/spf13/cobra"
)

type initCmd struct {
cmd *cobra.Command
config string
}

func newInitCmd() *initCmd {
var root = &initCmd{}
var cmd = &cobra.Command{
Use: "init",
Aliases: []string{"i"},
Short: "Generates a .goreleaser.yml file",
SilenceUsage: true,
SilenceErrors: true,
RunE: func(cmd *cobra.Command, args []string) error {
f, err := os.OpenFile(root.config, os.O_WRONLY|os.O_CREATE|os.O_TRUNC|os.O_EXCL, 0644)
if err != nil {
return err
}
defer f.Close()

log.Infof(color.New(color.Bold).Sprintf("Generating %s file", root.config))
if _, err := f.WriteString(static.ExampleConfig); err != nil {
return err
}

log.WithField("file", root.config).Info("config created; please edit accordingly to your needs")
return nil
},
}

cmd.Flags().StringVarP(&root.config, "config", "f", ".goreleaser.yml", "Load configuration from file")

root.cmd = cmd
return root
}
44 changes: 44 additions & 0 deletions cmd/init_test.go
@@ -0,0 +1,44 @@
package cmd

import (
"io/ioutil"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/require"
)

func TestInit(t *testing.T) {
var folder = mktemp(t)
var cmd = newInitCmd().cmd
var path = filepath.Join(folder, "foo.yaml")
cmd.SetArgs([]string{"-f", path})
require.NoError(t, cmd.Execute())
require.FileExists(t, path)
}

func TestInitFileExists(t *testing.T) {
var folder = mktemp(t)
var cmd = newInitCmd().cmd
var path = filepath.Join(folder, "twice.yaml")
cmd.SetArgs([]string{"-f", path})
require.NoError(t, cmd.Execute())
require.EqualError(t, cmd.Execute(), "open "+path+": file exists")
require.FileExists(t, path)
}

func TestInitFileError(t *testing.T) {
var folder = mktemp(t)
var cmd = newInitCmd().cmd
var path = filepath.Join(folder, "nope.yaml")
require.NoError(t, os.Chmod(folder, 0000))
cmd.SetArgs([]string{"-f", path})
require.EqualError(t, cmd.Execute(), "open "+path+": permission denied")
}

func mktemp(t *testing.T) string {
folder, err := ioutil.TempDir("", "")
require.NoError(t, err)
return folder
}

0 comments on commit 9bd0033

Please sign in to comment.