1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2024-12-31 01:53:50 +02:00
goreleaser/main.go

207 lines
6.3 KiB
Go
Raw Normal View History

2017-04-21 20:25:32 +02:00
package main
import (
2017-04-22 02:58:59 +02:00
"fmt"
"io/ioutil"
2017-04-21 20:25:32 +02:00
"os"
"time"
2017-04-21 20:25:32 +02:00
2017-06-22 05:09:14 +02:00
"github.com/apex/log"
"github.com/apex/log/handlers/cli"
"github.com/caarlos0/ctrlc"
2018-01-17 22:48:01 +02:00
"github.com/fatih/color"
"github.com/goreleaser/goreleaser/internal/middleware"
"github.com/goreleaser/goreleaser/internal/pipeline"
"github.com/goreleaser/goreleaser/internal/static"
"github.com/goreleaser/goreleaser/pkg/config"
"github.com/goreleaser/goreleaser/pkg/context"
"github.com/goreleaser/goreleaser/pkg/defaults"
kingpin "gopkg.in/alecthomas/kingpin.v2"
2017-04-21 20:25:32 +02:00
)
2018-11-08 02:04:49 +02:00
// nolint: gochecknoglobals
2017-04-21 20:25:32 +02:00
var (
version = "dev"
commit = ""
date = ""
builtBy = ""
2017-04-21 20:25:32 +02:00
)
type releaseOptions struct {
Config string
ReleaseNotes string
Snapshot bool
SkipPublish bool
SkipSign bool
SkipValidate bool
RmDist bool
Parallelism int
Timeout time.Duration
}
2018-11-08 02:04:49 +02:00
func main() {
2018-10-26 16:30:03 +02:00
// enable colored output on travis
2018-10-26 23:19:51 +02:00
if os.Getenv("CI") != "" {
2018-10-26 16:30:03 +02:00
color.NoColor = false
}
log.SetHandler(cli.Default)
2017-06-22 05:09:14 +02:00
fmt.Println()
defer fmt.Println()
var app = kingpin.New("goreleaser", "Deliver Go binaries as fast and easily as possible")
var debug = app.Flag("debug", "Enable debug mode").Bool()
var config = app.Flag("config", "Load configuration from file").Short('c').Short('f').PlaceHolder(".goreleaser.yml").String()
var initCmd = app.Command("init", "Generates a .goreleaser.yml file").Alias("i")
var checkCmd = app.Command("check", "Checks if configuration is valid").Alias("c")
var releaseCmd = app.Command("release", "Releases the current project").Alias("r").Default()
var releaseNotes = releaseCmd.Flag("release-notes", "Load custom release notes from a markdown file").PlaceHolder("notes.md").String()
var snapshot = releaseCmd.Flag("snapshot", "Generate an unversioned snapshot release, skipping all validations and without publishing any artifacts").Bool()
var skipPublish = releaseCmd.Flag("skip-publish", "Skips publishing artifacts").Bool()
var skipSign = releaseCmd.Flag("skip-sign", "Skips signing the artifacts").Bool()
var skipValidate = releaseCmd.Flag("skip-validate", "Skips several sanity checks").Bool()
var rmDist = releaseCmd.Flag("rm-dist", "Remove the dist folder before building").Bool()
var parallelism = releaseCmd.Flag("parallelism", "Amount tasks to run concurrently").Short('p').Default("4").Int()
var timeout = releaseCmd.Flag("timeout", "Timeout to the entire release process").Default("30m").Duration()
app.Version(buildVersion(version, commit, date, builtBy))
app.VersionFlag.Short('v')
app.HelpFlag.Short('h')
app.UsageTemplate(static.UsageTemplate)
cmd := kingpin.MustParse(app.Parse(os.Args[1:]))
if *debug {
log.SetLevel(log.DebugLevel)
}
switch cmd {
case initCmd.FullCommand():
var filename = *config
if err := initProject(filename); err != nil {
log.WithError(err).Error("failed to init project")
os.Exit(1)
return
}
log.WithField("file", filename).Info("config created; please edit accordingly to your needs")
case checkCmd.FullCommand():
if err := checkConfig(*config); err != nil {
log.WithError(err).Errorf(color.New(color.Bold).Sprintf("config is invalid"))
os.Exit(1)
return
}
log.Infof(color.New(color.Bold).Sprintf("config is valid"))
case releaseCmd.FullCommand():
start := time.Now()
log.Infof(color.New(color.Bold).Sprintf("releasing using goreleaser %s...", version))
var options = releaseOptions{
Config: *config,
ReleaseNotes: *releaseNotes,
Snapshot: *snapshot,
SkipPublish: *skipPublish,
SkipValidate: *skipValidate,
SkipSign: *skipSign,
RmDist: *rmDist,
Parallelism: *parallelism,
Timeout: *timeout,
2017-04-21 20:25:32 +02:00
}
if err := releaseProject(options); err != nil {
log.WithError(err).Errorf(color.New(color.Bold).Sprintf("release failed after %0.2fs", time.Since(start).Seconds()))
os.Exit(1)
return
}
log.Infof(color.New(color.Bold).Sprintf("release succeeded after %0.2fs", time.Since(start).Seconds()))
2017-04-21 20:25:32 +02:00
}
}
2017-04-27 11:03:26 +02:00
func checkConfig(filename string) error {
cfg, err := loadConfig(filename)
if err != nil {
return err
}
var ctx = context.New(cfg)
return ctrlc.Default.Run(ctx, func() error {
for _, pipe := range defaults.Defaulters {
if err := middleware.ErrHandler(pipe.Default)(ctx); err != nil {
return err
}
}
return nil
})
}
func releaseProject(options releaseOptions) error {
cfg, err := loadConfig(options.Config)
if err != nil {
return err
}
ctx, cancel := context.NewWithTimeout(cfg, options.Timeout)
defer cancel()
ctx.Parallelism = options.Parallelism
log.Debugf("parallelism: %v", ctx.Parallelism)
ctx.ReleaseNotes = options.ReleaseNotes
ctx.Snapshot = options.Snapshot
ctx.SkipPublish = ctx.Snapshot || options.SkipPublish
ctx.SkipValidate = ctx.Snapshot || options.SkipValidate
ctx.SkipSign = options.SkipSign
ctx.RmDist = options.RmDist
return ctrlc.Default.Run(ctx, func() error {
2018-09-12 19:18:01 +02:00
for _, pipe := range pipeline.Pipeline {
if err := middleware.Logging(
pipe.String(),
middleware.ErrHandler(pipe.Run),
middleware.DefaultInitialPadding,
)(ctx); err != nil {
return err
}
}
return nil
})
}
// 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)
}
log.Infof(color.New(color.Bold).Sprintf("Generating %s file", filename))
return ioutil.WriteFile(filename, []byte(static.ExampleConfig), 0644)
}
func loadConfig(path string) (config.Project, error) {
if path != "" {
return config.Load(path)
}
for _, f := range [4]string{
".goreleaser.yml",
".goreleaser.yaml",
"goreleaser.yml",
"goreleaser.yaml",
} {
proj, err := config.Load(f)
if err != nil && os.IsNotExist(err) {
continue
}
return proj, err
}
// the user didn't specify a config file and the known possible file names
// don't exist, so, return an empty config and a nil err.
log.Warn("could not find a config file, using defaults...")
return config.Project{}, nil
}
func buildVersion(version, commit, date, builtBy string) string {
var result = fmt.Sprintf("version: %s", version)
if commit != "" {
result = fmt.Sprintf("%s\ncommit: %s", result, commit)
}
if date != "" {
result = fmt.Sprintf("%s\nbuilt at: %s", result, date)
}
if builtBy != "" {
result = fmt.Sprintf("%s\nbuilt by: %s", result, builtBy)
}
return result
}