mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-08 03:31:59 +02:00
Merge pull request #489 from goreleaser/template
Name Template for fpm and snapcraft
This commit is contained in:
commit
8a37a654b1
@ -106,11 +106,12 @@ type FormatOverride struct {
|
||||
|
||||
// Archive config used for the archive
|
||||
type Archive struct {
|
||||
NameTemplate string `yaml:"name_template,omitempty"`
|
||||
Replacements map[string]string `yaml:",omitempty"`
|
||||
|
||||
Format string `yaml:",omitempty"`
|
||||
FormatOverrides []FormatOverride `yaml:"format_overrides,omitempty"`
|
||||
NameTemplate string `yaml:"name_template,omitempty"`
|
||||
WrapInDirectory bool `yaml:"wrap_in_directory,omitempty"`
|
||||
Replacements map[string]string `yaml:",omitempty"`
|
||||
Files []string `yaml:",omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
@ -129,6 +130,9 @@ type Release struct {
|
||||
|
||||
// FPM config
|
||||
type FPM struct {
|
||||
NameTemplate string `yaml:"name_template,omitempty"`
|
||||
Replacements map[string]string `yaml:",omitempty"`
|
||||
|
||||
Formats []string `yaml:",omitempty"`
|
||||
Dependencies []string `yaml:",omitempty"`
|
||||
Conflicts []string `yaml:",omitempty"`
|
||||
@ -160,6 +164,9 @@ type SnapcraftAppMetadata struct {
|
||||
|
||||
// Snapcraft config
|
||||
type Snapcraft struct {
|
||||
NameTemplate string `yaml:"name_template,omitempty"`
|
||||
Replacements map[string]string `yaml:",omitempty"`
|
||||
|
||||
Name string `yaml:",omitempty"`
|
||||
Summary string `yaml:",omitempty"`
|
||||
Description string `yaml:",omitempty"`
|
||||
|
@ -15,15 +15,30 @@ archive:
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - ProjectName
|
||||
# - Binary (Name of the binary if the packaging format is binary)
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Os
|
||||
# - Arch
|
||||
# - Arm (ARM version)
|
||||
# - Env (environment variables)
|
||||
# Default is `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`.
|
||||
# Defaults:
|
||||
# - if format is `tar.gz` or `zip`:
|
||||
# - `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`
|
||||
# - if format is `binary`:
|
||||
# - `{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||
|
||||
# Replacements for GOOS and GOARCH in the archive name.
|
||||
# Keys should be valid GOOSs or GOARCHs.
|
||||
# Values are the respective replacements.
|
||||
# Default is empty.
|
||||
replacements:
|
||||
amd64: 64-bit
|
||||
386: 32-bit
|
||||
darwin: macOS
|
||||
linux: Tux
|
||||
|
||||
# Set to true, if you want all files in the archive to be in a single directory.
|
||||
# If set to true and you extract the archive 'goreleaser_Linux_arm64.tar.gz',
|
||||
# you get a folder 'goreleaser_Linux_arm64'.
|
||||
@ -44,16 +59,6 @@ archive:
|
||||
- goos: windows
|
||||
format: zip
|
||||
|
||||
# Replacements for GOOS and GOARCH in the archive name.
|
||||
# Keys should be valid GOOSs or GOARCHs.
|
||||
# Values are the respective replacements.
|
||||
# Default is empty.
|
||||
replacements:
|
||||
amd64: 64-bit
|
||||
386: 32-bit
|
||||
darwin: macOS
|
||||
linux: Tux
|
||||
|
||||
# Additional files/globs you want to add to the archive.
|
||||
# Defaults are any files matching `LICENCE*`, `LICENSE*`,
|
||||
# `README*` and `CHANGELOG*` (case-insensitive).
|
||||
|
@ -9,6 +9,29 @@ generate `.deb`, `.rpm` and other archives. Check its
|
||||
```yml
|
||||
# .goreleaser.yml
|
||||
fpm:
|
||||
# You can change the name of the package.
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - ProjectName
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Os
|
||||
# - Arch
|
||||
# - Arm (ARM version)
|
||||
# - Env (environment variables)
|
||||
# Default: `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||
|
||||
# Replacements for GOOS and GOARCH in the package name.
|
||||
# Keys should be valid GOOSs or GOARCHs.
|
||||
# Values are the respective replacements.
|
||||
# Default is empty.
|
||||
replacements:
|
||||
amd64: 64-bit
|
||||
386: 32-bit
|
||||
darwin: macOS
|
||||
linux: Tux
|
||||
|
||||
# Your app's vendor.
|
||||
# Default is empty.
|
||||
vendor: Drum Roll Inc.
|
||||
|
@ -13,6 +13,28 @@ You can read more about it in the [snapcraft docs](https://snapcraft.io/docs/).
|
||||
```yml
|
||||
# .goreleaser.yml
|
||||
snapcraft:
|
||||
# You can change the name of the package.
|
||||
# This is parsed with the Go template engine and the following variables
|
||||
# are available:
|
||||
# - ProjectName
|
||||
# - Tag
|
||||
# - Version (Git tag without `v` prefix)
|
||||
# - Os
|
||||
# - Arch
|
||||
# - Arm (ARM version)
|
||||
# - Env (environment variables)
|
||||
# Default: `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||
|
||||
# Replacements for GOOS and GOARCH in the package name.
|
||||
# Keys should be valid GOOSs or GOARCHs.
|
||||
# Values are the respective replacements.
|
||||
# Default is empty.
|
||||
replacements:
|
||||
amd64: 64-bit
|
||||
386: 32-bit
|
||||
darwin: macOS
|
||||
linux: Tux
|
||||
|
||||
# The name of the snap. This is optional.
|
||||
# Default is project name.
|
||||
|
@ -1,49 +0,0 @@
|
||||
package nametemplate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
"text/template"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
)
|
||||
|
||||
var deprecatedBinary = regexp.MustCompile(`\{\{ ?\.Binary ?\}\}`)
|
||||
|
||||
// Apply applies the name template to the given artifact and name
|
||||
// TODO: this should be refactored alongside with other name template related todos
|
||||
func Apply(ctx *context.Context, a artifact.Artifact, name string) (string, error) {
|
||||
if deprecatedBinary.MatchString(ctx.Config.Archive.NameTemplate) {
|
||||
log.WithField("field", "{{.Binary}}").Warn("you are using a deprecated field on your template, please check the documentation")
|
||||
}
|
||||
var out bytes.Buffer
|
||||
t, err := template.New("archive_name").Parse(ctx.Config.Archive.NameTemplate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
data := struct {
|
||||
Os, Arch, Arm, Version, Tag, Binary, ProjectName string
|
||||
Env map[string]string
|
||||
}{
|
||||
Os: replace(ctx.Config.Archive.Replacements, a.Goos),
|
||||
Arch: replace(ctx.Config.Archive.Replacements, a.Goarch),
|
||||
Arm: replace(ctx.Config.Archive.Replacements, a.Goarm),
|
||||
Version: ctx.Version,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
ProjectName: name,
|
||||
Binary: name, // TODO: deprecated, remove soon
|
||||
Env: ctx.Env,
|
||||
}
|
||||
err = t.Execute(&out, data)
|
||||
return out.String(), err
|
||||
}
|
||||
|
||||
func replace(replacements map[string]string, original string) string {
|
||||
result := replacements[original]
|
||||
if result == "" {
|
||||
return original
|
||||
}
|
||||
return result
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
package nametemplate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/apex/log/handlers/cli"
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNameTemplate(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "proj",
|
||||
Archive: config.Archive{
|
||||
NameTemplate: "{{.Binary}}_{{.ProjectName}}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}",
|
||||
Replacements: map[string]string{
|
||||
"windows": "windao",
|
||||
},
|
||||
},
|
||||
})
|
||||
s, err := Apply(ctx, artifact.Artifact{
|
||||
Goos: "windows",
|
||||
Goarch: "amd64",
|
||||
Name: "winbin",
|
||||
}, "bin")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "bin_bin_windao_amd64", s)
|
||||
s, err = Apply(ctx, artifact.Artifact{
|
||||
Goos: "darwin",
|
||||
Goarch: "amd64",
|
||||
Name: "winbin",
|
||||
}, "bin")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "bin_bin_darwin_amd64", s)
|
||||
}
|
||||
|
||||
func TestInvalidNameTemplate(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "proj",
|
||||
Archive: config.Archive{
|
||||
NameTemplate: "{{.Binary}",
|
||||
},
|
||||
})
|
||||
s, err := Apply(ctx, artifact.Artifact{
|
||||
Goos: "windows",
|
||||
Goarch: "amd64",
|
||||
Name: "winbin",
|
||||
}, "bin")
|
||||
assert.EqualError(t, err, `template: archive_name:1: unexpected "}" in operand`)
|
||||
assert.Empty(t, s)
|
||||
}
|
||||
|
||||
func TestDeprecatedFieldOnNameTemplate(t *testing.T) {
|
||||
for _, temp := range []string{
|
||||
"{{.Binary}}",
|
||||
"{{ .Binary}}",
|
||||
"{{.Binary }}",
|
||||
"{{ .Binary }}",
|
||||
} {
|
||||
t.Run(temp, func(tt *testing.T) {
|
||||
var out bytes.Buffer
|
||||
log.SetHandler(cli.New(&out))
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "proj",
|
||||
Archive: config.Archive{
|
||||
NameTemplate: temp,
|
||||
},
|
||||
})
|
||||
s, err := Apply(ctx, artifact.Artifact{
|
||||
Goos: "windows",
|
||||
Goarch: "amd64",
|
||||
Name: "winbin",
|
||||
}, "bin")
|
||||
assert.NoError(tt, err)
|
||||
assert.Equal(tt, "bin", s)
|
||||
assert.Contains(tt, out.String(), "you are using a deprecated field on your template")
|
||||
})
|
||||
}
|
||||
}
|
57
internal/template/template.go
Normal file
57
internal/template/template.go
Normal file
@ -0,0 +1,57 @@
|
||||
// Package template contains the code used to template names of goreleaser's
|
||||
// packages and archives.
|
||||
package template
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
gotemplate "text/template"
|
||||
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
)
|
||||
|
||||
// Fields contains all accepted fields in the template string
|
||||
type Fields struct {
|
||||
Version string
|
||||
Tag string
|
||||
ProjectName string
|
||||
Env map[string]string
|
||||
Os string
|
||||
Arch string
|
||||
Arm string
|
||||
Binary string
|
||||
}
|
||||
|
||||
// NewFields returns a Fields instances filled with the data provided
|
||||
func NewFields(ctx *context.Context, a artifact.Artifact, replacements map[string]string) Fields {
|
||||
return Fields{
|
||||
Env: ctx.Env,
|
||||
Version: ctx.Version,
|
||||
Tag: ctx.Git.CurrentTag,
|
||||
ProjectName: ctx.Config.ProjectName,
|
||||
Binary: a.Extra["Binary"],
|
||||
Os: replace(replacements, a.Goos),
|
||||
Arch: replace(replacements, a.Goarch),
|
||||
Arm: replace(replacements, a.Goarm),
|
||||
}
|
||||
}
|
||||
|
||||
// Apply applies the given fields to the given template and returns the
|
||||
// evaluation and any error that might occur.
|
||||
func Apply(tmpl string, fields Fields) (string, error) {
|
||||
t, err := gotemplate.New(tmpl).Parse(tmpl)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var out bytes.Buffer
|
||||
err = t.Execute(&out, fields)
|
||||
return out.String(), err
|
||||
}
|
||||
|
||||
func replace(replacements map[string]string, original string) string {
|
||||
result := replacements[original]
|
||||
if result == "" {
|
||||
return original
|
||||
}
|
||||
return result
|
||||
}
|
59
internal/template/template_test.go
Normal file
59
internal/template/template_test.go
Normal file
@ -0,0 +1,59 @@
|
||||
package template
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestTemplate(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
ProjectName: "proj",
|
||||
})
|
||||
ctx.Env = map[string]string{
|
||||
"FOO": "bar",
|
||||
}
|
||||
ctx.Version = "1.0.0"
|
||||
ctx.Git.CurrentTag = "v1.0.0"
|
||||
var fields = NewFields(ctx, artifact.Artifact{
|
||||
Name: "not-this-binary",
|
||||
Goarch: "amd64",
|
||||
Goos: "linux",
|
||||
Goarm: "6",
|
||||
Extra: map[string]string{
|
||||
"Binary": "binary",
|
||||
},
|
||||
}, map[string]string{
|
||||
"linux": "Linux",
|
||||
})
|
||||
for expect, tmpl := range map[string]string{
|
||||
"bar": "{{.Env.FOO}}",
|
||||
"Linux": "{{.Os}}",
|
||||
"amd64": "{{.Arch}}",
|
||||
"6": "{{.Arm}}",
|
||||
"1.0.0": "{{.Version}}",
|
||||
"v1.0.0": "{{.Tag}}",
|
||||
"binary": "{{.Binary}}",
|
||||
"proj": "{{.ProjectName}}",
|
||||
} {
|
||||
tmpl := tmpl
|
||||
expect := expect
|
||||
t.Run(expect, func(tt *testing.T) {
|
||||
tt.Parallel()
|
||||
result, err := Apply(tmpl, fields)
|
||||
assert.NoError(tt, err)
|
||||
assert.Equal(tt, expect, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidTemplate(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
var fields = NewFields(ctx, artifact.Artifact{}, map[string]string{})
|
||||
result, err := Apply("{{.Foo}", fields)
|
||||
assert.Empty(t, result)
|
||||
assert.EqualError(t, err, `template: {{.Foo}:1: unexpected "}" in operand`)
|
||||
}
|
@ -16,10 +16,13 @@ import (
|
||||
"github.com/goreleaser/archive"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/nametemplate"
|
||||
"github.com/goreleaser/goreleaser/internal/template"
|
||||
)
|
||||
|
||||
const defaultNameTemplate = "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
const (
|
||||
defaultNameTemplate = "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
defaultBinaryNameTemplate = "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
)
|
||||
|
||||
// Pipe for archive
|
||||
type Pipe struct{}
|
||||
@ -28,6 +31,34 @@ func (Pipe) String() string {
|
||||
return "creating archives"
|
||||
}
|
||||
|
||||
// Default sets the pipe defaults
|
||||
func (Pipe) Default(ctx *context.Context) error {
|
||||
var archive = &ctx.Config.Archive
|
||||
if archive.Format == "" {
|
||||
archive.Format = "tar.gz"
|
||||
}
|
||||
if len(archive.Files) == 0 {
|
||||
archive.Files = []string{
|
||||
"licence*",
|
||||
"LICENCE*",
|
||||
"license*",
|
||||
"LICENSE*",
|
||||
"readme*",
|
||||
"README*",
|
||||
"changelog*",
|
||||
"CHANGELOG*",
|
||||
}
|
||||
}
|
||||
if archive.NameTemplate == "" {
|
||||
if archive.Format == "binary" {
|
||||
archive.NameTemplate = defaultBinaryNameTemplate
|
||||
} else {
|
||||
archive.NameTemplate = defaultNameTemplate
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
func (Pipe) Run(ctx *context.Context) error {
|
||||
var g errgroup.Group
|
||||
@ -44,32 +75,12 @@ func (Pipe) Run(ctx *context.Context) error {
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
// Default sets the pipe defaults
|
||||
func (Pipe) Default(ctx *context.Context) error {
|
||||
if ctx.Config.Archive.NameTemplate == "" {
|
||||
ctx.Config.Archive.NameTemplate = defaultNameTemplate
|
||||
}
|
||||
if ctx.Config.Archive.Format == "" {
|
||||
ctx.Config.Archive.Format = "tar.gz"
|
||||
}
|
||||
if len(ctx.Config.Archive.Files) == 0 {
|
||||
ctx.Config.Archive.Files = []string{
|
||||
"licence*",
|
||||
"LICENCE*",
|
||||
"license*",
|
||||
"LICENSE*",
|
||||
"readme*",
|
||||
"README*",
|
||||
"changelog*",
|
||||
"CHANGELOG*",
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func create(ctx *context.Context, artifacts []artifact.Artifact) error {
|
||||
var format = packageFormat(ctx, artifacts[0].Goos)
|
||||
folder, err := nametemplate.Apply(ctx, artifacts[0], ctx.Config.ProjectName)
|
||||
folder, err := template.Apply(
|
||||
ctx.Config.Archive.NameTemplate,
|
||||
template.NewFields(ctx, artifacts[0], ctx.Config.Archive.Replacements),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -111,7 +122,8 @@ func create(ctx *context.Context, artifacts []artifact.Artifact) error {
|
||||
func skip(ctx *context.Context, artifacts []artifact.Artifact) error {
|
||||
for _, a := range artifacts {
|
||||
log.WithField("binary", a.Name).Info("skip archiving")
|
||||
name, err := nametemplate.Apply(ctx, a, a.Extra["Binary"])
|
||||
var fields = template.NewFields(ctx, a, ctx.Config.Archive.Replacements)
|
||||
name, err := template.Apply(ctx.Config.Archive.NameTemplate, fields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -8,12 +8,11 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/goreleaser/goreleaser/config"
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/testlib"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDescription(t *testing.T) {
|
||||
@ -122,7 +121,7 @@ func TestRunPipeBinary(t *testing.T) {
|
||||
Dist: dist,
|
||||
Archive: config.Archive{
|
||||
Format: "binary",
|
||||
NameTemplate: defaultNameTemplate,
|
||||
NameTemplate: defaultBinaryNameTemplate,
|
||||
},
|
||||
},
|
||||
)
|
||||
@ -297,6 +296,18 @@ func TestDefaultSet(t *testing.T) {
|
||||
assert.Equal(t, "foo", ctx.Config.Archive.Files[0])
|
||||
}
|
||||
|
||||
func TestDefaultFormatBinary(t *testing.T) {
|
||||
var ctx = &context.Context{
|
||||
Config: config.Project{
|
||||
Archive: config.Archive{
|
||||
Format: "binary",
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.NoError(t, Pipe{}.Default(ctx))
|
||||
assert.Equal(t, defaultBinaryNameTemplate, ctx.Config.Archive.NameTemplate)
|
||||
}
|
||||
|
||||
func TestFormatFor(t *testing.T) {
|
||||
var ctx = &context.Context{
|
||||
Config: config.Project{
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/pipeline/fpm"
|
||||
"github.com/goreleaser/goreleaser/pipeline/release"
|
||||
"github.com/goreleaser/goreleaser/pipeline/sign"
|
||||
"github.com/goreleaser/goreleaser/pipeline/snapcraft"
|
||||
"github.com/goreleaser/goreleaser/pipeline/snapshot"
|
||||
)
|
||||
|
||||
@ -31,6 +32,7 @@ var defaulters = []pipeline.Defaulter{
|
||||
archive.Pipe{},
|
||||
build.Pipe{},
|
||||
fpm.Pipe{},
|
||||
snapcraft.Pipe{},
|
||||
checksums.Pipe{},
|
||||
sign.Pipe{},
|
||||
docker.Pipe{},
|
||||
|
@ -16,15 +16,18 @@ import (
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/linux"
|
||||
"github.com/goreleaser/goreleaser/internal/nametemplate"
|
||||
"github.com/goreleaser/goreleaser/internal/template"
|
||||
"github.com/goreleaser/goreleaser/pipeline"
|
||||
)
|
||||
|
||||
// ErrNoFPM is shown when fpm cannot be found in $PATH
|
||||
var ErrNoFPM = errors.New("fpm not present in $PATH")
|
||||
|
||||
const (
|
||||
defaultNameTemplate = "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
// path to gnu-tar on macOS when installed with homebrew
|
||||
const gnuTarPath = "/usr/local/opt/gnu-tar/libexec/gnubin"
|
||||
gnuTarPath = "/usr/local/opt/gnu-tar/libexec/gnubin"
|
||||
)
|
||||
|
||||
// Pipe for fpm packaging
|
||||
type Pipe struct{}
|
||||
@ -35,8 +38,12 @@ func (Pipe) String() string {
|
||||
|
||||
// Default sets the pipe defaults
|
||||
func (Pipe) Default(ctx *context.Context) error {
|
||||
if ctx.Config.FPM.Bindir == "" {
|
||||
ctx.Config.FPM.Bindir = "/usr/local/bin"
|
||||
var fpm = &ctx.Config.FPM
|
||||
if fpm.Bindir == "" {
|
||||
fpm.Bindir = "/usr/local/bin"
|
||||
}
|
||||
if fpm.NameTemplate == "" {
|
||||
fpm.NameTemplate = defaultNameTemplate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -79,12 +86,14 @@ func doRun(ctx *context.Context) error {
|
||||
}
|
||||
|
||||
func create(ctx *context.Context, format, arch string, binaries []artifact.Artifact) error {
|
||||
// TODO: should add template support here probably... for now, let's use archive's template
|
||||
folder, err := nametemplate.Apply(ctx, binaries[0], ctx.Config.ProjectName)
|
||||
name, err := template.Apply(
|
||||
ctx.Config.FPM.NameTemplate,
|
||||
template.NewFields(ctx, binaries[0], ctx.Config.FPM.Replacements),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var path = filepath.Join(ctx.Config.Dist, folder)
|
||||
var path = filepath.Join(ctx.Config.Dist, name)
|
||||
var file = path + "." + format
|
||||
var log = log.WithField("format", format).WithField("arch", arch)
|
||||
dir, err := ioutil.TempDir("", "fpm")
|
||||
@ -124,7 +133,7 @@ func create(ctx *context.Context, format, arch string, binaries []artifact.Artif
|
||||
}
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Type: artifact.LinuxPackage,
|
||||
Name: folder + "." + format,
|
||||
Name: name + "." + format,
|
||||
Path: file,
|
||||
Goos: binaries[0].Goos,
|
||||
Goarch: binaries[0].Goarch,
|
||||
|
@ -44,11 +44,8 @@ func TestRunPipe(t *testing.T) {
|
||||
Config: config.Project{
|
||||
ProjectName: "mybin",
|
||||
Dist: dist,
|
||||
// TODO: remove this when fpm have its own name template
|
||||
Archive: config.Archive{
|
||||
NameTemplate: "foo",
|
||||
},
|
||||
FPM: config.FPM{
|
||||
NameTemplate: defaultNameTemplate,
|
||||
Formats: []string{"deb", "rpm"},
|
||||
Dependencies: []string{"make"},
|
||||
Conflicts: []string{"git"},
|
||||
@ -92,6 +89,27 @@ func TestNoFPMInPath(t *testing.T) {
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), ErrNoFPM.Error())
|
||||
}
|
||||
|
||||
func TestInvalidNameTemplate(t *testing.T) {
|
||||
var ctx = &context.Context{
|
||||
Parallelism: runtime.NumCPU(),
|
||||
Artifacts: artifact.New(),
|
||||
Config: config.Project{
|
||||
FPM: config.FPM{
|
||||
NameTemplate: "{{.Foo}",
|
||||
Formats: []string{"deb"},
|
||||
},
|
||||
},
|
||||
}
|
||||
ctx.Artifacts.Add(artifact.Artifact{
|
||||
Name: "mybin",
|
||||
Goos: "linux",
|
||||
Goarch: "amd64",
|
||||
Type: artifact.Binary,
|
||||
})
|
||||
assert.Contains(t, Pipe{}.Run(ctx).Error(), `template: {{.Foo}:1: unexpected "}" in operand`)
|
||||
}
|
||||
|
||||
|
||||
func TestCreateFileDoesntExist(t *testing.T) {
|
||||
folder, err := ioutil.TempDir("", "archivetest")
|
||||
assert.NoError(t, err)
|
||||
@ -119,7 +137,7 @@ func TestCreateFileDoesntExist(t *testing.T) {
|
||||
Goarch: "amd64",
|
||||
Type: artifact.Binary,
|
||||
})
|
||||
assert.Error(t, Pipe{}.Run(ctx))
|
||||
assert.Contains(t, Pipe{}.Run(ctx).Error(), `dist/mybin/mybin', does it exist?`)
|
||||
}
|
||||
|
||||
func TestCmd(t *testing.T) {
|
||||
@ -136,6 +154,7 @@ func TestDefault(t *testing.T) {
|
||||
}
|
||||
assert.NoError(t, Pipe{}.Default(ctx))
|
||||
assert.Equal(t, "/usr/local/bin", ctx.Config.FPM.Bindir)
|
||||
assert.Equal(t, defaultNameTemplate, ctx.Config.FPM.NameTemplate)
|
||||
}
|
||||
|
||||
func TestDefaultSet(t *testing.T) {
|
||||
@ -143,9 +162,11 @@ func TestDefaultSet(t *testing.T) {
|
||||
Config: config.Project{
|
||||
FPM: config.FPM{
|
||||
Bindir: "/bin",
|
||||
NameTemplate: "foo",
|
||||
},
|
||||
},
|
||||
}
|
||||
assert.NoError(t, Pipe{}.Default(ctx))
|
||||
assert.Equal(t, "/bin", ctx.Config.FPM.Bindir)
|
||||
assert.Equal(t, "foo", ctx.Config.FPM.NameTemplate)
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import (
|
||||
"github.com/goreleaser/goreleaser/context"
|
||||
"github.com/goreleaser/goreleaser/internal/artifact"
|
||||
"github.com/goreleaser/goreleaser/internal/linux"
|
||||
"github.com/goreleaser/goreleaser/internal/nametemplate"
|
||||
"github.com/goreleaser/goreleaser/internal/template"
|
||||
"github.com/goreleaser/goreleaser/pipeline"
|
||||
)
|
||||
|
||||
@ -48,6 +48,8 @@ type AppMetadata struct {
|
||||
Daemon string `yaml:",omitempty"`
|
||||
}
|
||||
|
||||
const defaultNameTemplate = "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
|
||||
|
||||
// Pipe for snapcraft packaging
|
||||
type Pipe struct{}
|
||||
|
||||
@ -55,6 +57,15 @@ func (Pipe) String() string {
|
||||
return "creating Linux packages with snapcraft"
|
||||
}
|
||||
|
||||
// Default sets the pipe defaults
|
||||
func (Pipe) Default(ctx *context.Context) error {
|
||||
var snap = &ctx.Config.Snapcraft
|
||||
if snap.NameTemplate == "" {
|
||||
snap.NameTemplate = defaultNameTemplate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run the pipe
|
||||
func (Pipe) Run(ctx *context.Context) error {
|
||||
if ctx.Config.Snapcraft.Summary == "" && ctx.Config.Snapcraft.Description == "" {
|
||||
@ -89,8 +100,10 @@ func (Pipe) Run(ctx *context.Context) error {
|
||||
|
||||
func create(ctx *context.Context, arch string, binaries []artifact.Artifact) error {
|
||||
var log = log.WithField("arch", arch)
|
||||
// TODO: should add template support here probably... for now, let's use archive's template
|
||||
folder, err := nametemplate.Apply(ctx, binaries[0], ctx.Config.ProjectName)
|
||||
folder, err := template.Apply(
|
||||
ctx.Config.Snapcraft.NameTemplate,
|
||||
template.NewFields(ctx, binaries[0], ctx.Config.Snapcraft.Replacements),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -52,11 +52,8 @@ func TestRunPipe(t *testing.T) {
|
||||
Config: config.Project{
|
||||
ProjectName: "mybin",
|
||||
Dist: dist,
|
||||
// TODO: remove this when we start using our own name template
|
||||
Archive: config.Archive{
|
||||
NameTemplate: "foo_{{.Arch}}",
|
||||
},
|
||||
Snapcraft: config.Snapcraft{
|
||||
NameTemplate: "foo_{{.Arch}}",
|
||||
Summary: "test summary",
|
||||
Description: "test description",
|
||||
},
|
||||
@ -66,6 +63,29 @@ func TestRunPipe(t *testing.T) {
|
||||
assert.NoError(t, Pipe{}.Run(ctx))
|
||||
}
|
||||
|
||||
func TestRunPipeInvalidNameTemplate(t *testing.T) {
|
||||
folder, err := ioutil.TempDir("", "archivetest")
|
||||
assert.NoError(t, err)
|
||||
var dist = filepath.Join(folder, "dist")
|
||||
assert.NoError(t, os.Mkdir(dist, 0755))
|
||||
assert.NoError(t, err)
|
||||
var ctx = &context.Context{
|
||||
Version: "testversion",
|
||||
Artifacts: artifact.New(),
|
||||
Config: config.Project{
|
||||
ProjectName: "mybin",
|
||||
Dist: dist,
|
||||
Snapcraft: config.Snapcraft{
|
||||
NameTemplate: "foo_{{.Arch}",
|
||||
Summary: "test summary",
|
||||
Description: "test description",
|
||||
},
|
||||
},
|
||||
}
|
||||
addBinaries(t, ctx, "mybin", dist)
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), `template: foo_{{.Arch}:1: unexpected "}" in operand`)
|
||||
}
|
||||
|
||||
func TestRunPipeWithName(t *testing.T) {
|
||||
folder, err := ioutil.TempDir("", "archivetest")
|
||||
assert.NoError(t, err)
|
||||
@ -78,11 +98,8 @@ func TestRunPipeWithName(t *testing.T) {
|
||||
Config: config.Project{
|
||||
ProjectName: "testprojectname",
|
||||
Dist: dist,
|
||||
// TODO: remove this when we start using our own name template
|
||||
Archive: config.Archive{
|
||||
NameTemplate: "foo_{{.Arch}}",
|
||||
},
|
||||
Snapcraft: config.Snapcraft{
|
||||
NameTemplate: "foo_{{.Arch}}",
|
||||
Name: "testsnapname",
|
||||
Summary: "test summary",
|
||||
Description: "test description",
|
||||
@ -111,11 +128,8 @@ func TestRunPipeWithPlugsAndDaemon(t *testing.T) {
|
||||
Config: config.Project{
|
||||
ProjectName: "mybin",
|
||||
Dist: dist,
|
||||
// TODO: remove this when we start using our own name template
|
||||
Archive: config.Archive{
|
||||
NameTemplate: "foo_{{.Arch}}",
|
||||
},
|
||||
Snapcraft: config.Snapcraft{
|
||||
NameTemplate: "foo_{{.Arch}}",
|
||||
Summary: "test summary",
|
||||
Description: "test description",
|
||||
Apps: map[string]config.SnapcraftAppMetadata{
|
||||
@ -155,6 +169,22 @@ func TestNoSnapcraftInPath(t *testing.T) {
|
||||
assert.EqualError(t, Pipe{}.Run(ctx), ErrNoSnapcraft.Error())
|
||||
}
|
||||
|
||||
func TestDefault(t *testing.T) {
|
||||
var ctx = context.New(config.Project{})
|
||||
assert.NoError(t,Pipe{}.Default(ctx))
|
||||
assert.Equal(t, defaultNameTemplate, ctx.Config.Snapcraft.NameTemplate)
|
||||
}
|
||||
|
||||
func TestDefaultSet(t *testing.T) {
|
||||
var ctx = context.New(config.Project{
|
||||
Snapcraft: config.Snapcraft{
|
||||
NameTemplate: "foo",
|
||||
},
|
||||
})
|
||||
assert.NoError(t,Pipe{}.Default(ctx))
|
||||
assert.Equal(t, "foo", ctx.Config.Snapcraft.NameTemplate)
|
||||
}
|
||||
|
||||
func addBinaries(t *testing.T, ctx *context.Context, name, dist string) {
|
||||
for _, goos := range []string{"linux", "darwin"} {
|
||||
for _, goarch := range []string{"amd64", "386"} {
|
||||
|
@ -7,7 +7,7 @@ import "github.com/goreleaser/goreleaser/context"
|
||||
type Pipe struct{}
|
||||
|
||||
func (Pipe) String() string {
|
||||
return "generating changelog"
|
||||
return "snapshoting"
|
||||
}
|
||||
|
||||
// Default sets the pipe defaults
|
||||
|
Loading…
Reference in New Issue
Block a user