1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-14 03:51:24 +02:00

covered main cli action with tests

This commit is contained in:
Carlos Alexandro Becker 2017-04-21 15:25:32 -03:00
parent f1f4ff947e
commit dc7b9c6852
No known key found for this signature in database
GPG Key ID: E61E2F7DC14AB940
8 changed files with 284 additions and 110 deletions

1
.gitignore vendored
View File

@ -1,5 +1,6 @@
dist/
vendor
goreleaser
!cmd/goreleaser
.glide/
coverage.out

View File

@ -5,10 +5,10 @@ install:
- gem install fpm
script:
- make test
- go run main.go --skip-validate --skip-publish
- go run ./cmd/goreleaser/main.go --skip-validate --skip-publish
after_success:
- go get github.com/mattn/goveralls
- goveralls -coverprofile=coverage.out -service=travis-ci -repotoken="$COVERALLS_TOKEN"
- test -n "$TRAVIS_TAG" && go run main.go
- test -n "$TRAVIS_TAG" && go run ./cmd/goreleaser/main.go
notifications:
email: false

View File

@ -38,7 +38,8 @@ lint: ## Run all the linters
ci: lint test ## Run all the tests and code checks
build: ## Build a beta version of releaser
go build
go build -o goreleaser ./cmd/goreleaser/main.go
# Absolutely awesome: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
help:

51
cmd/goreleaser/main.go Normal file
View File

@ -0,0 +1,51 @@
package main
import (
"log"
"os"
"github.com/goreleaser/goreleaser"
"github.com/urfave/cli"
)
var (
version = "dev"
commit = "none"
date = "unknown"
)
func main() {
var app = cli.NewApp()
app.Name = "goreleaser"
app.Version = version + ", commit " + commit + ", built at " + date
app.Usage = "Deliver Go binaries as fast and easily as possible"
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "config, file, c, f",
Usage: "Load configuration from `FILE`",
Value: "goreleaser.yml",
},
cli.StringFlag{
Name: "release-notes",
Usage: "Load custom release notes from a markdown `FILE`",
},
cli.BoolFlag{
Name: "skip-validate",
Usage: "Skip all the validations against the release",
},
cli.BoolFlag{
Name: "skip-publish",
Usage: "Skip all publishing pipes of the release",
},
}
app.Action = func(c *cli.Context) error {
log.Printf("Running goreleaser %v\n", version)
if err := goreleaser.Release(c); err != nil {
return cli.NewExitError(err.Error(), 1)
}
return nil
}
if err := app.Run(os.Args); err != nil {
log.Fatalln(err)
}
}

79
goreleaser.go Normal file
View File

@ -0,0 +1,79 @@
package goreleaser
import (
"io/ioutil"
"log"
"os"
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/pipeline"
"github.com/goreleaser/goreleaser/pipeline/archive"
"github.com/goreleaser/goreleaser/pipeline/brew"
"github.com/goreleaser/goreleaser/pipeline/build"
"github.com/goreleaser/goreleaser/pipeline/checksums"
"github.com/goreleaser/goreleaser/pipeline/defaults"
"github.com/goreleaser/goreleaser/pipeline/env"
"github.com/goreleaser/goreleaser/pipeline/fpm"
"github.com/goreleaser/goreleaser/pipeline/git"
"github.com/goreleaser/goreleaser/pipeline/release"
)
var pipes = []pipeline.Pipe{
defaults.Pipe{}, // load default configs
git.Pipe{}, // get and validate git repo state
env.Pipe{}, // load and validate environment variables
build.Pipe{}, // build
archive.Pipe{}, // archive (tar.gz, zip, etc)
fpm.Pipe{}, // archive via fpm (deb, rpm, etc)
checksums.Pipe{}, // checksums of the files
release.Pipe{}, // release to github
brew.Pipe{}, // push to brew tap
}
func init() {
log.SetFlags(0)
}
// Flags interface represents an extractor of cli flags
type Flags interface {
IsSet(s string) bool
String(s string) string
Bool(s string) bool
}
// Release runs the release process with the given flags
func Release(flags Flags) error {
var file = flags.String("config")
var notes = flags.String("release-notes")
cfg, err := config.Load(file)
if err != nil {
// Allow file not found errors if config file was not
// explicitly specified
_, statErr := os.Stat(file)
if !os.IsNotExist(statErr) || flags.IsSet("config") {
return err
}
}
var ctx = context.New(cfg)
ctx.Validate = !flags.Bool("skip-validate")
ctx.Publish = !flags.Bool("skip-publish")
if notes != "" {
bts, err := ioutil.ReadFile(notes)
if err != nil {
return err
}
log.Println("Loaded custom release notes from", notes)
ctx.ReleaseNotes = string(bts)
}
for _, pipe := range pipes {
log.Println(pipe.Description())
log.SetPrefix(" -> ")
if err := pipe.Run(ctx); err != nil {
return err
}
log.SetPrefix("")
}
log.Println("Done!")
return nil
}

