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:
parent
f1f4ff947e
commit
dc7b9c6852
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
dist/
|
||||
vendor
|
||||
goreleaser
|
||||
!cmd/goreleaser
|
||||
.glide/
|
||||
coverage.out
|
||||
|
@ -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
|
||||
|
3
Makefile
3
Makefile
@ -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
51
cmd/goreleaser/main.go
Normal 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
79
goreleaser.go
Normal 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
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
build:
|
||||
main: ./cmd/goreleaser/main.go
|
||||
brew:
|
||||
github:
|
||||
owner: goreleaser
|
||||
|
147
goreleaser_test.go
Normal file
147
goreleaser_test.go
Normal 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
107
main.go
@ -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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user