-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add goreleaser mage package (#33)
- Loading branch information
Showing
8 changed files
with
864 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// Package build provides a simple interface to the goreleaser build. | ||
package build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
package build | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"strconv" | ||
"time" | ||
|
||
"github.com/magefile/mage/mg" | ||
|
||
"github.com/mesosphere/daggers/mage/goreleaser/cli" | ||
) | ||
|
||
const ( | ||
goreleaserConfigEnvVar = "GORELEASER_BUILD_CONFIG" | ||
goreleaserIDEnvVar = "GORELEASER_BUILD_ID" | ||
goreleaserOutputEnvVar = "GORELEASER_BUILD_OUTPUT" | ||
goreleaserParallelismEnvVar = "GORELEASER_BUILD_PARALLELISM" | ||
goreleaserRmDistEnvVar = "GORELEASER_BUILD_RM_DIST" | ||
goreleaserSingleTargetEnvVar = "GORELEASER_BUILD_SINGLE_TARGET" | ||
goreleaserSkipPostCommitHooksEnvVar = "GORELEASER_BUILD_SKIP_POST_COMMIT_HOOKS" | ||
goreleaserSkipValidateEnvVar = "GORELEASER_BUILD_SKIP_VALIDATE" | ||
goreleaserSnapshotEnvVar = "GORELEASER_BUILD_SNAPSHOT" | ||
goreleaserTimeoutEnvVar = "GORELEASER_BUILD_TIMEOUT" | ||
) | ||
|
||
// Build runs goreleaser build with --rm-dist and --single-target flags. | ||
func Build(_ context.Context) error { | ||
result, err := BuildWithOptions( | ||
WithRmDist(true), | ||
WithSingleTarget(true), | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Printf( | ||
"Build is successful for project: %s and version: %s\n", | ||
result.Metadata.ProjectName, | ||
result.Metadata.Version, | ||
) | ||
|
||
return nil | ||
} | ||
|
||
// BuildSnapshot runs goreleaser build with --snapshot, --rm-dist and --single-target flags. | ||
// | ||
//nolint:revive // Disable stuttering check. | ||
func BuildSnapshot(_ context.Context) error { | ||
result, err := BuildWithOptions( | ||
WithRmDist(true), | ||
WithSingleTarget(true), | ||
WithSnapshot(true), | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
fmt.Printf( | ||
"Build snapshot is successful for project: %s and version: %s\n", | ||
result.Metadata.ProjectName, | ||
result.Metadata.Version, | ||
) | ||
|
||
return nil | ||
} | ||
|
||
// BuildWithOptions runs goreleaser build with specific options. | ||
// | ||
//nolint:revive // Disable stuttering check. | ||
func BuildWithOptions(opts ...Option) (*cli.Result, error) { | ||
debug := mg.Debug() || mg.Verbose() | ||
|
||
envOpts, err := loadOptionsFromEnv() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
// Combine options from environment variables and options passed to this function. Environment variables | ||
// take precedence to allow overriding from the arguments passed to this function. | ||
var combinedOpts []Option | ||
|
||
combinedOpts = append(combinedOpts, envOpts...) | ||
combinedOpts = append(combinedOpts, opts...) | ||
|
||
options := config{} | ||
for _, opt := range combinedOpts { | ||
options = opt(options) | ||
} | ||
|
||
return cli.Run(cli.CommandBuild, debug, options.env, options.toArgs()) | ||
} | ||
|
||
func loadOptionsFromEnv() ([]Option, error) { | ||
var opts []Option | ||
|
||
opts = append(stringOptFromEnvVar(goreleaserConfigEnvVar, WithConfig), opts...) | ||
opts = append(stringOptFromEnvVar(goreleaserIDEnvVar, WithID), opts...) | ||
opts = append(stringOptFromEnvVar(goreleaserOutputEnvVar, WithOutput), opts...) | ||
opts = append(stringOptFromEnvVar(goreleaserParallelismEnvVar, WithParallelism), opts...) | ||
|
||
boolOpts, err := boolOptFromEnvVar(goreleaserRmDistEnvVar, WithRmDist) | ||
if err != nil { | ||
return nil, err | ||
} | ||
opts = append(boolOpts, opts...) | ||
|
||
boolOpts, err = boolOptFromEnvVar(goreleaserSingleTargetEnvVar, WithSingleTarget) | ||
if err != nil { | ||
return nil, err | ||
} | ||
opts = append(boolOpts, opts...) | ||
|
||
boolOpts, err = boolOptFromEnvVar(goreleaserSkipPostCommitHooksEnvVar, SkipPostCommitHooks) | ||
if err != nil { | ||
return nil, err | ||
} | ||
opts = append(boolOpts, opts...) | ||
|
||
boolOpts, err = boolOptFromEnvVar(goreleaserSkipValidateEnvVar, SkipValidate) | ||
if err != nil { | ||
return nil, err | ||
} | ||
opts = append(boolOpts, opts...) | ||
|
||
boolOpts, err = boolOptFromEnvVar(goreleaserSnapshotEnvVar, WithSnapshot) | ||
if err != nil { | ||
return nil, err | ||
} | ||
opts = append(boolOpts, opts...) | ||
|
||
durationOpts, err := durationOptFromEnvVar(goreleaserTimeoutEnvVar, WithTimeout) | ||
if err != nil { | ||
return nil, err | ||
} | ||
opts = append(durationOpts, opts...) | ||
|
||
return opts, nil | ||
} | ||
|
||
// stringOptFromEnvVar returns a slice containing a single option if the specified environment variable is set. | ||
// This function returns a slice to make it easier to chain calls in optsFromEnvVars. | ||
// Returns a nil slice if the env var is not set. | ||
func stringOptFromEnvVar(envVarName string, optFn func(string) Option) []Option { | ||
if envVarValue, ok := os.LookupEnv(envVarName); ok { | ||
return []Option{optFn(envVarValue)} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// boolOptFromEnvVar returns a slice containing a single option if the specified environment variable is set. | ||
// This function returns a slice to make it easier to chain calls in optsFromEnvVars. | ||
// Returns a nil slice if the env var is not set. | ||
func boolOptFromEnvVar(envVarName string, optFn func(bool) Option) ([]Option, error) { | ||
if envVarValue, ok := os.LookupEnv(envVarName); ok { | ||
boolVal, err := strconv.ParseBool(envVarValue) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse %q as a boolean: %w", envVarName, err) | ||
} | ||
return []Option{optFn(boolVal)}, nil | ||
} | ||
|
||
return nil, nil | ||
} | ||
|
||
// durationOptFromEnvVar returns a slice containing a single option if the specified environment variable is set. | ||
// This function returns a slice to make it easier to chain calls in optsFromEnvVars. | ||
// Returns a nil slice if the env var is not set. | ||
func durationOptFromEnvVar(envVarName string, optFn func(duration time.Duration) Option) ([]Option, error) { | ||
if envVarValue, ok := os.LookupEnv(envVarName); ok { | ||
durationVal, err := time.ParseDuration(envVarValue) | ||
if err != nil { | ||
return nil, fmt.Errorf("failed to parse %q as a duration: %w", envVarName, err) | ||
} | ||
return []Option{optFn(durationVal)}, nil | ||
} | ||
|
||
return nil, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package build | ||
|
||
import ( | ||
"time" | ||
) | ||
|
||
type config struct { | ||
env map[string]string | ||
config string | ||
id string | ||
output string | ||
parallelism string | ||
rmDist bool | ||
singleTarget bool | ||
skipPostCommitHooks bool | ||
skipValidate bool | ||
snapshot bool | ||
timeout string | ||
} | ||
|
||
// Option is a function that configures the goreleaser build options. | ||
type Option func(config config) config | ||
|
||
// WithEnv append extra env variables to goreleaser build process. | ||
func WithEnv(env map[string]string) Option { | ||
return func(config config) config { | ||
config.env = env | ||
return config | ||
} | ||
} | ||
|
||
// WithConfig sets --config flag. | ||
func WithConfig(configPath string) Option { | ||
return func(config config) config { | ||
config.config = configPath | ||
return config | ||
} | ||
} | ||
|
||
// WithID sets --id flag. | ||
func WithID(id string) Option { | ||
return func(config config) config { | ||
config.id = id | ||
return config | ||
} | ||
} | ||
|
||
// WithOutput sets --output. | ||
func WithOutput(output string) Option { | ||
return func(config config) config { | ||
config.output = output | ||
return config | ||
} | ||
} | ||
|
||
// WithParallelism sets --parallelism. | ||
func WithParallelism(parallelism string) Option { | ||
return func(config config) config { | ||
config.parallelism = parallelism | ||
return config | ||
} | ||
} | ||
|
||
// WithRmDist sets --rm-dist. | ||
func WithRmDist(rmDist bool) Option { | ||
return func(config config) config { | ||
config.rmDist = rmDist | ||
return config | ||
} | ||
} | ||
|
||
// WithSingleTarget sets --single-target. | ||
func WithSingleTarget(singleTarget bool) Option { | ||
return func(config config) config { | ||
config.singleTarget = singleTarget | ||
return config | ||
} | ||
} | ||
|
||
// SkipPostCommitHooks sets--skip-post-hooks. | ||
func SkipPostCommitHooks(skipPostCommitHooks bool) Option { | ||
return func(config config) config { | ||
config.skipPostCommitHooks = skipPostCommitHooks | ||
return config | ||
} | ||
} | ||
|
||
// SkipValidate sets --skip-validate. | ||
func SkipValidate(skipValidate bool) Option { | ||
return func(config config) config { | ||
config.skipValidate = skipValidate | ||
return config | ||
} | ||
} | ||
|
||
// WithSnapshot sets --snapshot. | ||
func WithSnapshot(snapshot bool) Option { | ||
return func(config config) config { | ||
config.snapshot = snapshot | ||
return config | ||
} | ||
} | ||
|
||
// WithTimeout sets --timeout duration. | ||
func WithTimeout(timeout time.Duration) Option { | ||
return func(config config) config { | ||
config.timeout = timeout.String() | ||
return config | ||
} | ||
} | ||
|
||
func (c *config) toArgs() []string { | ||
var args []string | ||
|
||
args = appendNonEmptyStringVal(args, "--config", c.config) | ||
args = appendNonEmptyStringVal(args, "--id", c.id) | ||
args = appendNonEmptyStringVal(args, "--output", c.output) | ||
args = appendNonEmptyStringVal(args, "--parallelism", c.parallelism) | ||
args = appendBoolVal(args, "--rm-dist", c.rmDist) | ||
args = appendBoolVal(args, "--single-target", c.singleTarget) | ||
args = appendBoolVal(args, "--skip-post-hooks", c.skipPostCommitHooks) | ||
args = appendBoolVal(args, "--skip-validate", c.skipValidate) | ||
args = appendBoolVal(args, "--snapshot", c.snapshot) | ||
args = appendNonEmptyStringVal(args, "--timeout", c.timeout) | ||
|
||
return args | ||
} | ||
|
||
func appendNonEmptyStringVal(slice []string, flag, val string) []string { | ||
// if val is empty return slice as it's | ||
if val == "" { | ||
return slice | ||
} | ||
|
||
return append(slice, flag, val) | ||
} | ||
|
||
func appendBoolVal(slice []string, flag string, val bool) []string { | ||
// if val is false, no need to append the flag | ||
if !val { | ||
return slice | ||
} | ||
|
||
return append(slice, flag) | ||
} |
Oops, something went wrong.