1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-01-10 03:47:03 +02:00
goreleaser/config/config.go

334 lines
10 KiB
Go
Raw Normal View History

2017-04-14 20:39:32 +02:00
// Package config contains the model and loader of the goreleaser configuration
// file.
2016-12-21 14:35:34 +02:00
package config
import (
2017-07-08 17:05:57 +02:00
"fmt"
2017-05-11 04:14:17 +02:00
"io"
2016-12-21 14:35:34 +02:00
"io/ioutil"
2017-05-18 14:02:02 +02:00
"os"
2017-07-08 17:05:57 +02:00
"strings"
2017-06-28 01:06:45 +02:00
"github.com/apex/log"
2017-07-08 17:05:57 +02:00
yaml "gopkg.in/yaml.v2"
2016-12-21 14:35:34 +02:00
)
2017-09-26 23:33:22 +02:00
// GitHubURLs holds the URLs to be used when using github enterprise
type GitHubURLs struct {
API string `yaml:"api,omitempty"`
Upload string `yaml:"upload,omitempty"`
Download string `yaml:"download,omitempty"`
}
2017-03-23 02:01:29 +02:00
// Repo represents any kind of repo (github, gitlab, etc)
type Repo struct {
2017-09-26 23:33:22 +02:00
Owner string `yaml:",omitempty"`
Name string `yaml:",omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
2017-03-23 02:01:29 +02:00
}
2017-03-23 02:27:04 +02:00
// String of the repo, e.g. owner/name
2017-03-23 02:01:29 +02:00
func (r Repo) String() string {
if r.Owner == "" && r.Name == "" {
return ""
}
2017-03-23 02:01:29 +02:00
return r.Owner + "/" + r.Name
}
// Homebrew contains the brew section
type Homebrew struct {
GitHub Repo `yaml:",omitempty"`
CommitAuthor CommitAuthor `yaml:"commit_author,omitempty"`
Folder string `yaml:",omitempty"`
Caveats string `yaml:",omitempty"`
Plist string `yaml:",omitempty"`
Install string `yaml:",omitempty"`
Dependencies []string `yaml:",omitempty"`
Test string `yaml:",omitempty"`
Conflicts []string `yaml:",omitempty"`
Description string `yaml:",omitempty"`
Homepage string `yaml:",omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
2016-12-21 14:35:34 +02:00
}
// CommitAuthor is the author of a Git commit
type CommitAuthor struct {
Name string `yaml:",omitempty"`
Email string `yaml:",omitempty"`
}
// Hooks define actions to run before and/or after something
type Hooks struct {
2017-04-28 18:18:32 +02:00
Pre string `yaml:",omitempty"`
Post string `yaml:",omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
}
2017-04-27 01:08:25 +02:00
// IgnoredBuild represents a build ignored by the user
type IgnoredBuild struct {
Goos, Goarch, Goarm string
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
2017-04-27 01:08:25 +02:00
}
// Build contains the build configuration section
type Build struct {
2017-05-01 17:04:31 +02:00
Goos []string `yaml:",omitempty"`
Goarch []string `yaml:",omitempty"`
Goarm []string `yaml:",omitempty"`
Ignore []IgnoredBuild `yaml:",omitempty"`
Main string `yaml:",omitempty"`
Ldflags string `yaml:",omitempty"`
Flags string `yaml:",omitempty"`
Binary string `yaml:",omitempty"`
Hooks Hooks `yaml:",omitempty"`
2017-05-11 15:43:25 +02:00
Env []string `yaml:",omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
2016-12-21 15:37:31 +02:00
}
// FormatOverride is used to specify a custom format for a specific GOOS.
type FormatOverride struct {
2017-04-28 18:18:32 +02:00
Goos string `yaml:",omitempty"`
Format string `yaml:",omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
}
// Archive config used for the archive
type Archive struct {
2017-04-28 18:18:32 +02:00
Format string `yaml:",omitempty"`
FormatOverrides []FormatOverride `yaml:"format_overrides,omitempty"`
NameTemplate string `yaml:"name_template,omitempty"`
WrapInDirectory bool `yaml:"wrap_in_directory,omitempty"`
2017-04-28 18:18:32 +02:00
Replacements map[string]string `yaml:",omitempty"`
Files []string `yaml:",omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
}
// Release config used for the GitHub release
type Release struct {
GitHub Repo `yaml:",omitempty"`
Draft bool `yaml:",omitempty"`
Prerelease bool `yaml:",omitempty"`
NameTemplate string `yaml:"name_template,omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
2017-01-14 18:06:57 +02:00
}
2017-01-30 01:55:32 +02:00
// FPM config
type FPM struct {
Formats []string `yaml:",omitempty"`
Dependencies []string `yaml:",omitempty"`
Conflicts []string `yaml:",omitempty"`
Vendor string `yaml:",omitempty"`
Homepage string `yaml:",omitempty"`
Maintainer string `yaml:",omitempty"`
Description string `yaml:",omitempty"`
License string `yaml:",omitempty"`
Bindir string `yaml:",omitempty"`
Files map[string]string `yaml:",omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
2017-01-30 01:55:32 +02:00
}
2017-08-04 07:44:49 +02:00
// SnapcraftAppMetadata for the binaries that will be in the snap package
2017-08-04 07:42:55 +02:00
type SnapcraftAppMetadata struct {
Plugs []string
Daemon string
}
2017-07-27 02:30:48 +02:00
// Snapcraft config
type Snapcraft struct {
2017-08-07 18:28:04 +02:00
Name string `yaml:",omitempty"`
2017-08-04 07:42:55 +02:00
Summary string `yaml:",omitempty"`
Description string `yaml:",omitempty"`
Grade string `yaml:",omitempty"`
Confinement string `yaml:",omitempty"`
Apps map[string]SnapcraftAppMetadata `yaml:",omitempty"`
2017-07-27 02:30:48 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
}
2017-04-29 12:49:22 +02:00
// Snapshot config
type Snapshot struct {
NameTemplate string `yaml:"name_template,omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
2017-01-30 01:55:32 +02:00
}
2017-08-28 01:45:33 +02:00
// Checksum config
type Checksum struct {
NameTemplate string `yaml:"name_template,omitempty"`
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
}
2017-09-12 04:31:00 +02:00
// Docker image config
type Docker struct {
Binary string `yaml:",omitempty"`
Goos string `yaml:",omitempty"`
Goarch string `yaml:",omitempty"`
Goarm string `yaml:",omitempty"`
Image string `yaml:",omitempty"`
Dockerfile string `yaml:",omitempty"`
Latest bool `yaml:",omitempty"`
TagTemplate string `yaml:"tag_template,omitempty"`
Files []string `yaml:"extra_files,omitempty"`
2017-09-12 04:31:00 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
}
// Artifactory server configuration
type Artifactory struct {
Target string `yaml:",omitempty"`
Username string `yaml:",omitempty"`
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
}
// Filters config
type Filters struct {
Exclude []string `yaml:",omitempty"`
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
}
// Changelog Config
type Changelog struct {
Filters Filters `yaml:",omitempty"`
Sort string `yaml:",omitempty"`
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
}
// Project includes all project configuration
type Project struct {
ProjectName string `yaml:"project_name,omitempty"`
Release Release `yaml:",omitempty"`
Brew Homebrew `yaml:",omitempty"`
Builds []Build `yaml:",omitempty"`
Archive Archive `yaml:",omitempty"`
FPM FPM `yaml:",omitempty"`
Snapcraft Snapcraft `yaml:",omitempty"`
Snapshot Snapshot `yaml:",omitempty"`
Checksum Checksum `yaml:",omitempty"`
Dockers []Docker `yaml:",omitempty"`
Artifactories []Artifactory `yaml:",omitempty"`
Changelog Changelog `yaml:",omitempty"`
Dist string `yaml:",omitempty"`
2017-03-26 02:29:38 +02:00
2017-07-02 02:27:30 +02:00
// this is a hack ¯\_(ツ)_/¯
SingleBuild Build `yaml:"build,omitempty"`
2017-09-26 23:33:22 +02:00
// should be set if using github enterprise
GitHubURLs GitHubURLs `yaml:"github_urls,omitempty"`
2017-07-08 17:05:57 +02:00
// Capture all undefined fields and should be empty after loading
XXX map[string]interface{} `yaml:",inline"`
2016-12-21 14:35:34 +02:00
}
2016-12-30 16:41:59 +02:00
// Load config file
func Load(file string) (config Project, err error) {
2017-05-18 14:02:02 +02:00
f, err := os.Open(file)
2016-12-21 14:35:34 +02:00
if err != nil {
2017-05-18 14:02:02 +02:00
return
2016-12-21 14:35:34 +02:00
}
2017-07-05 04:51:45 +02:00
log.WithField("file", file).Info("loading config file")
2017-05-18 14:02:02 +02:00
return LoadReader(f)
}
2017-05-11 04:14:17 +02:00
2017-05-18 14:02:02 +02:00
// LoadReader config via io.Reader
2017-05-11 04:14:17 +02:00
func LoadReader(fd io.Reader) (config Project, err error) {
data, err := ioutil.ReadAll(fd)
if err != nil {
2017-05-11 04:35:44 +02:00
return config, err
}
2017-08-02 14:16:59 +02:00
if err := yaml.Unmarshal(data, &config); err != nil {
return config, err
}
2017-07-02 02:27:30 +02:00
log.WithField("config", config).Debug("loaded config file")
2017-08-02 14:16:59 +02:00
return config, checkOverflows(config)
2017-05-11 04:14:17 +02:00
}
2017-07-08 17:05:57 +02:00
func checkOverflows(config Project) error {
2017-08-28 01:45:33 +02:00
var overflow = &overflowChecker{}
overflow.check(config.XXX, "")
overflow.check(config.Archive.XXX, "archive")
2017-07-08 17:05:57 +02:00
for i, ov := range config.Archive.FormatOverrides {
2017-08-28 01:45:33 +02:00
overflow.check(ov.XXX, fmt.Sprintf("archive.format_overrides[%d]", i))
2017-07-08 17:05:57 +02:00
}
2017-08-28 01:45:33 +02:00
overflow.check(config.Brew.XXX, "brew")
overflow.check(config.Brew.GitHub.XXX, "brew.github")
2017-07-08 17:05:57 +02:00
for i, build := range config.Builds {
2017-08-28 01:45:33 +02:00
overflow.check(build.XXX, fmt.Sprintf("builds[%d]", i))
overflow.check(build.Hooks.XXX, fmt.Sprintf("builds[%d].hooks", i))
2017-07-08 17:05:57 +02:00
for j, ignored := range build.Ignore {
2017-08-28 01:45:33 +02:00
overflow.check(ignored.XXX, fmt.Sprintf("builds[%d].ignored_builds[%d]", i, j))
2017-07-08 17:05:57 +02:00
}
}
2017-08-28 01:45:33 +02:00
overflow.check(config.FPM.XXX, "fpm")
overflow.check(config.Snapcraft.XXX, "snapcraft")
overflow.check(config.Release.XXX, "release")
overflow.check(config.Release.GitHub.XXX, "release.github")
overflow.check(config.SingleBuild.XXX, "build")
overflow.check(config.SingleBuild.Hooks.XXX, "builds.hooks")
2017-07-08 17:05:57 +02:00
for i, ignored := range config.SingleBuild.Ignore {
2017-08-28 01:45:33 +02:00
overflow.check(ignored.XXX, fmt.Sprintf("builds.ignored_builds[%d]", i))
2017-07-08 17:05:57 +02:00
}
2017-08-28 01:45:33 +02:00
overflow.check(config.Snapshot.XXX, "snapshot")
overflow.check(config.Checksum.XXX, "checksum")
2017-09-12 04:42:36 +02:00
for i, docker := range config.Dockers {
2017-09-12 04:31:00 +02:00
overflow.check(docker.XXX, fmt.Sprintf("docker[%d]", i))
}
for i, artifactory := range config.Artifactories {
overflow.check(artifactory.XXX, fmt.Sprintf("artifactory[%d]", i))
}
overflow.check(config.Changelog.XXX, "changelog")
overflow.check(config.Changelog.Filters.XXX, "changelog.filters")
2017-08-28 01:45:33 +02:00
return overflow.err()
2017-07-08 17:05:57 +02:00
}
type overflowChecker struct {
fields []string
}
func (o *overflowChecker) check(m map[string]interface{}, ctx string) {
for k := range m {
var key = fmt.Sprintf("%s.%s", ctx, k)
if ctx == "" {
key = k
}
o.fields = append(o.fields, key)
}
}
func (o *overflowChecker) err() error {
if len(o.fields) == 0 {
return nil
}
return fmt.Errorf(
"unknown fields in the config file: %s",
strings.Join(o.fields, ", "),
)
}