1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-03-17 20:47:50 +02:00

refactor: just started fixing tests

This commit is contained in:
Carlos Alexandro Becker 2018-01-22 01:10:17 -02:00
parent 4e6982a524
commit 9416dcc751
No known key found for this signature in database
GPG Key ID: E61E2F7DC14AB940
4 changed files with 283 additions and 183 deletions

View File

@ -11,22 +11,24 @@ import (
"text/template"
"time"
"github.com/goreleaser/goreleaser/build"
api "github.com/goreleaser/goreleaser/build"
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/artifact"
"github.com/pkg/errors"
)
// Default builder instance
var Default = &Builder{}
func init() {
build.Register("go", Default)
api.Register("go", Default)
}
type Builder struct {
}
// Builder is golang builder
type Builder struct{}
// Default set the defaults for a golang build
func (*Builder) Default(build config.Build) config.Build {
if build.Main == "" {
build.Main = "."
@ -43,28 +45,29 @@ func (*Builder) Default(build config.Build) config.Build {
if build.Ldflags == "" {
build.Ldflags = "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}"
}
if build.Lang == "go" && len(build.Targets) == 0 {
if len(build.Targets) == 0 {
build.Targets = matrix(build)
}
return build
}
func (*Builder) Build(ctx *context.Context, cfg config.Build, options build.Options) error {
if err := checkMain(ctx, cfg); err != nil {
// Build builds a golang build
func (*Builder) Build(ctx *context.Context, build config.Build, options api.Options) error {
if err := checkMain(ctx, build); err != nil {
return err
}
cmd := []string{"go", "build"}
if cfg.Flags != "" {
cmd = append(cmd, strings.Fields(cfg.Flags)...)
if build.Flags != "" {
cmd = append(cmd, strings.Fields(build.Flags)...)
}
flags, err := ldflags(ctx, cfg)
flags, err := ldflags(ctx, build)
if err != nil {
return err
}
cmd = append(cmd, "-ldflags="+flags, "-o", options.Path, cfg.Main)
cmd = append(cmd, "-ldflags="+flags, "-o", options.Path, build.Main)
var target = newBuildTarget(options.Target)
var env = append(cfg.Env, target.Env()...)
if err := build.Run(ctx, cmd, env); err != nil {
var env = append(build.Env, target.Env()...)
if err := api.Run(ctx, cmd, env); err != nil {
return errors.Wrapf(err, "failed to build for %s", options.Target)
}
ctx.Artifacts.Add(artifact.Artifact{
@ -75,7 +78,7 @@ func (*Builder) Build(ctx *context.Context, cfg config.Build, options build.Opti
Goarch: target.arch,
Goarm: target.arm,
Extra: map[string]string{
"Binary": cfg.Binary,
"Binary": build.Binary,
"Ext": options.Ext,
},
})

View File

@ -1,13 +1,214 @@
package golang
import (
"io/ioutil"
"path/filepath"
"runtime"
"testing"
api "github.com/goreleaser/goreleaser/build"
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/stretchr/testify/assert"
)
var runtimeTarget = runtime.GOOS + "_" + runtime.GOARCH
func TestBuild(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var config = config.Project{
Builds: []config.Build{
{
Binary: "foo",
Goos: []string{
"linux",
"windows",
"darwin",
},
Goarch: []string{
"amd64",
"arm",
},
Goarm: []string{
"6",
},
},
},
}
var ctx = context.New(config)
var build = Default.Default(ctx.Config.Builds[0])
assert.ElementsMatch(t, build.Targets, []string{
"linux_amd64",
"darwin_amd64",
"windows_amd64",
"linux_arm_6",
})
for _, target := range build.Targets {
var err = Default.Build(ctx, build, api.Options{
Target: target,
Name: build.Binary,
Path: filepath.Join(folder, "dist", target, build.Binary),
})
assert.NoError(t, err)
}
assert.Len(t, ctx.Artifacts.List(), len(build.Targets))
}
func TestBuildFailed(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var config = config.Project{
Builds: []config.Build{
{
Flags: "-flag-that-dont-exists-to-force-failure",
Targets: []string{
runtimeTarget,
},
},
},
}
var ctx = context.New(config)
var err = Default.Build(ctx, ctx.Config.Builds[0], api.Options{
Target: "darwin_amd64",
})
assertContainsError(t, err, `flag provided but not defined: -flag-that-dont-exists-to-force-failure`)
assert.Empty(t, ctx.Artifacts.List())
}
func TestRunInvalidLdflags(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var config = config.Project{
Builds: []config.Build{
{
Binary: "nametest",
Flags: "-v",
Ldflags: "-s -w -X main.version={{.Version}",
Targets: []string{
runtimeTarget,
},
},
},
}
var ctx = context.New(config)
var err = Default.Build(ctx, ctx.Config.Builds[0], api.Options{
Target: runtimeTarget,
})
assert.EqualError(t, err, `template: ldflags:1: unexpected "}" in operand`)
}
func TestRunPipeWithoutMainFunc(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeMainWithoutMainFunc(t, folder)
var config = config.Project{
Builds: []config.Build{
{
Binary: "no-main",
Hooks: config.Hooks{},
Targets: []string{
runtimeTarget,
},
},
},
}
var ctx = context.New(config)
t.Run("empty", func(t *testing.T) {
ctx.Config.Builds[0].Main = ""
assert.EqualError(t, Default.Build(ctx, ctx.Config.Builds[0], api.Options{
Target: runtimeTarget,
}), `build for no-main does not contain a main function`)
})
t.Run("not main.go", func(t *testing.T) {
ctx.Config.Builds[0].Main = "foo.go"
assert.EqualError(t, Default.Build(ctx, ctx.Config.Builds[0], api.Options{
Target: runtimeTarget,
}), `could not open foo.go: stat foo.go: no such file or directory`)
})
t.Run("glob", func(t *testing.T) {
ctx.Config.Builds[0].Main = "."
assert.EqualError(t, Default.Build(ctx, ctx.Config.Builds[0], api.Options{
Target: runtimeTarget,
}), `build for no-main does not contain a main function`)
})
t.Run("fixed main.go", func(t *testing.T) {
ctx.Config.Builds[0].Main = "main.go"
assert.EqualError(t, Default.Build(ctx, ctx.Config.Builds[0], api.Options{
Target: runtimeTarget,
}), `build for no-main does not contain a main function`)
})
}
func TestRunPipeWithMainFuncNotInMainGoFile(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
assert.NoError(t, ioutil.WriteFile(
filepath.Join(folder, "foo.go"),
[]byte("package main\nfunc main() {println(0)}"),
0644,
))
var config = config.Project{
Builds: []config.Build{
{
Binary: "foo",
Hooks: config.Hooks{},
Targets: []string{
runtimeTarget,
},
},
},
}
var ctx = context.New(config)
t.Run("empty", func(t *testing.T) {
ctx.Config.Builds[0].Main = ""
assert.NoError(t, Default.Build(ctx, ctx.Config.Builds[0], api.Options{
Target: runtimeTarget,
}))
})
t.Run("foo.go", func(t *testing.T) {
ctx.Config.Builds[0].Main = "foo.go"
assert.NoError(t, Default.Build(ctx, ctx.Config.Builds[0], api.Options{
Target: runtimeTarget,
}))
})
t.Run("glob", func(t *testing.T) {
ctx.Config.Builds[0].Main = "."
assert.NoError(t, Default.Build(ctx, ctx.Config.Builds[0], api.Options{
Target: runtimeTarget,
}))
})
}
// FIXME: probably should be refactored
func TestRunPipeWithInvalidOS(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var config = config.Project{
Builds: []config.Build{
{
Lang: "go",
Flags: "-v",
Goos: []string{
"windows",
},
Goarch: []string{
"arm",
},
},
},
}
assert.NoError(t, Default.Build(context.New(config), config.Builds[0], api.Options{
Target: "windows_arm",
}))
}
func TestLdFlagsFullTemplate(t *testing.T) {
var config = config.Project{
Builds: []config.Build{
@ -55,3 +256,28 @@ func TestInvalidTemplate(t *testing.T) {
})
}
}
//
// Helpers
//
func writeMainWithoutMainFunc(t *testing.T, folder string) {
assert.NoError(t, ioutil.WriteFile(
filepath.Join(folder, "main.go"),
[]byte("package main\nconst a = 2\nfunc notMain() {println(0)}"),
0644,
))
}
func writeGoodMain(t *testing.T, folder string) {
assert.NoError(t, ioutil.WriteFile(
filepath.Join(folder, "main.go"),
[]byte("package main\nvar a = 1\nfunc main() {println(0)}"),
0644,
))
}
func assertContainsError(t *testing.T, err error, s string) {
assert.Error(t, err)
assert.Contains(t, err.Error(), s)
}

View File

@ -1,4 +1,5 @@
// Package build needs to be documented
// Package build provides a pipe that can build binaries for several
// languages.
package build
import (

View File

@ -1,12 +1,12 @@
package build
import (
"io/ioutil"
"os"
"path/filepath"
"runtime"
"testing"
api "github.com/goreleaser/goreleaser/build"
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/testlib"
@ -15,14 +15,31 @@ import (
var emptyEnv []string
type fakeBuilder struct{}
func (*fakeBuilder) Default(build config.Build) config.Build {
return build
}
func (*fakeBuilder) Build(ctx *context.Context, build config.Build, options api.Options) error {
return nil
}
func init() {
api.Register("fake", &fakeBuilder{})
}
func TestPipeDescription(t *testing.T) {
assert.NotEmpty(t, Pipe{}.String())
}
func TestBuild(t *testing.T) {
var builder = &fakeBuilder{}
api.Register("fake", builder)
var config = config.Project{
Builds: []config.Build{
{
Lang: "fake",
Binary: "testing",
Flags: "-n",
Env: []string{"BLAH=1"},
@ -30,19 +47,21 @@ func TestBuild(t *testing.T) {
},
}
var ctx = context.New(config)
assert.NoError(t, doBuild(ctx, ctx.Config.Builds[0], buildtarget.Runtime))
assert.NoError(t, doBuild(ctx, ctx.Config.Builds[0], "darwin_amd64"))
}
// FIXME: test is wrong
func TestRunFullPipe(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var binary = filepath.Join(folder, buildtarget.Runtime.String(), "testing")
var binary = filepath.Join(folder, "darwin_amd64", "testing")
var pre = filepath.Join(folder, "pre")
var post = filepath.Join(folder, "post")
var config = config.Project{
Builds: []config.Build{
{
Lang: "fake",
Binary: "testing",
Flags: "-v",
Ldflags: "-X main.test=testing",
@ -103,74 +122,11 @@ func TestRunPipeArmBuilds(t *testing.T) {
assert.True(t, exists(binary), binary)
}
func TestBuildFailed(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var config = config.Project{
Builds: []config.Build{
{
Flags: "-flag-that-dont-exists-to-force-failure",
Goos: []string{
runtime.GOOS,
},
Goarch: []string{
runtime.GOARCH,
},
},
},
}
var ctx = context.New(config)
assertContainsError(t, Pipe{}.Run(ctx), `flag provided but not defined: -flag-that-dont-exists-to-force-failure`)
assert.Empty(t, ctx.Artifacts.List())
}
func TestRunPipeWithInvalidOS(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var config = config.Project{
Builds: []config.Build{
{
Flags: "-v",
Goos: []string{
"windows",
},
Goarch: []string{
"arm",
},
},
},
}
assert.NoError(t, Pipe{}.Run(context.New(config)))
}
func TestRunInvalidLdflags(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
var config = config.Project{
Builds: []config.Build{
{
Binary: "nametest",
Flags: "-v",
Ldflags: "-s -w -X main.version={{.Version}",
Goos: []string{
runtime.GOOS,
},
Goarch: []string{
runtime.GOARCH,
},
},
},
}
assert.EqualError(t, Pipe{}.Run(context.New(config)), `template: ldflags:1: unexpected "}" in operand`)
}
// FIXME: probably can use fake builder here
func TestRunPipeFailingHooks(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeGoodMain(t, folder)
// writeGoodMain(t, folder)
var config = config.Project{
Builds: []config.Build{
{
@ -199,80 +155,6 @@ func TestRunPipeFailingHooks(t *testing.T) {
})
}
func TestRunPipeWithouMainFunc(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
writeMainWithoutMainFunc(t, folder)
var config = config.Project{
Builds: []config.Build{
{
Binary: "no-main",
Hooks: config.Hooks{},
Goos: []string{
runtime.GOOS,
},
Goarch: []string{
runtime.GOARCH,
},
},
},
}
var ctx = context.New(config)
t.Run("empty", func(t *testing.T) {
ctx.Config.Builds[0].Main = ""
assert.EqualError(t, Pipe{}.Run(ctx), `build for no-main does not contain a main function`)
})
t.Run("not main.go", func(t *testing.T) {
ctx.Config.Builds[0].Main = "foo.go"
assert.EqualError(t, Pipe{}.Run(ctx), `could not open foo.go: stat foo.go: no such file or directory`)
})
t.Run("glob", func(t *testing.T) {
ctx.Config.Builds[0].Main = "."
assert.EqualError(t, Pipe{}.Run(ctx), `build for no-main does not contain a main function`)
})
t.Run("fixed main.go", func(t *testing.T) {
ctx.Config.Builds[0].Main = "main.go"
assert.EqualError(t, Pipe{}.Run(ctx), `build for no-main does not contain a main function`)
})
}
func TestRunPipeWithMainFuncNotInMainGoFile(t *testing.T) {
folder, back := testlib.Mktmp(t)
defer back()
assert.NoError(t, ioutil.WriteFile(
filepath.Join(folder, "foo.go"),
[]byte("package main\nfunc main() {println(0)}"),
0644,
))
var config = config.Project{
Builds: []config.Build{
{
Binary: "foo",
Hooks: config.Hooks{},
Goos: []string{
runtime.GOOS,
},
Goarch: []string{
runtime.GOARCH,
},
},
},
}
var ctx = context.New(config)
t.Run("empty", func(t *testing.T) {
ctx.Config.Builds[0].Main = ""
assert.NoError(t, Pipe{}.Run(ctx))
})
t.Run("foo.go", func(t *testing.T) {
ctx.Config.Builds[0].Main = "foo.go"
assert.NoError(t, Pipe{}.Run(ctx))
})
t.Run("glob", func(t *testing.T) {
ctx.Config.Builds[0].Main = "."
assert.NoError(t, Pipe{}.Run(ctx))
})
}
func TestDefaultNoBuilds(t *testing.T) {
var ctx = &context.Context{
Config: config.Project{},
@ -362,32 +244,6 @@ func TestDefaultFillSingleBuild(t *testing.T) {
assert.Equal(t, ctx.Config.Builds[0].Binary, "foo")
}
func exists(file string) bool {
_, err := os.Stat(file)
return !os.IsNotExist(err)
}
func writeMainWithoutMainFunc(t *testing.T, folder string) {
assert.NoError(t, ioutil.WriteFile(
filepath.Join(folder, "main.go"),
[]byte("package main\nconst a = 2\nfunc notMain() {println(0)}"),
0644,
))
}
func writeGoodMain(t *testing.T, folder string) {
assert.NoError(t, ioutil.WriteFile(
filepath.Join(folder, "main.go"),
[]byte("package main\nvar a = 1\nfunc main() {println(0)}"),
0644,
))
}
func assertContainsError(t *testing.T, err error, s string) {
assert.Error(t, err)
assert.Contains(t, err.Error(), s)
}
func TestExtWindows(t *testing.T) {
assert.Equal(t, ".exe", extFor("windows_amd64"))
assert.Equal(t, ".exe", extFor("windows_386"))
@ -398,3 +254,17 @@ func TestExtOthers(t *testing.T) {
assert.Empty(t, "", extFor("linuxwin_386"))
assert.Empty(t, "", extFor("winasdasd_sad"))
}
//
// Helpers
//
func exists(file string) bool {
_, err := os.Stat(file)
return !os.IsNotExist(err)
}
func assertContainsError(t *testing.T, err error, s string) {
assert.Error(t, err)
assert.Contains(t, err.Error(), s)
}