You've already forked goreleaser
mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-07-09 01:16:05 +02:00
29
README.md
29
README.md
@ -61,8 +61,8 @@ By default GoReleaser will build the current directory, but you can change the b
|
|||||||
```yml
|
```yml
|
||||||
# goreleaser.yml
|
# goreleaser.yml
|
||||||
# Build customization
|
# Build customization
|
||||||
build:
|
builds:
|
||||||
binary: drum-roll
|
- binary: drum-roll
|
||||||
goos:
|
goos:
|
||||||
- windows
|
- windows
|
||||||
- darwin
|
- darwin
|
||||||
@ -75,15 +75,15 @@ PS: Invalid GOOS/GOARCH combinations will automatically be skipped.
|
|||||||
|
|
||||||
This configuration specifies the build operating systems to Windows, Linux and MacOS using 64bit architecture, the name of the binaries is `drum-roll`.
|
This configuration specifies the build operating systems to Windows, Linux and MacOS using 64bit architecture, the name of the binaries is `drum-roll`.
|
||||||
|
|
||||||
GoReleaser will then archive the result binaries of each Os/Arch into a separate file. The default format is `{{.Binary}}_{{.Os}}_{{.Arch}}`.
|
GoReleaser will then archive the result binaries of each Os/Arch into a separate file. The default format is `{{.ProjectName}}_{{.Os}}_{{.Arch}}`.
|
||||||
You can change the archives name and format. You can also replace the OS and the Architecture with your own.
|
You can change the archives name and format. You can also replace the OS and the Architecture with your own.
|
||||||
Another useful feature is to add files to archives, this is very useful for integrating assets like resource files.
|
Another useful feature is to add files to archives, this is very useful for integrating assets like resource files.
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
# goreleaser.yml
|
# goreleaser.yml
|
||||||
# Build customization
|
# Build customization
|
||||||
build:
|
builds:
|
||||||
main: main.go
|
- main: main.go
|
||||||
binary: drum-roll
|
binary: drum-roll
|
||||||
goos:
|
goos:
|
||||||
- windows
|
- windows
|
||||||
@ -172,11 +172,22 @@ defaults are sensible and fit for most projects.
|
|||||||
|
|
||||||
We'll cover all customizations available bellow:
|
We'll cover all customizations available bellow:
|
||||||
|
|
||||||
|
### Project name
|
||||||
|
|
||||||
|
```yml
|
||||||
|
# goreleaser.yml
|
||||||
|
# The name of the project. It is used in the name of the brew formula, archives,
|
||||||
|
# etc. Defaults to the name of the git project.
|
||||||
|
project_name: myproject
|
||||||
|
```
|
||||||
|
|
||||||
### Build customization
|
### Build customization
|
||||||
|
|
||||||
```yml
|
```yml
|
||||||
# goreleaser.yml
|
# goreleaser.yml
|
||||||
build:
|
builds:
|
||||||
|
# You can have multiple builds, its a common yaml list
|
||||||
|
-
|
||||||
# Path to main.go file or main package.
|
# Path to main.go file or main package.
|
||||||
# Default is `.`
|
# Default is `.`
|
||||||
main: ./cmd/main.go
|
main: ./cmd/main.go
|
||||||
@ -252,14 +263,14 @@ archive:
|
|||||||
# You can change the name of the archive.
|
# You can change the name of the archive.
|
||||||
# This is parsed with Golang template engine and the following variables
|
# This is parsed with Golang template engine and the following variables
|
||||||
# are available:
|
# are available:
|
||||||
# - Binary
|
# - ProjectName
|
||||||
# - Tag
|
# - Tag
|
||||||
# - Version (Tag with the `v` prefix stripped)
|
# - Version (Tag with the `v` prefix stripped)
|
||||||
# - Os
|
# - Os
|
||||||
# - Arch
|
# - Arch
|
||||||
# - Arm (ARM version)
|
# - Arm (ARM version)
|
||||||
# The default is `{{ .Binary }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`
|
# The default is `{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}`
|
||||||
name_template: "{{.Binary}}_{{.Version}}_{{.Os}}_{{.Arch}}"
|
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||||
|
|
||||||
# Archive format. Valid options are `tar.gz` and `zip`.
|
# Archive format. Valid options are `tar.gz` and `zip`.
|
||||||
# Default is `tar.gz`
|
# Default is `tar.gz`
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/apex/log"
|
||||||
yaml "gopkg.in/yaml.v1"
|
yaml "gopkg.in/yaml.v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -99,13 +100,17 @@ type Snapshot struct {
|
|||||||
|
|
||||||
// Project includes all project configuration
|
// Project includes all project configuration
|
||||||
type Project struct {
|
type Project struct {
|
||||||
|
ProjectName string `yaml:"project_name,omitempty"`
|
||||||
Release Release `yaml:",omitempty"`
|
Release Release `yaml:",omitempty"`
|
||||||
Brew Homebrew `yaml:",omitempty"`
|
Brew Homebrew `yaml:",omitempty"`
|
||||||
Build Build `yaml:",omitempty"`
|
Builds []Build `yaml:",omitempty"`
|
||||||
Archive Archive `yaml:",omitempty"`
|
Archive Archive `yaml:",omitempty"`
|
||||||
FPM FPM `yaml:",omitempty"`
|
FPM FPM `yaml:",omitempty"`
|
||||||
Snapshot Snapshot `yaml:",omitempty"`
|
Snapshot Snapshot `yaml:",omitempty"`
|
||||||
|
|
||||||
|
// this is a hack ¯\_(ツ)_/¯
|
||||||
|
SingleBuild Build `yaml:"build,omitempty"`
|
||||||
|
|
||||||
// test only property indicating the path to the dist folder
|
// test only property indicating the path to the dist folder
|
||||||
Dist string `yaml:"-"`
|
Dist string `yaml:"-"`
|
||||||
}
|
}
|
||||||
@ -126,5 +131,6 @@ func LoadReader(fd io.Reader) (config Project, err error) {
|
|||||||
return config, err
|
return config, err
|
||||||
}
|
}
|
||||||
err = yaml.Unmarshal(data, &config)
|
err = yaml.Unmarshal(data, &config)
|
||||||
|
log.WithField("config", config).Debug("loaded config file")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ type Context struct {
|
|||||||
Config config.Project
|
Config config.Project
|
||||||
Token string
|
Token string
|
||||||
Git GitInfo
|
Git GitInfo
|
||||||
Archives map[string]string
|
Folders map[string]string
|
||||||
Artifacts []string
|
Artifacts []string
|
||||||
ReleaseNotes string
|
ReleaseNotes string
|
||||||
Version string
|
Version string
|
||||||
@ -36,16 +36,25 @@ type Context struct {
|
|||||||
Snapshot bool
|
Snapshot bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var lock sync.Mutex
|
var artifactsLock sync.Mutex
|
||||||
|
var foldersLock sync.Mutex
|
||||||
|
|
||||||
// AddArtifact adds a file to upload list
|
// AddArtifact adds a file to upload list
|
||||||
func (ctx *Context) AddArtifact(file string) {
|
func (ctx *Context) AddArtifact(file string) {
|
||||||
lock.Lock()
|
artifactsLock.Lock()
|
||||||
defer lock.Unlock()
|
defer artifactsLock.Unlock()
|
||||||
file = strings.TrimPrefix(file, ctx.Config.Dist)
|
file = strings.TrimPrefix(file, ctx.Config.Dist)
|
||||||
file = strings.Replace(file, "/", "", -1)
|
file = strings.Replace(file, "/", "", -1)
|
||||||
ctx.Artifacts = append(ctx.Artifacts, file)
|
ctx.Artifacts = append(ctx.Artifacts, file)
|
||||||
log.WithField("artifact", file).Info("registered")
|
log.WithField("artifact", file).Info("new artifact")
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddFolder adds a built binary to the current context
|
||||||
|
func (ctx *Context) AddFolder(key, folder string) {
|
||||||
|
foldersLock.Lock()
|
||||||
|
defer foldersLock.Unlock()
|
||||||
|
ctx.Folders[key] = folder
|
||||||
|
log.WithField("key", key).WithField("folder", folder).Info("new folder")
|
||||||
}
|
}
|
||||||
|
|
||||||
// New context
|
// New context
|
||||||
@ -53,6 +62,6 @@ func New(config config.Project) *Context {
|
|||||||
return &Context{
|
return &Context{
|
||||||
Context: ctx.Background(),
|
Context: ctx.Background(),
|
||||||
Config: config,
|
Config: config,
|
||||||
Archives: map[string]string{},
|
Folders: map[string]string{},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,3 +31,27 @@ func TestMultipleArtifactAdds(t *testing.T) {
|
|||||||
assert.Len(ctx.Artifacts, len(list))
|
assert.Len(ctx.Artifacts, len(list))
|
||||||
assert.Contains(ctx.Artifacts, "a", "b", "c", "d")
|
assert.Contains(ctx.Artifacts, "a", "b", "c", "d")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMultipleFolderAdds(t *testing.T) {
|
||||||
|
var assert = assert.New(t)
|
||||||
|
var list = map[string]string{
|
||||||
|
"key-a": "folder/a",
|
||||||
|
"key-b": "folder/b",
|
||||||
|
"key-c": "folder/c",
|
||||||
|
"key-d": "folder/d",
|
||||||
|
}
|
||||||
|
var ctx = New(config.Project{
|
||||||
|
Dist: "dist",
|
||||||
|
})
|
||||||
|
var g errgroup.Group
|
||||||
|
for k, f := range list {
|
||||||
|
f := f
|
||||||
|
k := k
|
||||||
|
g.Go(func() error {
|
||||||
|
ctx.AddFolder(k, f)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
assert.NoError(g.Wait())
|
||||||
|
assert.Len(ctx.Folders, len(list))
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
homepage: &homepage http://goreleaser.github.io
|
homepage: &homepage http://goreleaser.github.io
|
||||||
description: &description Deliver Go binaries as fast and easily as possible
|
description: &description Deliver Go binaries as fast and easily as possible
|
||||||
build:
|
builds:
|
||||||
|
-
|
||||||
env:
|
env:
|
||||||
- CGO_ENABLED=0
|
- CGO_ENABLED=0
|
||||||
goos:
|
goos:
|
||||||
|
@ -36,7 +36,7 @@ func (c *githubClient) CreateFile(
|
|||||||
},
|
},
|
||||||
Content: content.Bytes(),
|
Content: content.Bytes(),
|
||||||
Message: github.String(
|
Message: github.String(
|
||||||
ctx.Config.Build.Binary + " version " + ctx.Git.CurrentTag,
|
ctx.Config.ProjectName + " version " + ctx.Git.CurrentTag,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
49
internal/name/name.go
Normal file
49
internal/name/name.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Package name provides name template logic for the final archive, formulae,
|
||||||
|
// etc.
|
||||||
|
package name
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/goreleaser/goreleaser/context"
|
||||||
|
)
|
||||||
|
|
||||||
|
type nameData struct {
|
||||||
|
Os string
|
||||||
|
Arch string
|
||||||
|
Arm string
|
||||||
|
Version string
|
||||||
|
Tag string
|
||||||
|
Binary string // deprecated
|
||||||
|
ProjectName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// For returns the name for the given context, goos, goarch and goarm.
|
||||||
|
func For(ctx *context.Context, goos, goarch, goarm string) (string, error) {
|
||||||
|
var data = nameData{
|
||||||
|
Os: replace(ctx.Config.Archive.Replacements, goos),
|
||||||
|
Arch: replace(ctx.Config.Archive.Replacements, goarch),
|
||||||
|
Arm: replace(ctx.Config.Archive.Replacements, goarm),
|
||||||
|
Version: ctx.Version,
|
||||||
|
Tag: ctx.Git.CurrentTag,
|
||||||
|
Binary: ctx.Config.ProjectName,
|
||||||
|
ProjectName: ctx.Config.ProjectName,
|
||||||
|
}
|
||||||
|
|
||||||
|
var out bytes.Buffer
|
||||||
|
t, err := template.New(data.Binary).Parse(ctx.Config.Archive.NameTemplate)
|
||||||
|
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
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package build
|
package name
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
@ -20,9 +20,7 @@ func TestNameFor(t *testing.T) {
|
|||||||
"amd64": "x86_64",
|
"amd64": "x86_64",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Build: config.Build{
|
ProjectName: "test",
|
||||||
Binary: "test",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config,
|
Config: config,
|
||||||
@ -32,30 +30,26 @@ func TestNameFor(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
name, err := nameFor(ctx, buildTarget{"darwin", "amd64", ""})
|
name, err := For(ctx, "darwin", "amd64", "")
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal("test_Darwin_x86_64_v1.2.3_1.2.3", name)
|
assert.Equal("test_Darwin_x86_64_v1.2.3_1.2.3", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInvalidNameTemplate(t *testing.T) {
|
func TestInvalidNameTemplate(t *testing.T) {
|
||||||
assert := assert.New(t)
|
var assert = assert.New(t)
|
||||||
|
var ctx = &context.Context{
|
||||||
var config = config.Project{
|
Config: config.Project{
|
||||||
Archive: config.Archive{
|
Archive: config.Archive{
|
||||||
NameTemplate: "{{.Binary}_{{.Os}}_{{.Arch}}_{{.Version}}",
|
NameTemplate: "{{.Binary}_{{.Os}}_{{.Arch}}_{{.Version}}",
|
||||||
},
|
},
|
||||||
Build: config.Build{
|
ProjectName: "test",
|
||||||
Binary: "test",
|
|
||||||
},
|
},
|
||||||
}
|
|
||||||
var ctx = &context.Context{
|
|
||||||
Config: config,
|
|
||||||
Git: context.GitInfo{
|
Git: context.GitInfo{
|
||||||
CurrentTag: "v1.2.3",
|
CurrentTag: "v1.2.3",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := nameFor(ctx, buildTarget{"darwin", "amd64", ""})
|
_, err := For(ctx, "darwin", "amd64", "")
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,19 +60,20 @@ func TestNameDefaltTemplate(t *testing.T) {
|
|||||||
Archive: config.Archive{
|
Archive: config.Archive{
|
||||||
NameTemplate: defaults.NameTemplate,
|
NameTemplate: defaults.NameTemplate,
|
||||||
},
|
},
|
||||||
Build: config.Build{
|
ProjectName: "test",
|
||||||
Binary: "test",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Version: "1.2.3",
|
Version: "1.2.3",
|
||||||
}
|
}
|
||||||
|
type buildTarget struct {
|
||||||
|
goos, goarch, goarm string
|
||||||
|
}
|
||||||
for key, target := range map[string]buildTarget{
|
for key, target := range map[string]buildTarget{
|
||||||
"test_1.2.3_darwin_amd64": {"darwin", "amd64", ""},
|
"test_1.2.3_darwin_amd64": {"darwin", "amd64", ""},
|
||||||
"test_1.2.3_linux_arm64": {"linux", "arm64", ""},
|
"test_1.2.3_linux_arm64": {"linux", "arm64", ""},
|
||||||
"test_1.2.3_linux_armv7": {"linux", "arm", "7"},
|
"test_1.2.3_linux_armv7": {"linux", "arm", "7"},
|
||||||
} {
|
} {
|
||||||
t.Run(key, func(t *testing.T) {
|
t.Run(key, func(t *testing.T) {
|
||||||
name, err := nameFor(ctx, target)
|
name, err := For(ctx, target.goos, target.goarch, target.goarm)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Equal(key, name)
|
assert.Equal(key, name)
|
||||||
})
|
})
|
@ -4,6 +4,7 @@
|
|||||||
package archive
|
package archive
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
@ -11,7 +12,6 @@ import (
|
|||||||
"github.com/goreleaser/archive"
|
"github.com/goreleaser/archive"
|
||||||
"github.com/goreleaser/goreleaser/context"
|
"github.com/goreleaser/goreleaser/context"
|
||||||
"github.com/goreleaser/goreleaser/internal/archiveformat"
|
"github.com/goreleaser/goreleaser/internal/archiveformat"
|
||||||
"github.com/goreleaser/goreleaser/internal/ext"
|
|
||||||
"github.com/mattn/go-zglob"
|
"github.com/mattn/go-zglob"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
@ -27,11 +27,11 @@ func (Pipe) Description() string {
|
|||||||
// Run the pipe
|
// Run the pipe
|
||||||
func (Pipe) Run(ctx *context.Context) error {
|
func (Pipe) Run(ctx *context.Context) error {
|
||||||
var g errgroup.Group
|
var g errgroup.Group
|
||||||
for platform, archive := range ctx.Archives {
|
for platform, folder := range ctx.Folders {
|
||||||
archive := archive
|
folder := folder
|
||||||
platform := platform
|
platform := platform
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
return create(ctx, platform, archive)
|
return create(ctx, platform, folder)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return g.Wait()
|
return g.Wait()
|
||||||
@ -58,10 +58,16 @@ func create(ctx *context.Context, platform, name string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var binary = ctx.Config.Build.Binary + ext.For(platform)
|
var path = filepath.Join(ctx.Config.Dist, name)
|
||||||
if err := archive.Add(binary, filepath.Join(folder, binary)); err != nil {
|
binaries, err := ioutil.ReadDir(path)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
for _, binary := range binaries {
|
||||||
|
if err := archive.Add(binary.Name(), filepath.Join(path, binary.Name())); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
ctx.AddArtifact(file.Name())
|
ctx.AddArtifact(file.Name())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -27,23 +27,21 @@ func TestRunPipe(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
var dist = filepath.Join(folder, "dist")
|
var dist = filepath.Join(folder, "dist")
|
||||||
assert.NoError(os.Mkdir(dist, 0755))
|
assert.NoError(os.Mkdir(dist, 0755))
|
||||||
assert.NoError(os.Mkdir(filepath.Join(dist, "mybin"), 0755))
|
assert.NoError(os.Mkdir(filepath.Join(dist, "mybin_darwin_amd64"), 0755))
|
||||||
_, err = os.Create(filepath.Join(dist, "mybin", "mybin"))
|
assert.NoError(os.Mkdir(filepath.Join(dist, "mybin_windows_amd64"), 0755))
|
||||||
|
_, err = os.Create(filepath.Join(dist, "mybin_darwin_amd64", "mybin"))
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
_, err = os.Create(filepath.Join(dist, "mybin", "mybin.exe"))
|
_, err = os.Create(filepath.Join(dist, "mybin_windows_amd64", "mybin.exe"))
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
_, err = os.Create(filepath.Join(folder, "README.md"))
|
_, err = os.Create(filepath.Join(folder, "README.md"))
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Archives: map[string]string{
|
Folders: map[string]string{
|
||||||
"darwinamd64": "mybin",
|
"darwinamd64": "mybin_darwin_amd64",
|
||||||
"windowsamd64": "mybin",
|
"windowsamd64": "mybin_windows_amd64",
|
||||||
},
|
},
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
Dist: dist,
|
Dist: dist,
|
||||||
Build: config.Build{
|
|
||||||
Binary: "mybin",
|
|
||||||
},
|
|
||||||
Archive: config.Archive{
|
Archive: config.Archive{
|
||||||
Files: []string{
|
Files: []string{
|
||||||
"README.*",
|
"README.*",
|
||||||
@ -68,9 +66,8 @@ func TestRunPipe(t *testing.T) {
|
|||||||
func TestRunPipeDistRemoved(t *testing.T) {
|
func TestRunPipeDistRemoved(t *testing.T) {
|
||||||
var assert = assert.New(t)
|
var assert = assert.New(t)
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Archives: map[string]string{
|
Folders: map[string]string{
|
||||||
"darwinamd64": "mybin",
|
"darwinamd64": "whatever",
|
||||||
"windowsamd64": "mybin",
|
|
||||||
},
|
},
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
Dist: "/path/nope",
|
Dist: "/path/nope",
|
||||||
@ -85,8 +82,8 @@ func TestRunPipeDistRemoved(t *testing.T) {
|
|||||||
func TestRunPipeInvalidGlob(t *testing.T) {
|
func TestRunPipeInvalidGlob(t *testing.T) {
|
||||||
var assert = assert.New(t)
|
var assert = assert.New(t)
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Archives: map[string]string{
|
Folders: map[string]string{
|
||||||
"windowsamd64": "mybin",
|
"windowsamd64": "whatever",
|
||||||
},
|
},
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
Dist: "/tmp",
|
Dist: "/tmp",
|
||||||
@ -113,7 +110,7 @@ func TestRunPipeGlobFailsToAdd(t *testing.T) {
|
|||||||
assert.NoError(os.MkdirAll(filepath.Join(folder, "folder", "another"), 0755))
|
assert.NoError(os.MkdirAll(filepath.Join(folder, "folder", "another"), 0755))
|
||||||
|
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Archives: map[string]string{
|
Folders: map[string]string{
|
||||||
"windows386": "mybin",
|
"windows386": "mybin",
|
||||||
},
|
},
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
@ -127,18 +124,3 @@ func TestRunPipeGlobFailsToAdd(t *testing.T) {
|
|||||||
}
|
}
|
||||||
assert.Error(Pipe{}.Run(ctx))
|
assert.Error(Pipe{}.Run(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunPipeBinaryDontExist(t *testing.T) {
|
|
||||||
var assert = assert.New(t)
|
|
||||||
folder, err := ioutil.TempDir("", "archivetest")
|
|
||||||
assert.NoError(err)
|
|
||||||
var ctx = &context.Context{
|
|
||||||
Archives: map[string]string{
|
|
||||||
"windows386": "mybin",
|
|
||||||
},
|
|
||||||
Config: config.Project{
|
|
||||||
Dist: folder,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
assert.Error(Pipe{}.Run(ctx))
|
|
||||||
}
|
|
||||||
|
@ -21,6 +21,8 @@ import (
|
|||||||
// contain darwin and/or goarch doesn't contain amd64)
|
// contain darwin and/or goarch doesn't contain amd64)
|
||||||
var ErrNoDarwin64Build = errors.New("brew tap requires a darwin amd64 build")
|
var ErrNoDarwin64Build = errors.New("brew tap requires a darwin amd64 build")
|
||||||
|
|
||||||
|
const platform = "darwinamd64"
|
||||||
|
|
||||||
const formula = `class {{ .Name }} < Formula
|
const formula = `class {{ .Name }} < Formula
|
||||||
desc "{{ .Desc }}"
|
desc "{{ .Desc }}"
|
||||||
homepage "{{ .Homepage }}"
|
homepage "{{ .Homepage }}"
|
||||||
@ -70,7 +72,6 @@ type templateData struct {
|
|||||||
Repo config.Repo // FIXME: will not work for anything but github right now.
|
Repo config.Repo // FIXME: will not work for anything but github right now.
|
||||||
Tag string
|
Tag string
|
||||||
Version string
|
Version string
|
||||||
Binary string
|
|
||||||
Caveats string
|
Caveats string
|
||||||
File string
|
File string
|
||||||
SHA256 string
|
SHA256 string
|
||||||
@ -106,7 +107,7 @@ func doRun(ctx *context.Context, client client.Client) error {
|
|||||||
log.Warn("skipped because release is marked as draft")
|
log.Warn("skipped because release is marked as draft")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
path := filepath.Join(ctx.Config.Brew.Folder, ctx.Config.Build.Binary+".rb")
|
var path = filepath.Join(ctx.Config.Brew.Folder, ctx.Config.ProjectName+".rb")
|
||||||
log.WithField("formula", path).
|
log.WithField("formula", path).
|
||||||
WithField("repo", ctx.Config.Brew.GitHub.String()).
|
WithField("repo", ctx.Config.Brew.GitHub.String()).
|
||||||
Info("pushing")
|
Info("pushing")
|
||||||
@ -127,7 +128,7 @@ func buildFormula(ctx *context.Context, client client.Client) (bytes.Buffer, err
|
|||||||
|
|
||||||
func doBuildFormula(data templateData) (bytes.Buffer, error) {
|
func doBuildFormula(data templateData) (bytes.Buffer, error) {
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
tmpl, err := template.New(data.Binary).Parse(formula)
|
tmpl, err := template.New(data.Name).Parse(formula)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
@ -136,23 +137,22 @@ func doBuildFormula(data templateData) (bytes.Buffer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func dataFor(ctx *context.Context, client client.Client) (result templateData, err error) {
|
func dataFor(ctx *context.Context, client client.Client) (result templateData, err error) {
|
||||||
var folder = ctx.Archives["darwinamd64"]
|
var folder = ctx.Folders[platform]
|
||||||
if folder == "" {
|
if folder == "" {
|
||||||
return result, ErrNoDarwin64Build
|
return result, ErrNoDarwin64Build
|
||||||
}
|
}
|
||||||
var file = folder + "." + archiveformat.For(ctx, "darwinamd64")
|
var file = folder + "." + archiveformat.For(ctx, platform)
|
||||||
sum, err := checksum.SHA256(filepath.Join(ctx.Config.Dist, file))
|
sum, err := checksum.SHA256(filepath.Join(ctx.Config.Dist, file))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return templateData{
|
return templateData{
|
||||||
Name: formulaNameFor(ctx.Config.Build.Binary),
|
Name: formulaNameFor(ctx.Config.ProjectName),
|
||||||
Desc: ctx.Config.Brew.Description,
|
Desc: ctx.Config.Brew.Description,
|
||||||
Homepage: ctx.Config.Brew.Homepage,
|
Homepage: ctx.Config.Brew.Homepage,
|
||||||
Repo: ctx.Config.Release.GitHub,
|
Repo: ctx.Config.Release.GitHub,
|
||||||
Tag: ctx.Git.CurrentTag,
|
Tag: ctx.Git.CurrentTag,
|
||||||
Version: ctx.Version,
|
Version: ctx.Version,
|
||||||
Binary: ctx.Config.Build.Binary,
|
|
||||||
Caveats: ctx.Config.Brew.Caveats,
|
Caveats: ctx.Config.Brew.Caveats,
|
||||||
File: file,
|
File: file,
|
||||||
SHA256: sum,
|
SHA256: sum,
|
||||||
|
@ -29,7 +29,6 @@ func TestSimpleName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var defaultTemplateData = templateData{
|
var defaultTemplateData = templateData{
|
||||||
Binary: "test",
|
|
||||||
Desc: "Some desc",
|
Desc: "Some desc",
|
||||||
Homepage: "https://google.com",
|
Homepage: "https://google.com",
|
||||||
Name: "Test",
|
Name: "Test",
|
||||||
@ -104,7 +103,7 @@ func TestRunPipe(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Archives: map[string]string{
|
Folders: map[string]string{
|
||||||
"darwinamd64": "bin",
|
"darwinamd64": "bin",
|
||||||
},
|
},
|
||||||
Publish: true,
|
Publish: true,
|
||||||
@ -139,7 +138,7 @@ func TestRunPipeFormatOverride(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Archives: map[string]string{
|
Folders: map[string]string{
|
||||||
"darwinamd64": "bin",
|
"darwinamd64": "bin",
|
||||||
},
|
},
|
||||||
Publish: true,
|
Publish: true,
|
||||||
@ -167,7 +166,7 @@ func TestRunPipeArchiveDoesntExist(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Archives: map[string]string{
|
Folders: map[string]string{
|
||||||
"darwinamd64": "bin",
|
"darwinamd64": "bin",
|
||||||
},
|
},
|
||||||
Publish: true,
|
Publish: true,
|
||||||
|
@ -10,8 +10,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
|
"github.com/goreleaser/goreleaser/config"
|
||||||
"github.com/goreleaser/goreleaser/context"
|
"github.com/goreleaser/goreleaser/context"
|
||||||
"github.com/goreleaser/goreleaser/internal/ext"
|
"github.com/goreleaser/goreleaser/internal/ext"
|
||||||
|
"github.com/goreleaser/goreleaser/internal/name"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -25,31 +27,36 @@ func (Pipe) Description() string {
|
|||||||
|
|
||||||
// Run the pipe
|
// Run the pipe
|
||||||
func (Pipe) Run(ctx *context.Context) error {
|
func (Pipe) Run(ctx *context.Context) error {
|
||||||
if err := runHook(ctx.Config.Build.Env, ctx.Config.Build.Hooks.Pre); err != nil {
|
for _, build := range ctx.Config.Builds {
|
||||||
|
log.WithField("build", build).Debug("building")
|
||||||
|
if err := runPipeOnBuild(ctx, build); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runPipeOnBuild(ctx *context.Context, build config.Build) error {
|
||||||
|
if err := runHook(build.Env, build.Hooks.Pre); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
sem := make(chan bool, 4)
|
sem := make(chan bool, 4)
|
||||||
var g errgroup.Group
|
var g errgroup.Group
|
||||||
for _, target := range buildTargets(ctx) {
|
for _, target := range buildTargets(build) {
|
||||||
name, err := nameFor(ctx, target)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
ctx.Archives[target.String()] = name
|
|
||||||
|
|
||||||
sem <- true
|
sem <- true
|
||||||
target := target
|
target := target
|
||||||
|
build := build
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
defer func() {
|
defer func() {
|
||||||
<-sem
|
<-sem
|
||||||
}()
|
}()
|
||||||
return build(ctx, name, target)
|
return doBuild(ctx, build, target)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if err := g.Wait(); err != nil {
|
if err := g.Wait(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return runHook(ctx.Config.Build.Env, ctx.Config.Build.Hooks.Post)
|
return runHook(build.Env, build.Hooks.Post)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runHook(env []string, hook string) error {
|
func runHook(env []string, hook string) error {
|
||||||
@ -61,23 +68,28 @@ func runHook(env []string, hook string) error {
|
|||||||
return run(runtimeTarget, cmd, env)
|
return run(runtimeTarget, cmd, env)
|
||||||
}
|
}
|
||||||
|
|
||||||
func build(ctx *context.Context, name string, target buildTarget) error {
|
func doBuild(ctx *context.Context, build config.Build, target buildTarget) error {
|
||||||
output := filepath.Join(
|
folder, err := name.For(ctx, target.goos, target.goarch, target.goarm)
|
||||||
ctx.Config.Dist,
|
|
||||||
name,
|
|
||||||
ctx.Config.Build.Binary+ext.For(target.goos),
|
|
||||||
)
|
|
||||||
log.WithField("binary", output).Info("building")
|
|
||||||
cmd := []string{"go", "build"}
|
|
||||||
if ctx.Config.Build.Flags != "" {
|
|
||||||
cmd = append(cmd, strings.Fields(ctx.Config.Build.Flags)...)
|
|
||||||
}
|
|
||||||
flags, err := ldflags(ctx)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cmd = append(cmd, "-ldflags="+flags, "-o", output, ctx.Config.Build.Main)
|
ctx.AddFolder(target.String(), folder)
|
||||||
return run(target, cmd, ctx.Config.Build.Env)
|
var binary = filepath.Join(
|
||||||
|
ctx.Config.Dist,
|
||||||
|
folder,
|
||||||
|
build.Binary+ext.For(target.goos),
|
||||||
|
)
|
||||||
|
log.WithField("binary", binary).Info("building")
|
||||||
|
cmd := []string{"go", "build"}
|
||||||
|
if build.Flags != "" {
|
||||||
|
cmd = append(cmd, strings.Fields(build.Flags)...)
|
||||||
|
}
|
||||||
|
flags, err := ldflags(ctx, build)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cmd = append(cmd, "-ldflags="+flags, "-o", binary, build.Main)
|
||||||
|
return run(target, cmd, build.Env)
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(target buildTarget, command, env []string) error {
|
func run(target buildTarget, command, env []string) error {
|
||||||
|
@ -29,16 +29,19 @@ func TestRunInvalidCommand(t *testing.T) {
|
|||||||
func TestBuild(t *testing.T) {
|
func TestBuild(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
var config = config.Project{
|
var config = config.Project{
|
||||||
Build: config.Build{
|
Builds: []config.Build{
|
||||||
|
{
|
||||||
Binary: "testing",
|
Binary: "testing",
|
||||||
Flags: "-n",
|
Flags: "-n",
|
||||||
Env: []string{"BLAH=1"},
|
Env: []string{"BLAH=1"},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config,
|
Config: config,
|
||||||
|
Folders: map[string]string{},
|
||||||
}
|
}
|
||||||
assert.NoError(build(ctx, "build_test", runtimeTarget))
|
assert.NoError(doBuild(ctx, ctx.Config.Builds[0], runtimeTarget))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunFullPipe(t *testing.T) {
|
func TestRunFullPipe(t *testing.T) {
|
||||||
@ -50,7 +53,8 @@ func TestRunFullPipe(t *testing.T) {
|
|||||||
var post = filepath.Join(folder, "post")
|
var post = filepath.Join(folder, "post")
|
||||||
var config = config.Project{
|
var config = config.Project{
|
||||||
Dist: folder,
|
Dist: folder,
|
||||||
Build: config.Build{
|
Builds: []config.Build{
|
||||||
|
{
|
||||||
Binary: "testing",
|
Binary: "testing",
|
||||||
Flags: "-v",
|
Flags: "-v",
|
||||||
Ldflags: "-X main.test=testing",
|
Ldflags: "-X main.test=testing",
|
||||||
@ -65,10 +69,11 @@ func TestRunFullPipe(t *testing.T) {
|
|||||||
runtime.GOARCH,
|
runtime.GOARCH,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config,
|
Config: config,
|
||||||
Archives: map[string]string{},
|
Folders: map[string]string{},
|
||||||
}
|
}
|
||||||
assert.NoError(Pipe{}.Run(ctx))
|
assert.NoError(Pipe{}.Run(ctx))
|
||||||
assert.True(exists(binary), binary)
|
assert.True(exists(binary), binary)
|
||||||
@ -83,7 +88,8 @@ func TestRunPipeArmBuilds(t *testing.T) {
|
|||||||
var binary = filepath.Join(folder, "armtesting")
|
var binary = filepath.Join(folder, "armtesting")
|
||||||
var config = config.Project{
|
var config = config.Project{
|
||||||
Dist: folder,
|
Dist: folder,
|
||||||
Build: config.Build{
|
Builds: []config.Build{
|
||||||
|
{
|
||||||
Binary: "armtesting",
|
Binary: "armtesting",
|
||||||
Flags: "-v",
|
Flags: "-v",
|
||||||
Ldflags: "-X main.test=armtesting",
|
Ldflags: "-X main.test=armtesting",
|
||||||
@ -98,10 +104,11 @@ func TestRunPipeArmBuilds(t *testing.T) {
|
|||||||
"6",
|
"6",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config,
|
Config: config,
|
||||||
Archives: map[string]string{},
|
Folders: map[string]string{},
|
||||||
}
|
}
|
||||||
assert.NoError(Pipe{}.Run(ctx))
|
assert.NoError(Pipe{}.Run(ctx))
|
||||||
assert.True(exists(binary), binary)
|
assert.True(exists(binary), binary)
|
||||||
@ -110,7 +117,8 @@ func TestRunPipeArmBuilds(t *testing.T) {
|
|||||||
func TestBuildFailed(t *testing.T) {
|
func TestBuildFailed(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
var config = config.Project{
|
var config = config.Project{
|
||||||
Build: config.Build{
|
Builds: []config.Build{
|
||||||
|
{
|
||||||
Flags: "-flag-that-dont-exists-to-force-failure",
|
Flags: "-flag-that-dont-exists-to-force-failure",
|
||||||
Goos: []string{
|
Goos: []string{
|
||||||
runtime.GOOS,
|
runtime.GOOS,
|
||||||
@ -119,10 +127,11 @@ func TestBuildFailed(t *testing.T) {
|
|||||||
runtime.GOARCH,
|
runtime.GOARCH,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config,
|
Config: config,
|
||||||
Archives: map[string]string{},
|
Folders: map[string]string{},
|
||||||
}
|
}
|
||||||
assert.Error(Pipe{}.Run(ctx))
|
assert.Error(Pipe{}.Run(ctx))
|
||||||
}
|
}
|
||||||
@ -130,7 +139,8 @@ func TestBuildFailed(t *testing.T) {
|
|||||||
func TestRunPipeWithInvalidOS(t *testing.T) {
|
func TestRunPipeWithInvalidOS(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
var config = config.Project{
|
var config = config.Project{
|
||||||
Build: config.Build{
|
Builds: []config.Build{
|
||||||
|
{
|
||||||
Flags: "-v",
|
Flags: "-v",
|
||||||
Goos: []string{
|
Goos: []string{
|
||||||
"windows",
|
"windows",
|
||||||
@ -139,10 +149,11 @@ func TestRunPipeWithInvalidOS(t *testing.T) {
|
|||||||
"arm",
|
"arm",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config,
|
Config: config,
|
||||||
Archives: map[string]string{},
|
Folders: map[string]string{},
|
||||||
}
|
}
|
||||||
assert.NoError(Pipe{}.Run(ctx))
|
assert.NoError(Pipe{}.Run(ctx))
|
||||||
}
|
}
|
||||||
@ -151,7 +162,8 @@ func TestRunInvalidNametemplate(t *testing.T) {
|
|||||||
var assert = assert.New(t)
|
var assert = assert.New(t)
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
Build: config.Build{
|
Builds: []config.Build{
|
||||||
|
{
|
||||||
Binary: "nametest",
|
Binary: "nametest",
|
||||||
Flags: "-v",
|
Flags: "-v",
|
||||||
Goos: []string{
|
Goos: []string{
|
||||||
@ -161,6 +173,7 @@ func TestRunInvalidNametemplate(t *testing.T) {
|
|||||||
runtime.GOARCH,
|
runtime.GOARCH,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
Archive: config.Archive{
|
Archive: config.Archive{
|
||||||
NameTemplate: "{{.Binary}_{{.Os}}_{{.Arch}}_{{.Version}}",
|
NameTemplate: "{{.Binary}_{{.Os}}_{{.Arch}}_{{.Version}}",
|
||||||
},
|
},
|
||||||
@ -172,9 +185,10 @@ func TestRunInvalidNametemplate(t *testing.T) {
|
|||||||
func TestRunInvalidLdflags(t *testing.T) {
|
func TestRunInvalidLdflags(t *testing.T) {
|
||||||
var assert = assert.New(t)
|
var assert = assert.New(t)
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Archives: map[string]string{},
|
Folders: map[string]string{},
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
Build: config.Build{
|
Builds: []config.Build{
|
||||||
|
{
|
||||||
Binary: "nametest",
|
Binary: "nametest",
|
||||||
Flags: "-v",
|
Flags: "-v",
|
||||||
Ldflags: "-s -w -X main.version={{.Version}",
|
Ldflags: "-s -w -X main.version={{.Version}",
|
||||||
@ -186,6 +200,7 @@ func TestRunInvalidLdflags(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
assert.Error(Pipe{}.Run(ctx))
|
assert.Error(Pipe{}.Run(ctx))
|
||||||
}
|
}
|
||||||
@ -193,7 +208,8 @@ func TestRunInvalidLdflags(t *testing.T) {
|
|||||||
func TestRunPipeFailingHooks(t *testing.T) {
|
func TestRunPipeFailingHooks(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
var config = config.Project{
|
var config = config.Project{
|
||||||
Build: config.Build{
|
Builds: []config.Build{
|
||||||
|
{
|
||||||
Hooks: config.Hooks{},
|
Hooks: config.Hooks{},
|
||||||
Goos: []string{
|
Goos: []string{
|
||||||
runtime.GOOS,
|
runtime.GOOS,
|
||||||
@ -202,17 +218,18 @@ func TestRunPipeFailingHooks(t *testing.T) {
|
|||||||
runtime.GOARCH,
|
runtime.GOARCH,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config,
|
Config: config,
|
||||||
Archives: map[string]string{},
|
Folders: map[string]string{},
|
||||||
}
|
}
|
||||||
t.Run("pre-hook", func(t *testing.T) {
|
t.Run("pre-hook", func(t *testing.T) {
|
||||||
ctx.Config.Build.Hooks.Pre = "exit 1"
|
ctx.Config.Builds[0].Hooks.Pre = "exit 1"
|
||||||
assert.Error(Pipe{}.Run(ctx))
|
assert.Error(Pipe{}.Run(ctx))
|
||||||
})
|
})
|
||||||
t.Run("post-hook", func(t *testing.T) {
|
t.Run("post-hook", func(t *testing.T) {
|
||||||
ctx.Config.Build.Hooks.Post = "exit 1"
|
ctx.Config.Builds[0].Hooks.Post = "exit 1"
|
||||||
assert.Error(Pipe{}.Run(ctx))
|
assert.Error(Pipe{}.Run(ctx))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/goreleaser/goreleaser/config"
|
||||||
"github.com/goreleaser/goreleaser/context"
|
"github.com/goreleaser/goreleaser/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,7 +16,7 @@ type ldflagsData struct {
|
|||||||
Version string
|
Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
func ldflags(ctx *context.Context) (string, error) {
|
func ldflags(ctx *context.Context, build config.Build) (string, error) {
|
||||||
var data = ldflagsData{
|
var data = ldflagsData{
|
||||||
Commit: ctx.Git.Commit,
|
Commit: ctx.Git.Commit,
|
||||||
Tag: ctx.Git.CurrentTag,
|
Tag: ctx.Git.CurrentTag,
|
||||||
@ -23,7 +24,7 @@ func ldflags(ctx *context.Context) (string, error) {
|
|||||||
Date: time.Now().UTC().Format(time.RFC3339),
|
Date: time.Now().UTC().Format(time.RFC3339),
|
||||||
}
|
}
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
t, err := template.New("ldflags").Parse(ctx.Config.Build.Ldflags)
|
t, err := template.New("ldflags").Parse(build.Ldflags)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,11 @@ import (
|
|||||||
func TestLdFlagsFullTemplate(t *testing.T) {
|
func TestLdFlagsFullTemplate(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
var config = config.Project{
|
var config = config.Project{
|
||||||
Build: config.Build{
|
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}}",
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Git: context.GitInfo{
|
Git: context.GitInfo{
|
||||||
@ -23,7 +25,7 @@ func TestLdFlagsFullTemplate(t *testing.T) {
|
|||||||
Version: "1.2.3",
|
Version: "1.2.3",
|
||||||
Config: config,
|
Config: config,
|
||||||
}
|
}
|
||||||
flags, err := ldflags(ctx)
|
flags, err := ldflags(ctx, ctx.Config.Builds[0])
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.Contains(flags, "-s -w")
|
assert.Contains(flags, "-s -w")
|
||||||
assert.Contains(flags, "-X main.version=1.2.3")
|
assert.Contains(flags, "-X main.version=1.2.3")
|
||||||
@ -35,14 +37,14 @@ func TestLdFlagsFullTemplate(t *testing.T) {
|
|||||||
func TestInvalidTemplate(t *testing.T) {
|
func TestInvalidTemplate(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
var config = config.Project{
|
var config = config.Project{
|
||||||
Build: config.Build{
|
Builds: []config.Build{
|
||||||
Ldflags: "{invalid{.Template}}}{{}}}",
|
{Ldflags: "{invalid{.Template}}}{{}}}"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config,
|
Config: config,
|
||||||
}
|
}
|
||||||
flags, err := ldflags(ctx)
|
flags, err := ldflags(ctx, ctx.Config.Builds[0])
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
assert.Equal(flags, "")
|
assert.Equal(flags, "")
|
||||||
}
|
}
|
||||||
|
@ -1,44 +0,0 @@
|
|||||||
package build
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/goreleaser/goreleaser/context"
|
|
||||||
)
|
|
||||||
|
|
||||||
type nameData struct {
|
|
||||||
Os string
|
|
||||||
Arch string
|
|
||||||
Arm string
|
|
||||||
Version string
|
|
||||||
Tag string
|
|
||||||
Binary string
|
|
||||||
}
|
|
||||||
|
|
||||||
func nameFor(ctx *context.Context, target buildTarget) (string, error) {
|
|
||||||
var data = nameData{
|
|
||||||
Os: replace(ctx.Config.Archive.Replacements, target.goos),
|
|
||||||
Arch: replace(ctx.Config.Archive.Replacements, target.goarch),
|
|
||||||
Arm: replace(ctx.Config.Archive.Replacements, target.goarm),
|
|
||||||
Version: ctx.Version,
|
|
||||||
Tag: ctx.Git.CurrentTag,
|
|
||||||
Binary: ctx.Config.Build.Binary,
|
|
||||||
}
|
|
||||||
|
|
||||||
var out bytes.Buffer
|
|
||||||
t, err := template.New(data.Binary).Parse(ctx.Config.Archive.NameTemplate)
|
|
||||||
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
|
|
||||||
}
|
|
@ -5,7 +5,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
"github.com/goreleaser/goreleaser/context"
|
"github.com/goreleaser/goreleaser/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
var runtimeTarget = buildTarget{runtime.GOOS, runtime.GOARCH, ""}
|
var runtimeTarget = buildTarget{runtime.GOOS, runtime.GOARCH, ""}
|
||||||
@ -23,14 +23,14 @@ func (t buildTarget) PrettyString() string {
|
|||||||
return fmt.Sprintf("%v/%v%v", t.goos, t.goarch, t.goarm)
|
return fmt.Sprintf("%v/%v%v", t.goos, t.goarch, t.goarm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildTargets(ctx *context.Context) (targets []buildTarget) {
|
func buildTargets(build config.Build) (targets []buildTarget) {
|
||||||
for _, target := range allBuildTargets(ctx) {
|
for _, target := range allBuildTargets(build) {
|
||||||
if !valid(target) {
|
if !valid(target) {
|
||||||
log.WithField("target", target.PrettyString()).
|
log.WithField("target", target.PrettyString()).
|
||||||
Warn("skipped invalid build")
|
Warn("skipped invalid build")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if ignored(ctx, target) {
|
if ignored(build, target) {
|
||||||
log.WithField("target", target.PrettyString()).
|
log.WithField("target", target.PrettyString()).
|
||||||
Warn("skipped ignored build")
|
Warn("skipped ignored build")
|
||||||
continue
|
continue
|
||||||
@ -40,11 +40,11 @@ func buildTargets(ctx *context.Context) (targets []buildTarget) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func allBuildTargets(ctx *context.Context) (targets []buildTarget) {
|
func allBuildTargets(build config.Build) (targets []buildTarget) {
|
||||||
for _, goos := range ctx.Config.Build.Goos {
|
for _, goos := range build.Goos {
|
||||||
for _, goarch := range ctx.Config.Build.Goarch {
|
for _, goarch := range build.Goarch {
|
||||||
if goarch == "arm" {
|
if goarch == "arm" {
|
||||||
for _, goarm := range ctx.Config.Build.Goarm {
|
for _, goarm := range build.Goarm {
|
||||||
targets = append(targets, buildTarget{goos, goarch, goarm})
|
targets = append(targets, buildTarget{goos, goarch, goarm})
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -55,8 +55,8 @@ func allBuildTargets(ctx *context.Context) (targets []buildTarget) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func ignored(ctx *context.Context, target buildTarget) bool {
|
func ignored(build config.Build, target buildTarget) bool {
|
||||||
for _, ig := range ctx.Config.Build.Ignore {
|
for _, ig := range build.Ignore {
|
||||||
var ignored = buildTarget{ig.Goos, ig.Goarch, ig.Goarm}
|
var ignored = buildTarget{ig.Goos, ig.Goarch, ig.Goarm}
|
||||||
if ignored == target {
|
if ignored == target {
|
||||||
return true
|
return true
|
||||||
|
@ -5,15 +5,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/goreleaser/goreleaser/config"
|
"github.com/goreleaser/goreleaser/config"
|
||||||
"github.com/goreleaser/goreleaser/context"
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAllBuildTargets(t *testing.T) {
|
func TestAllBuildTargets(t *testing.T) {
|
||||||
var assert = assert.New(t)
|
var assert = assert.New(t)
|
||||||
var ctx = &context.Context{
|
var build = config.Build{
|
||||||
Config: config.Project{
|
|
||||||
Build: config.Build{
|
|
||||||
Goos: []string{
|
Goos: []string{
|
||||||
"linux",
|
"linux",
|
||||||
"darwin",
|
"darwin",
|
||||||
@ -39,8 +36,6 @@ func TestAllBuildTargets(t *testing.T) {
|
|||||||
Goarm: "7",
|
Goarm: "7",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
assert.Equal([]buildTarget{
|
assert.Equal([]buildTarget{
|
||||||
{"linux", "386", ""},
|
{"linux", "386", ""},
|
||||||
@ -52,7 +47,7 @@ func TestAllBuildTargets(t *testing.T) {
|
|||||||
{"freebsd", "amd64", ""},
|
{"freebsd", "amd64", ""},
|
||||||
{"freebsd", "arm", "6"},
|
{"freebsd", "arm", "6"},
|
||||||
{"freebsd", "arm", "7"},
|
{"freebsd", "arm", "7"},
|
||||||
}, buildTargets(ctx))
|
}, buildTargets(build))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidGoosGoarchCombos(t *testing.T) {
|
func TestValidGoosGoarchCombos(t *testing.T) {
|
||||||
|
@ -26,7 +26,7 @@ func (Pipe) Run(ctx *context.Context) (err error) {
|
|||||||
file, err := os.OpenFile(
|
file, err := os.OpenFile(
|
||||||
filepath.Join(
|
filepath.Join(
|
||||||
ctx.Config.Dist,
|
ctx.Config.Dist,
|
||||||
fmt.Sprintf("%v_checksums.txt", ctx.Config.Build.Binary),
|
fmt.Sprintf("%v_checksums.txt", ctx.Config.ProjectName),
|
||||||
),
|
),
|
||||||
os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC,
|
os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC,
|
||||||
0644,
|
0644,
|
||||||
|
@ -25,9 +25,7 @@ func TestPipe(t *testing.T) {
|
|||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
Dist: folder,
|
Dist: folder,
|
||||||
Build: config.Build{
|
ProjectName: binary,
|
||||||
Binary: binary,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx.AddArtifact(file)
|
ctx.AddArtifact(file)
|
||||||
|
@ -4,7 +4,10 @@ package defaults
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/apex/log"
|
||||||
|
"github.com/goreleaser/goreleaser/config"
|
||||||
"github.com/goreleaser/goreleaser/context"
|
"github.com/goreleaser/goreleaser/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,14 +34,44 @@ func (Pipe) Run(ctx *context.Context) error {
|
|||||||
if err := setReleaseDefaults(ctx); err != nil {
|
if err := setReleaseDefaults(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if ctx.Config.ProjectName == "" {
|
||||||
|
ctx.Config.ProjectName = ctx.Config.Release.GitHub.Name
|
||||||
|
}
|
||||||
setBuildDefaults(ctx)
|
setBuildDefaults(ctx)
|
||||||
if ctx.Config.Brew.Install == "" {
|
if ctx.Config.Brew.Install == "" {
|
||||||
ctx.Config.Brew.Install = fmt.Sprintf(
|
var installs []string
|
||||||
`bin.install "%s"`,
|
for _, build := range ctx.Config.Builds {
|
||||||
ctx.Config.Build.Binary,
|
if !isBrewBuild(build) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
installs = append(
|
||||||
|
installs,
|
||||||
|
fmt.Sprintf(`bin.install "%s"`, build.Binary),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
return setArchiveDefaults(ctx)
|
ctx.Config.Brew.Install = strings.Join(installs, "\n")
|
||||||
|
}
|
||||||
|
err := setArchiveDefaults(ctx)
|
||||||
|
log.WithField("config", ctx.Config).Debug("defaults set")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
func setReleaseDefaults(ctx *context.Context) error {
|
||||||
@ -54,24 +87,36 @@ func setReleaseDefaults(ctx *context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setBuildDefaults(ctx *context.Context) {
|
func setBuildDefaults(ctx *context.Context) {
|
||||||
if ctx.Config.Build.Binary == "" {
|
for i, build := range ctx.Config.Builds {
|
||||||
ctx.Config.Build.Binary = ctx.Config.Release.GitHub.Name
|
ctx.Config.Builds[i] = buildWithDefaults(ctx, build)
|
||||||
}
|
}
|
||||||
if ctx.Config.Build.Main == "" {
|
if len(ctx.Config.Builds) == 0 {
|
||||||
ctx.Config.Build.Main = "."
|
ctx.Config.Builds = []config.Build{
|
||||||
|
buildWithDefaults(ctx, ctx.Config.SingleBuild),
|
||||||
}
|
}
|
||||||
if len(ctx.Config.Build.Goos) == 0 {
|
|
||||||
ctx.Config.Build.Goos = []string{"linux", "darwin"}
|
|
||||||
}
|
}
|
||||||
if len(ctx.Config.Build.Goarch) == 0 {
|
}
|
||||||
ctx.Config.Build.Goarch = []string{"amd64", "386"}
|
|
||||||
|
func buildWithDefaults(ctx *context.Context, build config.Build) config.Build {
|
||||||
|
if build.Binary == "" {
|
||||||
|
build.Binary = ctx.Config.Release.GitHub.Name
|
||||||
}
|
}
|
||||||
if len(ctx.Config.Build.Goarm) == 0 {
|
if build.Main == "" {
|
||||||
ctx.Config.Build.Goarm = []string{"6"}
|
build.Main = "."
|
||||||
}
|
}
|
||||||
if ctx.Config.Build.Ldflags == "" {
|
if len(build.Goos) == 0 {
|
||||||
ctx.Config.Build.Ldflags = "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}"
|
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 {
|
func setArchiveDefaults(ctx *context.Context) error {
|
||||||
|
@ -15,33 +15,32 @@ func TestDescription(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFillBasicData(t *testing.T) {
|
func TestFillBasicData(t *testing.T) {
|
||||||
assert := assert.New(t)
|
var assert = assert.New(t)
|
||||||
|
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config.Project{},
|
Config: config.Project{},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(Pipe{}.Run(ctx))
|
assert.NoError(Pipe{}.Run(ctx))
|
||||||
|
|
||||||
assert.Equal("goreleaser", ctx.Config.Release.GitHub.Owner)
|
assert.Equal("goreleaser", ctx.Config.Release.GitHub.Owner)
|
||||||
assert.Equal("goreleaser", ctx.Config.Release.GitHub.Name)
|
assert.Equal("goreleaser", ctx.Config.Release.GitHub.Name)
|
||||||
assert.Equal("goreleaser", ctx.Config.Build.Binary)
|
assert.NotEmpty(ctx.Config.Builds)
|
||||||
assert.Equal(".", ctx.Config.Build.Main)
|
assert.Equal("goreleaser", ctx.Config.Builds[0].Binary)
|
||||||
|
assert.Equal(".", ctx.Config.Builds[0].Main)
|
||||||
|
assert.Contains(ctx.Config.Builds[0].Goos, "darwin")
|
||||||
|
assert.Contains(ctx.Config.Builds[0].Goos, "linux")
|
||||||
|
assert.Contains(ctx.Config.Builds[0].Goarch, "386")
|
||||||
|
assert.Contains(ctx.Config.Builds[0].Goarch, "amd64")
|
||||||
assert.Equal("tar.gz", ctx.Config.Archive.Format)
|
assert.Equal("tar.gz", ctx.Config.Archive.Format)
|
||||||
assert.Contains(ctx.Config.Build.Goos, "darwin")
|
|
||||||
assert.Contains(ctx.Config.Build.Goos, "linux")
|
|
||||||
assert.Contains(ctx.Config.Build.Goarch, "386")
|
|
||||||
assert.Contains(ctx.Config.Build.Goarch, "amd64")
|
|
||||||
assert.Contains(ctx.Config.Brew.Install, "bin.install \"goreleaser\"")
|
assert.Contains(ctx.Config.Brew.Install, "bin.install \"goreleaser\"")
|
||||||
assert.NotEmpty(
|
assert.NotEmpty(
|
||||||
ctx.Config.Archive.NameTemplate,
|
ctx.Config.Archive.NameTemplate,
|
||||||
ctx.Config.Build.Ldflags,
|
ctx.Config.Builds[0].Ldflags,
|
||||||
ctx.Config.Archive.Files,
|
ctx.Config.Archive.Files,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFillPartial(t *testing.T) {
|
func TestFillPartial(t *testing.T) {
|
||||||
assert := assert.New(t)
|
var assert = assert.New(t)
|
||||||
|
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
@ -56,10 +55,36 @@ func TestFillPartial(t *testing.T) {
|
|||||||
"glob/*",
|
"glob/*",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Builds: []config.Build{
|
||||||
|
{Binary: "testreleaser"},
|
||||||
|
{Goos: []string{"linux"}},
|
||||||
|
{
|
||||||
|
Binary: "another",
|
||||||
|
Ignore: []config.IgnoredBuild{
|
||||||
|
{Goos: "darwin", Goarch: "amd64"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
assert.NoError(Pipe{}.Run(ctx))
|
assert.NoError(Pipe{}.Run(ctx))
|
||||||
assert.Len(ctx.Config.Archive.Files, 1)
|
assert.Len(ctx.Config.Archive.Files, 1)
|
||||||
|
assert.Equal(`bin.install "testreleaser"`, ctx.Config.Brew.Install)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFillSingleBuild(t *testing.T) {
|
||||||
|
var assert = assert.New(t)
|
||||||
|
|
||||||
|
var ctx = &context.Context{
|
||||||
|
Config: config.Project{
|
||||||
|
SingleBuild: config.Build{
|
||||||
|
Main: "testreleaser",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert.NoError(Pipe{}.Run(ctx))
|
||||||
|
assert.Len(ctx.Config.Builds, 1)
|
||||||
|
assert.Equal(ctx.Config.Builds[0].Binary, "goreleaser")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNotAGitRepo(t *testing.T) {
|
func TestNotAGitRepo(t *testing.T) {
|
||||||
|
@ -3,19 +3,17 @@ package fpm
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
"github.com/goreleaser/goreleaser/context"
|
"github.com/goreleaser/goreleaser/context"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
var goarchToUnix = map[string]string{
|
|
||||||
"386": "i386",
|
|
||||||
"amd64": "x86_64",
|
|
||||||
}
|
|
||||||
|
|
||||||
// ErrNoFPM is shown when fpm cannot be found in $PATH
|
// ErrNoFPM is shown when fpm cannot be found in $PATH
|
||||||
var ErrNoFPM = errors.New("fpm not present in $PATH")
|
var ErrNoFPM = errors.New("fpm not present in $PATH")
|
||||||
|
|
||||||
@ -40,31 +38,38 @@ func (Pipe) Run(ctx *context.Context) error {
|
|||||||
|
|
||||||
var g errgroup.Group
|
var g errgroup.Group
|
||||||
for _, format := range ctx.Config.FPM.Formats {
|
for _, format := range ctx.Config.FPM.Formats {
|
||||||
format := format
|
for key, folder := range ctx.Folders {
|
||||||
for _, goarch := range ctx.Config.Build.Goarch {
|
if !strings.Contains(key, "linux") {
|
||||||
if ctx.Archives["linux"+goarch] == "" {
|
log.WithField("key", key).Debug("skipped non-linux builds for fpm")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
archive := ctx.Archives["linux"+goarch]
|
folder := folder
|
||||||
arch := goarchToUnix[goarch]
|
format := format
|
||||||
|
arch := archFor(key)
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
return create(ctx, format, archive, arch)
|
return create(ctx, format, folder, arch)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return g.Wait()
|
return g.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func create(ctx *context.Context, format, archive, arch string) error {
|
func archFor(key string) string {
|
||||||
var path = filepath.Join(ctx.Config.Dist, archive)
|
if strings.Contains(key, "386") {
|
||||||
|
return "i386"
|
||||||
|
}
|
||||||
|
return "x86_64"
|
||||||
|
}
|
||||||
|
|
||||||
|
func create(ctx *context.Context, format, folder, arch string) error {
|
||||||
|
var path = filepath.Join(ctx.Config.Dist, folder)
|
||||||
var file = path + "." + format
|
var file = path + "." + format
|
||||||
var name = ctx.Config.Build.Binary
|
log.WithField("file", file).Info("creating fpm archive")
|
||||||
log.WithField("file", file).Info("Creating")
|
|
||||||
|
|
||||||
var options = []string{
|
var options = []string{
|
||||||
"--input-type", "dir",
|
"--input-type", "dir",
|
||||||
"--output-type", format,
|
"--output-type", format,
|
||||||
"--name", name,
|
"--name", ctx.Config.ProjectName,
|
||||||
"--version", ctx.Version,
|
"--version", ctx.Version,
|
||||||
"--architecture", arch,
|
"--architecture", arch,
|
||||||
"--chdir", path,
|
"--chdir", path,
|
||||||
@ -94,9 +99,21 @@ func create(ctx *context.Context, format, archive, arch string) error {
|
|||||||
options = append(options, "--conflicts", conflict)
|
options = append(options, "--conflicts", conflict)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
files, err := ioutil.ReadDir(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, file := range files {
|
||||||
|
// XXX: skip non executable files here?
|
||||||
// This basically tells fpm to put the binary in the /usr/local/bin
|
// This basically tells fpm to put the binary in the /usr/local/bin
|
||||||
// binary=/usr/local/bin/binary
|
// binary=/usr/local/bin/binary
|
||||||
options = append(options, name+"="+filepath.Join("/usr/local/bin", name))
|
log.WithField("file", file.Name()).Debug("passed binary to fpm")
|
||||||
|
options = append(options, fmt.Sprintf(
|
||||||
|
"%s=%s",
|
||||||
|
file.Name(),
|
||||||
|
filepath.Join("/usr/local/bin", file.Name()),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
if out, err := exec.Command("fpm", options...).CombinedOutput(); err != nil {
|
if out, err := exec.Command("fpm", options...).CombinedOutput(); err != nil {
|
||||||
return errors.New(string(out))
|
return errors.New(string(out))
|
||||||
|
@ -33,18 +33,14 @@ func TestRunPipe(t *testing.T) {
|
|||||||
_, err = os.Create(filepath.Join(dist, "mybin", "mybin"))
|
_, err = os.Create(filepath.Join(dist, "mybin", "mybin"))
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Archives: map[string]string{
|
Folders: map[string]string{
|
||||||
"linuxamd64": "mybin",
|
"linuxamd64": "mybin",
|
||||||
|
"linux386": "mybin",
|
||||||
|
"darwinamd64": "anotherbin",
|
||||||
},
|
},
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
|
ProjectName: "mybin",
|
||||||
Dist: dist,
|
Dist: dist,
|
||||||
Build: config.Build{
|
|
||||||
Goarch: []string{
|
|
||||||
"amd64",
|
|
||||||
"i386",
|
|
||||||
},
|
|
||||||
Binary: "mybin",
|
|
||||||
},
|
|
||||||
FPM: config.FPM{
|
FPM: config.FPM{
|
||||||
Formats: []string{"deb"},
|
Formats: []string{"deb"},
|
||||||
Dependencies: []string{"make"},
|
Dependencies: []string{"make"},
|
||||||
@ -85,18 +81,11 @@ func TestCreateFileDoesntExist(t *testing.T) {
|
|||||||
assert.NoError(os.Mkdir(dist, 0755))
|
assert.NoError(os.Mkdir(dist, 0755))
|
||||||
assert.NoError(os.Mkdir(filepath.Join(dist, "mybin"), 0755))
|
assert.NoError(os.Mkdir(filepath.Join(dist, "mybin"), 0755))
|
||||||
var ctx = &context.Context{
|
var ctx = &context.Context{
|
||||||
Archives: map[string]string{
|
Folders: map[string]string{
|
||||||
"linuxamd64": "mybin",
|
"linuxamd64": "mybin",
|
||||||
},
|
},
|
||||||
Config: config.Project{
|
Config: config.Project{
|
||||||
Dist: dist,
|
Dist: dist,
|
||||||
Build: config.Build{
|
|
||||||
Goarch: []string{
|
|
||||||
"amd64",
|
|
||||||
"i386",
|
|
||||||
},
|
|
||||||
Binary: "mybin",
|
|
||||||
},
|
|
||||||
FPM: config.FPM{
|
FPM: config.FPM{
|
||||||
Formats: []string{"deb"},
|
Formats: []string{"deb"},
|
||||||
},
|
},
|
||||||
@ -104,3 +93,12 @@ func TestCreateFileDoesntExist(t *testing.T) {
|
|||||||
}
|
}
|
||||||
assert.Error(Pipe{}.Run(ctx))
|
assert.Error(Pipe{}.Run(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCreatePathDoesntExist(t *testing.T) {
|
||||||
|
var assert = assert.New(t)
|
||||||
|
var ctx = &context.Context{}
|
||||||
|
assert.Contains(
|
||||||
|
create(ctx, "tar.gz", "/nope/noooo", "windowsarm64").Error(),
|
||||||
|
"no such file",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user