diff --git a/internal/builders/golang/build.go b/internal/builders/golang/build.go index ee3ef4a55142..042094fe5433 100644 --- a/internal/builders/golang/build.go +++ b/internal/builders/golang/build.go @@ -1,6 +1,7 @@ package golang import ( + "errors" "fmt" "go/ast" "go/parser" @@ -237,6 +238,12 @@ func withOverrides(ctx *context.Context, build config.Build, options api.Options func buildGoBuildLine(ctx *context.Context, build config.Build, details config.BuildDetails, options api.Options, artifact *artifact.Artifact, env []string) ([]string, error) { cmd := []string{build.GoBinary, build.Command} + // tags, ldflags, and buildmode, can only appear once + err := validateUniqueFlags(details) + if err != nil { + return cmd, err + } + flags, err := processFlags(ctx, artifact, env, details.Flags, "") if err != nil { return cmd, err @@ -283,6 +290,21 @@ func buildGoBuildLine(ctx *context.Context, build config.Build, details config.B return cmd, nil } +func validateUniqueFlags(details config.BuildDetails) error { + for _, flag := range details.Flags { + if strings.HasPrefix(flag, "-tags") && len(details.Tags) > 0 { + return errors.New("tags is defined multiple times") + } + if strings.HasPrefix(flag, "-ldflags") && len(details.Ldflags) > 0 { + return errors.New("ldflags is defined multiple times") + } + if strings.HasPrefix(flag, "-buildmode") && details.Buildmode != "" { + return errors.New("buildmode is defined multiple times") + } + } + return nil +} + func processFlags(ctx *context.Context, a *artifact.Artifact, env, flags []string, flagPrefix string) ([]string, error) { processed := make([]string, 0, len(flags)) for _, rawFlag := range flags { diff --git a/internal/builders/golang/build_test.go b/internal/builders/golang/build_test.go index 40f63800edd6..6333d9e15fe6 100644 --- a/internal/builders/golang/build_test.go +++ b/internal/builders/golang/build_test.go @@ -606,6 +606,34 @@ func TestBuildFailed(t *testing.T) { require.Empty(t, ctx.Artifacts.List()) } +func TestBuildWithMultipleFlagsFails(t *testing.T) { + folder := testlib.Mktmp(t) + writeGoodMain(t, folder) + config := config.Project{ + Builds: []config.Build{ + { + ID: "buildid", + BuildDetails: config.BuildDetails{ + Flags: []string{"-tags=test"}, + Tags: []string{"xyz"}, + }, + Targets: []string{ + runtimeTarget, + }, + GoBinary: "go", + Command: "build", + }, + }, + } + ctx := context.New(config) + ctx.Git.CurrentTag = "5.6.7" + err := Default.Build(ctx, ctx.Config.Builds[0], api.Options{ + Target: "darwin_amd64", + }) + assertContainsError(t, err, `tags is defined multiple times`) + require.Empty(t, ctx.Artifacts.List()) +} + func TestRunInvalidAsmflags(t *testing.T) { folder := testlib.Mktmp(t) writeGoodMain(t, folder)