1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-02-03 13:11:48 +02:00

refactor: removed goreleaserlib: moved all to main (#574)

* refactor: removed goreleaserlib: moved all to main

* test: fixed tests
This commit is contained in:
Carlos Alexandro Becker 2018-02-21 20:04:22 -03:00 committed by GitHub
parent f2bd64f146
commit e999e34d96
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 189 additions and 208 deletions

View File

@ -1,192 +0,0 @@
package goreleaserlib
import (
"fmt"
"io/ioutil"
"os"
"strings"
"time"
"github.com/apex/log"
"github.com/apex/log/handlers/cli"
"github.com/caarlos0/ctrlc"
"github.com/fatih/color"
yaml "gopkg.in/yaml.v2"
"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/artifactory"
"github.com/goreleaser/goreleaser/pipeline/brew"
"github.com/goreleaser/goreleaser/pipeline/build"
"github.com/goreleaser/goreleaser/pipeline/changelog"
"github.com/goreleaser/goreleaser/pipeline/checksums"
"github.com/goreleaser/goreleaser/pipeline/defaults"
"github.com/goreleaser/goreleaser/pipeline/dist"
"github.com/goreleaser/goreleaser/pipeline/docker"
"github.com/goreleaser/goreleaser/pipeline/effectiveconfig"
"github.com/goreleaser/goreleaser/pipeline/env"
"github.com/goreleaser/goreleaser/pipeline/fpm"
"github.com/goreleaser/goreleaser/pipeline/git"
"github.com/goreleaser/goreleaser/pipeline/nfpm"
"github.com/goreleaser/goreleaser/pipeline/release"
"github.com/goreleaser/goreleaser/pipeline/scoop"
"github.com/goreleaser/goreleaser/pipeline/sign"
"github.com/goreleaser/goreleaser/pipeline/snapcraft"
)
var (
normalPadding = cli.Default.Padding
increasedPadding = normalPadding * 2
)
func init() {
log.SetHandler(cli.Default)
}
var pipes = []pipeline.Piper{
defaults.Pipe{}, // load default configs
dist.Pipe{}, // ensure ./dist is clean
git.Pipe{}, // get and validate git repo state
effectiveconfig.Pipe{}, // writes the actual config (with defaults et al set) to dist
changelog.Pipe{}, // builds the release changelog
env.Pipe{}, // load and validate environment variables
build.Pipe{}, // build
archive.Pipe{}, // archive in tar.gz, zip or binary (which does no archiving at all)
fpm.Pipe{}, // archive via fpm (deb, rpm) using fpm
nfpm.Pipe{}, // archive via fpm (deb, rpm) using "native" go impl
snapcraft.Pipe{}, // archive via snapcraft (snap)
checksums.Pipe{}, // checksums of the files
sign.Pipe{}, // sign artifacts
docker.Pipe{}, // create and push docker images
artifactory.Pipe{}, // push to artifactory
release.Pipe{}, // release to github
brew.Pipe{}, // push to brew tap
scoop.Pipe{}, // push to scoop bucket
}
// Flags interface represents an extractor of cli flags
type Flags interface {
IsSet(s string) bool
String(s string) string
Int(s string) int
Bool(s string) bool
Duration(s string) time.Duration
}
// Release runs the release process with the given flags
func Release(flags Flags) error {
var file = getConfigFile(flags)
var notes = flags.String("release-notes")
if flags.Bool("debug") {
log.SetLevel(log.DebugLevel)
}
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
}
log.WithField("file", file).Warn("could not load config, using defaults")
}
ctx, cancel := context.NewWithTimeout(cfg, flags.Duration("timeout"))
defer cancel()
ctx.Parallelism = flags.Int("parallelism")
ctx.Debug = flags.Bool("debug")
log.Debugf("parallelism: %v", ctx.Parallelism)
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.WithField("file", notes).Info("loaded custom release notes")
log.WithField("file", notes).Debugf("custom release notes: \n%s", string(bts))
ctx.ReleaseNotes = string(bts)
}
ctx.Snapshot = flags.Bool("snapshot")
if ctx.Snapshot {
log.Info("publishing disabled in snapshot mode")
ctx.Publish = false
}
ctx.RmDist = flags.Bool("rm-dist")
return doRelease(ctx)
}
func doRelease(ctx *context.Context) error {
defer restoreOutputPadding()
return ctrlc.Default.Run(ctx, func() error {
for _, pipe := range pipes {
restoreOutputPadding()
log.Infof(color.New(color.Bold).Sprint(strings.ToUpper(pipe.String())))
cli.Default.Padding = increasedPadding
if err := handle(pipe.Run(ctx)); err != nil {
return err
}
}
return nil
})
}
func restoreOutputPadding() {
cli.Default.Padding = normalPadding
}
func handle(err error) error {
if err == nil {
return nil
}
if pipeline.IsSkip(err) {
log.WithField("reason", err.Error()).Warn("skipped")
return nil
}
return err
}
// InitProject creates an example goreleaser.yml in the current directory
func InitProject(filename string) error {
if _, err := os.Stat(filename); !os.IsNotExist(err) {
if err != nil {
return err
}
return fmt.Errorf("%s already exists", filename)
}
var ctx = context.New(config.Project{})
var pipe = defaults.Pipe{}
defer restoreOutputPadding()
log.Infof(color.New(color.Bold).Sprint(strings.ToUpper(pipe.String())))
cli.Default.Padding = increasedPadding
if err := pipe.Run(ctx); err != nil {
return err
}
out, err := yaml.Marshal(ctx.Config)
if err != nil {
return err
}
return ioutil.WriteFile(filename, out, 0644)
}
func getConfigFile(flags Flags) string {
var config = flags.String("config")
if flags.IsSet("config") {
return config
}
for _, f := range []string{
".goreleaser.yml",
".goreleaser.yaml",
"goreleaser.yml",
"goreleaser.yaml",
} {
_, ferr := os.Stat(f)
if ferr == nil || os.IsExist(ferr) {
return f
}
}
return config
}

