github.com/tomsquest/goreleaser@v0.34.3-0.20171008022654-7d6ef4d338b3/goreleaserlib/goreleaser.go (about)

     1  package goreleaserlib
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/apex/log"
    10  	"github.com/goreleaser/goreleaser/config"
    11  	"github.com/goreleaser/goreleaser/context"
    12  	"github.com/goreleaser/goreleaser/pipeline"
    13  	"github.com/goreleaser/goreleaser/pipeline/archive"
    14  	"github.com/goreleaser/goreleaser/pipeline/brew"
    15  	"github.com/goreleaser/goreleaser/pipeline/build"
    16  	"github.com/goreleaser/goreleaser/pipeline/checksums"
    17  	"github.com/goreleaser/goreleaser/pipeline/cleandist"
    18  	"github.com/goreleaser/goreleaser/pipeline/defaults"
    19  	"github.com/goreleaser/goreleaser/pipeline/docker"
    20  	"github.com/goreleaser/goreleaser/pipeline/env"
    21  	"github.com/goreleaser/goreleaser/pipeline/fpm"
    22  	"github.com/goreleaser/goreleaser/pipeline/git"
    23  	"github.com/goreleaser/goreleaser/pipeline/release"
    24  	"github.com/goreleaser/goreleaser/pipeline/snapcraft"
    25  	yaml "gopkg.in/yaml.v2"
    26  )
    27  
    28  var pipes = []pipeline.Pipe{
    29  	defaults.Pipe{},  // load default configs
    30  	git.Pipe{},       // get and validate git repo state
    31  	env.Pipe{},       // load and validate environment variables
    32  	cleandist.Pipe{}, // ensure ./dist is clean
    33  	build.Pipe{},     // build
    34  	archive.Pipe{},   // archive (tar.gz, zip, etc)
    35  	fpm.Pipe{},       // archive via fpm (deb, rpm, etc)
    36  	snapcraft.Pipe{}, // archive via snapcraft (snap)
    37  	checksums.Pipe{}, // checksums of the files
    38  	docker.Pipe{},    // create and push docker images
    39  	release.Pipe{},   // release to github
    40  	brew.Pipe{},      // push to brew tap
    41  }
    42  
    43  // Flags interface represents an extractor of cli flags
    44  type Flags interface {
    45  	IsSet(s string) bool
    46  	String(s string) string
    47  	Int(s string) int
    48  	Bool(s string) bool
    49  }
    50  
    51  // Release runs the release process with the given flags
    52  func Release(flags Flags) error {
    53  	var file = getConfigFile(flags)
    54  	var notes = flags.String("release-notes")
    55  	if flags.Bool("debug") {
    56  		log.SetLevel(log.DebugLevel)
    57  	}
    58  	cfg, err := config.Load(file)
    59  	if err != nil {
    60  		// Allow file not found errors if config file was not
    61  		// explicitly specified
    62  		_, statErr := os.Stat(file)
    63  		if !os.IsNotExist(statErr) || flags.IsSet("config") {
    64  			return err
    65  		}
    66  		log.WithField("file", file).Warn("could not load config, using defaults")
    67  	}
    68  	var ctx = context.New(cfg)
    69  	ctx.Parallelism = flags.Int("parallelism")
    70  	log.Debugf("parallelism: %v", ctx.Parallelism)
    71  	ctx.Validate = !flags.Bool("skip-validate")
    72  	ctx.Publish = !flags.Bool("skip-publish")
    73  	if notes != "" {
    74  		bts, err := ioutil.ReadFile(notes)
    75  		if err != nil {
    76  			return err
    77  		}
    78  		log.WithField("file", notes).Info("loaded custom release notes")
    79  		log.WithField("file", notes).Debugf("custon release notes: \n%s", string(bts))
    80  		ctx.ReleaseNotes = string(bts)
    81  	}
    82  	ctx.Snapshot = flags.Bool("snapshot")
    83  	if ctx.Snapshot {
    84  		log.Info("publishing disabled in snapshot mode")
    85  		ctx.Publish = false
    86  	}
    87  	ctx.RmDist = flags.Bool("rm-dist")
    88  	for _, pipe := range pipes {
    89  		log.Infof("\033[1m%s\033[0m", strings.ToUpper(pipe.Description()))
    90  		if err := handle(pipe.Run(ctx)); err != nil {
    91  			return err
    92  		}
    93  	}
    94  	log.Infof("\033[1mSUCCESS!\033[0m")
    95  	return nil
    96  }
    97  
    98  func handle(err error) error {
    99  	if err == nil {
   100  		return nil
   101  	}
   102  	if pipeline.IsSkip(err) {
   103  		log.WithField("reason", err.Error()).Warn("skipped")
   104  		return nil
   105  	}
   106  	return err
   107  }
   108  
   109  // InitProject creates an example goreleaser.yml in the current directory
   110  func InitProject(filename string) error {
   111  	if _, err := os.Stat(filename); !os.IsNotExist(err) {
   112  		if err != nil {
   113  			return err
   114  		}
   115  		return fmt.Errorf("%s already exists", filename)
   116  	}
   117  
   118  	var ctx = context.New(config.Project{})
   119  	var pipe = defaults.Pipe{}
   120  	if err := pipe.Run(ctx); err != nil {
   121  		return err
   122  	}
   123  	out, err := yaml.Marshal(ctx.Config)
   124  	if err != nil {
   125  		return err
   126  	}
   127  
   128  	return ioutil.WriteFile(filename, out, 0644)
   129  }
   130  
   131  func getConfigFile(flags Flags) string {
   132  	var config = flags.String("config")
   133  	if flags.IsSet("config") {
   134  		return config
   135  	}
   136  	for _, f := range []string{
   137  		".goreleaser.yml",
   138  		".goreleaser.yaml",
   139  		"goreleaser.yml",
   140  		"goreleaser.yaml",
   141  	} {
   142  		_, ferr := os.Stat(f)
   143  		if ferr == nil || os.IsExist(ferr) {
   144  			return f
   145  		}
   146  	}
   147  	return config
   148  }