mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-03-11 14:39:28 +02:00
feat: build single target and/or build id (#2179)
* feat: build single target Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com> * feat: build single id Signed-off-by: Carlos Alexandro Becker <caarlos0@gmail.com>
This commit is contained in:
parent
e7f1ec0ea6
commit
0c2e80ae93
71
cmd/build.go
71
cmd/build.go
@ -1,6 +1,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
@ -9,6 +11,7 @@ import (
|
||||
"github.com/fatih/color"
|
||||
"github.com/goreleaser/goreleaser/internal/middleware"
|
||||
"github.com/goreleaser/goreleaser/internal/pipeline"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
@ -20,6 +23,7 @@ type buildCmd struct {
|
||||
|
||||
type buildOpts struct {
|
||||
config string
|
||||
id string
|
||||
snapshot bool
|
||||
skipValidate bool
|
||||
skipPostHooks bool
|
||||
@ -27,12 +31,13 @@ type buildOpts struct {
|
||||
deprecated bool
|
||||
parallelism int
|
||||
timeout time.Duration
|
||||
singleTarget bool
|
||||
}
|
||||
|
||||
func newBuildCmd() *buildCmd {
|
||||
var root = &buildCmd{}
|
||||
root := &buildCmd{}
|
||||
// nolint: dupl
|
||||
var cmd = &cobra.Command{
|
||||
cmd := &cobra.Command{
|
||||
Use: "build",
|
||||
Aliases: []string{"b"},
|
||||
Short: "Builds the current project",
|
||||
@ -65,6 +70,8 @@ func newBuildCmd() *buildCmd {
|
||||
cmd.Flags().BoolVar(&root.opts.rmDist, "rm-dist", false, "Remove the dist folder before building")
|
||||
cmd.Flags().IntVarP(&root.opts.parallelism, "parallelism", "p", runtime.NumCPU(), "Amount tasks to run concurrently")
|
||||
cmd.Flags().DurationVar(&root.opts.timeout, "timeout", 30*time.Minute, "Timeout to the entire build process")
|
||||
cmd.Flags().BoolVar(&root.opts.singleTarget, "single-target", false, "Builds only for current GOOS and GOARCH")
|
||||
cmd.Flags().StringVar(&root.opts.id, "id", "", "Builds only the specified build id")
|
||||
cmd.Flags().BoolVar(&root.opts.deprecated, "deprecated", false, "Force print the deprecation message - tests only")
|
||||
_ = cmd.Flags().MarkHidden("deprecated")
|
||||
|
||||
@ -79,7 +86,9 @@ func buildProject(options buildOpts) (*context.Context, error) {
|
||||
}
|
||||
ctx, cancel := context.NewWithTimeout(cfg, options.timeout)
|
||||
defer cancel()
|
||||
setupBuildContext(ctx, options)
|
||||
if err := setupBuildContext(ctx, options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ctx, ctrlc.Default.Run(ctx, func() error {
|
||||
for _, pipe := range pipeline.BuildPipeline {
|
||||
if err := middleware.Logging(
|
||||
@ -94,7 +103,7 @@ func buildProject(options buildOpts) (*context.Context, error) {
|
||||
})
|
||||
}
|
||||
|
||||
func setupBuildContext(ctx *context.Context, options buildOpts) *context.Context {
|
||||
func setupBuildContext(ctx *context.Context, options buildOpts) error {
|
||||
ctx.Parallelism = options.parallelism
|
||||
log.Debugf("parallelism: %v", ctx.Parallelism)
|
||||
ctx.Snapshot = options.snapshot
|
||||
@ -103,7 +112,59 @@ func setupBuildContext(ctx *context.Context, options buildOpts) *context.Context
|
||||
ctx.RmDist = options.rmDist
|
||||
ctx.SkipTokenCheck = true
|
||||
|
||||
if options.singleTarget {
|
||||
setupBuildSingleTarget(ctx)
|
||||
}
|
||||
|
||||
if options.id != "" {
|
||||
if err := setupBuildID(ctx, options.id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// test only
|
||||
ctx.Deprecated = options.deprecated
|
||||
return ctx
|
||||
return nil
|
||||
}
|
||||
|
||||
func setupBuildSingleTarget(ctx *context.Context) {
|
||||
goos := os.Getenv("GOOS")
|
||||
if goos == "" {
|
||||
goos = runtime.GOOS
|
||||
}
|
||||
goarch := os.Getenv("GOARCH")
|
||||
if goarch == "" {
|
||||
goarch = runtime.GOARCH
|
||||
}
|
||||
log.Infof("building only for %s/%s", goos, goarch)
|
||||
if len(ctx.Config.Builds) == 0 {
|
||||
ctx.Config.Builds = append(ctx.Config.Builds, config.Build{})
|
||||
}
|
||||
for i := range ctx.Config.Builds {
|
||||
build := &ctx.Config.Builds[i]
|
||||
build.Goos = []string{goos}
|
||||
build.Goarch = []string{goarch}
|
||||
}
|
||||
}
|
||||
|
||||
func setupBuildID(ctx *context.Context, id string) error {
|
||||
if len(ctx.Config.Builds) < 2 {
|
||||
log.Warn("single build in config, '--id' ignored")
|
||||
return nil
|
||||
}
|
||||
|
||||
var keep []config.Build
|
||||
for _, build := range ctx.Config.Builds {
|
||||
if build.ID == id {
|
||||
keep = append(keep, build)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if len(keep) == 0 {
|
||||
return fmt.Errorf("no builds with id '%s'", id)
|
||||
}
|
||||
|
||||
ctx.Config.Builds = keep
|
||||
return nil
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
@ -10,15 +12,22 @@ import (
|
||||
|
||||
func TestBuild(t *testing.T) {
|
||||
setup(t)
|
||||
var cmd = newBuildCmd()
|
||||
cmd := newBuildCmd()
|
||||
cmd.cmd.SetArgs([]string{"--snapshot", "--timeout=1m", "--parallelism=2", "--deprecated"})
|
||||
require.NoError(t, cmd.cmd.Execute())
|
||||
}
|
||||
|
||||
func TestBuildSingleTarget(t *testing.T) {
|
||||
setup(t)
|
||||
cmd := newBuildCmd()
|
||||
cmd.cmd.SetArgs([]string{"--snapshot", "--timeout=1m", "--parallelism=2", "--deprecated", "--single-target"})
|
||||
require.NoError(t, cmd.cmd.Execute())
|
||||
}
|
||||
|
||||
func TestBuildInvalidConfig(t *testing.T) {
|
||||
setup(t)
|
||||
createFile(t, "goreleaser.yml", "foo: bar")
|
||||
var cmd = newBuildCmd()
|
||||
cmd := newBuildCmd()
|
||||
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")
|
||||
}
|
||||
@ -26,18 +35,20 @@ func TestBuildInvalidConfig(t *testing.T) {
|
||||
func TestBuildBrokenProject(t *testing.T) {
|
||||
setup(t)
|
||||
createFile(t, "main.go", "not a valid go file")
|
||||
var cmd = newBuildCmd()
|
||||
cmd := newBuildCmd()
|
||||
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 TestBuildFlags(t *testing.T) {
|
||||
var setup = func(opts buildOpts) *context.Context {
|
||||
return setupBuildContext(context.New(config.Project{}), opts)
|
||||
setup := func(opts buildOpts) *context.Context {
|
||||
ctx := context.New(config.Project{})
|
||||
require.NoError(t, setupBuildContext(ctx, opts))
|
||||
return ctx
|
||||
}
|
||||
|
||||
t.Run("snapshot", func(t *testing.T) {
|
||||
var ctx = setup(buildOpts{
|
||||
ctx := setup(buildOpts{
|
||||
snapshot: true,
|
||||
})
|
||||
require.True(t, ctx.Snapshot)
|
||||
@ -46,7 +57,7 @@ func TestBuildFlags(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("skips", func(t *testing.T) {
|
||||
var ctx = setup(buildOpts{
|
||||
ctx := setup(buildOpts{
|
||||
skipValidate: true,
|
||||
skipPostHooks: true,
|
||||
})
|
||||
@ -66,4 +77,82 @@ func TestBuildFlags(t *testing.T) {
|
||||
rmDist: true,
|
||||
}).RmDist)
|
||||
})
|
||||
|
||||
t.Run("single-target", func(t *testing.T) {
|
||||
opts := buildOpts{
|
||||
singleTarget: true,
|
||||
}
|
||||
|
||||
t.Run("runtime", func(t *testing.T) {
|
||||
result := setup(opts)
|
||||
require.Equal(t, []string{runtime.GOOS}, result.Config.Builds[0].Goos)
|
||||
require.Equal(t, []string{runtime.GOARCH}, result.Config.Builds[0].Goarch)
|
||||
})
|
||||
|
||||
t.Run("from env", func(t *testing.T) {
|
||||
os.Setenv("GOOS", "linux")
|
||||
os.Setenv("GOARCH", "arm64")
|
||||
t.Cleanup(func() {
|
||||
os.Unsetenv("GOOS")
|
||||
os.Unsetenv("GOARCH")
|
||||
})
|
||||
result := setup(opts)
|
||||
require.Equal(t, []string{"linux"}, result.Config.Builds[0].Goos)
|
||||
require.Equal(t, []string{"arm64"}, result.Config.Builds[0].Goarch)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("id", func(t *testing.T) {
|
||||
t.Run("match", func(t *testing.T) {
|
||||
ctx := context.New(config.Project{
|
||||
Builds: []config.Build{
|
||||
{
|
||||
ID: "default",
|
||||
},
|
||||
{
|
||||
ID: "foo",
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, setupBuildContext(ctx, buildOpts{
|
||||
id: "foo",
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("dont match", func(t *testing.T) {
|
||||
ctx := context.New(config.Project{
|
||||
Builds: []config.Build{
|
||||
{
|
||||
ID: "foo",
|
||||
},
|
||||
{
|
||||
ID: "bazz",
|
||||
},
|
||||
},
|
||||
})
|
||||
require.EqualError(t, setupBuildContext(ctx, buildOpts{
|
||||
id: "bar",
|
||||
}), "no builds with id 'bar'")
|
||||
})
|
||||
|
||||
t.Run("default config", func(t *testing.T) {
|
||||
ctx := context.New(config.Project{})
|
||||
require.NoError(t, setupBuildContext(ctx, buildOpts{
|
||||
id: "aaa",
|
||||
}))
|
||||
})
|
||||
|
||||
t.Run("single build config", func(t *testing.T) {
|
||||
ctx := context.New(config.Project{
|
||||
Builds: []config.Build{
|
||||
{
|
||||
ID: "foo",
|
||||
},
|
||||
},
|
||||
})
|
||||
require.NoError(t, setupBuildContext(ctx, buildOpts{
|
||||
id: "not foo but doesnt matter",
|
||||
}))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user