181
main.go
View File

@ -2,14 +2,40 @@ package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
"time"
"github.com/apex/log"
lcli "github.com/apex/log/handlers/cli"
"github.com/caarlos0/ctrlc"
yaml "gopkg.in/yaml.v2"
"github.com/fatih/color"
"github.com/goreleaser/goreleaser/goreleaserlib"
"github.com/urfave/cli"
"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/artifactory"
"github.com/goreleaser/goreleaser/pipeline/brew"
"github.com/goreleaser/goreleaser/pipeline/build"
"github.com/goreleaser/goreleaser/pipeline/changelog"
"github.com/goreleaser/goreleaser/pipeline/checksums"
"github.com/goreleaser/goreleaser/pipeline/defaults"
"github.com/goreleaser/goreleaser/pipeline/dist"
"github.com/goreleaser/goreleaser/pipeline/docker"
"github.com/goreleaser/goreleaser/pipeline/effectiveconfig"
"github.com/goreleaser/goreleaser/pipeline/env"
"github.com/goreleaser/goreleaser/pipeline/fpm"
"github.com/goreleaser/goreleaser/pipeline/git"
"github.com/goreleaser/goreleaser/pipeline/nfpm"
"github.com/goreleaser/goreleaser/pipeline/release"
"github.com/goreleaser/goreleaser/pipeline/scoop"
"github.com/goreleaser/goreleaser/pipeline/sign"
"github.com/goreleaser/goreleaser/pipeline/snapcraft"
)
var (
@ -17,9 +43,41 @@ var (
commit = "none"
date = "unknown"
bold = color.New(color.Bold)
bold = color.New(color.Bold)
normalPadding = lcli.Default.Padding
increasedPadding = normalPadding * 2
pipes = []pipeline.Piper{
defaults.Pipe{}, // load default configs
dist.Pipe{}, // ensure ./dist is clean
git.Pipe{}, // get and validate git repo state
effectiveconfig.Pipe{}, // writes the actual config (with defaults et al set) to dist
changelog.Pipe{}, // builds the release changelog
env.Pipe{}, // load and validate environment variables
build.Pipe{}, // build
archive.Pipe{}, // archive in tar.gz, zip or binary (which does no archiving at all)
fpm.Pipe{}, // archive via fpm (deb, rpm) using fpm
nfpm.Pipe{}, // archive via fpm (deb, rpm) using "native" go impl
snapcraft.Pipe{}, // archive via snapcraft (snap)
checksums.Pipe{}, // checksums of the files
sign.Pipe{}, // sign artifacts
docker.Pipe{}, // create and push docker images
artifactory.Pipe{}, // push to artifactory
release.Pipe{}, // release to github
brew.Pipe{}, // push to brew tap
scoop.Pipe{}, // push to scoop bucket
}
)
// Flags interface represents an extractor of cli flags
type Flags interface {
IsSet(s string) bool
String(s string) string
Int(s string) int
Bool(s string) bool
Duration(s string) time.Duration
}
func init() {
log.SetHandler(lcli.Default)
}
@ -75,7 +133,7 @@ func main() {
app.Action = func(c *cli.Context) error {
start := time.Now()
log.Infof(bold.Sprint("releasing..."))
if err := goreleaserlib.Release(c); err != nil {
if err := releaseProject(c); err != nil {
log.WithError(err).Errorf(bold.Sprintf("release failed after %0.2fs", time.Since(start).Seconds()))
return cli.NewExitError("\n", 1)
}
@ -89,7 +147,7 @@ func main() {
Usage: "generate .goreleaser.yml",
Action: func(c *cli.Context) error {
var filename = ".goreleaser.yml"
if err := goreleaserlib.InitProject(filename); err != nil {
if err := initProject(filename); err != nil {
log.WithError(err).Error("failed to init project")
return cli.NewExitError("\n", 1)
}
@ -104,3 +162,118 @@ func main() {
log.WithError(err).Fatal("failed")
}
}
func releaseProject(flags Flags) error {
var file = getConfigFile(flags)
var notes = flags.String("release-notes")
if flags.Bool("debug") {
log.SetLevel(log.DebugLevel)
}
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
}
log.WithField("file", file).Warn("could not load config, using defaults")
}
ctx, cancel := context.NewWithTimeout(cfg, flags.Duration("timeout"))
defer cancel()
ctx.Parallelism = flags.Int("parallelism")
ctx.Debug = flags.Bool("debug")
log.Debugf("parallelism: %v", ctx.Parallelism)
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.WithField("file", notes).Info("loaded custom release notes")
log.WithField("file", notes).Debugf("custom release notes: \n%s", string(bts))
ctx.ReleaseNotes = string(bts)
}
ctx.Snapshot = flags.Bool("snapshot")
if ctx.Snapshot {
log.Info("publishing disabled in snapshot mode")
ctx.Publish = false
}
ctx.RmDist = flags.Bool("rm-dist")
return doRelease(ctx)
}
func doRelease(ctx *context.Context) error {
defer restoreOutputPadding()
return ctrlc.Default.Run(ctx, func() error {
for _, pipe := range pipes {
restoreOutputPadding()
log.Infof(color.New(color.Bold).Sprint(strings.ToUpper(pipe.String())))
lcli.Default.Padding = increasedPadding
if err := handle(pipe.Run(ctx)); err != nil {
return err
}
}
return nil
})
}
func restoreOutputPadding() {
lcli.Default.Padding = normalPadding
}
func handle(err error) error {
if err == nil {
return nil
}
if pipeline.IsSkip(err) {
log.WithField("reason", err.Error()).Warn("skipped")
return nil
}
return err
}
// InitProject creates an example goreleaser.yml in the current directory
func initProject(filename string) error {
if _, err := os.Stat(filename); !os.IsNotExist(err) {
if err != nil {
return err
}
return fmt.Errorf("%s already exists", filename)
}
var ctx = context.New(config.Project{})
var pipe = defaults.Pipe{}
defer restoreOutputPadding()
log.Infof(color.New(color.Bold).Sprint(strings.ToUpper(pipe.String())))
lcli.Default.Padding = increasedPadding
if err := pipe.Run(ctx); err != nil {
return err
}
out, err := yaml.Marshal(ctx.Config)
if err != nil {
return err
}
return ioutil.WriteFile(filename, out, 0644)
}
func getConfigFile(flags Flags) string {
var config = flags.String("config")
if flags.IsSet("config") {
return config
}
for _, f := range []string{
".goreleaser.yml",
".goreleaser.yaml",
"goreleaser.yml",
"goreleaser.yaml",
} {
_, ferr := os.Stat(f)
if ferr == nil || os.IsExist(ferr) {
return f
}
}
return config
}

View File

@ -1,4 +1,4 @@
package goreleaserlib
package main
import (
"io/ioutil"
@ -18,24 +18,24 @@ func init() {
_ = os.Unsetenv("GITHUB_TOKEN")
}
func TestRelease(t *testing.T) {
func TestReleaseProject(t *testing.T) {
_, back := setup(t)
defer back()
assert.NoError(t, Release(newFlags(t, testParams())))
assert.NoError(t, releaseProject(newFlags(t, testParams())))
}
func TestSnapshotRelease(t *testing.T) {
func TestSnapshotreleaseProject(t *testing.T) {
_, back := setup(t)
defer back()
params := testParams()
params["snapshot"] = "true"
assert.NoError(t, Release(newFlags(t, params)))
assert.NoError(t, releaseProject(newFlags(t, params)))
}
func TestConfigFileIsSetAndDontExist(t *testing.T) {
params := testParams()
params["config"] = "/this/wont/exist"
assert.Error(t, Release(newFlags(t, params)))
assert.Error(t, releaseProject(newFlags(t, params)))
}
func TestConfigFlagNotSetButExists(t *testing.T) {
@ -63,7 +63,7 @@ func TestConfigFlagNotSetButExists(t *testing.T) {
func TestReleaseNotesFileDontExist(t *testing.T) {
params := testParams()
params["release-notes"] = "/this/also/wont/exist"
assert.Error(t, Release(newFlags(t, params)))
assert.Error(t, releaseProject(newFlags(t, params)))
}
func TestCustomReleaseNotesFile(t *testing.T) {
@ -73,21 +73,21 @@ func TestCustomReleaseNotesFile(t *testing.T) {
createFile(t, releaseNotes, "nothing important at all")
var params = testParams()
params["release-notes"] = releaseNotes
assert.NoError(t, Release(newFlags(t, params)))
assert.NoError(t, releaseProject(newFlags(t, params)))
}
func TestBrokenPipe(t *testing.T) {
_, back := setup(t)
defer back()
createFile(t, "main.go", "not a valid go file")
assert.Error(t, Release(newFlags(t, testParams())))
assert.Error(t, releaseProject(newFlags(t, testParams())))
}
func TestInitProject(t *testing.T) {
_, back := setup(t)
defer back()
var filename = "test_goreleaser.yml"
assert.NoError(t, InitProject(filename))
assert.NoError(t, initProject(filename))
file, err := os.Open(filename)
assert.NoError(t, err)
@ -103,7 +103,7 @@ func TestInitProjectFileExist(t *testing.T) {
defer back()
var filename = "test_goreleaser.yml"
createFile(t, filename, "")
assert.Error(t, InitProject(filename))
assert.Error(t, initProject(filename))
}
func TestInitProjectDefaultPipeFails(t *testing.T) {
@ -111,7 +111,7 @@ func TestInitProjectDefaultPipeFails(t *testing.T) {
defer back()
var filename = "test_goreleaser.yml"
assert.NoError(t, os.RemoveAll(".git"))
assert.Error(t, InitProject(filename))
assert.Error(t, initProject(filename))
}
// fakeFlags is a mock of the cli flags