Skip to content

Commit

Permalink
feat: meta archives
Browse files Browse the repository at this point in the history
adds support for creating meta archives

closes #3085

Signed-off-by: Carlos A Becker <caarlos0@gmail.com>
  • Loading branch information
caarlos0 committed May 10, 2022
1 parent 8ee53b6 commit dff42e1
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 26 deletions.
28 changes: 18 additions & 10 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
env:
- GO111MODULE=on

before:
hooks:
- go mod tidy
- ./scripts/completions.sh
- ./scripts/manpages.sh
# before:
# hooks:
# - go mod tidy
# - ./scripts/completions.sh
# - ./scripts/manpages.sh

snapshot:
name_template: '{{ incpatch .Version }}-next'
Expand All @@ -18,13 +18,13 @@ builds:
- CGO_ENABLED=0
goos:
- linux
- darwin
- windows
# - darwin
# - windows
goarch:
- "386"
# - "386"
- amd64
- arm
- arm64
# - arm
# - arm64
goarm:
- "7"
mod_timestamp: '{{ .CommitTimestamp }}'
Expand Down Expand Up @@ -140,6 +140,14 @@ archives:
- LICENSE.md
- completions/*
- manpages/*
- id: meta
files:
- README.md
- LICENSE.md
- completions/*
- manpages/*
name_template: meta_files
meta: true

brews:
- tap:
Expand Down
48 changes: 32 additions & 16 deletions internal/pipe/archive/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ func (Pipe) Run(ctx *context.Context) error {
g := semerrgroup.New(ctx.Parallelism)
for i, archive := range ctx.Config.Archives {
archive := archive
if archive.Meta {
return createMeta(ctx, archive)
}

filter := []artifact.Filter{artifact.Or(
artifact.ByType(artifact.Binary),
artifact.ByType(artifact.UniversalBinary),
Expand Down Expand Up @@ -120,11 +124,18 @@ func checkArtifacts(artifacts map[string][]*artifact.Artifact) error {
return ErrArchiveDifferentBinaryCount
}

func createMeta(ctx *context.Context, arch config.Archive) error {
return doCreate(ctx, arch, nil, arch.Format, tmpl.New(ctx))
}

func create(ctx *context.Context, arch config.Archive, binaries []*artifact.Artifact) error {
template := tmpl.New(ctx).WithArtifact(binaries[0], arch.Replacements)
format := packageFormat(arch, binaries[0].Goos)
folder, err := tmpl.New(ctx).
WithArtifact(binaries[0], arch.Replacements).
Apply(arch.NameTemplate)
return doCreate(ctx, arch, binaries, format, template)
}

func doCreate(ctx *context.Context, arch config.Archive, binaries []*artifact.Artifact, format string, template *tmpl.Template) error {
folder, err := template.Apply(arch.NameTemplate)
if err != nil {
return err
}
Expand All @@ -149,8 +160,6 @@ func create(ctx *context.Context, arch config.Archive, binaries []*artifact.Arti
log := log.WithField("archive", archivePath)
log.Info("creating")

template := tmpl.New(ctx).
WithArtifact(binaries[0], arch.Replacements)
wrap, err := template.Apply(wrapFolder(arch))
if err != nil {
return err
Expand All @@ -163,6 +172,9 @@ func create(ctx *context.Context, arch config.Archive, binaries []*artifact.Arti
if err != nil {
return fmt.Errorf("failed to find files to archive: %w", err)
}
if arch.Meta && len(files) == 0 {
return fmt.Errorf("no files found")
}
for _, f := range files {
if err = a.Add(f); err != nil {
return fmt.Errorf("failed to add: '%s' -> '%s': %w", f.Source, f.Destination, err)
Expand All @@ -178,24 +190,28 @@ func create(ctx *context.Context, arch config.Archive, binaries []*artifact.Arti
}
bins = append(bins, binary.Name)
}
ctx.Artifacts.Add(&artifact.Artifact{
Type: artifact.UploadableArchive,
Name: folder + "." + format,
Path: archivePath,
Goos: binaries[0].Goos,
Goarch: binaries[0].Goarch,
Goarm: binaries[0].Goarm,
Gomips: binaries[0].Gomips,
Goamd64: binaries[0].Goamd64,
art := &artifact.Artifact{
Type: artifact.UploadableArchive,
Name: folder + "." + format,
Path: archivePath,
Extra: map[string]interface{}{
artifact.ExtraBuilds: binaries,
artifact.ExtraID: arch.ID,
artifact.ExtraFormat: arch.Format,
artifact.ExtraWrappedIn: wrap,
artifact.ExtraBinaries: bins,
artifact.ExtraReplaces: binaries[0].Extra[artifact.ExtraReplaces],
},
})
}
if len(binaries) > 0 {
art.Goos = binaries[0].Goos
art.Goarch = binaries[0].Goarch
art.Goarm = binaries[0].Goarm
art.Gomips = binaries[0].Gomips
art.Goamd64 = binaries[0].Goamd64
art.Extra[artifact.ExtraReplaces] = binaries[0].Extra[artifact.ExtraReplaces]
}

ctx.Artifacts.Add(art)
return nil
}

Expand Down
71 changes: 71 additions & 0 deletions internal/pipe/archive/archive_meta_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package archive

import (
"path/filepath"
"testing"

"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/stretchr/testify/require"
)

func TestMeta(t *testing.T) {
t.Run("good", func(t *testing.T) {
dist := t.TempDir()
ctx := context.New(config.Project{
Dist: dist,
Archives: []config.Archive{
{
Meta: true,
NameTemplate: "foo",
Files: []config.File{
{Source: "testdata/**/*.txt"},
},
},
},
})

