diff --git a/cmd/check.go b/cmd/check.go new file mode 100644 index 00000000000..a2a9cbb33d0 --- /dev/null +++ b/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 +} diff --git a/cmd/check_test.go b/cmd/check_test.go new file mode 100644 index 00000000000..ff369445647 --- /dev/null +++ b/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") +} diff --git a/cmd/config.go b/cmd/config.go new file mode 100644 index 00000000000..0d86c50fb46 --- /dev/null +++ b/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 +} diff --git a/cmd/config_test.go b/cmd/config_test.go new file mode 100644 index 00000000000..51b752eb9e4 --- /dev/null +++ b/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) +} diff --git a/cmd/error.go b/cmd/error.go new file mode 100644 index 00000000000..5ae0235945d --- /dev/null +++ b/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() +} diff --git a/cmd/init.go b/cmd/init.go new file mode 100644 index 00000000000..a0ad076892f --- /dev/null +++ b/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 +} diff --git a/cmd/init_test.go b/cmd/init_test.go new file mode 100644 index 00000000000..91fc412e779 --- /dev/null +++ b/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 +} diff --git a/cmd/release.go b/cmd/release.go new file mode 100644 index 00000000000..3043a31043f --- /dev/null +++ b/cmd/release.go @@ -0,0 +1,117 @@ +package cmd + +import ( + "time" + + "github.com/apex/log" + "github.com/caarlos0/ctrlc" + "github.com/fatih/color" + "github.com/goreleaser/goreleaser/internal/middleware" + "github.com/goreleaser/goreleaser/internal/pipeline" + "github.com/goreleaser/goreleaser/pkg/context" + "github.com/spf13/cobra" +) + +type releaseCmd struct { + cmd *cobra.Command + opts releaseOpts +} + +type releaseOpts struct { + config string + releaseNotes string + releaseHeader string + releaseFooter string + snapshot bool + skipPublish bool + skipSign bool + skipValidate bool + rmDist bool + deprecated bool + parallelism int + timeout time.Duration +} + +func newReleaseCmd() *releaseCmd { + var root = &releaseCmd{} + var cmd = &cobra.Command{ + Use: "release", + Aliases: []string{"r"}, + Short: "Releases the current project", + SilenceUsage: true, + SilenceErrors: true, + RunE: func(cmd *cobra.Command, args []string) error { + start := time.Now() + + log.Infof(color.New(color.Bold).Sprint("releasing...")) + + ctx, err := releaseProject(root.opts) + if err != nil { + return wrapError(err, color.New(color.Bold).Sprintf("release failed after %0.2fs", time.Since(start).Seconds())) + } + + if ctx.Deprecated { + log.Warn(color.New(color.Bold).Sprintf("your config is using deprecated properties, check logs above for details")) + } + + log.Infof(color.New(color.Bold).Sprintf("release succeeded after %0.2fs", time.Since(start).Seconds())) + return nil + }, + } + + cmd.Flags().StringVarP(&root.opts.config, "config", "f", "", "Load configuration from file") + cmd.Flags().StringVar(&root.opts.releaseNotes, "release-notes", "", "Load custom release notes from a markdown file") + cmd.Flags().StringVar(&root.opts.releaseHeader, "release-header", "", "Load custom release notes header from a markdown file") + cmd.Flags().StringVar(&root.opts.releaseFooter, "release-footer", "", "Load custom release notes footer from a markdown file") + cmd.Flags().BoolVar(&root.opts.snapshot, "snapshot", false, "Generate an unversioned snapshot release, skipping all validations and without publishing any artifacts") + cmd.Flags().BoolVar(&root.opts.skipPublish, "skip-publish", false, "Skips publishing artifacts") + cmd.Flags().BoolVar(&root.opts.skipSign, "skip-sign", false, "Skips signing the artifacts") + cmd.Flags().BoolVar(&root.opts.skipValidate, "skip-validate", false, "Skips several sanity checks") + cmd.Flags().BoolVar(&root.opts.rmDist, "rm-dist", false, "Remove the dist folder before building") + cmd.Flags().IntVarP(&root.opts.parallelism, "parallelism", "p", 4, "Amount tasks to run concurrently") + cmd.Flags().DurationVar(&root.opts.timeout, "timeout", 30*time.Minute, "Timeout to the entire release process") + cmd.Flags().BoolVar(&root.opts.deprecated, "deprecated", false, "Force print the deprecation message - tests only") + _ = cmd.Flags().MarkHidden("deprecated") + + root.cmd = cmd + return root +} + +func releaseProject(options releaseOpts) (*context.Context, error) { + cfg, err := loadConfig(options.config) + if err != nil { + return nil, err + } + ctx, cancel := context.NewWithTimeout(cfg, options.timeout) + defer cancel() + setupContext(ctx, options) + return ctx, ctrlc.Default.Run(ctx, func() error { + for _, pipe := range pipeline.Pipeline { + if err := middleware.Logging( + pipe.String(), + middleware.ErrHandler(pipe.Run), + middleware.DefaultInitialPadding, + )(ctx); err != nil { + return err + } + } + return nil + }) +} + +func setupContext(ctx *context.Context, options releaseOpts) *context.Context { + ctx.Parallelism = options.parallelism + log.Debugf("parallelism: %v", ctx.Parallelism) + ctx.ReleaseNotes = options.releaseNotes + ctx.ReleaseHeader = options.releaseHeader + ctx.ReleaseFooter = options.releaseFooter + ctx.Snapshot = options.snapshot + ctx.SkipPublish = ctx.Snapshot || options.skipPublish + ctx.SkipValidate = ctx.Snapshot || options.skipValidate + ctx.SkipSign = options.skipSign + ctx.RmDist = options.rmDist + + // test only + ctx.Deprecated = options.deprecated + return ctx +} diff --git a/cmd/release_test.go b/cmd/release_test.go new file mode 100644 index 00000000000..6019d7edda1 --- /dev/null +++ b/cmd/release_test.go @@ -0,0 +1,87 @@ +package cmd + +import ( + "testing" + + "github.com/goreleaser/goreleaser/pkg/config" + "github.com/goreleaser/goreleaser/pkg/context" + "github.com/stretchr/testify/require" +) + +func TestRelease(t *testing.T) { + _, back := setup(t) + defer back() + var cmd = newReleaseCmd() + cmd.cmd.SetArgs([]string{"--snapshot", "--timeout=1m", "--parallelism=2", "--deprecated"}) + require.NoError(t, cmd.cmd.Execute()) +} + +func TestReleaseInvalidConfig(t *testing.T) { + _, back := setup(t) + defer back() + createFile(t, "goreleaser.yml", "foo: bar") + var cmd = newReleaseCmd() + cmd.cmd.SetArgs([]string{"--snapshot", "--timeout=1m", "--parallelism=2", "--deprecated"}) + require.EqualError(t, cmd.cmd.Execute(), "yaml: unmarshal errors:\n line 1: field foo not found in type config.Project") +} + +func TestReleaseBrokenProject(t *testing.T) { + _, back := setup(t) + defer back() + createFile(t, "main.go", "not a valid go file") + var cmd = newReleaseCmd() + cmd.cmd.SetArgs([]string{"--snapshot", "--timeout=1m", "--parallelism=2"}) + require.EqualError(t, cmd.cmd.Execute(), "failed to parse dir: .: main.go:1:1: expected 'package', found not") +} + +func TestReleaseFlags(t *testing.T) { + var setup = func(opts releaseOpts) *context.Context { + return setupContext(context.New(config.Project{}), opts) + } + + t.Run("snapshot", func(t *testing.T) { + var ctx = setup(releaseOpts{ + snapshot: true, + }) + require.True(t, ctx.Snapshot) + require.True(t, ctx.SkipPublish) + require.True(t, ctx.SkipPublish) + }) + + t.Run("skips", func(t *testing.T) { + var ctx = setup(releaseOpts{ + skipPublish: true, + skipSign: true, + skipValidate: true, + }) + require.True(t, ctx.SkipSign) + require.True(t, ctx.SkipPublish) + require.True(t, ctx.SkipPublish) + }) + + t.Run("parallelism", func(t *testing.T) { + require.Equal(t, 1, setup(releaseOpts{ + parallelism: 1, + }).Parallelism) + }) + + t.Run("notes", func(t *testing.T) { + var notes = "foo.md" + var header = "header.md" + var footer = "footer.md" + var ctx = setup(releaseOpts{ + releaseNotes: notes, + releaseHeader: header, + releaseFooter: footer, + }) + require.Equal(t, notes, ctx.ReleaseNotes) + require.Equal(t, header, ctx.ReleaseHeader) + require.Equal(t, footer, ctx.ReleaseFooter) + }) + + t.Run("rm dist", func(t *testing.T) { + require.True(t, setup(releaseOpts{ + rmDist: true, + }).RmDist) + }) +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 00000000000..87bbe802bda --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,106 @@ +package cmd + +import ( + "fmt" + "os" + + "github.com/apex/log" + "github.com/apex/log/handlers/cli" + "github.com/fatih/color" + "github.com/spf13/cobra" +) + +func Execute(version string, exit func(int), args []string) { + // enable colored output on travis + if os.Getenv("CI") != "" { + color.NoColor = false + } + + log.SetHandler(cli.Default) + + fmt.Println() + defer fmt.Println() + newRootCmd(version, exit).Execute(args) +} + +func (cmd *rootCmd) Execute(args []string) { + cmd.cmd.SetArgs(args) + + if shouldPrependRelease(cmd.cmd, args) { + cmd.cmd.SetArgs(append([]string{"release"}, args...)) + } + + if err := cmd.cmd.Execute(); err != nil { + var code = 1 + var msg = "command failed" + if eerr, ok := err.(*exitError); ok { + code = eerr.code + if eerr.details != "" { + msg = eerr.details + } + } + log.WithError(err).Error(msg) + cmd.exit(code) + } +} + +type rootCmd struct { + cmd *cobra.Command + debug bool + exit func(int) +} + +func newRootCmd(version string, exit func(int)) *rootCmd { + var root = &rootCmd{ + exit: exit, + } + var cmd = &cobra.Command{ + Use: "goreleaser", + Short: "Deliver Go binaries as fast and easily as possible", + Version: version, + SilenceUsage: true, + SilenceErrors: true, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + if root.debug { + log.SetLevel(log.DebugLevel) + log.Debug("debug logs enabled") + } + }, + } + + cmd.PersistentFlags().BoolVar(&root.debug, "debug", false, "Enable debug mode") + cmd.AddCommand( + newReleaseCmd().cmd, + newCheckCmd().cmd, + newInitCmd().cmd, + ) + + root.cmd = cmd + return root +} + +func shouldPrependRelease(cmd *cobra.Command, args []string) bool { + // find current cmd, if its not root, it means the user actively + // set a command, so let it go + xmd, _, _ := cmd.Find(args) + if xmd != cmd { + return false + } + + // if we have != 1 args, assume its a release + if len(args) != 1 { + return true + } + + // given that its 1, check if its one of the valid standalone flags + // for the root cmd + for _, s := range []string{"-h", "--help", "-v", "--version"} { + if s == args[0] { + // if it is, we should run the root cmd + return false + } + } + + // otherwise, we should probably prepend release + return true +} diff --git a/cmd/root_test.go b/cmd/root_test.go new file mode 100644 index 00000000000..59bfd9322f7 --- /dev/null +++ b/cmd/root_test.go @@ -0,0 +1,87 @@ +package cmd + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestRootCmd(t *testing.T) { + var mem = &exitMemento{} + Execute("1.2.3", mem.Exit, []string{"-h"}) + require.Equal(t, 0, mem.code) +} + +func TestRootCmdHelp(t *testing.T) { + var mem = &exitMemento{} + var cmd = newRootCmd("", mem.Exit).cmd + cmd.SetArgs([]string{"-h"}) + require.NoError(t, cmd.Execute()) + require.Equal(t, 0, mem.code) +} + +func TestRootCmdVersion(t *testing.T) { + var b bytes.Buffer + var mem = &exitMemento{} + var cmd = newRootCmd("1.2.3", mem.Exit).cmd + cmd.SetOut(&b) + cmd.SetArgs([]string{"-v"}) + require.NoError(t, cmd.Execute()) + require.Equal(t, "goreleaser version 1.2.3\n", b.String()) + require.Equal(t, 0, mem.code) +} + +func TestRootCmdExitCode(t *testing.T) { + var mem = &exitMemento{} + var cmd = newRootCmd("", mem.Exit) + var args = []string{"check", "--deprecated", "-f", "testdata/good.yml"} + cmd.Execute(args) + require.Equal(t, 2, mem.code) +} + +func TestRootRelease(t *testing.T) { + _, back := setup(t) + defer back() + var mem = &exitMemento{} + var cmd = newRootCmd("", mem.Exit) + cmd.Execute([]string{}) + require.Equal(t, 1, mem.code) +} + +func TestRootReleaseDebug(t *testing.T) { + _, back := setup(t) + defer back() + var mem = &exitMemento{} + var cmd = newRootCmd("", mem.Exit) + cmd.Execute([]string{"r", "--debug"}) + require.Equal(t, 1, mem.code) +} + +func TestShouldPrependRelease(t *testing.T) { + var result = func(args []string) bool { + return shouldPrependRelease(newRootCmd("1", func(_ int) {}).cmd, args) + } + + t.Run("no args", func(t *testing.T) { + require.True(t, result([]string{})) + }) + + t.Run("release args", func(t *testing.T) { + require.True(t, result([]string{"--skip-validate"})) + }) + + t.Run("several release args", func(t *testing.T) { + require.True(t, result([]string{"--skip-validate", "--snapshot"})) + }) + + for _, s := range []string{"--help", "-h", "-v", "--version"} { + t.Run(s, func(t *testing.T) { + require.False(t, result([]string{s})) + }) + } + + t.Run("check", func(t *testing.T) { + require.False(t, result([]string{"check", "-f", "testdata/good.yml"})) + }) +} diff --git a/cmd/testdata/good.yml b/cmd/testdata/good.yml new file mode 100644 index 00000000000..462e7201e01 --- /dev/null +++ b/cmd/testdata/good.yml @@ -0,0 +1,28 @@ +# This is an example goreleaser.yaml file with some sane defaults. +# Make sure to check the documentation at http://goreleaser.com +before: + hooks: + # You may remove this if you don't use go modules. + - go mod download + # you may remove this if you don't need go generate + - go generate ./... +builds: +- env: + - CGO_ENABLED=0 +archives: +- replacements: + darwin: Darwin + linux: Linux + windows: Windows + 386: i386 + amd64: x86_64 +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ .Tag }}-next" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' diff --git a/cmd/testdata/invalid.yml b/cmd/testdata/invalid.yml new file mode 100644 index 00000000000..9b3aa1ba9b7 --- /dev/null +++ b/cmd/testdata/invalid.yml @@ -0,0 +1,5 @@ +builds: +- id: a +- id: b +- id: c +- id: a diff --git a/cmd/testdata/unmarshal_error.yml b/cmd/testdata/unmarshal_error.yml new file mode 100644 index 00000000000..20e9ff3feaa --- /dev/null +++ b/cmd/testdata/unmarshal_error.yml @@ -0,0 +1 @@ +foo: bar diff --git a/cmd/util_test.go b/cmd/util_test.go new file mode 100644 index 00000000000..a4ade6a898c --- /dev/null +++ b/cmd/util_test.go @@ -0,0 +1,75 @@ +package cmd + +import ( + "io/ioutil" + "os" + "testing" + + "github.com/goreleaser/goreleaser/internal/testlib" + "github.com/stretchr/testify/require" + "github.com/tj/assert" +) + +type exitMemento struct { + code int +} + +func (e *exitMemento) Exit(i int) { + e.code = i +} + +func setup(t *testing.T) (current string, back func()) { + _ = os.Unsetenv("GITHUB_TOKEN") + _ = os.Unsetenv("GITLAB_TOKEN") + + folder, err := ioutil.TempDir("", "") + require.NoError(t, err) + previous, err := os.Getwd() + assert.NoError(t, err) + assert.NoError(t, os.Chdir(folder)) + createGoreleaserYaml(t) + createMainGo(t) + goModInit(t) + testlib.GitInit(t) + testlib.GitAdd(t) + testlib.GitCommit(t, "asdf") + testlib.GitTag(t, "v0.0.1") + testlib.GitCommit(t, "asas89d") + testlib.GitCommit(t, "assssf") + testlib.GitCommit(t, "assd") + testlib.GitTag(t, "v0.0.2") + testlib.GitRemoteAdd(t, "git@github.com:goreleaser/fake.git") + return folder, func() { + assert.NoError(t, os.Chdir(previous)) + } +} + +func createFile(t *testing.T, filename, contents string) { + assert.NoError(t, ioutil.WriteFile(filename, []byte(contents), 0644)) +} + +func createMainGo(t *testing.T) { + createFile(t, "main.go", "package main\nfunc main() {println(0)}") +} + +func goModInit(t *testing.T) { + createFile(t, "go.mod", `module foo + +go 1.14 +`) +} + +func createGoreleaserYaml(t *testing.T) { + var yaml = `build: + binary: fake + goos: + - linux + goarch: + - amd64 +release: + github: + owner: goreleaser + name: fake +` + createFile(t, "goreleaser.yml", yaml) +} diff --git a/go.mod b/go.mod index 6301c523559..d4a3a6e7531 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,9 @@ require ( github.com/mattn/go-zglob v0.0.1 github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 + github.com/spf13/cobra v1.0.0 github.com/stretchr/testify v1.5.1 + github.com/tj/assert v0.0.0-20171129193455-018094318fb0 github.com/ulikunitz/xz v0.5.7 github.com/xanzy/go-gitlab v0.31.0 gocloud.dev v0.19.0 @@ -26,6 +28,5 @@ require ( golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e google.golang.org/appengine v1.6.5 // indirect - gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/yaml.v2 v2.2.8 ) diff --git a/go.sum b/go.sum index 2e6fc708934..0b035a7ee02 100644 --- a/go.sum +++ b/go.sum @@ -34,9 +34,12 @@ github.com/Masterminds/semver/v3 v3.0.3 h1:znjIyLfpXEDQjOIEWh+ehwpTU14UzUPub3c3s github.com/Masterminds/semver/v3 v3.0.3/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk= github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/apex/log v1.1.4 h1:3Zk+boorIQAAGBrHn0JUtAau4ihMamT4WdnfdnXM1zQ= @@ -44,6 +47,7 @@ github.com/apex/log v1.1.4/go.mod h1:AlpoD9aScyQfJDVHmLMEcx4oU6LqzkWp4Mg9GdAcEvQ github.com/apex/logs v0.0.4/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.19.45/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= @@ -51,6 +55,8 @@ github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN github.com/aws/aws-sdk-go v1.25.11 h1:wUivbsVOH3LpHdC3Rl5i+FLHfg4sOmYgv4bvHe7+/Pg= github.com/aws/aws-sdk-go v1.25.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4= github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI= github.com/caarlos0/ctrlc v1.0.0 h1:2DtF8GSIcajgffDFJzyG15vO+1PuBWOMUdFut7NnXhw= @@ -61,13 +67,21 @@ github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e h1:hHg27A0RS github.com/cavaliercoder/go-cpio v0.0.0-20180626203310-925f9528c45e/go.mod h1:oDpT4efm8tSYHXV5tHSdRvBet/b/QzxZ+XyyPehvm3A= github.com/census-instrumentation/opencensus-proto v0.2.0 h1:LzQXZOgg4CQfE6bFvXGM30YZL1WW/M337pXml+GrcZ4= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.1.0 h1:FcM3g+nofKgUteL8dm/UpdRXNC9KmADgTpLKsu0TRo4= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= @@ -79,11 +93,17 @@ github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -129,7 +149,11 @@ github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/goreleaser/nfpm v1.2.1 h1:AEnu9XVmupRDTR930Z2rAs31Mj6sLIPxFcR9ESYvgDA= github.com/goreleaser/nfpm v1.2.1/go.mod h1:TtWrABZozuLOttX2uDlYyECfQX7x5XYkVxhjYcR6G9w= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.2 h1:S+ef0492XaIknb8LMjcwgW2i3cNTzDYMmDrOThOJNWc= github.com/grpc-ecosystem/grpc-gateway v1.9.2/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= @@ -143,19 +167,27 @@ github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jarcoal/httpmock v1.0.5 h1:cHtVEcTxRSX4J0je7mWPfc9BpDpqzXSJ5HbymZmyHck= github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -163,6 +195,7 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -179,14 +212,18 @@ github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvO github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/mattn/go-zglob v0.0.1 h1:xsEx/XUoVlI6yXjqBK062zYhRTZltCNmYPx6v+8DNaY= github.com/mattn/go-zglob v0.0.1/go.mod h1:9fxibJccNxU2cnpIKLRRFA7zX7qhkJIQWBb449FYHOo= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -194,15 +231,38 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b h1:+gCnWOZV8Z/8jehJ2CdqB47Z3S+SREmQcuXkRFLNsiI= github.com/sassoftware/go-rpmutils v0.0.0-20190420191620-a8f1baeba37b/go.mod h1:am+Fp8Bt506lA3Rk3QCmSqmYmLMnPDhdDUcosQCAx+I= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -211,10 +271,13 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/tj/assert v0.0.0-20171129193455-018094318fb0 h1:Rw8kxzWo1mr6FSaYXjQELRe88y2KdfynXdnK72rdjtA= github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4= @@ -223,14 +286,21 @@ github.com/xanzy/go-gitlab v0.31.0 h1:+nHztQuCXGSMluKe5Q9IRaPdz6tO8O0gMkQ0vqGpiB github.com/xanzy/go-gitlab v0.31.0/go.mod h1:sPLojNBn68fMUWSxIJtdVVIP8uSBYqesTfDUseX11Ug= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2 h1:75k/FF0Q2YM8QYo07VPddOLBslDt1MZOdEslOHvmzAs= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= gocloud.dev v0.19.0 h1:EDRyaRAnMGSq/QBto486gWFxMLczAfIYUmusV7XLNBM= gocloud.dev v0.19.0/go.mod h1:SmKwiR8YwIMMJvQBKLsC3fHNyMwXLw3PMDO+VVteJMI= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -249,6 +319,7 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -256,6 +327,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= @@ -280,8 +352,10 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -302,6 +376,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= diff --git a/main.go b/main.go index dc7f021479c..656de35ff07 100644 --- a/main.go +++ b/main.go @@ -2,21 +2,9 @@ package main import ( "fmt" - "io/ioutil" "os" - "time" - "github.com/apex/log" - "github.com/apex/log/handlers/cli" - "github.com/caarlos0/ctrlc" - "github.com/fatih/color" - "github.com/goreleaser/goreleaser/internal/middleware" - "github.com/goreleaser/goreleaser/internal/pipe/defaults" - "github.com/goreleaser/goreleaser/internal/pipeline" - "github.com/goreleaser/goreleaser/internal/static" - "github.com/goreleaser/goreleaser/pkg/config" - "github.com/goreleaser/goreleaser/pkg/context" - "gopkg.in/alecthomas/kingpin.v2" + "github.com/goreleaser/goreleaser/cmd" ) // nolint: gochecknoglobals @@ -27,186 +15,16 @@ var ( builtBy = "" ) -type releaseOptions struct { - Config string - ReleaseNotes string - ReleaseHeader string - ReleaseFooter string - Snapshot bool - SkipPublish bool - SkipSign bool - SkipValidate bool - RmDist bool - Parallelism int - Timeout time.Duration -} - func main() { - // enable colored output on travis - if os.Getenv("CI") != "" { - color.NoColor = false - } - log.SetHandler(cli.Default) - - fmt.Println() - defer fmt.Println() - - var app = kingpin.New("goreleaser", "Deliver Go binaries as fast and easily as possible") - var debug = app.Flag("debug", "Enable debug mode").Bool() - var config = app.Flag("config", "Load configuration from file").Short('c').Short('f').PlaceHolder(".goreleaser.yml").String() - var initCmd = app.Command("init", "Generates a .goreleaser.yml file").Alias("i") - var checkCmd = app.Command("check", "Checks if configuration is valid").Alias("c") - var releaseCmd = app.Command("release", "Releases the current project").Alias("r").Default() - var releaseNotes = releaseCmd.Flag("release-notes", "Load custom release notes from a markdown file").PlaceHolder("notes.md").String() - var releaseHeader = releaseCmd.Flag("release-header", "Load custom release notes header from a markdown file").PlaceHolder("notes-header.md").String() - var releaseFooter = releaseCmd.Flag("release-footer", "Load custom release notes footer from a markdown file").PlaceHolder("notes-footer.md").String() - var snapshot = releaseCmd.Flag("snapshot", "Generate an unversioned snapshot release, skipping all validations and without publishing any artifacts").Bool() - var skipPublish = releaseCmd.Flag("skip-publish", "Skips publishing artifacts").Bool() - var skipSign = releaseCmd.Flag("skip-sign", "Skips signing the artifacts").Bool() - var skipValidate = releaseCmd.Flag("skip-validate", "Skips several sanity checks").Bool() - var rmDist = releaseCmd.Flag("rm-dist", "Remove the dist folder before building").Bool() - var parallelism = releaseCmd.Flag("parallelism", "Amount tasks to run concurrently").Short('p').Default("4").Int() - var timeout = releaseCmd.Flag("timeout", "Timeout to the entire release process").Default("30m").Duration() - - app.Version(buildVersion(version, commit, date, builtBy)) - app.VersionFlag.Short('v') - app.HelpFlag.Short('h') - app.UsageTemplate(static.UsageTemplate) - - cmd := kingpin.MustParse(app.Parse(os.Args[1:])) - if *debug { - log.SetLevel(log.DebugLevel) - } - switch cmd { - case initCmd.FullCommand(): - var filename = *config - if filename == "" { - filename = ".goreleaser.yml" - } - if err := initProject(filename); err != nil { - log.WithError(err).Error("failed to init project") - os.Exit(1) - } - log.WithField("file", filename).Info("config created; please edit accordingly to your needs") - case checkCmd.FullCommand(): - ctx, err := checkConfig(*config) - if err != nil { - log.WithError(err).Errorf(color.New(color.Bold).Sprintf("config is invalid")) - os.Exit(1) - } - if ctx.Deprecated { - log.Warn(color.New(color.Bold).Sprintf("config is valid, but uses deprecated properties, check logs above for details")) - os.Exit(2) - } - log.Infof(color.New(color.Bold).Sprintf("config is valid")) - case releaseCmd.FullCommand(): - start := time.Now() - log.Infof(color.New(color.Bold).Sprintf("releasing using goreleaser %s...", version)) - var options = releaseOptions{ - Config: *config, - ReleaseNotes: *releaseNotes, - ReleaseHeader: *releaseHeader, - ReleaseFooter: *releaseFooter, - Snapshot: *snapshot, - SkipPublish: *skipPublish, - SkipValidate: *skipValidate, - SkipSign: *skipSign, - RmDist: *rmDist, - Parallelism: *parallelism, - Timeout: *timeout, - } - ctx, err := releaseProject(options) - if err != nil { - log.WithError(err).Errorf(color.New(color.Bold).Sprintf("release failed after %0.2fs", time.Since(start).Seconds())) - os.Exit(1) - return - } - if ctx.Deprecated { - log.Warn(color.New(color.Bold).Sprintf("your config is using deprecated properties, check logs above for details")) - } - log.Infof(color.New(color.Bold).Sprintf("release succeeded after %0.2fs", time.Since(start).Seconds())) - } -} - -func checkConfig(filename string) (*context.Context, error) { - cfg, err := loadConfig(filename) - if err != nil { - return nil, err - } - var ctx = context.New(cfg) - return ctx, ctrlc.Default.Run(ctx, func() error { - log.Info(color.New(color.Bold).Sprint("checking config:")) - return defaults.Pipe{}.Run(ctx) - }) -} - -func releaseProject(options releaseOptions) (*context.Context, error) { - cfg, err := loadConfig(options.Config) - if err != nil { - return nil, err - } - ctx, cancel := context.NewWithTimeout(cfg, options.Timeout) - defer cancel() - ctx.Parallelism = options.Parallelism - log.Debugf("parallelism: %v", ctx.Parallelism) - ctx.ReleaseNotes = options.ReleaseNotes - ctx.ReleaseHeader = options.ReleaseHeader - ctx.ReleaseFooter = options.ReleaseFooter - ctx.Snapshot = options.Snapshot - ctx.SkipPublish = ctx.Snapshot || options.SkipPublish - ctx.SkipValidate = ctx.Snapshot || options.SkipValidate - ctx.SkipSign = options.SkipSign - ctx.RmDist = options.RmDist - return ctx, ctrlc.Default.Run(ctx, func() error { - for _, pipe := range pipeline.Pipeline { - if err := middleware.Logging( - pipe.String(), - middleware.ErrHandler(pipe.Run), - middleware.DefaultInitialPadding, - )(ctx); err != nil { - return err - } - } - return nil - }) -} - -// InitProject creates an example goreleaser.yml in the current directory -func initProject(filename string) error { - if _, err := os.Stat(filename); !os.IsNotExist(err) { - if err != nil { - return err - } - return fmt.Errorf("%s already exists", filename) - } - log.Infof(color.New(color.Bold).Sprintf("Generating %s file", filename)) - return ioutil.WriteFile(filename, []byte(static.ExampleConfig), 0644) -} - -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 + cmd.Execute( + buildVersion(version, commit, date, builtBy), + os.Exit, + os.Args[1:], + ) } func buildVersion(version, commit, date, builtBy string) string { - var result = fmt.Sprintf("version: %s", version) + var result = version if commit != "" { result = fmt.Sprintf("%s\ncommit: %s", result, commit) } diff --git a/main_test.go b/main_test.go index b4275313d75..c9e2db7e1d9 100644 --- a/main_test.go +++ b/main_test.go @@ -1,295 +1,40 @@ package main import ( - "io/ioutil" - "os" - "path/filepath" "testing" - "time" - "github.com/goreleaser/goreleaser/internal/testlib" - "github.com/goreleaser/goreleaser/pkg/config" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "gopkg.in/yaml.v2" ) -func init() { - _ = os.Unsetenv("GITHUB_TOKEN") - _ = os.Unsetenv("GITLAB_TOKEN") -} - -func TestReleaseProject(t *testing.T) { - _, back := setup(t) - defer back() - _, err := releaseProject(testParams()) - assert.NoError(t, err) -} - -func TestCheckConfig(t *testing.T) { - _, back := setup(t) - defer back() - _, err := checkConfig(testParams().Config) - assert.NoError(t, err) -} - -func TestCheckConfigFails(t *testing.T) { - _, back := setup(t) - defer back() - var filename = "fail.yaml" - assert.NoError(t, ioutil.WriteFile(filename, []byte("nope: 1"), 0644)) - _, err := checkConfig(filename) - assert.Error(t, err) -} - -func TestReleaseProjectSkipPublish(t *testing.T) { - _, back := setup(t) - defer back() - params := testParams() - params.Snapshot = true - params.SkipPublish = true - _, err := releaseProject(params) - assert.NoError(t, err) -} - -func TestConfigFileIsSetAndDontExist(t *testing.T) { - _, back := setup(t) - defer back() - params := testParams() - params.Config = "/this/wont/exist" - _, err := releaseProject(params) - assert.Error(t, err) -} - -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() - err := os.Rename( - filepath.Join(folder, "goreleaser.yml"), - filepath.Join(folder, name), - ) - assert.NoError(t, err) - proj, err := loadConfig("") - assert.NoError(t, err) - assert.NotEqual(t, config.Project{}, proj) - }) - } -} - -func TestConfigFileDoesntExist(t *testing.T) { - folder, back := setup(t) - defer back() - err := os.Remove(filepath.Join(folder, "goreleaser.yml")) - assert.NoError(t, err) - proj, err := loadConfig("") - assert.NoError(t, err) - assert.Equal(t, config.Project{}, proj) -} - -func TestReleaseNotesFileDontExist(t *testing.T) { - _, back := setup(t) - defer back() - params := testParams() - params.ReleaseNotes = "/this/also/wont/exist" - _, err := releaseProject(params) - assert.Error(t, err) -} - -func TestCustomReleaseNotesFile(t *testing.T) { - _, back := setup(t) - defer back() - releaseNotes, err := ioutil.TempFile("", "") - assert.NoError(t, err) - createFile(t, releaseNotes.Name(), "nothing important at all") - var params = testParams() - params.ReleaseNotes = releaseNotes.Name() - _, err = releaseProject(params) - assert.NoError(t, err) -} - -func TestCustomReleaseHeaderFileDontExist(t *testing.T) { - _, back := setup(t) - defer back() - params := testParams() - params.ReleaseHeader = "/header/that/dont/exist" - params.Snapshot = false - _, err := releaseProject(params) - assert.Error(t, err) -} - -func TestCustomReleaseHeaderFile(t *testing.T) { - _, back := setup(t) - defer back() - releaseHeader, err := ioutil.TempFile("", "") - assert.NoError(t, err) - createFile(t, releaseHeader.Name(), "some release header") - params := testParams() - params.ReleaseHeader = releaseHeader.Name() - params.Snapshot = false - params.SkipPublish = true - _, err = releaseProject(params) - assert.NoError(t, err) -} - -func TestCustomReleaseFooterFileDontExist(t *testing.T) { - _, back := setup(t) - defer back() - params := testParams() - params.ReleaseFooter = "/footer/that/dont/exist" - params.Snapshot = false - _, err := releaseProject(params) - assert.Error(t, err) -} - -func TestCustomReleaseFooterFile(t *testing.T) { - _, back := setup(t) - defer back() - releaseFooter, err := ioutil.TempFile("", "") - assert.NoError(t, err) - createFile(t, releaseFooter.Name(), "some release footer") - params := testParams() - params.ReleaseFooter = releaseFooter.Name() - params.Snapshot = false - params.SkipPublish = true - _, err = releaseProject(params) - assert.NoError(t, err) -} - -func TestBrokenPipe(t *testing.T) { - _, back := setup(t) - defer back() - createFile(t, "main.go", "not a valid go file") - _, err := releaseProject(testParams()) - assert.Error(t, err) -} - -func TestInitProject(t *testing.T) { - _, back := setup(t) - defer back() - var filename = "test_goreleaser.yml" - assert.NoError(t, initProject(filename)) - - file, err := os.Open(filename) - assert.NoError(t, err) - out, err := ioutil.ReadAll(file) - assert.NoError(t, err) - - assert.NoError(t, yaml.Unmarshal(out, &config.Project{})) -} - -func TestInitProjectFileExist(t *testing.T) { - _, back := setup(t) - defer back() - var filename = "test_goreleaser.yml" - createFile(t, filename, "") - assert.Error(t, initProject(filename)) -} - -func TestInitProjectDefaultPipeFails(t *testing.T) { - folder, back := setup(t) - defer back() - var filename = "test_goreleaser.yml" - assert.NoError(t, os.Chmod(folder, 0000)) - assert.EqualError(t, initProject(filename), `stat test_goreleaser.yml: permission denied`) -} - -func testParams() releaseOptions { - return releaseOptions{ - Parallelism: 4, - Snapshot: true, - Timeout: time.Minute, - } -} - -func setup(t *testing.T) (current string, back func()) { - folder, err := ioutil.TempDir("", "") - assert.NoError(t, err) - previous, err := os.Getwd() - assert.NoError(t, err) - assert.NoError(t, os.Chdir(folder)) - createGoreleaserYaml(t) - createMainGo(t) - goModInit(t) - testlib.GitInit(t) - testlib.GitAdd(t) - testlib.GitCommit(t, "asdf") - testlib.GitTag(t, "v0.0.1") - testlib.GitCommit(t, "asas89d") - testlib.GitCommit(t, "assssf") - testlib.GitCommit(t, "assd") - testlib.GitTag(t, "v0.0.2") - testlib.GitRemoteAdd(t, "git@github.com:goreleaser/fake.git") - return folder, func() { - assert.NoError(t, os.Chdir(previous)) - } -} - -func createFile(t *testing.T, filename, contents string) { - assert.NoError(t, ioutil.WriteFile(filename, []byte(contents), 0644)) -} - -func createMainGo(t *testing.T) { - createFile(t, "main.go", "package main\nfunc main() {println(0)}") -} - -func goModInit(t *testing.T) { - createFile(t, "go.mod", `module foo - -go 1.14 -`) -} - -func createGoreleaserYaml(t *testing.T) { - var yaml = `build: - binary: fake - goos: - - linux - goarch: - - amd64 -release: - github: - owner: goreleaser - name: fake -` - createFile(t, "goreleaser.yml", yaml) -} - func TestVersion(t *testing.T) { for name, tt := range map[string]struct { version, commit, date, builtBy string out string }{ "all empty": { - out: "version: ", + out: "", }, "complete": { version: "1.2.3", date: "12/12/12", commit: "aaaa", builtBy: "me", - out: "version: 1.2.3\ncommit: aaaa\nbuilt at: 12/12/12\nbuilt by: me", + out: "1.2.3\ncommit: aaaa\nbuilt at: 12/12/12\nbuilt by: me", }, "only version": { version: "1.2.3", - out: "version: 1.2.3", + out: "1.2.3", }, "version and date": { version: "1.2.3", date: "12/12/12", - out: "version: 1.2.3\nbuilt at: 12/12/12", + out: "1.2.3\nbuilt at: 12/12/12", }, "version, date, built by": { version: "1.2.3", date: "12/12/12", builtBy: "me", - out: "version: 1.2.3\nbuilt at: 12/12/12\nbuilt by: me", + out: "1.2.3\nbuilt at: 12/12/12\nbuilt by: me", }, } { tt := tt