View File

@ -1,3 +1,5 @@
build:
main: ./cmd/goreleaser/main.go
brew:
github:
owner: goreleaser

147
goreleaser_test.go Normal file
View File

@ -0,0 +1,147 @@
package goreleaser
import (
"io/ioutil"
"log"
"os"
"os/exec"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
)
func init() {
_ = os.Unsetenv("GITHUB_TOKEN")
}
func TestRelease(t *testing.T) {
var assert = assert.New(t)
_, back := setup(t)
defer back()
var flags = fakeFlags{
flags: map[string]string{
"skip-publish": "true",
"skip-validate": "true",
},
}
assert.NoError(Release(flags))
}
func TestConfigFileIsSetAndDontExist(t *testing.T) {
var assert = assert.New(t)
var flags = fakeFlags{
flags: map[string]string{
"config": "/this/wont/exist",
},
}
assert.Error(Release(flags))
}
func TestReleaseNotesFileDontExist(t *testing.T) {
var assert = assert.New(t)
var flags = fakeFlags{
flags: map[string]string{
"release-notes": "/this/also/wont/exist",
},
}
assert.Error(Release(flags))
}
func TestCustomReleaseNotesFile(t *testing.T) {
var assert = assert.New(t)
folder, back := setup(t)
defer back()
var releaseNotes = filepath.Join(folder, "notes.md")
createFile(t, releaseNotes, "nothing important at all")
var flags = fakeFlags{
flags: map[string]string{
"release-notes": releaseNotes,
"skip-publish": "true",
"skip-validate": "true",
},
}
assert.NoError(Release(flags))
}
func TestBrokenPipe(t *testing.T) {
var assert = assert.New(t)
_, back := setup(t)
defer back()
createFile(t, "main.go", "not a valid go file")
var flags = fakeFlags{
flags: map[string]string{
"skip-publish": "true",
"skip-validate": "true",
},
}
assert.Error(Release(flags))
}
// fakeFlags is a mock of the cli flags
type fakeFlags struct {
flags map[string]string
}
func (f fakeFlags) IsSet(s string) bool {
return f.flags[s] != ""
}
func (f fakeFlags) String(s string) string {
return f.flags[s]
}
func (f fakeFlags) Bool(s string) bool {
return f.flags[s] == "true"
}
func setup(t *testing.T) (current string, back func()) {
var assert = assert.New(t)
folder, err := ioutil.TempDir("", "goreleaser")
assert.NoError(err)
log.Println("Folder:", folder)
previous, err := os.Getwd()
assert.NoError(err)
assert.NoError(os.Chdir(folder))
var gitCmds = [][]string{
{"init"},
{"add", "-A"},
{"commit", "--allow-empty", "-m", "asdf"},
{"tag", "v0.0.1"},
{"commit", "--allow-empty", "-m", "asas89d"},
{"commit", "--allow-empty", "-m", "assssf"},
{"commit", "--allow-empty", "-m", "assd"},
{"tag", "v0.0.2"},
{"remote", "add", "origin", "git@github.com:goreleaser/fake.git"},
}
createGoreleaserYaml(t)
createMainGo(t)
for _, cmd := range gitCmds {
assert.NoError(exec.Command("git", cmd...).Run())
}
return folder, func() {
assert.NoError(os.Chdir(previous))
}
}
func createFile(t *testing.T, filename, contents string) {
var assert = assert.New(t)
assert.NoError(ioutil.WriteFile(filename, []byte(contents), 0644))
}
func createMainGo(t *testing.T) {
createFile(t, "main.go", "package main\nfunc main() {println(0)}")
}
func createGoreleaserYaml(t *testing.T) {
var yaml = `build:
binary: fake
goos:
- linux
goarch:
- amd64
release:
github:
owner: goreleaser
name: fake
`
createFile(t, "goreleaser.yml", yaml)
}

