From 72329ab722698481a2989a41958558a687ffbbb6 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Thu, 23 Jun 2022 23:36:19 -0300 Subject: [PATCH] refactor: improve handling of extra fields in artifacts (#3191) * refactor: improve handling of extra fields in artifacts Backporting from pro: with this we can parse the artifacts list from json into the context and use them again. Signed-off-by: Carlos A Becker * fix: tests Signed-off-by: Carlos A Becker * test: fix Signed-off-by: Carlos A Becker --- internal/artifact/artifact.go | 52 ++++++++++++---- internal/artifact/artifact_test.go | 62 +++++++++++++++---- internal/pipe/archive/archive.go | 2 +- internal/pipe/archive/archive_test.go | 20 +++--- internal/pipe/aur/aur.go | 11 ++-- internal/pipe/brew/brew.go | 10 +-- internal/pipe/docker/docker.go | 6 +- internal/pipe/gofish/gofish.go | 11 ++-- internal/pipe/krew/krew.go | 9 ++- internal/pipe/nfpm/nfpm_test.go | 12 ++-- internal/pipe/scoop/scoop.go | 26 +++++--- internal/pipe/snapcraft/snapcraft.go | 2 +- .../universalbinary/universalbinary_test.go | 4 +- internal/tmpl/tmpl.go | 6 +- 14 files changed, 159 insertions(+), 74 deletions(-) diff --git a/internal/artifact/artifact.go b/internal/artifact/artifact.go index 91c48a696..16ed3d0bd 100644 --- a/internal/artifact/artifact.go +++ b/internal/artifact/artifact.go @@ -3,6 +3,7 @@ package artifact // nolint: gosec import ( + "bytes" "crypto/md5" "crypto/sha1" "crypto/sha256" @@ -125,10 +126,10 @@ const ( ) // Extras represents the extra fields in an artifact. -type Extras map[string]interface{} +type Extras map[string]any func (e Extras) MarshalJSON() ([]byte, error) { - m := map[string]interface{}{} + m := map[string]any{} for k, v := range e { if k == ExtraRefresh { // refresh is a func, so we can't serialize it. @@ -157,13 +158,42 @@ func (a Artifact) String() string { return a.Name } +// Extra tries to get the extra field with the given name, returning either +// its value, the default value for its type, or an error. +// +// If the extra value cannot be cast into the given type, it'll try to convert +// it to JSON and unmarshal it into the correct type after. +// +// If that fails as well, it'll error. +func Extra[T any](a Artifact, key string) (T, error) { + ex := a.Extra[key] + if ex == nil { + return *(new(T)), nil + } + + t, ok := ex.(T) + if ok { + return t, nil + } + + bts, err := json.Marshal(ex) + if err != nil { + return t, err + } + + decoder := json.NewDecoder(bytes.NewReader(bts)) + decoder.DisallowUnknownFields() + err = decoder.Decode(&t) + return t, err +} + // ExtraOr returns the Extra field with the given key or the or value specified // if it is nil. -func (a Artifact) ExtraOr(key string, or interface{}) interface{} { +func ExtraOr[T any](a Artifact, key string, or T) T { if a.Extra[key] == nil { return or } - return a.Extra[key] + return a.Extra[key].(T) } // Checksum calculates the checksum of the artifact. @@ -210,11 +240,7 @@ func (a Artifact) Refresh() error { if a.Type != Checksum { return nil } - fn, ok := a.ExtraOr(ExtraRefresh, noRefresh).(func() error) - if !ok { - return nil - } - if err := fn(); err != nil { + if err := ExtraOr(a, ExtraRefresh, noRefresh)(); err != nil { return fmt.Errorf("failed to refresh %q: %w", a.Name, err) } return nil @@ -222,12 +248,12 @@ func (a Artifact) Refresh() error { // ID returns the artifact ID if it exists, empty otherwise. func (a Artifact) ID() string { - return a.ExtraOr(ExtraID, "").(string) + return ExtraOr(a, ExtraID, "") } // Format returns the artifact Format if it exists, empty otherwise. func (a Artifact) Format() string { - return a.ExtraOr(ExtraFormat, "").(string) + return ExtraOr(a, ExtraFormat, "") } // Artifacts is a list of artifacts. @@ -318,7 +344,7 @@ type Filter func(a *Artifact) bool // // This is useful specially on homebrew et al, where you'll want to use only either the single-arch or the universal binaries. func OnlyReplacingUnibins(a *Artifact) bool { - return a.ExtraOr(ExtraReplaces, true).(bool) + return ExtraOr(*a, ExtraReplaces, true) } // ByGoos is a predefined filter that filters by the given goos. @@ -389,7 +415,7 @@ func ByExt(exts ...string) Filter { for _, ext := range exts { ext := ext filters = append(filters, func(a *Artifact) bool { - return a.ExtraOr(ExtraExt, "") == ext + return ExtraOr(*a, ExtraExt, "") == ext }) } return Or(filters...) diff --git a/internal/artifact/artifact_test.go b/internal/artifact/artifact_test.go index 0f4860c26..c3e3452ca 100644 --- a/internal/artifact/artifact_test.go +++ b/internal/artifact/artifact_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/goreleaser/goreleaser/internal/golden" + "github.com/goreleaser/goreleaser/pkg/config" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/sync/errgroup" @@ -359,14 +360,58 @@ func TestInvalidAlgorithm(t *testing.T) { require.Empty(t, sum) } -func TestExtraOr(t *testing.T) { - a := &Artifact{ +func TestExtra(t *testing.T) { + a := Artifact{ Extra: map[string]interface{}{ "Foo": "foo", + "docker": config.Docker{ + ID: "id", + Use: "docker", + }, + "fail-plz": config.Homebrew{ + Plist: "aaaa", + }, + "unsupported": func() {}, + "binaries": []string{"foo", "bar"}, }, } - require.Equal(t, "foo", a.ExtraOr("Foo", "bar")) - require.Equal(t, "bar", a.ExtraOr("Foobar", "bar")) + + t.Run("string", func(t *testing.T) { + foo, err := Extra[string](a, "Foo") + require.NoError(t, err) + require.Equal(t, "foo", foo) + require.Equal(t, "foo", ExtraOr(a, "Foo", "bar")) + }) + + t.Run("missing field", func(t *testing.T) { + bar, err := Extra[string](a, "Foobar") + require.NoError(t, err) + require.Equal(t, "", bar) + require.Equal(t, "bar", ExtraOr(a, "Foobar", "bar")) + }) + + t.Run("complex", func(t *testing.T) { + docker, err := Extra[config.Docker](a, "docker") + require.NoError(t, err) + require.Equal(t, "id", docker.ID) + }) + + t.Run("array", func(t *testing.T) { + binaries, err := Extra[[]string](a, "binaries") + require.NoError(t, err) + require.Equal(t, []string{"foo", "bar"}, binaries) + require.Equal(t, []string{"foo", "bar"}, ExtraOr(a, "binaries", []string{})) + }) + + t.Run("unmarshal error", func(t *testing.T) { + _, err := Extra[config.Docker](a, "fail-plz") + require.EqualError(t, err, "json: unknown field \"Name\"") + }) + + t.Run("marshal error", func(t *testing.T) { + _, err := Extra[config.Docker](a, "unsupported") + require.EqualError(t, err, "json: unsupported type: func()") + }) } func TestByIDs(t *testing.T) { @@ -508,15 +553,6 @@ func TestRefresher(t *testing.T) { }, }, }) - artifacts.Add(&Artifact{ - Name: "invalid", - Type: Checksum, - Extra: map[string]interface{}{ - "Refresh": func() { - t.Fatalf("should not have been called") - }, - }, - }) artifacts.Add(&Artifact{ Name: "no refresh", Type: Checksum, diff --git a/internal/pipe/archive/archive.go b/internal/pipe/archive/archive.go index c87ff6ffa..50199b23d 100644 --- a/internal/pipe/archive/archive.go +++ b/internal/pipe/archive/archive.go @@ -236,7 +236,7 @@ func skip(ctx *context.Context, archive config.Archive, binaries []*artifact.Art if err != nil { return err } - finalName := name + binary.ExtraOr(artifact.ExtraExt, "").(string) + finalName := name + artifact.ExtraOr(*binary, artifact.ExtraExt, "") log.WithField("binary", binary.Name). WithField("name", finalName). Info("skip archiving") diff --git a/internal/pipe/archive/archive_test.go b/internal/pipe/archive/archive_test.go index fa3685f17..373d3e958 100644 --- a/internal/pipe/archive/archive_test.go +++ b/internal/pipe/archive/archive_test.go @@ -175,8 +175,8 @@ func TestRunPipe(t *testing.T) { expectBin += ".exe" } require.Equal(t, "myid", arch.ID(), "all archives must have the archive ID set") - require.Equal(t, []string{expectBin}, arch.ExtraOr(artifact.ExtraBinaries, []string{}).([]string)) - require.Equal(t, "", arch.ExtraOr(artifact.ExtraBinary, "").(string)) + require.Equal(t, []string{expectBin}, artifact.ExtraOr(*arch, artifact.ExtraBinaries, []string{})) + require.Equal(t, "", artifact.ExtraOr(*arch, artifact.ExtraBinary, "")) } require.Len(t, archives, 7) // TODO: should verify the artifact fields here too @@ -426,14 +426,14 @@ func TestRunPipeBinary(t *testing.T) { artifact.ByGoos("darwin"), artifact.ByGoarch("all"), )).List()[0] - require.True(t, darwinUniversal.ExtraOr(artifact.ExtraReplaces, false).(bool)) + require.True(t, artifact.ExtraOr(*darwinUniversal, artifact.ExtraReplaces, false)) windows := binaries.Filter(artifact.ByGoos("windows")).List()[0] require.Equal(t, "mybin_0.0.1_darwin_amd64", darwinThin.Name) - require.Equal(t, "mybin", darwinThin.ExtraOr(artifact.ExtraBinary, "")) + require.Equal(t, "mybin", artifact.ExtraOr(*darwinThin, artifact.ExtraBinary, "")) require.Equal(t, "myunibin_0.0.1_darwin_all", darwinUniversal.Name) - require.Equal(t, "myunibin", darwinUniversal.ExtraOr(artifact.ExtraBinary, "")) + require.Equal(t, "myunibin", artifact.ExtraOr(*darwinUniversal, artifact.ExtraBinary, "")) require.Equal(t, "mybin_0.0.1_windows_amd64.exe", windows.Name) - require.Equal(t, "mybin.exe", windows.ExtraOr(artifact.ExtraBinary, "")) + require.Equal(t, "mybin.exe", artifact.ExtraOr(*windows, artifact.ExtraBinary, "")) } func TestRunPipeDistRemoved(t *testing.T) { @@ -659,7 +659,7 @@ func TestRunPipeWrap(t *testing.T) { archives := ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableArchive)).List() require.Len(t, archives, 1) - require.Equal(t, "foo_macOS", archives[0].ExtraOr(artifact.ExtraWrappedIn, "")) + require.Equal(t, "foo_macOS", artifact.ExtraOr(*archives[0], artifact.ExtraWrappedIn, "")) // Check archive contents f, err = os.Open(filepath.Join(dist, "foo.tar.gz")) @@ -817,13 +817,13 @@ func TestBinaryOverride(t *testing.T) { darwin := archives.Filter(artifact.ByGoos("darwin")).List()[0] require.Equal(t, "foobar_0.0.1_darwin_amd64."+format, darwin.Name) require.Equal(t, format, darwin.Format()) - require.Empty(t, darwin.ExtraOr(artifact.ExtraWrappedIn, "")) + require.Empty(t, artifact.ExtraOr(*darwin, artifact.ExtraWrappedIn, "")) archives = ctx.Artifacts.Filter(artifact.ByType(artifact.UploadableBinary)) windows := archives.Filter(artifact.ByGoos("windows")).List()[0] require.Equal(t, "foobar_0.0.1_windows_amd64.exe", windows.Name) - require.Empty(t, windows.ExtraOr(artifact.ExtraWrappedIn, "")) - require.Equal(t, "mybin.exe", windows.ExtraOr(artifact.ExtraBinary, "")) + require.Empty(t, artifact.ExtraOr(*windows, artifact.ExtraWrappedIn, "")) + require.Equal(t, "mybin.exe", artifact.ExtraOr(*windows, artifact.ExtraBinary, "")) }) } } diff --git a/internal/pipe/aur/aur.go b/internal/pipe/aur/aur.go index 0abcf8e86..3dff67d8d 100644 --- a/internal/pipe/aur/aur.go +++ b/internal/pipe/aur/aur.go @@ -137,10 +137,10 @@ func doRun(ctx *context.Context, aur config.AUR, cl client.Client) error { switch art.Type { case artifact.UploadableBinary: name := art.Name - bin := art.ExtraOr(artifact.ExtraBinary, art.Name).(string) + bin := artifact.ExtraOr(*art, artifact.ExtraBinary, art.Name) pkg = fmt.Sprintf(`install -Dm755 "./%s "${pkgdir}/usr/bin/%s"`, name, bin) case artifact.UploadableArchive: - for _, bin := range art.ExtraOr(artifact.ExtraBinaries, []string{}).([]string) { + for _, bin := range artifact.ExtraOr(*art, artifact.ExtraBinaries, []string{}) { pkg = fmt.Sprintf(`install -Dm755 "./%s" "${pkgdir}/usr/bin/%[1]s"`, bin) break } @@ -318,7 +318,7 @@ func dataFor(ctx *context.Context, cfg config.AUR, cl client.Client, artifacts [ DownloadURL: url, SHA256: sum, Arch: toPkgBuildArch(art.Goarch + art.Goarm), - Format: art.ExtraOr(artifact.ExtraFormat, "").(string), + Format: artifact.ExtraOr(*art, artifact.ExtraFormat, ""), } result.ReleasePackages = append(result.ReleasePackages, releasePackage) result.Arches = append(result.Arches, releasePackage.Arch) @@ -353,7 +353,10 @@ func (Pipe) Publish(ctx *context.Context) error { } func doPublish(ctx *context.Context, pkgs []*artifact.Artifact) error { - cfg := pkgs[0].Extra[aurExtra].(config.AUR) + cfg, err := artifact.Extra[config.AUR](*pkgs[0], aurExtra) + if err != nil { + return err + } if strings.TrimSpace(cfg.SkipUpload) == "true" { return pipe.Skip("aur.skip_upload is set") diff --git a/internal/pipe/brew/brew.go b/internal/pipe/brew/brew.go index 7bc320654..6a483525d 100644 --- a/internal/pipe/brew/brew.go +++ b/internal/pipe/brew/brew.go @@ -108,8 +108,10 @@ func publishAll(ctx *context.Context, cli client.Client) error { } func doPublish(ctx *context.Context, formula *artifact.Artifact, cl client.Client) error { - brew := formula.Extra[brewConfigExtra].(config.Homebrew) - var err error + brew, err := artifact.Extra[config.Homebrew](*formula, brewConfigExtra) + if err != nil { + return err + } cl, err = client.NewIfToken(ctx, cl, brew.Tap.Token) if err != nil { return err @@ -295,10 +297,10 @@ func installs(cfg config.Homebrew, art *artifact.Artifact) []string { switch art.Type { case artifact.UploadableBinary: name := art.Name - bin := art.ExtraOr(artifact.ExtraBinary, art.Name).(string) + bin := artifact.ExtraOr(*art, artifact.ExtraBinary, art.Name) install[fmt.Sprintf("bin.install %q => %q", name, bin)] = true case artifact.UploadableArchive: - for _, bin := range art.ExtraOr(artifact.ExtraBinaries, []string{}).([]string) { + for _, bin := range artifact.ExtraOr(*art, artifact.ExtraBinaries, []string{}) { install[fmt.Sprintf("bin.install %q", bin)] = true } } diff --git a/internal/pipe/docker/docker.go b/internal/pipe/docker/docker.go index 25c414f65..5dd7d9921 100644 --- a/internal/pipe/docker/docker.go +++ b/internal/pipe/docker/docker.go @@ -242,7 +242,11 @@ func processBuildFlagTemplates(ctx *context.Context, docker config.Docker) ([]st func dockerPush(ctx *context.Context, image *artifact.Artifact) error { log.WithField("image", image.Name).Info("pushing") - docker := image.Extra[dockerConfigExtra].(config.Docker) + docker, err := artifact.Extra[config.Docker](*image, dockerConfigExtra) + if err != nil { + return err + } + if strings.TrimSpace(docker.SkipPush) == "true" { return pipe.Skip("docker.skip_push is set: " + image.Name) } diff --git a/internal/pipe/gofish/gofish.go b/internal/pipe/gofish/gofish.go index d43c6742d..03cfa6bda 100644 --- a/internal/pipe/gofish/gofish.go +++ b/internal/pipe/gofish/gofish.go @@ -229,7 +229,7 @@ func dataFor(ctx *context.Context, cfg config.GoFish, cl client.Client, artifact } switch art.Type { case artifact.UploadableArchive: - for _, bin := range art.ExtraOr(artifact.ExtraBinaries, []string{}).([]string) { + for _, bin := range artifact.ExtraOr(*art, artifact.ExtraBinaries, []string{}) { releasePackage.Binaries = append(releasePackage.Binaries, binary{ Name: bin, Target: bin, @@ -238,7 +238,7 @@ func dataFor(ctx *context.Context, cfg config.GoFish, cl client.Client, artifact case artifact.UploadableBinary: releasePackage.Binaries = append(releasePackage.Binaries, binary{ Name: art.Name, - Target: art.ExtraOr(artifact.ExtraBinary, art.Name).(string), + Target: artifact.ExtraOr(*art, artifact.ExtraBinary, art.Name), }) } result.ReleasePackages = append(result.ReleasePackages, releasePackage) @@ -273,8 +273,11 @@ func publishAll(ctx *context.Context, cli client.Client) error { } func doPublish(ctx *context.Context, food *artifact.Artifact, cl client.Client) error { - rig := food.Extra[goFishConfigExtra].(config.GoFish) - var err error + rig, err := artifact.Extra[config.GoFish](*food, goFishConfigExtra) + if err != nil { + return err + } + cl, err = client.NewIfToken(ctx, cl, rig.Rig.Token) if err != nil { return err diff --git a/internal/pipe/krew/krew.go b/internal/pipe/krew/krew.go index ed3ebbc02..71f22f96d 100644 --- a/internal/pipe/krew/krew.go +++ b/internal/pipe/krew/krew.go @@ -233,7 +233,7 @@ func manifestFor(ctx *context.Context, cfg config.Krew, cl client.Client, artifa } for _, arch := range goarch { - bins := art.ExtraOr(artifact.ExtraBinaries, []string{}).([]string) + bins := artifact.ExtraOr(*art, artifact.ExtraBinaries, []string{}) if len(bins) != 1 { return result, fmt.Errorf("krew: only one binary per archive allowed, got %d on %q", len(bins), art.Name) } @@ -283,8 +283,11 @@ func publishAll(ctx *context.Context, cli client.Client) error { } func doPublish(ctx *context.Context, manifest *artifact.Artifact, cl client.Client) error { - cfg := manifest.Extra[krewConfigExtra].(config.Krew) - var err error + cfg, err := artifact.Extra[config.Krew](*manifest, krewConfigExtra) + if err != nil { + return err + } + cl, err = client.NewIfToken(ctx, cl, cfg.Index.Token) if err != nil { return err diff --git a/internal/pipe/nfpm/nfpm_test.go b/internal/pipe/nfpm/nfpm_test.go index 5abc644ae..26c8b62fb 100644 --- a/internal/pipe/nfpm/nfpm_test.go +++ b/internal/pipe/nfpm/nfpm_test.go @@ -242,7 +242,7 @@ func TestRunPipe(t *testing.T) { "./testdata/folder", "./testdata/testfile-" + pkg.Goarch + pkg.Goamd64 + pkg.Goarm + pkg.Gomips + ".txt", binPath, - }, sources(pkg.ExtraOr(extraFiles, files.Contents{}).(files.Contents))) + }, sources(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) require.ElementsMatch(t, []string{ "/var/log/foobar", "/usr/share/testfile.txt", @@ -253,7 +253,7 @@ func TestRunPipe(t *testing.T) { "/etc/nope3_mybin.conf", "/etc/folder", "/usr/bin/subdir/mybin", - }, destinations(pkg.ExtraOr(extraFiles, files.Contents{}).(files.Contents))) + }, destinations(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) } require.Len(t, ctx.Config.NFPMs[0].Contents, 8, "should not modify the config file list") } @@ -389,8 +389,8 @@ func TestRunPipeConventionalNameTemplate(t *testing.T) { "foo_1.0.0_x86_64v4.apk", }, pkg.Name, "package name is not expected") require.Equal(t, "someid", pkg.ID()) - require.ElementsMatch(t, []string{binPath}, sources(pkg.ExtraOr(extraFiles, files.Contents{}).(files.Contents))) - require.ElementsMatch(t, []string{"/usr/bin/subdir/mybin"}, destinations(pkg.ExtraOr(extraFiles, files.Contents{}).(files.Contents))) + require.ElementsMatch(t, []string{binPath}, sources(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) + require.ElementsMatch(t, []string{"/usr/bin/subdir/mybin"}, destinations(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) } } @@ -1207,7 +1207,7 @@ func TestMeta(t *testing.T) { "/usr/share/testfile.txt", "/etc/nope.conf", "/etc/nope-rpm.conf", - }, destinations(pkg.ExtraOr(extraFiles, files.Contents{}).(files.Contents))) + }, destinations(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) } require.Len(t, ctx.Config.NFPMs[0].Contents, 4, "should not modify the config file list") @@ -1355,7 +1355,7 @@ func TestBinDirTemplating(t *testing.T) { // the final binary should contain the evaluated bindir (after template eval) require.ElementsMatch(t, []string{ "/usr/lib/pro/nagios/plugins/subdir/mybin", - }, destinations(pkg.ExtraOr(extraFiles, files.Contents{}).(files.Contents))) + }, destinations(artifact.ExtraOr(*pkg, extraFiles, files.Contents{}))) } } diff --git a/internal/pipe/scoop/scoop.go b/internal/pipe/scoop/scoop.go index 2dcd9881b..284d19aa4 100644 --- a/internal/pipe/scoop/scoop.go +++ b/internal/pipe/scoop/scoop.go @@ -120,9 +120,12 @@ func doPublish(ctx *context.Context, cl client.Client) error { } manifest := manifests[0] - scoop := manifest.Extra[scoopConfigExtra].(config.Scoop) - var err error + scoop, err := artifact.Extra[config.Scoop](*manifest, scoopConfigExtra) + if err != nil { + return err + } + cl, err = client.NewIfToken(ctx, cl, scoop.Bucket.Token) if err != nil { return err @@ -251,9 +254,14 @@ func dataFor(ctx *context.Context, cl client.Client, artifacts []*artifact.Artif "sum": sum, }).Debug("scoop url templating") + binaries, err := binaries(*artifact) + if err != nil { + return manifest, err + } + manifest.Architecture[arch] = Resource{ URL: url, - Bin: binaries(artifact), + Bin: binaries, Hash: sum, } } @@ -261,12 +269,16 @@ func dataFor(ctx *context.Context, cl client.Client, artifacts []*artifact.Artif return manifest, nil } -func binaries(a *artifact.Artifact) []string { +func binaries(a artifact.Artifact) ([]string, error) { // nolint: prealloc var bins []string - wrap := a.ExtraOr(artifact.ExtraWrappedIn, "").(string) - for _, b := range a.ExtraOr(artifact.ExtraBuilds, []*artifact.Artifact{}).([]*artifact.Artifact) { + wrap := artifact.ExtraOr(a, artifact.ExtraWrappedIn, "") + builds, err := artifact.Extra[[]artifact.Artifact](a, artifact.ExtraBuilds) + if err != nil { + return nil, err + } + for _, b := range builds { bins = append(bins, filepath.Join(wrap, b.Name)) } - return bins + return bins, nil } diff --git a/internal/pipe/snapcraft/snapcraft.go b/internal/pipe/snapcraft/snapcraft.go index 67a3beb11..3c44d2f48 100644 --- a/internal/pipe/snapcraft/snapcraft.go +++ b/internal/pipe/snapcraft/snapcraft.go @@ -418,7 +418,7 @@ const ( func push(ctx *context.Context, snap *artifact.Artifact) error { log := log.WithField("snap", snap.Name) - releases := snap.Extra[releasesExtra].([]string) + releases := artifact.ExtraOr(*snap, releasesExtra, []string{}) /* #nosec */ cmd := exec.CommandContext(ctx, "snapcraft", "upload", "--release="+strings.Join(releases, ","), snap.Path) log.WithField("args", cmd.Args).Info("pushing snap") diff --git a/internal/pipe/universalbinary/universalbinary_test.go b/internal/pipe/universalbinary/universalbinary_test.go index 719a1d7b1..7961a2078 100644 --- a/internal/pipe/universalbinary/universalbinary_test.go +++ b/internal/pipe/universalbinary/universalbinary_test.go @@ -255,7 +255,7 @@ func TestRun(t *testing.T) { unis := ctx1.Artifacts.Filter(artifact.ByType(artifact.UniversalBinary)).List() require.Len(t, unis, 1) checkUniversalBinary(t, unis[0]) - require.True(t, unis[0].Extra[artifact.ExtraReplaces].(bool)) + require.True(t, artifact.ExtraOr(*unis[0], artifact.ExtraReplaces, false)) }) t.Run("keeping", func(t *testing.T) { @@ -264,7 +264,7 @@ func TestRun(t *testing.T) { unis := ctx2.Artifacts.Filter(artifact.ByType(artifact.UniversalBinary)).List() require.Len(t, unis, 1) checkUniversalBinary(t, unis[0]) - require.False(t, unis[0].Extra[artifact.ExtraReplaces].(bool)) + require.False(t, artifact.ExtraOr(*unis[0], artifact.ExtraReplaces, true)) }) t.Run("bad template", func(t *testing.T) { diff --git a/internal/tmpl/tmpl.go b/internal/tmpl/tmpl.go index c41b569a3..6000db491 100644 --- a/internal/tmpl/tmpl.go +++ b/internal/tmpl/tmpl.go @@ -139,16 +139,12 @@ func (t *Template) WithExtraFields(f Fields) *Template { // WithArtifact populates Fields from the artifact and replacements. func (t *Template) WithArtifact(a *artifact.Artifact, replacements map[string]string) *Template { - bin := a.Extra[binary] - if bin == nil { - bin = t.fields[projectName] - } t.fields[osKey] = replace(replacements, a.Goos) t.fields[arch] = replace(replacements, a.Goarch) t.fields[arm] = replace(replacements, a.Goarm) t.fields[mips] = replace(replacements, a.Gomips) t.fields[amd64] = replace(replacements, a.Goamd64) - t.fields[binary] = bin.(string) + t.fields[binary] = artifact.ExtraOr(*a, binary, t.fields[projectName].(string)) t.fields[artifactName] = a.Name t.fields[artifactPath] = a.Path return t