require.NoError(t, Pipe{}.Default(ctx))
require.NoError(t, Pipe{}.Run(ctx))
require.Equal(
t,
[]string{"testdata/a/a.txt", "testdata/a/b/a.txt", "testdata/a/b/c/d.txt"},
tarFiles(t, filepath.Join(dist, "foo.tar.gz")),
)
})

t.Run("bad tmpl", func(t *testing.T) {
dist := t.TempDir()
ctx := context.New(config.Project{
Dist: dist,
Archives: []config.Archive{
{
Meta: true,
NameTemplate: "foo{{.Os}}",
Files: []config.File{
{Source: "testdata/**/*.txt"},
},
},
},
})

require.NoError(t, Pipe{}.Default(ctx))
require.EqualError(t, Pipe{}.Run(ctx), `template: tmpl:1:5: executing "tmpl" at <.Os>: map has no entry for key "Os"`)
})

t.Run("no files", func(t *testing.T) {
dist := t.TempDir()
ctx := context.New(config.Project{
Dist: dist,
Archives: []config.Archive{
{
Meta: true,
NameTemplate: "foo",
},
},
})

require.NoError(t, Pipe{}.Default(ctx))
require.EqualError(t, Pipe{}.Run(ctx), `no files found`)
})
}
1 change: 1 addition & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ type Archive struct {
FormatOverrides []FormatOverride `yaml:"format_overrides,omitempty"`
WrapInDirectory string `yaml:"wrap_in_directory,omitempty"`
Files []File `yaml:"files,omitempty"`
Meta bool `yaml:"meta,omitempty"`
AllowDifferentBinaryCount bool `yaml:"allow_different_binary_count,omitempty"`
}

Expand Down
6 changes: 6 additions & 0 deletions www/docs/customization/archive.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ archives:
id: my-archive

# Builds reference which build instances should be archived in this archive.
# Default is empty, which includes all builds.
builds:
- default

Expand All @@ -24,6 +25,11 @@ archives:
# Default is `tar.gz`.
format: zip

# This will create an archive without any binaries, only the files are there.
# The name template must not contain any references to `Os`, `Arch` and etc, since the archive will be meta.
# Defaul is false.
meta: true

# Archive name template.
# Defaults:
# - if format is `tar.gz`, `tar.xz`, `gz` or `zip`:
Expand Down

0 comments on commit dff42e1

Please sign in to comment.