107
main.go
View File

@ -1,107 +0,0 @@
package main
import (
"io/ioutil"
"log"
"os"
"github.com/goreleaser/goreleaser/config"
"github.com/goreleaser/goreleaser/context"
"github.com/goreleaser/goreleaser/pipeline"
"github.com/goreleaser/goreleaser/pipeline/archive"
"github.com/goreleaser/goreleaser/pipeline/brew"
"github.com/goreleaser/goreleaser/pipeline/build"
"github.com/goreleaser/goreleaser/pipeline/checksums"
"github.com/goreleaser/goreleaser/pipeline/defaults"
"github.com/goreleaser/goreleaser/pipeline/env"
"github.com/goreleaser/goreleaser/pipeline/fpm"
"github.com/goreleaser/goreleaser/pipeline/git"
"github.com/goreleaser/goreleaser/pipeline/release"
"github.com/urfave/cli"
)
var (
version = "dev"
commit = "none"
date = "unknown"
)
var pipes = []pipeline.Pipe{
defaults.Pipe{}, // load default configs
git.Pipe{}, // get and validate git repo state
env.Pipe{}, // load and validate environment variables
build.Pipe{}, // build
archive.Pipe{}, // archive (tar.gz, zip, etc)
fpm.Pipe{}, // archive via fpm (deb, rpm, etc)
checksums.Pipe{}, // checksums of the files
release.Pipe{}, // release to github
brew.Pipe{}, // push to brew tap
}
func init() {
log.SetFlags(0)
}
func main() {
var app = cli.NewApp()
app.Name = "goreleaser"
app.Version = version + ", commit " + commit + ", built at " + date
app.Usage = "Deliver Go binaries as fast and easily as possible"
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "config, file, c, f",
Usage: "Load configuration from `FILE`",
Value: "goreleaser.yml",
},
cli.StringFlag{
Name: "release-notes",
Usage: "Path to a markdown file with custom release notes",
},
cli.BoolFlag{
Name: "skip-validate",
Usage: "Skip all the validations against the release",
},
cli.BoolFlag{
Name: "skip-publish",
Usage: "Skip all publishing pipes of the release",
},
}
app.Action = func(c *cli.Context) (err error) {
// TODO: cover this with tests
var file = c.String("config")
var notes = c.String("release-notes")
cfg, err := config.Load(file)
if err != nil {
// Allow file not found errors if config file was not
// explicitly specified
_, statErr := os.Stat(file)
if !os.IsNotExist(statErr) || c.IsSet("config") {
return cli.NewExitError(err.Error(), 1)
}
}
var ctx = context.New(cfg)
ctx.Validate = !c.Bool("skip-validate")
ctx.Publish = !c.Bool("skip-publish")
if notes != "" {
bts, err := ioutil.ReadFile(notes)
if err != nil {
return cli.NewExitError(err.Error(), 1)
}
log.Println("Loaded custom release notes from", notes)
ctx.ReleaseNotes = string(bts)
}
for _, pipe := range pipes {
log.Println(pipe.Description())
log.SetPrefix(" -> ")
if err := pipe.Run(ctx); err != nil {
return cli.NewExitError(err.Error(), 1)
}
log.SetPrefix("")
}
log.Println("Done!")
return
}
if err := app.Run(os.Args); err != nil {
log.Fatalln(err)
}
}