diff --git a/.github/config.yml b/.github/config.yml new file mode 100644 index 000000000..7efa5af4e --- /dev/null +++ b/.github/config.yml @@ -0,0 +1,2 @@ +todo: + keyword: "TODO: " diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 000000000..dc90e5a1c --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,17 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 60 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/.goreleaser.yml b/.goreleaser.yml index 7d09b4ec7..eee494fbb 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -23,6 +23,7 @@ changelog: dockers: - image: goreleaser/goreleaser latest: true + tag_template: '{{ .Tag }}' archive: name_template: '{{ .ProjectName }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}' replacements: diff --git a/.travis.yml b/.travis.yml index e03579e93..e8ff9ac29 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,5 +18,15 @@ after_success: - bash <(curl -s https://codecov.io/bash) - test -n "$TRAVIS_TAG" && docker login -u="$DOCKER_USERNAME" -p="$DOCKER_PASSWORD" - test -n "$TRAVIS_TAG" && go run main.go + - make static +deploy: + provider: pages + skip_cleanup: true + github_token: $GITHUB_TOKEN + repo: goreleaser/goreleaser.github.io + local_dir: ./dist/goreleaser.github.io + target_branch: master + on: + tags: true notifications: email: false diff --git a/Makefile b/Makefile index 197d053ce..4d146f808 100644 --- a/Makefile +++ b/Makefile @@ -8,49 +8,53 @@ setup: go get -u github.com/golang/dep/cmd/dep go get -u github.com/pierrre/gotestcover go get -u golang.org/x/tools/cmd/cover + go get -u github.com/apex/static/cmd/static-docs dep ensure gometalinter --install +.PHONY: setup # Run all the tests test: gotestcover $(TEST_OPTIONS) -covermode=atomic -coverprofile=coverage.txt $(SOURCE_FILES) -run $(TEST_PATTERN) -timeout=2m +.PHONY: cover # Run all the tests and opens the coverage report cover: test go tool cover -html=coverage.txt +.PHONY: cover # gofmt and goimports all go files fmt: find . -name '*.go' -not -wholename './vendor/*' | while read -r file; do gofmt -w -s "$$file"; goimports -w "$$file"; done +.PHONY: fmt # Run all the linters lint: gometalinter --vendor ./... +.PHONY: lint # Run all the tests and code checks ci: test lint +.PHONY: ci # Build a beta version of goreleaser build: go build - -HIGHLIGHT=https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0 +.PHONY: build # Generate the static documentation static: + @rm -rf dist/goreleaser.github.io + @mkdir -p dist + @git clone https://github.com/goreleaser/goreleaser.github.io.git dist/goreleaser.github.io + @rm -rf dist/goreleaser.github.io/theme @static-docs \ --in docs \ - --out ../goreleaser.github.io \ + --out dist/goreleaser.github.io \ --title GoReleaser \ --subtitle "Deliver Go binaries as fast and easily as possible" \ - --google UA-106198408-1 \ - --script "$(HIGHLIGHT)/highlight.min.js" \ - --script "$(HIGHLIGHT)/languages/go.min.js" \ - --script "$(HIGHLIGHT)/languages/yaml.min.js" \ - --script "$(HIGHLIGHT)/languages/dockerfile.min.js" \ - --style "$(HIGHLIGHT)/styles/atom-one-dark.min.css" \ - --inline-script 'hljs.initHighlightingOnLoad();' \ - --inline-style 'pre { padding: 0; }' + --google UA-106198408-1 +.PHONY: static # Show to-do items per file. todo: diff --git a/README.md b/README.md index 4b719fdd9..91892e64c 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@
-
+
diff --git a/checksum/checksum.go b/checksum/checksum.go
index 7cfbb6bbe..099a4d91d 100644
--- a/checksum/checksum.go
+++ b/checksum/checksum.go
@@ -12,14 +12,14 @@ import (
)
// SHA256 sum of the given file
-func SHA256(path string) (result string, err error) {
+func SHA256(path string) (string, error) {
return calculate(sha256.New(), path)
}
-func calculate(hash hash.Hash, path string) (result string, err error) {
+func calculate(hash hash.Hash, path string) (string, error) {
file, err := os.Open(path)
if err != nil {
- return
+ return "", err
}
defer func() {
if err := file.Close(); err != nil {
@@ -30,12 +30,10 @@ func calculate(hash hash.Hash, path string) (result string, err error) {
return doCalculate(hash, file)
}
-func doCalculate(hash hash.Hash, file io.Reader) (result string, err error) {
- _, err = io.Copy(hash, file)
+func doCalculate(hash hash.Hash, file io.Reader) (string, error) {
+ _, err := io.Copy(hash, file)
if err != nil {
- return
+ return "", err
}
-
- result = hex.EncodeToString(hash.Sum(nil))
- return
+ return hex.EncodeToString(hash.Sum(nil)), nil
}
diff --git a/config/config.go b/config/config.go
index 7a269529c..4a1a35846 100644
--- a/config/config.go
+++ b/config/config.go
@@ -181,14 +181,15 @@ type Checksum struct {
// Docker image config
type Docker struct {
- Binary string `yaml:",omitempty"`
- Goos string `yaml:",omitempty"`
- Goarch string `yaml:",omitempty"`
- Goarm string `yaml:",omitempty"`
- Image string `yaml:",omitempty"`
- Dockerfile string `yaml:",omitempty"`
- Latest bool `yaml:",omitempty"`
- Files []string `yaml:"extra_files,omitempty"`
+ Binary string `yaml:",omitempty"`
+ Goos string `yaml:",omitempty"`
+ Goarch string `yaml:",omitempty"`
+ Goarm string `yaml:",omitempty"`
+ Image string `yaml:",omitempty"`
+ Dockerfile string `yaml:",omitempty"`
+ Latest bool `yaml:",omitempty"`
+ TagTemplate string `yaml:"tag_template,omitempty"`
+ Files []string `yaml:"extra_files,omitempty"`
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
diff --git a/context/context.go b/context/context.go
index 76b698c15..7780aa39b 100644
--- a/context/context.go
+++ b/context/context.go
@@ -8,6 +8,7 @@ package context
import (
ctx "context"
+ "os"
"path/filepath"
"strings"
"sync"
@@ -31,11 +32,13 @@ type Binary struct {
type Context struct {
ctx.Context
Config config.Project
+ Env map[string]string
Token string
Git GitInfo
Binaries map[string]map[string][]Binary
Artifacts []string
Dockers []string
+ Brews []string
ReleaseNotes string
Version string
Validate bool
@@ -46,9 +49,12 @@ type Context struct {
Parallelism int
}
-var artifactsLock sync.Mutex
-var dockersLock sync.Mutex
-var binariesLock sync.Mutex
+var (
+ artifactsLock sync.Mutex
+ dockersLock sync.Mutex
+ binariesLock sync.Mutex
+ brewsLock sync.Mutex
+)
// AddArtifact adds a file to upload list
func (ctx *Context) AddArtifact(file string) {
@@ -59,6 +65,14 @@ func (ctx *Context) AddArtifact(file string) {
log.WithField("artifact", file).Info("new release artifact")
}
+// AddBrew adds a brew tap to the brews list
+func (ctx *Context) AddBrew(tap string) {
+ brewsLock.Lock()
+ defer brewsLock.Unlock()
+ ctx.Brews = append(ctx.Brews, tap)
+ log.WithField("tap", tap).Info("new brew tap")
+}
+
// AddDocker adds a docker image to the docker images list
func (ctx *Context) AddDocker(image string) {
dockersLock.Lock()
@@ -96,6 +110,16 @@ func New(config config.Project) *Context {
return &Context{
Context: ctx.Background(),
Config: config,
+ Env: splitEnv(os.Environ()),
Parallelism: 4,
}
}
+
+func splitEnv(env []string) map[string]string {
+ r := map[string]string{}
+ for _, e := range env {
+ p := strings.SplitN(e, "=", 2)
+ r[p[0]] = p[1]
+ }
+ return r
+}
diff --git a/context/context_test.go b/context/context_test.go
index 910a5b5b3..202acf0b6 100644
--- a/context/context_test.go
+++ b/context/context_test.go
@@ -20,6 +20,10 @@ func TestMultipleAdds(t *testing.T) {
"c/d:2.0.0",
"e/f:3.0.0",
}
+ var brews = []string{
+ "foo/tap/foo",
+ "bar/bar/bar",
+ }
var ctx = New(config.Project{
Dist: "dist",
})
@@ -40,10 +44,20 @@ func TestMultipleAdds(t *testing.T) {
})
}
assert.NoError(t, g.Wait())
+ for _, b := range brews {
+ b := b
+ g.Go(func() error {
+ ctx.AddBrew(b)
+ return nil
+ })
+ }
+ assert.NoError(t, g.Wait())
assert.Len(t, ctx.Artifacts, len(artifacts))
assert.Contains(t, ctx.Artifacts, "a", "b", "c", "d")
assert.Len(t, ctx.Dockers, len(dockerfiles))
assert.Contains(t, ctx.Dockers, "a/b:1.0.0", "c/d:2.0.0", "e/f:3.0.0")
+ assert.Len(t, ctx.Brews, len(brews))
+ assert.Contains(t, ctx.Brews, "foo/tap/foo", "bar/bar/bar")
}
func TestMultipleBinaryAdds(t *testing.T) {
diff --git a/docs/000-introduction.md b/docs/000-introduction.md
index 196db00f6..55c808f97 100644
--- a/docs/000-introduction.md
+++ b/docs/000-introduction.md
@@ -22,5 +22,5 @@ that and rewrote the whole thing in Go.
There are three ways to get going.
1. Install Goreleaser via go get (`goreleaser` command will be globally available) `go get github.com/goreleaser/goreleaser`
-2. On a Mac use [Homebrew](https://github.com/goreleaser/homebrew-tap).
-3. Install directly [from the binaries](https://github.com/goreleaser/goreleaser/releases/latest).
+1. On a Mac use [Homebrew](https://github.com/goreleaser/homebrew-tap).
+1. Install directly [from the binaries](https://github.com/goreleaser/goreleaser/releases/latest).
diff --git a/docs/020-environment.md b/docs/020-environment.md
index 816fc7432..9d9cb3399 100644
--- a/docs/020-environment.md
+++ b/docs/020-environment.md
@@ -2,7 +2,7 @@
title: Environment
---
-### GitHub Token
+## GitHub Token
GoReleaser requires a GitHub API token with the `repo` scope selected to
deploy the artifacts to GitHub.
@@ -12,7 +12,7 @@ This token should be added to the environment variables as `GITHUB_TOKEN`.
Here is how to do it with Travis CI:
[Defining Variables in Repository Settings](https://docs.travis-ci.com/user/environment-variables/#Defining-Variables-in-Repository-Settings).
-### The dist folder
+## The dist folder
By default, GoReleaser will create its artifacts in the `./dist` folder.
If you must, you can change it by setting it in the `.goreleaser.yml` file:
@@ -23,7 +23,7 @@ If you must, you can change it by setting it in the `.goreleaser.yml` file:
dist: another-folder-that-is-not-dist
```
-### Using the `main.version`
+## Using the `main.version`
GoReleaser always sets a `main.version` *ldflag*.
You can use it in your `main.go` file:
diff --git a/docs/040-project.md b/docs/040-project.md
index 18fe0f9da..fa09c551f 100644
--- a/docs/040-project.md
+++ b/docs/040-project.md
@@ -5,7 +5,6 @@ title: Project Name
The project name is used in the name of the Brew formula, archives, etc.
If none is given, it will be inferred from the name of the Git project.
-
```yaml
# .goreleaser.yml
project_name: myproject
diff --git a/docs/050-build.md b/docs/050-build.md
index fa5324eed..946ff834d 100644
--- a/docs/050-build.md
+++ b/docs/050-build.md
@@ -78,3 +78,19 @@ builds:
pre: rice embed-go
post: ./script.sh
```
+
+## Passing environment variables to ldflags
+
+You can do that by using `{{ .Env.VARIABLE_NAME }}` in the template, for
+example:
+
+```yaml
+builds:
+ - ldflags: -s -w -X "main.goversion={{.Env.GOVERSION}}"
+```
+
+Then you can run:
+
+```console
+GOVERSION=$(go version) goreleaser
+```
diff --git a/docs/060-archive.md b/docs/060-archive.md
index b53212d88..8f9d314be 100644
--- a/docs/060-archive.md
+++ b/docs/060-archive.md
@@ -20,6 +20,7 @@ archive:
# - Os
# - Arch
# - Arm (ARM version)
+ # - Env (environment variables)
# Default is `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`.
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
@@ -63,3 +64,19 @@ archive:
- docs/*
- design/*.png
```
+
+## Passing environment variables to name_template
+
+You can do that by using `{{ .Env.VARIABLE_NAME }}` in the template, for
+example:
+
+```yaml
+archive:
+ name_template: '{{.ProjectName}}-{{.Version}}-{{.Env.GOVERSION_NR}}'
+```
+
+Then you can run:
+
+```console
+GOVERSION_NR=$(go version | awk '{print $3;}') goreleaser
+```
diff --git a/docs/120-homebrew.md b/docs/120-homebrew.md
index eb9eed5ad..133de95f3 100644
--- a/docs/120-homebrew.md
+++ b/docs/120-homebrew.md
@@ -95,5 +95,5 @@ end
**Important**": Note that GoReleaser does not yet generate a valid
homebrew-core formula. The generated formulas are meant to be published as
-[homebrew taps](https://docs.brew.sh/brew-tap.html), and in their current
+[homebrew taps](https://docs.brew.sh/Taps.html), and in their current
form will not be accepted in any of the official homebrew repositories.
diff --git a/docs/130-docker.md b/docs/130-docker.md
index a3d8a67c2..ab85a4aba 100644
--- a/docs/130-docker.md
+++ b/docs/130-docker.md
@@ -50,6 +50,9 @@ dockers:
image: myuser/myimage
# Path to the Dockerfile (from the project root).
dockerfile: Dockerfile
+ # Template of the docker tag. Defaults to `{{ .Version }}`. Other allowed
+ # fields are `.Tag` and `.Env.VARIABLE_NAME`.
+ tag_template: "{{ .Tag }}"
# Also tag and push myuser/myimage:latest.
latest: true
# If your Dockerfile copies files other than the binary itself,
@@ -61,3 +64,20 @@ dockers:
These settings should allow you to generate multiple Docker images,
for example, using multiple `FROM` statements,
as well as generate one image for each binary in your project.
+
+## Passing environment variables to tag_template
+
+You can do that by using `{{ .Env.VARIABLE_NAME }}` in the template, for
+example:
+
+```yaml
+dockers:
+ -
+ tag_template: "{{ .Tag }}-{{ .Env.GOVERSION_NR }}"
+```
+
+Then you can run:
+
+```console
+GOVERSION_NR=$(go version | awk '{print $3}') goreleaser
+```
diff --git a/docs/apple-touch-icon-144-precomposed.png b/docs/apple-touch-icon-144-precomposed.png
deleted file mode 100644
index c1aefd7ad..000000000
Binary files a/docs/apple-touch-icon-144-precomposed.png and /dev/null differ
diff --git a/docs/favicon.ico b/docs/favicon.ico
deleted file mode 100644
index 77b2a8e7f..000000000
Binary files a/docs/favicon.ico and /dev/null differ
diff --git a/goreleaserlib/goreleaser.go b/goreleaserlib/goreleaser.go
index 4bf734262..6dad0eeac 100644
--- a/goreleaserlib/goreleaser.go
+++ b/goreleaserlib/goreleaser.go
@@ -27,7 +27,7 @@ import (
yaml "gopkg.in/yaml.v2"
)
-var pipes = []pipeline.Pipe{
+var pipes = []pipeline.Piper{
defaults.Pipe{}, // load default configs
git.Pipe{}, // get and validate git repo state
changelog.Pipe{}, // builds the release changelog
@@ -91,7 +91,7 @@ func Release(flags Flags) error {
}
ctx.RmDist = flags.Bool("rm-dist")
for _, pipe := range pipes {
- log.Infof("\033[1m%s\033[0m", strings.ToUpper(pipe.Description()))
+ log.Infof("\033[1m%s\033[0m", strings.ToUpper(pipe.String()))
if err := handle(pipe.Run(ctx)); err != nil {
return err
}
diff --git a/internal/client/github.go b/internal/client/github.go
index 78f4696cb..95a6a42a7 100644
--- a/internal/client/github.go
+++ b/internal/client/github.go
@@ -8,7 +8,6 @@ import (
"github.com/apex/log"
"github.com/google/go-github/github"
"github.com/goreleaser/goreleaser/context"
- "github.com/goreleaser/goreleaser/internal/name"
"golang.org/x/oauth2"
)
@@ -84,12 +83,12 @@ func (c *githubClient) CreateFile(
func (c *githubClient) CreateRelease(ctx *context.Context, body string) (releaseID int, err error) {
var release *github.RepositoryRelease
- releaseTitle, err := name.ForTitle(ctx)
+ title, err := releaseTitle(ctx)
if err != nil {
return 0, err
}
var data = &github.RepositoryRelease{
- Name: github.String(releaseTitle),
+ Name: github.String(title),
TagName: github.String(ctx.Git.CurrentTag),
Body: github.String(body),
Draft: github.Bool(ctx.Config.Release.Draft),
diff --git a/internal/client/name.go b/internal/client/name.go
new file mode 100644
index 000000000..ca4886e5e
--- /dev/null
+++ b/internal/client/name.go
@@ -0,0 +1,24 @@
+package client
+
+import (
+ "bytes"
+ "text/template"
+
+ "github.com/goreleaser/goreleaser/context"
+)
+
+func releaseTitle(ctx *context.Context) (string, error) {
+ var out bytes.Buffer
+ t, err := template.New("github").Parse(ctx.Config.Release.NameTemplate)
+ if err != nil {
+ return "", err
+ }
+ err = t.Execute(&out, struct {
+ ProjectName, Tag, Version string
+ }{
+ ProjectName: ctx.Config.ProjectName,
+ Tag: ctx.Git.CurrentTag,
+ Version: ctx.Version,
+ })
+ return out.String(), err
+}
diff --git a/internal/name/name.go b/internal/name/name.go
deleted file mode 100644
index b899fe2f3..000000000
--- a/internal/name/name.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Package name provides name template logic for the final archive, formulae,
-// etc.
-package name
-
-import (
- "bytes"
- "text/template"
-
- "github.com/goreleaser/goreleaser/config"
- "github.com/goreleaser/goreleaser/context"
- "github.com/goreleaser/goreleaser/internal/buildtarget"
-)
-
-type nameData struct {
- Os string
- Arch string
- Arm string
- Version string
- Tag string
- Binary string // deprecated
- ProjectName string
-}
-
-// ForBuild return the name for the given context, goos, goarch, goarm and
-// build, using the build.Binary property instead of project_name.
-func ForBuild(ctx *context.Context, build config.Build, target buildtarget.Target) (string, error) {
- return apply(
- nameData{
- Os: replace(ctx.Config.Archive.Replacements, target.OS),
- Arch: replace(ctx.Config.Archive.Replacements, target.Arch),
- Arm: replace(ctx.Config.Archive.Replacements, target.Arm),
- Version: ctx.Version,
- Tag: ctx.Git.CurrentTag,
- Binary: build.Binary,
- ProjectName: build.Binary,
- },
- ctx.Config.Archive.NameTemplate,
- )
-}
-
-// For returns the name for the given context, goos, goarch and goarm.
-func For(ctx *context.Context, target buildtarget.Target) (string, error) {
- return apply(
- nameData{
- Os: replace(ctx.Config.Archive.Replacements, target.OS),
- Arch: replace(ctx.Config.Archive.Replacements, target.Arch),
- Arm: replace(ctx.Config.Archive.Replacements, target.Arm),
- Version: ctx.Version,
- Tag: ctx.Git.CurrentTag,
- Binary: ctx.Config.ProjectName,
- ProjectName: ctx.Config.ProjectName,
- },
- ctx.Config.Archive.NameTemplate,
- )
-}
-
-// ForChecksums returns the filename for the checksums file based on its
-// template
-func ForChecksums(ctx *context.Context) (string, error) {
- return apply(
- nameData{
- ProjectName: ctx.Config.ProjectName,
- Tag: ctx.Git.CurrentTag,
- Version: ctx.Version,
- },
- ctx.Config.Checksum.NameTemplate,
- )
-}
-
-// ForTitle returns the release title based upon its template
-func ForTitle(ctx *context.Context) (string, error) {
- return apply(
- nameData{
- ProjectName: ctx.Config.ProjectName,
- Tag: ctx.Git.CurrentTag,
- Version: ctx.Version,
- },
- ctx.Config.Release.NameTemplate,
- )
-}
-
-func apply(data nameData, templateStr string) (string, error) {
- var out bytes.Buffer
- t, err := template.New(data.ProjectName).Parse(templateStr)
- if err != nil {
- return "", err
- }
- 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
-}
diff --git a/internal/name/name_test.go b/internal/name/name_test.go
deleted file mode 100644
index fc02c41a2..000000000
--- a/internal/name/name_test.go
+++ /dev/null
@@ -1,141 +0,0 @@
-package name
-
-import (
- "testing"
-
- "github.com/goreleaser/goreleaser/config"
- "github.com/goreleaser/goreleaser/context"
- "github.com/goreleaser/goreleaser/internal/buildtarget"
- "github.com/goreleaser/goreleaser/pipeline/defaults"
- "github.com/stretchr/testify/assert"
-)
-
-func TestChecksums(t *testing.T) {
- var config = config.Project{
- Checksum: config.Checksum{
- NameTemplate: "{{.ProjectName }}_{{.Tag}}_{{.Version}}_checksums.txt",
- },
- ProjectName: "testcheck",
- }
- var ctx = &context.Context{
- Config: config,
- Version: "1.0.0",
- Git: context.GitInfo{
- CurrentTag: "v1.0.0",
- },
- }
-
- name, err := ForChecksums(ctx)
- assert.NoError(t, err)
- assert.Equal(t, "testcheck_v1.0.0_1.0.0_checksums.txt", name)
-}
-
-func TestNameFor(t *testing.T) {
- var config = config.Project{
- Archive: config.Archive{
- NameTemplate: "{{.Binary}}_{{.Os}}_{{.Arch}}_{{.Tag}}_{{.Version}}",
- Replacements: map[string]string{
- "darwin": "Darwin",
- "amd64": "x86_64",
- },
- },
- ProjectName: "test",
- }
- var ctx = &context.Context{
- Config: config,
- Version: "1.2.3",
- Git: context.GitInfo{
- CurrentTag: "v1.2.3",
- },
- }
-
- name, err := For(ctx, buildtarget.New("darwin", "amd64", ""))
- assert.NoError(t, err)
- assert.Equal(t, "test_Darwin_x86_64_v1.2.3_1.2.3", name)
-}
-
-func TestNameForBuild(t *testing.T) {
- var ctx = &context.Context{
- Config: config.Project{
- Archive: config.Archive{
- NameTemplate: "{{.Binary}}_{{.Os}}_{{.Arch}}_{{.Tag}}_{{.Version}}",
- Replacements: map[string]string{
- "darwin": "Darwin",
- "amd64": "x86_64",
- },
- },
- ProjectName: "test",
- },
- Version: "1.2.3",
- Git: context.GitInfo{
- CurrentTag: "v1.2.3",
- },
- }
-
- name, err := ForBuild(
- ctx,
- config.Build{Binary: "foo"},
- buildtarget.New("darwin", "amd64", ""),
- )
- assert.NoError(t, err)
- assert.Equal(t, "foo_Darwin_x86_64_v1.2.3_1.2.3", name)
-}
-
-func TestInvalidNameTemplate(t *testing.T) {
- var ctx = &context.Context{
- Config: config.Project{
- Archive: config.Archive{
- NameTemplate: "{{.Binary}_{{.Os}}_{{.Arch}}_{{.Version}}",
- },
- ProjectName: "test",
- },
- Git: context.GitInfo{
- CurrentTag: "v1.2.3",
- },
- }
-
- _, err := For(ctx, buildtarget.New("darwin", "amd64", ""))
- assert.Error(t, err)
-}
-
-func TestNameDefaultTemplate(t *testing.T) {
- var ctx = &context.Context{
- Config: config.Project{
- Archive: config.Archive{
- NameTemplate: defaults.NameTemplate,
- },
- ProjectName: "test",
- },
- Version: "1.2.3",
- }
- for key, target := range map[string]buildtarget.Target{
- "test_1.2.3_darwin_amd64": buildtarget.New("darwin", "amd64", ""),
- "test_1.2.3_linux_arm64": buildtarget.New("linux", "arm64", ""),
- "test_1.2.3_linux_armv7": buildtarget.New("linux", "arm", "7"),
- } {
- t.Run(key, func(t *testing.T) {
- name, err := For(ctx, target)
- assert.NoError(t, err)
- assert.Equal(t, key, name)
- })
- }
-}
-
-func TestNameForTitle(t *testing.T) {
- var ctx = &context.Context{
- Config: config.Project{
- Release: config.Release{
- NameTemplate: "{{.ProjectName}}-v{{.Version}}",
- },
- ProjectName: "test",
- },
- Version: "1.2.3",
- Git: context.GitInfo{
- CurrentTag: "v1.2.3",
- },
- }
-
- name, err := ForTitle(ctx)
- assert.NoError(t, err)
- assert.Equal(t, "test-v1.2.3", name)
-}
diff --git a/pipeline/archive/archive.go b/pipeline/archive/archive.go
index e6a3b0469..25a313683 100644
--- a/pipeline/archive/archive.go
+++ b/pipeline/archive/archive.go
@@ -19,9 +19,8 @@ import (
// Pipe for archive
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Creating archives"
+func (Pipe) String() string {
+ return "creating archives"
}
// Run the pipe
@@ -40,6 +39,29 @@ 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 = "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
+ }
+ 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, platform string, groups map[string][]context.Binary) error {
for folder, binaries := range groups {
var format = archiveformat.For(ctx, platform)
diff --git a/pipeline/archive/archive_test.go b/pipeline/archive/archive_test.go
index 1a6acad3e..031b48278 100644
--- a/pipeline/archive/archive_test.go
+++ b/pipeline/archive/archive_test.go
@@ -15,7 +15,7 @@ import (
)
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestRunPipe(t *testing.T) {
@@ -195,3 +195,33 @@ func TestRunPipeWrap(t *testing.T) {
assert.Equal(t, filepath.Join("mybin_darwin_amd64", n), h.Name)
}
}
+
+func TestDefault(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Archive: config.Archive{},
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.NotEmpty(t, ctx.Config.Archive.NameTemplate)
+ assert.Equal(t, "tar.gz", ctx.Config.Archive.Format)
+ assert.NotEmpty(t, ctx.Config.Archive.Files)
+}
+
+func TestDefaultSet(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Archive: config.Archive{
+ NameTemplate: "foo",
+ Format: "zip",
+ Files: []string{
+ "foo",
+ },
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Equal(t, "foo", ctx.Config.Archive.NameTemplate)
+ assert.Equal(t, "zip", ctx.Config.Archive.Format)
+ assert.Equal(t, "foo", ctx.Config.Archive.Files[0])
+}
diff --git a/pipeline/artifactory/artifactory.go b/pipeline/artifactory/artifactory.go
index f39d3cef8..8aa0c42e1 100644
--- a/pipeline/artifactory/artifactory.go
+++ b/pipeline/artifactory/artifactory.go
@@ -50,8 +50,8 @@ type artifactoryChecksums struct {
type Pipe struct{}
// Description of the pipe
-func (Pipe) Description() string {
- return "Releasing to Artifactory"
+func (Pipe) String() string {
+ return "releasing to Artifactory"
}
// Run the pipe
diff --git a/pipeline/artifactory/artifactory_test.go b/pipeline/artifactory/artifactory_test.go
index 42a3a12e0..ec2ed0f39 100644
--- a/pipeline/artifactory/artifactory_test.go
+++ b/pipeline/artifactory/artifactory_test.go
@@ -393,7 +393,7 @@ func TestRunPipe_DirUpload(t *testing.T) {
}
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestNoArtifactories(t *testing.T) {
diff --git a/pipeline/brew/brew.go b/pipeline/brew/brew.go
index 31602b909..cdf3fbc43 100644
--- a/pipeline/brew/brew.go
+++ b/pipeline/brew/brew.go
@@ -5,12 +5,14 @@ package brew
import (
"bytes"
"errors"
+ "fmt"
"path/filepath"
"strings"
"text/template"
"github.com/apex/log"
"github.com/goreleaser/goreleaser/checksum"
+ "github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/archiveformat"
"github.com/goreleaser/goreleaser/internal/client"
@@ -26,9 +28,8 @@ const platform = "darwinamd64"
// Pipe for brew deployment
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Creating homebrew formula"
+func (Pipe) String() string {
+ return "creating homebrew formula"
}
// Run the pipe
@@ -40,6 +41,49 @@ func (Pipe) Run(ctx *context.Context) error {
return doRun(ctx, client)
}
+// Default sets the pipe defaults
+func (Pipe) Default(ctx *context.Context) error {
+ if ctx.Config.Brew.Install == "" {
+ var installs []string
+ for _, build := range ctx.Config.Builds {
+ if !isBrewBuild(build) {
+ continue
+ }
+ installs = append(
+ installs,
+ fmt.Sprintf(`bin.install "%s"`, build.Binary),
+ )
+ }
+ ctx.Config.Brew.Install = strings.Join(installs, "\n")
+ }
+
+ if ctx.Config.Brew.CommitAuthor.Name == "" {
+ ctx.Config.Brew.CommitAuthor.Name = "goreleaserbot"
+ }
+ if ctx.Config.Brew.CommitAuthor.Email == "" {
+ ctx.Config.Brew.CommitAuthor.Email = "goreleaser@carlosbecker.com"
+ }
+ return nil
+}
+
+func isBrewBuild(build config.Build) bool {
+ for _, ignore := range build.Ignore {
+ if ignore.Goos == "darwin" && ignore.Goarch == "amd64" {
+ return false
+ }
+ }
+ return contains(build.Goos, "darwin") && contains(build.Goarch, "amd64")
+}
+
+func contains(ss []string, s string) bool {
+ for _, zs := range ss {
+ if zs == s {
+ return true
+ }
+ }
+ return false
+}
+
func doRun(ctx *context.Context, client client.Client) error {
if !ctx.Publish {
return pipeline.Skip("--skip-publish is set")
@@ -71,9 +115,21 @@ func doRun(ctx *context.Context, client client.Client) error {
if err != nil {
return err
}
+ ctx.AddBrew(brewTapPath(ctx))
return client.CreateFile(ctx, content, path)
}
+func brewTapPath(ctx *context.Context) string {
+ return strings.Join(
+ []string{
+ ctx.Config.Brew.GitHub.Owner,
+ strings.TrimPrefix(ctx.Config.Brew.GitHub.Name, "homebrew-"),
+ ctx.Config.ProjectName,
+ },
+ "/",
+ )
+}
+
func buildFormula(ctx *context.Context, client client.Client, folder string) (bytes.Buffer, error) {
data, err := dataFor(ctx, client, folder)
if err != nil {
diff --git a/pipeline/brew/brew_test.go b/pipeline/brew/brew_test.go
index ae910e306..8d225c3b6 100644
--- a/pipeline/brew/brew_test.go
+++ b/pipeline/brew/brew_test.go
@@ -14,7 +14,7 @@ import (
)
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestNameWithDash(t *testing.T) {
@@ -139,6 +139,8 @@ func TestRunPipe(t *testing.T) {
// ioutil.WriteFile("testdata/run_pipe.rb", []byte(client.Content), 0644)
assert.Equal(t, string(bts), client.Content)
+
+ assert.Equal(t, "test/test/run-pipe", ctx.Brews[0])
}
func TestRunPipeFormatOverride(t *testing.T) {
@@ -268,6 +270,54 @@ func TestRunPipeFormatBinary(t *testing.T) {
assert.False(t, client.CreatedFile)
}
+func TestDefault(t *testing.T) {
+ _, back := testlib.Mktmp(t)
+ defer back()
+
+ var ctx = &context.Context{
+ Config: config.Project{
+ Builds: []config.Build{
+ {
+ Binary: "foo",
+ Goos: []string{"linux", "darwin"},
+ Goarch: []string{"386", "amd64"},
+ },
+ {
+ Binary: "bar",
+ Goos: []string{"linux", "darwin"},
+ Goarch: []string{"386", "amd64"},
+ Ignore: []config.IgnoredBuild{
+ {Goos: "darwin", Goarch: "amd64"},
+ },
+ },
+ {
+ Binary: "foobar",
+ Goos: []string{"linux"},
+ Goarch: []string{"amd64"},
+ },
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.NotEmpty(t, ctx.Config.Brew.CommitAuthor.Name)
+ assert.NotEmpty(t, ctx.Config.Brew.CommitAuthor.Email)
+ assert.Equal(t, `bin.install "foo"`, ctx.Config.Brew.Install)
+}
+
+func TestBrewTapPath(t *testing.T) {
+ assert.Equal(t, "goreleaser/tap/goreleaser", brewTapPath(&context.Context{
+ Config: config.Project{
+ ProjectName: "goreleaser",
+ Brew: config.Homebrew{
+ GitHub: config.Repo{
+ Owner: "goreleaser",
+ Name: "homebrew-tap",
+ },
+ },
+ },
+ }))
+}
+
type DummyClient struct {
CreatedFile bool
Content string
diff --git a/pipeline/build/build.go b/pipeline/build/build.go
index 9f9f2b73b..1aef8e5a1 100644
--- a/pipeline/build/build.go
+++ b/pipeline/build/build.go
@@ -1,12 +1,6 @@
-// Package build implements Pipe and can build Go projects for
-// several platforms, with pre and post hook support.
package build
import (
- "fmt"
- "go/ast"
- "go/parser"
- "go/token"
"os"
"os/exec"
"path/filepath"
@@ -17,7 +11,6 @@ import (
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/buildtarget"
"github.com/goreleaser/goreleaser/internal/ext"
- "github.com/goreleaser/goreleaser/internal/name"
"github.com/pkg/errors"
"golang.org/x/sync/errgroup"
)
@@ -25,9 +18,8 @@ import (
// Pipe for build
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Building binaries"
+func (Pipe) String() string {
+ return "building binaries"
}
// Run the pipe
@@ -44,50 +36,39 @@ func (Pipe) Run(ctx *context.Context) error {
return nil
}
-func checkMain(ctx *context.Context, build config.Build) error {
- var main = build.Main
- if main == "" {
- main = "."
+// Default sets the pipe defaults
+func (Pipe) Default(ctx *context.Context) error {
+ for i, build := range ctx.Config.Builds {
+ ctx.Config.Builds[i] = buildWithDefaults(ctx, build)
}
- stat, ferr := os.Stat(main)
- if os.IsNotExist(ferr) {
- return errors.Wrapf(ferr, "could not open %s", main)
- }
- if stat.IsDir() {
- packs, err := parser.ParseDir(token.NewFileSet(), main, nil, 0)
- if err != nil {
- return errors.Wrapf(err, "failed to parse dir: %s", main)
+ if len(ctx.Config.Builds) == 0 {
+ ctx.Config.Builds = []config.Build{
+ buildWithDefaults(ctx, ctx.Config.SingleBuild),
}
- for _, pack := range packs {
- for _, file := range pack.Files {
- if hasMain(file) {
- return nil
- }
- }
- }
- return fmt.Errorf("build for %s does not contain a main function", build.Binary)
}
- file, err := parser.ParseFile(token.NewFileSet(), build.Main, nil, 0)
- if err != nil {
- return errors.Wrapf(err, "failed to parse file: %s", build.Main)
- }
- if hasMain(file) {
- return nil
- }
- return fmt.Errorf("build for %s does not contain a main function", build.Binary)
+ return nil
}
-func hasMain(file *ast.File) bool {
- for _, decl := range file.Decls {
- fn, isFn := decl.(*ast.FuncDecl)
- if !isFn {
- continue
- }
- if fn.Name.Name == "main" && fn.Recv == nil {
- return true
- }
+func buildWithDefaults(ctx *context.Context, build config.Build) config.Build {
+ if build.Binary == "" {
+ build.Binary = ctx.Config.Release.GitHub.Name
}
- return false
+ if build.Main == "" {
+ build.Main = "."
+ }
+ if len(build.Goos) == 0 {
+ build.Goos = []string{"linux", "darwin"}
+ }
+ if len(build.Goarch) == 0 {
+ build.Goarch = []string{"amd64", "386"}
+ }
+ if len(build.Goarm) == 0 {
+ build.Goarm = []string{"6"}
+ }
+ if build.Ldflags == "" {
+ build.Ldflags = "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}"
+ }
+ return build
}
func runPipeOnBuild(ctx *context.Context, build config.Build) error {
@@ -123,19 +104,20 @@ func runHook(env []string, hook string) error {
}
func doBuild(ctx *context.Context, build config.Build, target buildtarget.Target) error {
- folder, err := name.For(ctx, target)
- if err != nil {
- return err
- }
var binaryName = build.Binary + ext.For(target)
var prettyName = binaryName
if ctx.Config.Archive.Format == "binary" {
- binaryName, err = name.ForBuild(ctx, build, target)
+ var err error
+ binaryName, err = nameFor(ctx, target, build.Binary)
if err != nil {
return err
}
binaryName = binaryName + ext.For(target)
}
+ folder, err := nameFor(ctx, target, ctx.Config.ProjectName)
+ if err != nil {
+ return err
+ }
var binary = filepath.Join(ctx.Config.Dist, folder, binaryName)
ctx.AddBinary(target.String(), folder, prettyName, binary)
log.WithField("binary", binary).Info("building")
diff --git a/pipeline/build/build_test.go b/pipeline/build/build_test.go
index 765a4d10d..c4c01934a 100644
--- a/pipeline/build/build_test.go
+++ b/pipeline/build/build_test.go
@@ -17,7 +17,7 @@ import (
var emptyEnv []string
func TestPipeDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestRun(t *testing.T) {
@@ -67,6 +67,12 @@ func TestRunFullPipe(t *testing.T) {
},
},
},
+ Archive: config.Archive{
+ Replacements: map[string]string{
+ "linux": "linuxx",
+ "darwin": "darwinn",
+ },
+ },
}
assert.NoError(t, Pipe{}.Run(context.New(config)))
assert.True(t, exists(binary), binary)
@@ -78,7 +84,7 @@ func TestRunPipeFormatBinary(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
- var binary = filepath.Join(folder, "binary-testing")
+ var binary = filepath.Join(folder, "binary-testing-bar")
var config = config.Project{
ProjectName: "testing",
Dist: folder,
@@ -95,10 +101,12 @@ func TestRunPipeFormatBinary(t *testing.T) {
},
Archive: config.Archive{
Format: "binary",
- NameTemplate: "binary-{{.Binary}}",
+ NameTemplate: "binary-{{.Binary}}-{{.Env.Foo}}",
},
}
- assert.NoError(t, Pipe{}.Run(context.New(config)))
+ ctx := context.New(config)
+ ctx.Env = map[string]string{"Foo": "bar"}
+ assert.NoError(t, Pipe{}.Run(ctx))
assert.True(t, exists(binary))
}
@@ -174,27 +182,33 @@ func TestRunInvalidNametemplate(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
- for _, format := range []string{"tar.gz", "zip", "binary"} {
- var config = config.Project{
- ProjectName: "nameeeee",
- Builds: []config.Build{
- {
- Binary: "namet{{.est}",
- Flags: "-v",
- Goos: []string{
- runtime.GOOS,
- },
- Goarch: []string{
- runtime.GOARCH,
+ for format, msg := range map[string]string{
+ "binary": `template: bar:1: unexpected "}" in operand`,
+ "tar.gz": `template: foo:1: unexpected "}" in operand`,
+ "zip": `template: foo:1: unexpected "}" in operand`,
+ } {
+ t.Run(format, func(t *testing.T) {
+ var config = config.Project{
+ ProjectName: "foo",
+ Builds: []config.Build{
+ {
+ Binary: "bar",
+ Flags: "-v",
+ Goos: []string{
+ runtime.GOOS,
+ },
+ Goarch: []string{
+ runtime.GOARCH,
+ },
},
},
- },
- Archive: config.Archive{
- Format: format,
- NameTemplate: "{{.Binary}",
- },
- }
- assert.EqualError(t, Pipe{}.Run(context.New(config)), `template: nameeeee:1: unexpected "}" in operand`)
+ Archive: config.Archive{
+ Format: format,
+ NameTemplate: "{{.Binary}",
+ },
+ }
+ assert.EqualError(t, Pipe{}.Run(context.New(config)), msg)
+ })
}
}
@@ -326,6 +340,95 @@ func TestRunPipeWithMainFuncNotInMainGoFile(t *testing.T) {
})
}
+func TestDefaultNoBuilds(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{},
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+}
+
+func TestDefaultEmptyBuild(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Release: config.Release{
+ GitHub: config.Repo{
+ Name: "foo",
+ },
+ },
+ Builds: []config.Build{
+ {},
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ var build = ctx.Config.Builds[0]
+ assert.Equal(t, ctx.Config.Release.GitHub.Name, build.Binary)
+ assert.Equal(t, ".", build.Main)
+ assert.Equal(t, []string{"linux", "darwin"}, build.Goos)
+ assert.Equal(t, []string{"amd64", "386"}, build.Goarch)
+ assert.Equal(t, []string{"6"}, build.Goarm)
+ assert.Equal(t, "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}", build.Ldflags)
+}
+
+func TestDefaultPartialBuilds(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Builds: []config.Build{
+ {
+ Binary: "bar",
+ Goos: []string{"linux"},
+ Main: "./cmd/main.go",
+ },
+ {
+ Binary: "foo",
+ Ldflags: "-s -w",
+ Goarch: []string{"386"},
+ },
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ t.Run("build0", func(t *testing.T) {
+ var build = ctx.Config.Builds[0]
+ assert.Equal(t, "bar", build.Binary)
+ assert.Equal(t, "./cmd/main.go", build.Main)
+ assert.Equal(t, []string{"linux"}, build.Goos)
+ assert.Equal(t, []string{"amd64", "386"}, build.Goarch)
+ assert.Equal(t, []string{"6"}, build.Goarm)
+ assert.Equal(t, "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}", build.Ldflags)
+ })
+ t.Run("build1", func(t *testing.T) {
+ var build = ctx.Config.Builds[1]
+ assert.Equal(t, "foo", build.Binary)
+ assert.Equal(t, ".", build.Main)
+ assert.Equal(t, []string{"linux", "darwin"}, build.Goos)
+ assert.Equal(t, []string{"386"}, build.Goarch)
+ assert.Equal(t, []string{"6"}, build.Goarm)
+ assert.Equal(t, "-s -w", build.Ldflags)
+ })
+}
+
+func TestDefaultFillSingleBuild(t *testing.T) {
+ _, back := testlib.Mktmp(t)
+ defer back()
+
+ var ctx = &context.Context{
+ Config: config.Project{
+ Release: config.Release{
+ GitHub: config.Repo{
+ Name: "foo",
+ },
+ },
+ SingleBuild: config.Build{
+ Main: "testreleaser",
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Len(t, ctx.Config.Builds, 1)
+ assert.Equal(t, ctx.Config.Builds[0].Binary, "foo")
+}
+
func exists(file string) bool {
_, err := os.Stat(file)
return !os.IsNotExist(err)
diff --git a/pipeline/build/checkmain.go b/pipeline/build/checkmain.go
new file mode 100644
index 000000000..f89fde77b
--- /dev/null
+++ b/pipeline/build/checkmain.go
@@ -0,0 +1,59 @@
+package build
+
+import (
+ "fmt"
+ "go/ast"
+ "go/parser"
+ "go/token"
+ "os"
+
+ "github.com/goreleaser/goreleaser/config"
+ "github.com/goreleaser/goreleaser/context"
+ "github.com/pkg/errors"
+)
+
+func checkMain(ctx *context.Context, build config.Build) error {
+ var main = build.Main
+ if main == "" {
+ main = "."
+ }
+ stat, ferr := os.Stat(main)
+ if os.IsNotExist(ferr) {
+ return errors.Wrapf(ferr, "could not open %s", main)
+ }
+ if stat.IsDir() {
+ packs, err := parser.ParseDir(token.NewFileSet(), main, nil, 0)
+ if err != nil {
+ return errors.Wrapf(err, "failed to parse dir: %s", main)
+ }
+ for _, pack := range packs {
+ for _, file := range pack.Files {
+ if hasMain(file) {
+ return nil
+ }
+ }
+ }
+ return fmt.Errorf("build for %s does not contain a main function", build.Binary)
+ }
+ file, err := parser.ParseFile(token.NewFileSet(), build.Main, nil, 0)
+ if err != nil {
+ return errors.Wrapf(err, "failed to parse file: %s", build.Main)
+ }
+ if hasMain(file) {
+ return nil
+ }
+ return fmt.Errorf("build for %s does not contain a main function", build.Binary)
+}
+
+func hasMain(file *ast.File) bool {
+ for _, decl := range file.Decls {
+ fn, isFn := decl.(*ast.FuncDecl)
+ if !isFn {
+ continue
+ }
+ if fn.Name.Name == "main" && fn.Recv == nil {
+ return true
+ }
+ }
+ return false
+}
diff --git a/pipeline/build/doc.go b/pipeline/build/doc.go
new file mode 100644
index 000000000..e4d81c9af
--- /dev/null
+++ b/pipeline/build/doc.go
@@ -0,0 +1,5 @@
+// Package build implements Piper and Defaulter and can build Go projects for
+// several platforms, with pre and post hook support.
+// Build also checks wether the current project has a main function, parses
+// ldflags and other goodies.
+package build
diff --git a/pipeline/build/ldflags.go b/pipeline/build/ldflags.go
index cf6633616..f21061287 100644
--- a/pipeline/build/ldflags.go
+++ b/pipeline/build/ldflags.go
@@ -14,6 +14,7 @@ type ldflagsData struct {
Tag string
Commit string
Version string
+ Env map[string]string
}
func ldflags(ctx *context.Context, build config.Build) (string, error) {
@@ -22,6 +23,7 @@ func ldflags(ctx *context.Context, build config.Build) (string, error) {
Tag: ctx.Git.CurrentTag,
Version: ctx.Version,
Date: time.Now().UTC().Format(time.RFC3339),
+ Env: ctx.Env,
}
var out bytes.Buffer
t, err := template.New("ldflags").Parse(build.Ldflags)
diff --git a/pipeline/build/ldflags_test.go b/pipeline/build/ldflags_test.go
index ae3ea4250..d8a3c3e39 100644
--- a/pipeline/build/ldflags_test.go
+++ b/pipeline/build/ldflags_test.go
@@ -12,7 +12,7 @@ func TestLdFlagsFullTemplate(t *testing.T) {
var config = config.Project{
Builds: []config.Build{
{
- Ldflags: "-s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}}",
+ Ldflags: `-s -w -X main.version={{.Version}} -X main.tag={{.Tag}} -X main.date={{.Date}} -X main.commit={{.Commit}} -X "main.foo={{.Env.FOO}}"`,
},
},
}
@@ -23,6 +23,7 @@ func TestLdFlagsFullTemplate(t *testing.T) {
},
Version: "1.2.3",
Config: config,
+ Env: map[string]string{"FOO": "123"},
}
flags, err := ldflags(ctx, ctx.Config.Builds[0])
assert.NoError(t, err)
@@ -31,6 +32,7 @@ func TestLdFlagsFullTemplate(t *testing.T) {
assert.Contains(t, flags, "-X main.tag=v1.2.3")
assert.Contains(t, flags, "-X main.commit=123")
assert.Contains(t, flags, "-X main.date=")
+ assert.Contains(t, flags, `-X "main.foo=123"`)
}
func TestInvalidTemplate(t *testing.T) {
diff --git a/pipeline/build/name.go b/pipeline/build/name.go
new file mode 100644
index 000000000..5cd155103
--- /dev/null
+++ b/pipeline/build/name.go
@@ -0,0 +1,40 @@
+package build
+
+import (
+ "bytes"
+ "text/template"
+
+ "github.com/goreleaser/goreleaser/context"
+ "github.com/goreleaser/goreleaser/internal/buildtarget"
+)
+
+func nameFor(ctx *context.Context, target buildtarget.Target, name string) (string, error) {
+ var out bytes.Buffer
+ t, err := template.New(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, target.OS),
+ Arch: replace(ctx.Config.Archive.Replacements, target.Arch),
+ Arm: replace(ctx.Config.Archive.Replacements, target.Arm),
+ Version: ctx.Version,
+ Tag: ctx.Git.CurrentTag,
+ Binary: name, // TODO: deprecated: remove this sometime
+ ProjectName: name,
+ 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
+}
diff --git a/pipeline/changelog/changelog.go b/pipeline/changelog/changelog.go
index d72b974f9..4cd86354c 100644
--- a/pipeline/changelog/changelog.go
+++ b/pipeline/changelog/changelog.go
@@ -19,9 +19,8 @@ var ErrInvalidSortDirection = errors.New("invalid sort direction")
// Pipe for checksums
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Generating changelog"
+func (Pipe) String() string {
+ return "generating changelog"
}
// Run the pipe
@@ -125,7 +124,7 @@ func getChangelog(tag string) (string, error) {
}
func gitLog(refs ...string) (string, error) {
- var args = []string{"log", "--pretty=oneline", "--abbrev-commit"}
+ var args = []string{"log", "--pretty=oneline", "--abbrev-commit", "--no-decorate"}
args = append(args, refs...)
return git.Run(args...)
}
diff --git a/pipeline/changelog/changelog_test.go b/pipeline/changelog/changelog_test.go
index 55a776b2d..5cf58fd90 100644
--- a/pipeline/changelog/changelog_test.go
+++ b/pipeline/changelog/changelog_test.go
@@ -12,7 +12,7 @@ import (
)
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestChangelogProvidedViaFlag(t *testing.T) {
diff --git a/pipeline/checksums/checksums.go b/pipeline/checksums/checksums.go
index 5373598c4..5051c66be 100644
--- a/pipeline/checksums/checksums.go
+++ b/pipeline/checksums/checksums.go
@@ -10,21 +10,19 @@ import (
"github.com/apex/log"
"github.com/goreleaser/goreleaser/checksum"
"github.com/goreleaser/goreleaser/context"
- "github.com/goreleaser/goreleaser/internal/name"
"golang.org/x/sync/errgroup"
)
// Pipe for checksums
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Calculating checksums"
+func (Pipe) String() string {
+ return "calculating checksums"
}
// Run the pipe
func (Pipe) Run(ctx *context.Context) (err error) {
- filename, err := name.ForChecksums(ctx)
+ filename, err := filenameFor(ctx)
if err != nil {
return err
}
@@ -52,6 +50,14 @@ func (Pipe) Run(ctx *context.Context) (err error) {
return g.Wait()
}
+// Default sets the pipe defaults
+func (Pipe) Default(ctx *context.Context) error {
+ if ctx.Config.Checksum.NameTemplate == "" {
+ ctx.Config.Checksum.NameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
+ }
+ return nil
+}
+
func checksums(ctx *context.Context, file *os.File, name string) error {
log.WithField("file", name).Info("checksumming")
var artifact = filepath.Join(ctx.Config.Dist, name)
diff --git a/pipeline/checksums/checksums_test.go b/pipeline/checksums/checksums_test.go
index 24d4a35c3..246eb299a 100644
--- a/pipeline/checksums/checksums_test.go
+++ b/pipeline/checksums/checksums_test.go
@@ -11,7 +11,7 @@ import (
)
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestPipe(t *testing.T) {
@@ -35,7 +35,7 @@ func TestPipe(t *testing.T) {
assert.Contains(t, ctx.Artifacts, checksums, binary)
bts, err := ioutil.ReadFile(filepath.Join(folder, checksums))
assert.NoError(t, err)
- assert.Equal(t, string(bts), "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc binary\n")
+ assert.Equal(t, "61d034473102d7dac305902770471fd50f4c5b26f6831a56dd90b5184b3c30fc binary\n", string(bts))
}
func TestPipeFileNotExist(t *testing.T) {
@@ -70,7 +70,7 @@ func TestPipeInvalidNameTemplate(t *testing.T) {
ctx.AddArtifact("whatever")
err = Pipe{}.Run(ctx)
assert.Error(t, err)
- assert.Equal(t, `template: name:1: unexpected "}" in operand`, err.Error())
+ assert.Equal(t, `template: checksums:1: unexpected "}" in operand`, err.Error())
}
func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) {
@@ -91,3 +91,29 @@ func TestPipeCouldNotOpenChecksumsTxt(t *testing.T) {
assert.Error(t, err)
assert.Contains(t, err.Error(), "/checksums.txt: permission denied")
}
+
+func TestDefault(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Checksum: config.Checksum{},
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Equal(
+ t,
+ "{{ .ProjectName }}_{{ .Version }}_checksums.txt",
+ ctx.Config.Checksum.NameTemplate,
+ )
+}
+
+func TestDefaultSet(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Checksum: config.Checksum{
+ NameTemplate: "checksums.txt",
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Equal(t, "checksums.txt", ctx.Config.Checksum.NameTemplate)
+}
diff --git a/pipeline/checksums/name.go b/pipeline/checksums/name.go
new file mode 100644
index 000000000..9d7a41c45
--- /dev/null
+++ b/pipeline/checksums/name.go
@@ -0,0 +1,24 @@
+package checksums
+
+import (
+ "bytes"
+ "text/template"
+
+ "github.com/goreleaser/goreleaser/context"
+)
+
+func filenameFor(ctx *context.Context) (string, error) {
+ var out bytes.Buffer
+ t, err := template.New("checksums").Parse(ctx.Config.Checksum.NameTemplate)
+ if err != nil {
+ return "", err
+ }
+ err = t.Execute(&out, struct {
+ ProjectName, Tag, Version string
+ }{
+ ProjectName: ctx.Config.ProjectName,
+ Tag: ctx.Git.CurrentTag,
+ Version: ctx.Version,
+ })
+ return out.String(), err
+}
diff --git a/pipeline/cleandist/dist.go b/pipeline/cleandist/dist.go
index 6e19ca7c3..412d6ac78 100644
--- a/pipeline/cleandist/dist.go
+++ b/pipeline/cleandist/dist.go
@@ -14,9 +14,8 @@ import (
// Pipe for cleandis
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Checking ./dist"
+func (Pipe) String() string {
+ return "checking ./dist"
}
// Run the pipe
diff --git a/pipeline/cleandist/dist_test.go b/pipeline/cleandist/dist_test.go
index 3c3628e29..7429d45ad 100644
--- a/pipeline/cleandist/dist_test.go
+++ b/pipeline/cleandist/dist_test.go
@@ -59,5 +59,5 @@ func TestEmptyDistExists(t *testing.T) {
}
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
diff --git a/pipeline/default.go b/pipeline/default.go
new file mode 100644
index 000000000..5a9d2e329
--- /dev/null
+++ b/pipeline/default.go
@@ -0,0 +1,16 @@
+package pipeline
+
+import (
+ "fmt"
+
+ "github.com/goreleaser/goreleaser/context"
+)
+
+// Defaulter can be implemented by a Piper to set default values for its
+// configuration.
+type Defaulter interface {
+ fmt.Stringer
+
+ // Default sets the configuration defaults
+ Default(ctx *context.Context) error
+}
diff --git a/pipeline/defaults/defaults.go b/pipeline/defaults/defaults.go
index 8fd1bf97a..c1e69cd76 100644
--- a/pipeline/defaults/defaults.go
+++ b/pipeline/defaults/defaults.go
@@ -3,190 +3,51 @@
package defaults
import (
- "fmt"
- "strings"
-
"github.com/apex/log"
- "github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
+ "github.com/goreleaser/goreleaser/pipeline"
+ "github.com/goreleaser/goreleaser/pipeline/archive"
+ "github.com/goreleaser/goreleaser/pipeline/brew"
+ "github.com/goreleaser/goreleaser/pipeline/build"
+ "github.com/goreleaser/goreleaser/pipeline/checksums"
+ "github.com/goreleaser/goreleaser/pipeline/docker"
+ "github.com/goreleaser/goreleaser/pipeline/fpm"
+ "github.com/goreleaser/goreleaser/pipeline/release"
+ "github.com/goreleaser/goreleaser/pipeline/snapshot"
)
-// NameTemplate default name_template for the archive.
-const NameTemplate = "{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
-
-// ReleaseNameTemplate is the default name for the release.
-const ReleaseNameTemplate = "{{.Tag}}"
-
-// SnapshotNameTemplate represents the default format for snapshot release names.
-const SnapshotNameTemplate = "SNAPSHOT-{{ .Commit }}"
-
-// ChecksumNameTemplate is the default name_template for the checksum file.
-const ChecksumNameTemplate = "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
-
// Pipe for brew deployment
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Setting defaults"
+func (Pipe) String() string {
+ return "setting defaults for:"
+}
+
+var defaulters = []pipeline.Defaulter{
+ snapshot.Pipe{},
+ release.Pipe{},
+ archive.Pipe{},
+ build.Pipe{},
+ fpm.Pipe{},
+ checksums.Pipe{},
+ docker.Pipe{},
+ brew.Pipe{},
}
// Run the pipe
-func (Pipe) Run(ctx *context.Context) error { // nolint: gocyclo
+func (Pipe) Run(ctx *context.Context) error {
if ctx.Config.Dist == "" {
ctx.Config.Dist = "dist"
}
- if ctx.Config.Release.NameTemplate == "" {
- ctx.Config.Release.NameTemplate = ReleaseNameTemplate
- }
- if ctx.Config.Snapshot.NameTemplate == "" {
- ctx.Config.Snapshot.NameTemplate = SnapshotNameTemplate
- }
- if ctx.Config.Checksum.NameTemplate == "" {
- ctx.Config.Checksum.NameTemplate = ChecksumNameTemplate
- }
- if err := setReleaseDefaults(ctx); err != nil {
- return err
+ for _, defaulter := range defaulters {
+ log.Infof("\t%s", defaulter.String())
+ if err := defaulter.Default(ctx); err != nil {
+ return err
+ }
}
if ctx.Config.ProjectName == "" {
ctx.Config.ProjectName = ctx.Config.Release.GitHub.Name
}
-
- setBuildDefaults(ctx)
-
- if ctx.Config.Brew.Install == "" {
- var installs []string
- for _, build := range ctx.Config.Builds {
- if !isBrewBuild(build) {
- continue
- }
- installs = append(
- installs,
- fmt.Sprintf(`bin.install "%s"`, build.Binary),
- )
- }
- ctx.Config.Brew.Install = strings.Join(installs, "\n")
- }
-
- if ctx.Config.Brew.CommitAuthor.Name == "" {
- ctx.Config.Brew.CommitAuthor.Name = "goreleaserbot"
- }
- if ctx.Config.Brew.CommitAuthor.Email == "" {
- ctx.Config.Brew.CommitAuthor.Email = "goreleaser@carlosbecker.com"
- }
-
- err := setArchiveDefaults(ctx)
- setDockerDefaults(ctx)
- setFpmDefaults(ctx)
log.WithField("config", ctx.Config).Debug("defaults set")
- return err
-}
-
-func setDockerDefaults(ctx *context.Context) {
- if len(ctx.Config.Dockers) != 1 {
- return
- }
- if ctx.Config.Dockers[0].Goos == "" {
- ctx.Config.Dockers[0].Goos = "linux"
- }
- if ctx.Config.Dockers[0].Goarch == "" {
- ctx.Config.Dockers[0].Goarch = "amd64"
- }
- if ctx.Config.Dockers[0].Binary == "" {
- ctx.Config.Dockers[0].Binary = ctx.Config.Builds[0].Binary
- }
- if ctx.Config.Dockers[0].Dockerfile == "" {
- ctx.Config.Dockers[0].Dockerfile = "Dockerfile"
- }
-}
-
-func isBrewBuild(build config.Build) bool {
- for _, ignore := range build.Ignore {
- if ignore.Goos == "darwin" && ignore.Goarch == "amd64" {
- return false
- }
- }
- return contains(build.Goos, "darwin") && contains(build.Goarch, "amd64")
-}
-
-func contains(ss []string, s string) bool {
- for _, zs := range ss {
- if zs == s {
- return true
- }
- }
- return false
-}
-
-func setReleaseDefaults(ctx *context.Context) error {
- if ctx.Config.Release.GitHub.Name != "" {
- return nil
- }
- repo, err := remoteRepo()
- if err != nil {
- return err
- }
- ctx.Config.Release.GitHub = repo
return nil
}
-
-func setBuildDefaults(ctx *context.Context) {
- for i, build := range ctx.Config.Builds {
- ctx.Config.Builds[i] = buildWithDefaults(ctx, build)
- }
- if len(ctx.Config.Builds) == 0 {
- ctx.Config.Builds = []config.Build{
- buildWithDefaults(ctx, ctx.Config.SingleBuild),
- }
- }
-}
-
-func buildWithDefaults(ctx *context.Context, build config.Build) config.Build {
- if build.Binary == "" {
- build.Binary = ctx.Config.Release.GitHub.Name
- }
- if build.Main == "" {
- build.Main = "."
- }
- if len(build.Goos) == 0 {
- build.Goos = []string{"linux", "darwin"}
- }
- if len(build.Goarch) == 0 {
- build.Goarch = []string{"amd64", "386"}
- }
- if len(build.Goarm) == 0 {
- build.Goarm = []string{"6"}
- }
- if build.Ldflags == "" {
- build.Ldflags = "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}"
- }
- return build
-}
-
-func setArchiveDefaults(ctx *context.Context) error {
- if ctx.Config.Archive.NameTemplate == "" {
- ctx.Config.Archive.NameTemplate = NameTemplate
- }
- 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 setFpmDefaults(ctx *context.Context) {
- if ctx.Config.FPM.Bindir == "" {
- ctx.Config.FPM.Bindir = "/usr/local/bin"
- }
-}
diff --git a/pipeline/defaults/defaults_test.go b/pipeline/defaults/defaults_test.go
index 0130a9aab..70a7ce0cc 100644
--- a/pipeline/defaults/defaults_test.go
+++ b/pipeline/defaults/defaults_test.go
@@ -10,7 +10,7 @@ import (
)
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestFillBasicData(t *testing.T) {
@@ -90,42 +90,3 @@ func TestFillPartial(t *testing.T) {
assert.Empty(t, ctx.Config.Dockers[0].Goarm)
assert.Equal(t, "disttt", ctx.Config.Dist)
}
-
-func TestFillSingleBuild(t *testing.T) {
- _, back := testlib.Mktmp(t)
- defer back()
- testlib.GitInit(t)
- testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git")
-
- var ctx = &context.Context{
- Config: config.Project{
- SingleBuild: config.Build{
- Main: "testreleaser",
- },
- },
- }
- assert.NoError(t, Pipe{}.Run(ctx))
- assert.Len(t, ctx.Config.Builds, 1)
- assert.Equal(t, ctx.Config.Builds[0].Binary, "goreleaser")
-}
-
-func TestNotAGitRepo(t *testing.T) {
- _, back := testlib.Mktmp(t)
- defer back()
- testlib.GitInit(t)
- var ctx = &context.Context{
- Config: config.Project{},
- }
- assert.Error(t, Pipe{}.Run(ctx))
- assert.Empty(t, ctx.Config.Release.GitHub.String())
-}
-
-func TestGitRepoWithoutRemote(t *testing.T) {
- _, back := testlib.Mktmp(t)
- defer back()
- var ctx = &context.Context{
- Config: config.Project{},
- }
- assert.Error(t, Pipe{}.Run(ctx))
- assert.Empty(t, ctx.Config.Release.GitHub.String())
-}
diff --git a/pipeline/docker/docker.go b/pipeline/docker/docker.go
index d94574006..88a2fad49 100644
--- a/pipeline/docker/docker.go
+++ b/pipeline/docker/docker.go
@@ -2,17 +2,17 @@
package docker
import (
+ "bytes"
"fmt"
"os"
"os/exec"
"path/filepath"
+ "text/template"
+ "github.com/apex/log"
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/pipeline"
-
- "github.com/apex/log"
-
"github.com/pkg/errors"
)
@@ -22,9 +22,8 @@ var ErrNoDocker = errors.New("docker not present in $PATH")
// Pipe for docker
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Creating Docker images"
+func (Pipe) String() string {
+ return "creating Docker images"
}
// Run the pipe
@@ -39,6 +38,32 @@ func (Pipe) Run(ctx *context.Context) error {
return doRun(ctx)
}
+// Default sets the pipe defaults
+func (Pipe) Default(ctx *context.Context) error {
+ for i := range ctx.Config.Dockers {
+ if ctx.Config.Dockers[i].TagTemplate == "" {
+ ctx.Config.Dockers[i].TagTemplate = "{{ .Version }}"
+ }
+ }
+ // only set defaults if there is exacly 1 docker setup in the config file.
+ if len(ctx.Config.Dockers) != 1 {
+ return nil
+ }
+ if ctx.Config.Dockers[0].Goos == "" {
+ ctx.Config.Dockers[0].Goos = "linux"
+ }
+ if ctx.Config.Dockers[0].Goarch == "" {
+ ctx.Config.Dockers[0].Goarch = "amd64"
+ }
+ if ctx.Config.Dockers[0].Binary == "" {
+ ctx.Config.Dockers[0].Binary = ctx.Config.Builds[0].Binary
+ }
+ if ctx.Config.Dockers[0].Dockerfile == "" {
+ ctx.Config.Dockers[0].Dockerfile = "Dockerfile"
+ }
+ return nil
+}
+
func doRun(ctx *context.Context) error {
for _, docker := range ctx.Config.Dockers {
var imagePlatform = docker.Goos + docker.Goarch + docker.Goarm
@@ -62,10 +87,32 @@ func doRun(ctx *context.Context) error {
return nil
}
+func tagName(ctx *context.Context, docker config.Docker) (string, error) {
+ var out bytes.Buffer
+ t, err := template.New("tag").Parse(docker.TagTemplate)
+ if err != nil {
+ return "", err
+ }
+ data := struct {
+ Version, Tag string
+ Env map[string]string
+ }{
+ Version: ctx.Version,
+ Tag: ctx.Git.CurrentTag,
+ Env: ctx.Env,
+ }
+ err = t.Execute(&out, data)
+ return out.String(), err
+}
+
func process(ctx *context.Context, folder string, docker config.Docker, binary context.Binary) error {
var root = filepath.Join(ctx.Config.Dist, folder)
var dockerfile = filepath.Join(root, filepath.Base(docker.Dockerfile))
- var image = fmt.Sprintf("%s:%s", docker.Image, ctx.Version)
+ tag, err := tagName(ctx, docker)
+ if err != nil {
+ return err
+ }
+ var image = fmt.Sprintf("%s:%s", docker.Image, tag)
var latest = fmt.Sprintf("%s:latest", docker.Image)
if err := os.Link(docker.Dockerfile, dockerfile); err != nil {
diff --git a/pipeline/docker/docker_test.go b/pipeline/docker/docker_test.go
index 0e2e74003..04d9348a7 100644
--- a/pipeline/docker/docker_test.go
+++ b/pipeline/docker/docker_test.go
@@ -8,11 +8,9 @@ import (
"testing"
"github.com/apex/log"
-
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/pipeline"
-
"github.com/stretchr/testify/assert"
)
@@ -42,50 +40,89 @@ func TestRunPipe(t *testing.T) {
var binPath = filepath.Join(dist, "mybin", "mybin")
_, err = os.Create(binPath)
assert.NoError(t, err)
+
+ var table = map[string]struct {
+ docker config.Docker
+ err string
+ }{
+ "valid": {
+ docker: config.Docker{
+ Image: "localhost:5000/goreleaser/test_run_pipe",
+ Goos: "linux",
+ Goarch: "amd64",
+ Dockerfile: "testdata/Dockerfile",
+ Binary: "mybin",
+ Latest: true,
+ TagTemplate: "{{.Tag}}-{{.Env.FOO}}",
+ },
+ err: "",
+ },
+ "invalid": {
+ docker: config.Docker{
+ Image: "localhost:5000/goreleaser/test_run_pipe_nope",
+ Goos: "linux",
+ Goarch: "amd64",
+ Dockerfile: "testdata/Dockerfile",
+ Binary: "otherbin",
+ TagTemplate: "{{.Version}}",
+ },
+ err: "",
+ },
+ "template_error": {
+ docker: config.Docker{
+ Image: "localhost:5000/goreleaser/test_run_pipe_template_error",
+ Goos: "linux",
+ Goarch: "amd64",
+ Dockerfile: "testdata/Dockerfile",
+ Binary: "mybin",
+ Latest: true,
+ TagTemplate: "{{.Tag}",
+ },
+ err: `template: tag:1: unexpected "}" in operand`,
+ },
+ }
var images = []string{
- "localhost:5000/goreleaser/test_run_pipe:1.0.0",
+ "localhost:5000/goreleaser/test_run_pipe:v1.0.0-123",
"localhost:5000/goreleaser/test_run_pipe:latest",
}
// this might fail as the image doesnt exist yet, so lets ignore the error
for _, img := range images {
_ = exec.Command("docker", "rmi", img).Run()
}
- var ctx = &context.Context{
- Version: "1.0.0",
- Publish: true,
- Config: config.Project{
- ProjectName: "mybin",
- Dist: dist,
- Dockers: []config.Docker{
- {
- Image: "localhost:5000/goreleaser/test_run_pipe",
- Goos: "linux",
- Goarch: "amd64",
- Dockerfile: "testdata/Dockerfile",
- Binary: "mybin",
- Latest: true,
+
+ for name, docker := range table {
+ t.Run(name, func(t *testing.T) {
+ var ctx = &context.Context{
+ Version: "1.0.0",
+ Publish: true,
+ Git: context.GitInfo{
+ CurrentTag: "v1.0.0",
},
- {
- Image: "localhost:5000/goreleaser/test_run_pipe_nope",
- Goos: "linux",
- Goarch: "amd64",
- Dockerfile: "testdata/Dockerfile",
- Binary: "otherbin",
+ Config: config.Project{
+ ProjectName: "mybin",
+ Dist: dist,
+ Dockers: []config.Docker{
+ docker.docker,
+ },
},
- },
- },
+ Env: map[string]string{"FOO": "123"},
+ }
+ for _, plat := range []string{"linuxamd64", "linux386", "darwinamd64"} {
+ ctx.AddBinary(plat, "mybin", "mybin", binPath)
+ }
+ if docker.err == "" {
+ assert.NoError(t, Pipe{}.Run(ctx))
+ } else {
+ assert.EqualError(t, Pipe{}.Run(ctx), docker.err)
+ }
+ })
}
- for _, plat := range []string{"linuxamd64", "linux386", "darwinamd64"} {
- ctx.AddBinary(plat, "mybin", "mybin", binPath)
- }
- assert.NoError(t, Pipe{}.Run(ctx))
// this might should not fail as the image should have been created when
// the step ran
for _, img := range images {
assert.NoError(t, exec.Command("docker", "rmi", img).Run())
}
-
// the test_run_pipe_nope image should not have been created, so deleting
// it should fail
assert.Error(t,
@@ -96,7 +133,7 @@ func TestRunPipe(t *testing.T) {
}
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestNoDockers(t *testing.T) {
@@ -131,3 +168,61 @@ func TestDockerNotInPath(t *testing.T) {
}
assert.EqualError(t, Pipe{}.Run(ctx), ErrNoDocker.Error())
}
+
+func TestDefault(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Builds: []config.Build{
+ {
+ Binary: "foo",
+ },
+ },
+ Dockers: []config.Docker{
+ {
+ Latest: true,
+ },
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Len(t, ctx.Config.Dockers, 1)
+ var docker = ctx.Config.Dockers[0]
+ assert.Equal(t, "linux", docker.Goos)
+ assert.Equal(t, "amd64", docker.Goarch)
+ assert.Equal(t, ctx.Config.Builds[0].Binary, docker.Binary)
+ assert.Equal(t, "Dockerfile", docker.Dockerfile)
+ assert.Equal(t, "{{ .Version }}", docker.TagTemplate)
+}
+
+func TestDefaultNoDockers(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Dockers: []config.Docker{},
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Empty(t, ctx.Config.Dockers)
+}
+
+func TestDefaultSet(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Dockers: []config.Docker{
+ {
+ Goos: "windows",
+ Goarch: "i386",
+ Binary: "bar",
+ Dockerfile: "Dockerfile.foo",
+ },
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Len(t, ctx.Config.Dockers, 1)
+ var docker = ctx.Config.Dockers[0]
+ assert.Equal(t, "windows", docker.Goos)
+ assert.Equal(t, "i386", docker.Goarch)
+ assert.Equal(t, "bar", docker.Binary)
+ assert.Equal(t, "{{ .Version }}", docker.TagTemplate)
+ assert.Equal(t, "Dockerfile.foo", docker.Dockerfile)
+}
diff --git a/pipeline/env/env.go b/pipeline/env/env.go
index a2e8b72a3..1e199eb37 100644
--- a/pipeline/env/env.go
+++ b/pipeline/env/env.go
@@ -16,9 +16,8 @@ var ErrMissingToken = errors.New("missing GITHUB_TOKEN")
// Pipe for env
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Loading environment variables"
+func (Pipe) String() string {
+ return "loading environment variables"
}
// Run the pipe
diff --git a/pipeline/env/env_test.go b/pipeline/env/env_test.go
index b3ef5131d..d1981b24d 100644
--- a/pipeline/env/env_test.go
+++ b/pipeline/env/env_test.go
@@ -12,7 +12,7 @@ import (
)
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestValidEnv(t *testing.T) {
diff --git a/pipeline/fpm/fpm.go b/pipeline/fpm/fpm.go
index 2c9a1f5e3..141367cec 100644
--- a/pipeline/fpm/fpm.go
+++ b/pipeline/fpm/fpm.go
@@ -22,9 +22,16 @@ var ErrNoFPM = errors.New("fpm not present in $PATH")
// Pipe for fpm packaging
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Creating Linux packages with fpm"
+func (Pipe) String() string {
+ return "creating Linux packages with fpm"
+}
+
+// Default sets the pipe defaults
+func (Pipe) Default(ctx *context.Context) error {
+ if ctx.Config.FPM.Bindir == "" {
+ ctx.Config.FPM.Bindir = "/usr/local/bin"
+ }
+ return nil
}
// Run the pipe
diff --git a/pipeline/fpm/fpm_test.go b/pipeline/fpm/fpm_test.go
index 7a7baedc9..0c9f22f4f 100644
--- a/pipeline/fpm/fpm_test.go
+++ b/pipeline/fpm/fpm_test.go
@@ -14,7 +14,7 @@ import (
)
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestRunPipeNoFormats(t *testing.T) {
@@ -113,3 +113,25 @@ func TestRunPipeWithExtraFiles(t *testing.T) {
}
assert.NoError(t, Pipe{}.Run(ctx))
}
+
+func TestDefault(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ FPM: config.FPM{},
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Equal(t, "/usr/local/bin", ctx.Config.FPM.Bindir)
+}
+
+func TestDefaultSet(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ FPM: config.FPM{
+ Bindir: "/bin",
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Equal(t, "/bin", ctx.Config.FPM.Bindir)
+}
diff --git a/pipeline/git/git.go b/pipeline/git/git.go
index 884aaec82..ce514099c 100644
--- a/pipeline/git/git.go
+++ b/pipeline/git/git.go
@@ -19,9 +19,8 @@ import (
// Pipe for brew deployment
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Getting and validating git state"
+func (Pipe) String() string {
+ return "getting and validating git state"
}
// Run the pipe
diff --git a/pipeline/git/git_test.go b/pipeline/git/git_test.go
index ffe1dde24..7d34cce58 100644
--- a/pipeline/git/git_test.go
+++ b/pipeline/git/git_test.go
@@ -9,12 +9,11 @@ import (
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/testlib"
- "github.com/goreleaser/goreleaser/pipeline/defaults"
"github.com/stretchr/testify/assert"
)
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestNotAGitFolder(t *testing.T) {
@@ -57,7 +56,7 @@ func TestNoTagsSnapshot(t *testing.T) {
var ctx = &context.Context{
Config: config.Project{
Snapshot: config.Snapshot{
- NameTemplate: defaults.SnapshotNameTemplate,
+ NameTemplate: "SNAPSHOT-{{.Commit}}",
},
},
Snapshot: true,
@@ -95,7 +94,7 @@ func TestNoTagsNoSnapshot(t *testing.T) {
var ctx = &context.Context{
Config: config.Project{
Snapshot: config.Snapshot{
- NameTemplate: defaults.SnapshotNameTemplate,
+ NameTemplate: "SNAPSHOT-{{.Commit}}",
},
},
Snapshot: false,
diff --git a/pipeline/pipe.go b/pipeline/piper.go
similarity index 76%
rename from pipeline/pipe.go
rename to pipeline/piper.go
index f09b385aa..767250b50 100644
--- a/pipeline/pipe.go
+++ b/pipeline/piper.go
@@ -1,12 +1,15 @@
// Package pipeline provides a generic pipe interface.
package pipeline
-import "github.com/goreleaser/goreleaser/context"
+import (
+ "fmt"
-// Pipe interface
-type Pipe interface {
- // Name of the pipe
- Description() string
+ "github.com/goreleaser/goreleaser/context"
+)
+
+// Piper defines a pipe, which can be part of a pipeline (a serie of pipes).
+type Piper interface {
+ fmt.Stringer
// Run the pipe
Run(ctx *context.Context) error
diff --git a/pipeline/pipe_test.go b/pipeline/piper_test.go
similarity index 100%
rename from pipeline/pipe_test.go
rename to pipeline/piper_test.go
diff --git a/pipeline/release/body.go b/pipeline/release/body.go
index d4e4f1a64..54381e517 100644
--- a/pipeline/release/body.go
+++ b/pipeline/release/body.go
@@ -12,10 +12,18 @@ const bodyTemplate = `{{ .ReleaseNotes }}
{{- if .DockerImages }}
-Docker images:
+## Docker images
{{ range $element := .DockerImages }}
-- {{ . -}}
-{{ end -}}
+- ` + "`docker pull {{ . -}}`" + `
+{{- end -}}
+{{- end }}
+
+{{- if .Brews }}
+
+## Homebrew taps
+{{ range $element := .Brews }}
+- ` + "`brew install {{ . -}}`" + `
+{{- end -}}
{{- end }}
---
@@ -37,10 +45,12 @@ func describeBodyVersion(ctx *context.Context, version string) (bytes.Buffer, er
err := template.Execute(&out, struct {
ReleaseNotes, GoVersion string
DockerImages []string
+ Brews []string
}{
ReleaseNotes: ctx.ReleaseNotes,
GoVersion: version,
DockerImages: ctx.Dockers,
+ Brews: ctx.Brews,
})
return out, err
}
diff --git a/pipeline/release/body_test.go b/pipeline/release/body_test.go
index 754853eb6..ef23f2a35 100644
--- a/pipeline/release/body_test.go
+++ b/pipeline/release/body_test.go
@@ -15,7 +15,12 @@ func TestDescribeBody(t *testing.T) {
ReleaseNotes: changelog,
Dockers: []string{
"goreleaser/goreleaser:0.40.0",
- "goreleaser/godownloader:0.1.0",
+ "goreleaser/goreleaser:latest",
+ "goreleaser/godownloader:v0.1.0",
+ },
+ Brews: []string{
+ "caarlos0/tap/foo",
+ "goreleaser/tap/bar",
},
}
out, err := describeBodyVersion(ctx, "go version go1.9 darwin/amd64")
@@ -28,7 +33,7 @@ func TestDescribeBody(t *testing.T) {
assert.Equal(t, string(bts), out.String())
}
-func TestDescribeBodyNoDockerImages(t *testing.T) {
+func TestDescribeBodyNoDockerImagesNoBrews(t *testing.T) {
var changelog = "\nfeature1: description\nfeature2: other description"
var ctx = &context.Context{
ReleaseNotes: changelog,
diff --git a/pipeline/release/release.go b/pipeline/release/release.go
index 4336307c5..6644a3bab 100644
--- a/pipeline/release/release.go
+++ b/pipeline/release/release.go
@@ -16,9 +16,8 @@ import (
// Pipe for github release
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Releasing to GitHub"
+func (Pipe) String() string {
+ return "releasing to GitHub"
}
// Run the pipe
@@ -30,6 +29,22 @@ func (Pipe) Run(ctx *context.Context) error {
return doRun(ctx, c)
}
+// Default sets the pipe defaults
+func (Pipe) Default(ctx *context.Context) error {
+ if ctx.Config.Release.NameTemplate == "" {
+ ctx.Config.Release.NameTemplate = "{{.Tag}}"
+ }
+ if ctx.Config.Release.GitHub.Name != "" {
+ return nil
+ }
+ repo, err := remoteRepo()
+ if err != nil {
+ return err
+ }
+ ctx.Config.Release.GitHub = repo
+ return nil
+}
+
func doRun(ctx *context.Context, c client.Client) error {
if !ctx.Publish {
return pipeline.Skip("--skip-publish is set")
diff --git a/pipeline/release/release_test.go b/pipeline/release/release_test.go
index 82ef2b16a..6f2bd37c9 100644
--- a/pipeline/release/release_test.go
+++ b/pipeline/release/release_test.go
@@ -15,7 +15,7 @@ import (
)
func TestPipeDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestRunPipe(t *testing.T) {
@@ -122,6 +122,62 @@ func TestSkipPublish(t *testing.T) {
assert.False(t, client.UploadedFile)
}
+func TestDefault(t *testing.T) {
+ _, back := testlib.Mktmp(t)
+ defer back()
+ testlib.GitInit(t)
+ testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git")
+
+ var ctx = &context.Context{
+ Config: config.Project{},
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Equal(t, "goreleaser", ctx.Config.Release.GitHub.Name)
+ assert.Equal(t, "goreleaser", ctx.Config.Release.GitHub.Owner)
+}
+
+func TestDefaultFilled(t *testing.T) {
+ _, back := testlib.Mktmp(t)
+ defer back()
+ testlib.GitInit(t)
+ testlib.GitRemoteAdd(t, "git@github.com:goreleaser/goreleaser.git")
+
+ var ctx = &context.Context{
+ Config: config.Project{
+ Release: config.Release{
+ GitHub: config.Repo{
+ Name: "foo",
+ Owner: "bar",
+ },
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Equal(t, "foo", ctx.Config.Release.GitHub.Name)
+ assert.Equal(t, "bar", ctx.Config.Release.GitHub.Owner)
+}
+
+func TestDefaultNotAGitRepo(t *testing.T) {
+ _, back := testlib.Mktmp(t)
+ defer back()
+ testlib.GitInit(t)
+ var ctx = &context.Context{
+ Config: config.Project{},
+ }
+ assert.Error(t, Pipe{}.Default(ctx))
+ assert.Empty(t, ctx.Config.Release.GitHub.String())
+}
+
+func TestDefaultGitRepoWithoutRemote(t *testing.T) {
+ _, back := testlib.Mktmp(t)
+ defer back()
+ var ctx = &context.Context{
+ Config: config.Project{},
+ }
+ assert.Error(t, Pipe{}.Default(ctx))
+ assert.Empty(t, ctx.Config.Release.GitHub.String())
+}
+
type DummyClient struct {
FailToCreateRelease bool
FailToUpload bool
diff --git a/pipeline/defaults/remote.go b/pipeline/release/remote.go
similarity index 98%
rename from pipeline/defaults/remote.go
rename to pipeline/release/remote.go
index 194f32920..391e30be3 100644
--- a/pipeline/defaults/remote.go
+++ b/pipeline/release/remote.go
@@ -1,4 +1,4 @@
-package defaults
+package release
import (
"strings"
diff --git a/pipeline/defaults/remote_test.go b/pipeline/release/remote_test.go
similarity index 97%
rename from pipeline/defaults/remote_test.go
rename to pipeline/release/remote_test.go
index 4ecd8bcf2..39fdf46b7 100644
--- a/pipeline/defaults/remote_test.go
+++ b/pipeline/release/remote_test.go
@@ -1,4 +1,4 @@
-package defaults
+package release
import (
"testing"
diff --git a/pipeline/release/testdata/release1.txt b/pipeline/release/testdata/release1.txt
index 00f95645a..f4a52b356 100644
--- a/pipeline/release/testdata/release1.txt
+++ b/pipeline/release/testdata/release1.txt
@@ -2,10 +2,16 @@
feature1: description
feature2: other description
-Docker images:
+## Docker images
-- goreleaser/goreleaser:0.40.0
-- goreleaser/godownloader:0.1.0
+- `docker pull goreleaser/goreleaser:0.40.0`
+- `docker pull goreleaser/goreleaser:latest`
+- `docker pull goreleaser/godownloader:v0.1.0`
+
+## Homebrew taps
+
+- `brew install caarlos0/tap/foo`
+- `brew install goreleaser/tap/bar`
---
Automated with [GoReleaser](https://github.com/goreleaser)
diff --git a/pipeline/snapcraft/snapcraft.go b/pipeline/snapcraft/snapcraft.go
index f7d25724d..001dd7eba 100644
--- a/pipeline/snapcraft/snapcraft.go
+++ b/pipeline/snapcraft/snapcraft.go
@@ -49,9 +49,8 @@ type AppMetadata struct {
// Pipe for snapcraft packaging
type Pipe struct{}
-// Description of the pipe
-func (Pipe) Description() string {
- return "Creating Linux packages with snapcraft"
+func (Pipe) String() string {
+ return "creating Linux packages with snapcraft"
}
// Run the pipe
diff --git a/pipeline/snapcraft/snapcraft_test.go b/pipeline/snapcraft/snapcraft_test.go
index b9fe5a306..d6dfd7b38 100644
--- a/pipeline/snapcraft/snapcraft_test.go
+++ b/pipeline/snapcraft/snapcraft_test.go
@@ -15,7 +15,7 @@ import (
)
func TestDescription(t *testing.T) {
- assert.NotEmpty(t, Pipe{}.Description())
+ assert.NotEmpty(t, Pipe{}.String())
}
func TestRunPipeMissingInfo(t *testing.T) {
diff --git a/pipeline/snapshot/snapshot.go b/pipeline/snapshot/snapshot.go
new file mode 100644
index 000000000..c3fc1d6af
--- /dev/null
+++ b/pipeline/snapshot/snapshot.go
@@ -0,0 +1,19 @@
+// Package snapshot provides the snapshoting functionality to goreleaser.
+package snapshot
+
+import "github.com/goreleaser/goreleaser/context"
+
+// Pipe for checksums
+type Pipe struct{}
+
+func (Pipe) String() string {
+ return "generating changelog"
+}
+
+// Default sets the pipe defaults
+func (Pipe) Default(ctx *context.Context) error {
+ if ctx.Config.Snapshot.NameTemplate == "" {
+ ctx.Config.Snapshot.NameTemplate = "SNAPSHOT-{{ .Commit }}"
+ }
+ return nil
+}
diff --git a/pipeline/snapshot/snapshot_test.go b/pipeline/snapshot/snapshot_test.go
new file mode 100644
index 000000000..86c00cb05
--- /dev/null
+++ b/pipeline/snapshot/snapshot_test.go
@@ -0,0 +1,34 @@
+package snapshot
+
+import (
+ "testing"
+
+ "github.com/goreleaser/goreleaser/config"
+ "github.com/goreleaser/goreleaser/context"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestStringer(t *testing.T) {
+ assert.NotEmpty(t, Pipe{}.String())
+}
+func TestDefault(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Snapshot: config.Snapshot{},
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Equal(t, "SNAPSHOT-{{ .Commit }}", ctx.Config.Snapshot.NameTemplate)
+}
+
+func TestDefaultSet(t *testing.T) {
+ var ctx = &context.Context{
+ Config: config.Project{
+ Snapshot: config.Snapshot{
+ NameTemplate: "snap",
+ },
+ },
+ }
+ assert.NoError(t, Pipe{}.Default(ctx))
+ assert.Equal(t, "snap", ctx.Config.Snapshot.NameTemplate)
+}