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

Commit

Permalink
LDflags for images works
Browse files Browse the repository at this point in the history
  • Loading branch information
cardil committed Oct 13, 2021
1 parent 63afe71 commit 8dddcc9
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 36 deletions.
11 changes: 9 additions & 2 deletions config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ type Publisher interface {
// Resolver is a func that resolves to a string.
type Resolver func() string

// StaticResolver can be used to create a Resolver from static data.
func StaticResolver(value string) Resolver {
return func() string {
return value
}
}

// MageTag holds a mage tag.
type MageTag struct {
Color color.Attribute
Expand Down Expand Up @@ -103,8 +110,8 @@ type Version struct {

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

func (m Metadata) GetName() string {
Expand Down
6 changes: 3 additions & 3 deletions pkg/artifact/binary.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ func (b Binary) buildForPlatform(
"build",
}
version := config.Actual().Version
if version != nil || len(b.Args) > 0 {
if version != nil || len(b.BuildVariables) > 0 {
builder := ldflags.NewBuilder()
if version != nil {
builder.Add(version.Path, version.Resolver)
}
for key, resolver := range b.Args {
for key, resolver := range b.BuildVariables {
builder.Add(key, resolver)
}
args = builder.Build(args)
args = builder.BuildOnto(args)
}
binary := fullBinaryName(platform, name)
args = append(args, "-o", binary, fullBinaryDirectory(name))
Expand Down
1 change: 1 addition & 0 deletions pkg/artifact/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const imageReferenceKey = "oci.image.reference"
// Image is an OCI image that will be built from a binary.
type Image struct {
config.Metadata
Labels map[string]config.Resolver
Architectures []platform.Architecture
}

Expand Down
58 changes: 53 additions & 5 deletions pkg/artifact/ko_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/google/ko/pkg/commands/options"
"github.com/wavesoftware/go-magetasks/config"
"github.com/wavesoftware/go-magetasks/pkg/files"
"github.com/wavesoftware/go-magetasks/pkg/ldflags"
"github.com/wavesoftware/go-magetasks/pkg/output/color"
"golang.org/x/mod/modfile"
)
Expand All @@ -38,13 +39,17 @@ func (kb KoBuilder) Build(artifact config.Artifact, notifier config.Notifier) co
if !ok {
return config.Result{Error: ErrInvalidArtifact}
}
bo := &options.BuildOptions{}
ctx := config.Actual().Context
builder, err := commands.NewBuilder(ctx, bo)
importPath, err := imageImportPath(image)
if err != nil {
return resultErrKoFailed(err)
}
importPath, err := imageImportPath(image)
bo := &options.BuildOptions{
Platform: buildPlatformString(image),
Labels: buildLabels(image, importPath),
}
fillInLdflags(bo, importPath, image)
ctx := config.Actual().Context
builder, err := commands.NewBuilder(ctx, bo)
if err != nil {
return resultErrKoFailed(err)
}
Expand All @@ -63,6 +68,49 @@ func (kb KoBuilder) Build(artifact config.Artifact, notifier config.Notifier) co
}}
}

func fillInLdflags(bo *options.BuildOptions, importPath string, image Image) {
version := config.Actual().Version
args := make([]string, 0)
if version != nil || len(image.BuildVariables) > 0 {
builder := ldflags.NewBuilder()
if version != nil {
builder.Add(version.Path, version.Resolver)
}
for key, resolver := range image.BuildVariables {
builder.Add(key, resolver)
}
args = builder.Build()
}
if len(args) > 0 {
bo.BuildConfigs = map[string]build.Config{
importPath: {
ID: "ldflags-config",
Ldflags: args,
},
}
}
}

func buildLabels(image Image, importPath string) []string {
labels := make([]string, 0, len(image.Labels))
if version := config.Actual().Version; version != nil {
labels = append(labels, fmt.Sprintf("version=%s", version.Resolver()))
}
labels = append(labels, fmt.Sprintf("%s=%s", koImportPath, importPath))
for key, resolver := range image.Labels {
labels = append(labels, fmt.Sprintf("%s=%s", key, resolver()))
}
return labels
}

func buildPlatformString(im Image) string {
platforms := make([]string, len(im.Architectures))
for i, architecture := range im.Architectures {
platforms[i] = fmt.Sprintf("linux/%s", architecture)
}
return strings.Join(platforms, ",")
}

func calculateImageReference(result build.Result, artifact config.Artifact) (name.Reference, error) {
kp := KoPublisher{}
po, err := kp.publishOptions()
Expand Down Expand Up @@ -99,7 +147,7 @@ func imageImportPath(image Image) (string, error) {
return "", err
}
importPath := rs.resolve(binDir)
if resolver, ok := image.Args[koImportPath]; ok {
if resolver, ok := image.Labels[koImportPath]; ok {
importPath = resolver()
}
return importPath, nil
Expand Down
6 changes: 3 additions & 3 deletions pkg/artifact/ko_publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ func (kp KoPublisher) publishOptions() (*options.PublishOptions, error) {
opts := &options.PublishOptions{
BaseImportPaths: true,
Push: true,
Tags: []string{
config.Actual().Version.Resolver(),
},
}
if version := config.Actual().Version; version != nil {
opts.Tags = []string{version.Resolver()}
}
if v, ok := os.LookupEnv(magetasksImageBasenameSeparator); ok {
opts.ImageNameSeparator = v
Expand Down
20 changes: 13 additions & 7 deletions pkg/ldflags/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import (
type Builder interface {
// Add a name and a resolver to the builder.
Add(name string, resolver config.Resolver) Builder
// Build onto the args.
Build(args []string) []string
// Build into slice args for ldflags.
Build() []string
// BuildOnto provided args.
BuildOnto(args []string) []string
}

// NewBuilder creates a new builder.
Expand All @@ -31,13 +33,17 @@ func (d *defaultBuilder) Add(name string, resolver config.Resolver) Builder {
return d
}

func (d *defaultBuilder) Build(args []string) []string {
if len(args) == 0 {
return args
}
func (d *defaultBuilder) Build() []string {
collected := make([]string, 0, len(d.resolvers))
if len(d.resolvers) == 0 {
return collected
}
for name, resolver := range d.resolvers {
collected = append(collected, fmt.Sprintf("-X %s=%s", name, resolver()))
}
return append(args, "-ldflags", strings.Join(collected, " "))
return collected
}

func (d *defaultBuilder) BuildOnto(args []string) []string {
return append(args, "-ldflags", strings.Join(d.Build(), " "))
}
2 changes: 1 addition & 1 deletion testing.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func appendVersion(args []string) []string {
if version != nil {
args = ldflags.NewBuilder().
Add(version.Path, version.Resolver).
Build(args)
BuildOnto(args)
}
return args
}
1 change: 1 addition & 0 deletions tests/example/.ko.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
defaultBaseImage: registry.access.redhat.com/ubi8/ubi-minimal
12 changes: 4 additions & 8 deletions tests/example/Magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@ var Default = magetasks.Build

func init() { //nolint:gochecknoinits
dummy := artifact.Image{
Metadata: config.Metadata{
Name: "dummy",
Args: map[string]config.Resolver{
"DESC": func() string {
return "A dummy image"
},
},
Metadata: config.Metadata{Name: "dummy"},
Labels: map[string]config.Resolver{
"description": config.StaticResolver("A dummy image description"),
},
Architectures: []platform.Architecture{
platform.AMD64, platform.ARM64, platform.S390X, platform.PPC64LE,
Expand All @@ -37,7 +33,7 @@ func init() { //nolint:gochecknoinits
other := artifact.Binary{
Metadata: config.Metadata{
Name: "other",
Args: map[string]config.Resolver{
BuildVariables: map[string]config.Resolver{
metadata.ImagePath(): artifact.ImageReferenceOf(dummy),
},
},
Expand Down
7 changes: 0 additions & 7 deletions tests/example/cmd/dummy/Containerfile

This file was deleted.

18 changes: 18 additions & 0 deletions tests/project_build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"
"os/exec"
"runtime"
"strings"
"testing"

"gotest.tools/v3/assert"
Expand All @@ -19,9 +20,26 @@ func TestProjectBuild(t *testing.T) {
func execCmd(tb testing.TB, dir, name string, args ...string) {
tb.Helper()
c := exec.Command(name, args...)
c.Env = env(func(e string) bool {
return e == "GOARCH" || e == "GOOS" || e == "GOARM"
})
c.Dir = dir
c.Stdout = os.Stdout
c.Stderr = os.Stderr
err := c.Run()
assert.NilError(tb, err)
}

func env(filter func(string) bool) []string {
ret := make([]string, 0, len(os.Environ()))
for _, e := range os.Environ() {
envPair := strings.SplitN(e, "=", 2)
key := envPair[0]
if filter(key) {
continue
}

ret = append(ret, e)
}
return ret
}

0 comments on commit 8dddcc9

Please sign in to comment.