1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-03-19 20:57:53 +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" "text/template"
"time" "time"
"github.com/goreleaser/goreleaser/build" api "github.com/goreleaser/goreleaser/build"
"github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context" "github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/artifact" "github.com/goreleaser/goreleaser/internal/artifact"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// Default builder instance
var Default = &Builder{} var Default = &Builder{}
func init() { 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 { func (*Builder) Default(build config.Build) config.Build {
if build.Main == "" { if build.Main == "" {
build.Main = "." build.Main = "."
@ -43,28 +45,29 @@ func (*Builder) Default(build config.Build) config.Build {
if build.Ldflags == "" { if build.Ldflags == "" {
build.Ldflags = "-s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}" 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) build.Targets = matrix(build)
} }
return build return build
} }
func (*Builder) Build(ctx *context.Context, cfg config.Build, options build.Options) error { // Build builds a golang build
if err := checkMain(ctx, cfg); err != nil { func (*Builder) Build(ctx *context.Context, build config.Build, options api.Options) error {
if err := checkMain(ctx, build); err != nil {
return err return err
} }
cmd := []string{"go", "build"} cmd := []string{"go", "build"}
if cfg.Flags != "" { if build.Flags != "" {
cmd = append(cmd, strings.Fields(cfg.Flags)...) cmd = append(cmd, strings.Fields(build.Flags)...)
} }
flags, err := ldflags(ctx, cfg) flags, err := ldflags(ctx, build)
if err != nil { if err != nil {
return err 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 target = newBuildTarget(options.Target)
var env = append(cfg.Env, target.Env()...) var env = append(build.Env, target.Env()...)
if err := build.Run(ctx, cmd, env); err != nil { if err := api.Run(ctx, cmd, env); err != nil {
return errors.Wrapf(err, "failed to build for %s", options.Target) return errors.Wrapf(err, "failed to build for %s", options.Target)
} }
ctx.Artifacts.Add(artifact.Artifact{ ctx.Artifacts.Add(artifact.Artifact{
@ -75,7 +78,7 @@ func (*Builder) Build(ctx *context.Context, cfg config.Build, options build.Opti
Goarch: target.arch, Goarch: target.arch,
Goarm: target.arm, Goarm: target.arm,
Extra: map[string]string{ Extra: map[string]string{
"Binary": cfg.Binary, "Binary": build.Binary,
"Ext": options.Ext, "Ext": options.Ext,
}, },
}) })

View File

@ -1,13 +1,214 @@
package golang package golang
import ( import (
"io/ioutil"
"path/filepath"
"runtime"
"testing" "testing"
api "github.com/goreleaser/goreleaser/build"
"github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context" "github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/testlib"
"github.com/stretchr/testify/assert" "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) { func TestLdFlagsFullTemplate(t *testing.T) {
var config = config.Project{ var config = config.Project{
Builds: []config.Build{ 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 package build
import ( import (

View File

@ -1,12 +1,12 @@
package build package build
import ( import (
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
"testing" "testing"
api "github.com/goreleaser/goreleaser/build"
"github.com/goreleaser/goreleaser/config" "github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context" "github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/internal/testlib" "github.com/goreleaser/goreleaser/internal/testlib"
@ -15,14 +15,31 @@ import (
var emptyEnv []string 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) { func TestPipeDescription(t *testing.T) {
assert.NotEmpty(t, Pipe{}.String()) assert.NotEmpty(t, Pipe{}.String())
} }
func TestBuild(t *testing.T) { func TestBuild(t *testing.T) {
var builder = &fakeBuilder{}
api.Register("fake", builder)
var config = config.Project{ var config = config.Project{
Builds: []config.Build{ Builds: []config.Build{
{ {
Lang: "fake",
Binary: "testing", Binary: "testing",
Flags: "-n", Flags: "-n",
Env: []string{"BLAH=1"}, Env: []string{"BLAH=1"},
@ -30,19 +47,21 @@ func TestBuild(t *testing.T) {
}, },
} }
var ctx = context.New(config) 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) { func TestRunFullPipe(t *testing.T) {
folder, back := testlib.Mktmp(t) folder, back := testlib.Mktmp(t)
defer back() defer back()
writeGoodMain(t, folder) 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 pre = filepath.Join(folder, "pre")
var post = filepath.Join(folder, "post") var post = filepath.Join(folder, "post")
var config = config.Project{ var config = config.Project{
Builds: []config.Build{ Builds: []config.Build{
{ {
Lang: "fake",
Binary: "testing", Binary: "testing",
Flags: "-v", Flags: "-v",
Ldflags: "-X main.test=testing", Ldflags: "-X main.test=testing",
@ -103,74 +122,11 @@ func TestRunPipeArmBuilds(t *testing.T) {
assert.True(t, exists(binary), binary) assert.True(t, exists(binary), binary)
} }
func TestBuildFailed(t *testing.T) { // FIXME: probably can use fake builder here
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`)
}
func TestRunPipeFailingHooks(t *testing.T) { func TestRunPipeFailingHooks(t *testing.T) {
folder, back := testlib.Mktmp(t) folder, back := testlib.Mktmp(t)
defer back() defer back()
writeGoodMain(t, folder) // writeGoodMain(t, folder)
var config = config.Project{ var config = config.Project{
Builds: []config.Build{ 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) { func TestDefaultNoBuilds(t *testing.T) {
var ctx = &context.Context{ var ctx = &context.Context{
Config: config.Project{}, Config: config.Project{},
@ -362,32 +244,6 @@ func TestDefaultFillSingleBuild(t *testing.T) {
assert.Equal(t, ctx.Config.Builds[0].Binary, "foo") 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) { func TestExtWindows(t *testing.T) {
assert.Equal(t, ".exe", extFor("windows_amd64")) assert.Equal(t, ".exe", extFor("windows_amd64"))
assert.Equal(t, ".exe", extFor("windows_386")) 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("linuxwin_386"))
assert.Empty(t, "", extFor("winasdasd_sad")) 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)
}