Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Commit

Permalink
Global build variables (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
cardil committed Oct 14, 2021
1 parent bce621a commit 344999d
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 26 deletions.
41 changes: 41 additions & 0 deletions config/buildvars.go
@@ -0,0 +1,41 @@
package config

// BuildVariables will be passed to a Golang's ldflags for variable injection.
type BuildVariables map[string]Resolver

// BuildVariablesBuilder for a build variables.
type BuildVariablesBuilder interface {
// Add a key/value pair.
Add(key string, resolver Resolver) BuildVariablesBuilder
// ConditionallyAdd a key/value pair if cnd is true.
ConditionallyAdd(cnd func() bool, key string, resolver Resolver) BuildVariablesBuilder
// Build a build variables instance.
Build() BuildVariables
}

// NewBuildVariablesBuilder creates a new BuildVariablesBuilder.
func NewBuildVariablesBuilder() BuildVariablesBuilder {
return &defaultBuilder{
bv: make(BuildVariables),
}
}

type defaultBuilder struct {
bv BuildVariables
}

func (d defaultBuilder) Add(key string, resolver Resolver) BuildVariablesBuilder {
d.bv[key] = resolver
return d
}

func (d defaultBuilder) ConditionallyAdd(cnd func() bool, key string, resolver Resolver) BuildVariablesBuilder {
if cnd() {
return d.Add(key, resolver)
}
return d
}

func (d defaultBuilder) Build() BuildVariables {
return d.bv
}
8 changes: 6 additions & 2 deletions config/types.go
Expand Up @@ -41,6 +41,10 @@ type Config struct {
// Checks holds a list of checks to perform.
Checks []Task

// BuildVariables holds extra list of variables to be passed to Golang's
// ldflags.
BuildVariables

// Overrides holds a list of overrides of this configuration.
Overrides []Configurator

Expand Down Expand Up @@ -110,8 +114,8 @@ type Version struct {

// Metadata holds additional contextual information.
type Metadata struct {
Name string
BuildVariables map[string]Resolver
Name string
BuildVariables
}

func (m Metadata) GetName() string {
Expand Down
11 changes: 7 additions & 4 deletions pkg/artifact/binary.go
Expand Up @@ -81,11 +81,14 @@ func (b Binary) buildForPlatform(
args := []string{
"build",
}
version := config.Actual().Version
if version != nil || len(b.BuildVariables) > 0 {
c := config.Actual()
if c.Version != nil || len(c.BuildVariables) > 0 || len(b.BuildVariables) > 0 {
builder := ldflags.NewBuilder()
if version != nil {
builder.Add(version.Path, version.Resolver)
for key, resolver := range c.BuildVariables {
builder.Add(key, resolver)
}
if c.Version != nil {
builder.Add(c.Version.Path, c.Version.Resolver)
}
for key, resolver := range b.BuildVariables {
builder.Add(key, resolver)
Expand Down
11 changes: 7 additions & 4 deletions pkg/artifact/ko_build.go
Expand Up @@ -69,12 +69,15 @@ func (kb KoBuilder) Build(artifact config.Artifact, notifier config.Notifier) co
}

func fillInLdflags(bo *options.BuildOptions, importPath string, image Image) {
version := config.Actual().Version
c := config.Actual()
args := make([]string, 0)
if version != nil || len(image.BuildVariables) > 0 {
if c.Version != nil || len(c.BuildVariables) > 0 || len(image.BuildVariables) > 0 {
builder := ldflags.NewBuilder()
if version != nil {
builder.Add(version.Path, version.Resolver)
for key, resolver := range c.BuildVariables {
builder.Add(key, resolver)
}
if c.Version != nil {
builder.Add(c.Version.Path, c.Version.Resolver)
}
for key, resolver := range image.BuildVariables {
builder.Add(key, resolver)
Expand Down
19 changes: 12 additions & 7 deletions testing.go
Expand Up @@ -24,17 +24,22 @@ func Test() {
"test", "-v", "-covermode=count",
fmt.Sprintf("-coverprofile=%s/coverage.out", files.BuildDir()),
}
args = append(appendVersion(args), "./...")
args = append(appendBuildVariables(args), "./...")
err := sh.RunV(cmd, args...)
t.End(err)
}

func appendVersion(args []string) []string {
version := config.Actual().Version
if version != nil {
args = ldflags.NewBuilder().
Add(version.Path, version.Resolver).
BuildOnto(args)
func appendBuildVariables(args []string) []string {
c := config.Actual()
if c.Version != nil || len(c.BuildVariables) > 0 {
builder := ldflags.NewBuilder()
if c.Version != nil {
builder.Add(c.Version.Path, c.Version.Resolver)
}
for key, resolver := range c.BuildVariables {
builder.Add(key, resolver)
}
args = builder.BuildOnto(args)
}
return args
}
25 changes: 22 additions & 3 deletions tests/example/Magefile.go
Expand Up @@ -4,6 +4,8 @@
package main

import (
"os"
"strings"

// mage:import
"github.com/wavesoftware/go-magetasks"
Expand Down Expand Up @@ -33,9 +35,10 @@ func init() { //nolint:gochecknoinits
other := artifact.Binary{
Metadata: config.Metadata{
Name: "other",
BuildVariables: map[string]config.Resolver{
metadata.ImagePath(): artifact.ImageReferenceOf(dummy),
},
BuildVariables: config.NewBuildVariablesBuilder().
ConditionallyAdd(referenceImageByDigest,
metadata.ImagePath(), artifact.ImageReferenceOf(dummy)).
Build(),
},
Platforms: []artifact.Platform{
{OS: platform.Linux, Architecture: platform.AMD64},
Expand All @@ -57,6 +60,22 @@ func init() { //nolint:gochecknoinits
checks.Revive(),
checks.Staticcheck(),
},
BuildVariables: map[string]config.Resolver{
metadata.ImageBasenamePath(): func() string {
return os.Getenv("IMAGE_BASENAME")
},
},
Overrides: overrides.List,
})
}

func skipImageReference() bool {
if val, ok := os.LookupEnv("SKIP_IMAGE_REFERENCE"); ok {
return strings.ToLower(val) == "true"
}
return false
}

func referenceImageByDigest() bool {
return !skipImageReference()
}
2 changes: 1 addition & 1 deletion tests/example/cmd/other/main.go
Expand Up @@ -8,5 +8,5 @@ import (

func main() {
log.Printf("Version: %s\n", metadata.Version)
log.Printf("Image: %s\n", metadata.Image)
log.Printf("Image: %s\n", metadata.ResolveImage())
}
29 changes: 25 additions & 4 deletions tests/example/pkg/metadata/image.go
@@ -1,10 +1,31 @@
package metadata

// Image holds information about companion image reference.
//goland:noinspection GoUnusedGlobalVariable
var Image = ""
import "fmt"

var (
// Image holds information about companion image reference.
Image = "" //nolint:gochecknoglobals
// ImageBasename holds a basename of a image, so the development reference
// could be built from it.
ImageBasename = "" //nolint:gochecknoglobals
)

// ResolveImage will try to resolve the image reference from set values. If
// Image is given it will be used, otherwise the ImageBasename and Version will
// be used.
func ResolveImage() string {
if Image == "" {
return fmt.Sprintf("%s:%s", ImageBasename, Version)
}
return Image
}

// ImagePath return a path to the image variable.
func ImagePath() string {
return "github.com/wavesoftware/go-magetasks/tests/example/pkg/metadata.Image"
return importPath("Image")
}

// ImageBasenamePath return a path to the image basename variable.
func ImageBasenamePath() string {
return importPath("ImageBasename")
}
18 changes: 18 additions & 0 deletions tests/example/pkg/metadata/reflect.go
@@ -0,0 +1,18 @@
package metadata

import (
"fmt"
"reflect"
)

type marker struct{}

func importPath(variable string) string {
m := marker{}
p := findPackageForType(m)
return fmt.Sprintf("%s.%s", p, variable)
}

func findPackageForType(any interface{}) string {
return reflect.TypeOf(any).PkgPath()
}
2 changes: 1 addition & 1 deletion tests/example/pkg/metadata/version.go
Expand Up @@ -5,5 +5,5 @@ var Version = "0.0.0"

// VersionPath return a path to the version variable.
func VersionPath() string {
return "github.com/wavesoftware/go-magetasks/tests/example/pkg/metadata.Version"
return importPath("Version")
}

0 comments on commit 344999d

Please sign in to comment.