mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-03-11 14:39:28 +02:00
feat: allow a --output flag on goreleaser build (#2701)
* feat: allow a --output flag on goreleaser build Signed-off-by: Carlos A Becker <caarlos0@gmail.com> * fix: single build always to copies to root Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
This commit is contained in:
parent
750d520638
commit
c42a2fdc76
32
cmd/build.go
32
cmd/build.go
@ -3,12 +3,15 @@ package cmd
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/caarlos0/ctrlc"
|
||||
"github.com/fatih/color"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/gio"
|
||||
"github.com/goreleaser/goreleaser/internal/middleware/errhandler"
|
||||
"github.com/goreleaser/goreleaser/internal/middleware/logging"
|
||||
"github.com/goreleaser/goreleaser/internal/middleware/skip"
|
||||
@ -34,6 +37,7 @@ type buildOpts struct {
|
||||
parallelism int
|
||||
timeout time.Duration
|
||||
singleTarget bool
|
||||
output string
|
||||
}
|
||||
|
||||
func newBuildCmd() *buildCmd {
|
||||
@ -90,6 +94,7 @@ defaulting to the current's machine target if not set.
|
||||
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().StringVarP(&root.opts.output, "output", "o", "", "Path to the binary, defaults to the distribution folder according to configs. Only taked into account when using --single-target and a single id (either with --id or if config only has one build)")
|
||||
_ = cmd.Flags().MarkHidden("deprecated")
|
||||
|
||||
root.cmd = cmd
|
||||
@ -107,7 +112,7 @@ func buildProject(options buildOpts) (*context.Context, error) {
|
||||
return nil, err
|
||||
}
|
||||
return ctx, ctrlc.Default.Run(ctx, func() error {
|
||||
for _, pipe := range pipeline.BuildCmdPipeline {
|
||||
for _, pipe := range setupPipeline(ctx, options) {
|
||||
if err := skip.Maybe(
|
||||
pipe,
|
||||
logging.Log(
|
||||
@ -123,6 +128,13 @@ func buildProject(options buildOpts) (*context.Context, error) {
|
||||
})
|
||||
}
|
||||
|
||||
func setupPipeline(ctx *context.Context, options buildOpts) []pipeline.Piper {
|
||||
if options.singleTarget && (options.id != "" || len(ctx.Config.Builds) == 1) {
|
||||
return append(pipeline.BuildCmdPipeline, withOutputPipe{options.output})
|
||||
}
|
||||
return pipeline.BuildCmdPipeline
|
||||
}
|
||||
|
||||
func setupBuildContext(ctx *context.Context, options buildOpts) error {
|
||||
ctx.Parallelism = runtime.NumCPU()
|
||||
if options.parallelism > 0 {
|
||||
@ -191,3 +203,21 @@ func setupBuildID(ctx *context.Context, id string) error {
|
||||
ctx.Config.Builds = keep
|
||||
return nil
|
||||
}
|
||||
|
||||
// withOutputPipe copies the binary from dist to the specified output path.
|
||||
type withOutputPipe struct {
|
||||
output string
|
||||
}
|
||||
|
||||
func (w withOutputPipe) String() string {
|
||||
return fmt.Sprintf("copying binary to %q", w.output)
|
||||
}
|
||||
|
||||
func (w withOutputPipe) Run(ctx *context.Context) error {
|
||||
path := ctx.Artifacts.Filter(artifact.ByType(artifact.Binary)).List()[0].Path
|
||||
out := w.output
|
||||
if out == "" {
|
||||
out = filepath.Base(path)
|
||||
}
|
||||
return gio.Copy(path, out)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/internal/pipeline"
|
||||
"github.com/goreleaser/goreleaser/pkg/config"
|
||||
"github.com/goreleaser/goreleaser/pkg/context"
|
||||
"github.com/stretchr/testify/require"
|
||||
@ -40,6 +41,83 @@ func TestBuildBrokenProject(t *testing.T) {
|
||||
require.EqualError(t, cmd.cmd.Execute(), "failed to parse dir: .: main.go:1:1: expected 'package', found not")
|
||||
}
|
||||
|
||||
func TestSetupPipeline(t *testing.T) {
|
||||
t.Run("regular", func(t *testing.T) {
|
||||
require.Equal(
|
||||
t,
|
||||
pipeline.BuildCmdPipeline,
|
||||
setupPipeline(context.New(config.Project{}), buildOpts{}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("single-target", func(t *testing.T) {
|
||||
require.Equal(
|
||||
t,
|
||||
pipeline.BuildCmdPipeline,
|
||||
setupPipeline(context.New(config.Project{}), buildOpts{
|
||||
singleTarget: true,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("single-target and id", func(t *testing.T) {
|
||||
require.Equal(
|
||||
t,
|
||||
append(pipeline.BuildCmdPipeline, withOutputPipe{""}),
|
||||
setupPipeline(context.New(config.Project{}), buildOpts{
|
||||
singleTarget: true,
|
||||
id: "foo",
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("single-target and single build on config", func(t *testing.T) {
|
||||
require.Equal(
|
||||
t,
|
||||
append(pipeline.BuildCmdPipeline, withOutputPipe{""}),
|
||||
setupPipeline(
|
||||
context.New(config.Project{
|
||||
Builds: []config.Build{{}},
|
||||
}),
|
||||
buildOpts{
|
||||
singleTarget: true,
|
||||
},
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("single-target, id and output", func(t *testing.T) {
|
||||
require.Equal(
|
||||
t,
|
||||
append(pipeline.BuildCmdPipeline, withOutputPipe{"foobar"}),
|
||||
setupPipeline(
|
||||
context.New(config.Project{}),
|
||||
buildOpts{
|
||||
singleTarget: true,
|
||||
id: "foo",
|
||||
output: "foobar",
|
||||
},
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("single-target, single build on config and output", func(t *testing.T) {
|
||||
require.Equal(
|
||||
t,
|
||||
append(pipeline.BuildCmdPipeline, withOutputPipe{"zaz"}),
|
||||
setupPipeline(
|
||||
context.New(config.Project{
|
||||
Builds: []config.Build{{}},
|
||||
}),
|
||||
buildOpts{
|
||||
singleTarget: true,
|
||||
output: "zaz",
|
||||
},
|
||||
),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
func TestBuildFlags(t *testing.T) {
|
||||
setup := func(opts buildOpts) *context.Context {
|
||||
ctx := context.New(config.Project{})
|
||||
|
Loading…
x
Reference in New Issue
Block a user