mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-01-10 03:47:03 +02:00
Merge pull request #528 from goreleaser/simplified-config
Simplified config
This commit is contained in:
commit
41a09ea45a
121
config/config.go
121
config/config.go
@ -3,11 +3,9 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/apex/log"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
@ -24,9 +22,6 @@ type GitHubURLs struct {
|
||||
type Repo struct {
|
||||
Owner string `yaml:",omitempty"`
|
||||
Name string `yaml:",omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// String of the repo, e.g. owner/name
|
||||
@ -52,9 +47,6 @@ type Homebrew struct {
|
||||
Homepage string `yaml:",omitempty"`
|
||||
SkipUpload bool `yaml:"skip_upload,omitempty"`
|
||||
DownloadStrategy string `yaml:"download_strategy,omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// CommitAuthor is the author of a Git commit
|
||||
@ -67,17 +59,11 @@ type CommitAuthor struct {
|
||||
type Hooks struct {
|
||||
Pre string `yaml:",omitempty"`
|
||||
Post string `yaml:",omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// IgnoredBuild represents a build ignored by the user
|
||||
type IgnoredBuild struct {
|
||||
Goos, Goarch, Goarm string
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// Build contains the build configuration section
|
||||
@ -92,18 +78,12 @@ type Build struct {
|
||||
Binary string `yaml:",omitempty"`
|
||||
Hooks Hooks `yaml:",omitempty"`
|
||||
Env []string `yaml:",omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// FormatOverride is used to specify a custom format for a specific GOOS.
|
||||
type FormatOverride struct {
|
||||
Goos string `yaml:",omitempty"`
|
||||
Format string `yaml:",omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// Archive config used for the archive
|
||||
@ -115,9 +95,6 @@ type Archive struct {
|
||||
FormatOverrides []FormatOverride `yaml:"format_overrides,omitempty"`
|
||||
WrapInDirectory bool `yaml:"wrap_in_directory,omitempty"`
|
||||
Files []string `yaml:",omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// Release config used for the GitHub release
|
||||
@ -126,8 +103,6 @@ type Release struct {
|
||||
Draft bool `yaml:",omitempty"`
|
||||
Prerelease bool `yaml:",omitempty"`
|
||||
NameTemplate string `yaml:"name_template,omitempty"`
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// FPM config
|
||||
@ -145,9 +120,6 @@ type FPM struct {
|
||||
License string `yaml:",omitempty"`
|
||||
Bindir string `yaml:",omitempty"`
|
||||
Files map[string]string `yaml:",omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// Sign config
|
||||
@ -175,25 +147,16 @@ type Snapcraft struct {
|
||||
Grade string `yaml:",omitempty"`
|
||||
Confinement string `yaml:",omitempty"`
|
||||
Apps map[string]SnapcraftAppMetadata `yaml:",omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// Snapshot config
|
||||
type Snapshot struct {
|
||||
NameTemplate string `yaml:"name_template,omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// Docker image config
|
||||
@ -208,9 +171,6 @@ type Docker struct {
|
||||
OldTagTemplate string `yaml:"tag_template,omitempty"`
|
||||
TagTemplates []string `yaml:"tag_templates,omitempty"`
|
||||
Files []string `yaml:"extra_files,omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// Artifactory server configuration
|
||||
@ -219,26 +179,17 @@ type Artifactory struct {
|
||||
Name string `yaml:",omitempty"`
|
||||
Username string `yaml:",omitempty"`
|
||||
Mode 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
|
||||
@ -263,9 +214,6 @@ type Project struct {
|
||||
|
||||
// should be set if using github enterprise
|
||||
GitHubURLs GitHubURLs `yaml:"github_urls,omitempty"`
|
||||
|
||||
// Capture all undefined fields and should be empty after loading
|
||||
XXX map[string]interface{} `yaml:",inline"`
|
||||
}
|
||||
|
||||
// Load config file
|
||||
@ -284,72 +232,7 @@ func LoadReader(fd io.Reader) (config Project, err error) {
|
||||
if err != nil {
|
||||
return config, err
|
||||
}
|
||||
if err := yaml.Unmarshal(data, &config); err != nil {
|
||||
return config, err
|
||||
}
|
||||
err = yaml.UnmarshalStrict(data, &config)
|
||||
log.WithField("config", config).Debug("loaded config file")
|
||||
return config, checkOverflows(config)
|
||||
}
|
||||
|
||||
// TODO: check if we can use UnmarshalStrict instead of the manual checkOverflow
|
||||
func checkOverflows(config Project) error {
|
||||
var overflow = &overflowChecker{}
|
||||
overflow.check(config.XXX, "")
|
||||
overflow.check(config.Archive.XXX, "archive")
|
||||
for i, ov := range config.Archive.FormatOverrides {
|
||||
overflow.check(ov.XXX, fmt.Sprintf("archive.format_overrides[%d]", i))
|
||||
}
|
||||
overflow.check(config.Brew.XXX, "brew")
|
||||
overflow.check(config.Brew.GitHub.XXX, "brew.github")
|
||||
for i, build := range config.Builds {
|
||||
overflow.check(build.XXX, fmt.Sprintf("builds[%d]", i))
|
||||
overflow.check(build.Hooks.XXX, fmt.Sprintf("builds[%d].hooks", i))
|
||||
for j, ignored := range build.Ignore {
|
||||
overflow.check(ignored.XXX, fmt.Sprintf("builds[%d].ignored_builds[%d]", i, j))
|
||||
}
|
||||
}
|
||||
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")
|
||||
for i, ignored := range config.SingleBuild.Ignore {
|
||||
overflow.check(ignored.XXX, fmt.Sprintf("builds.ignored_builds[%d]", i))
|
||||
}
|
||||
overflow.check(config.Snapshot.XXX, "snapshot")
|
||||
overflow.check(config.Checksum.XXX, "checksum")
|
||||
for i, docker := range config.Dockers {
|
||||
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")
|
||||
return overflow.err()
|
||||
}
|
||||
|
||||
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, ", "),
|
||||
)
|
||||
return config, err
|
||||
}
|
||||
|
@ -59,10 +59,15 @@ func TestFileNotFound(t *testing.T) {
|
||||
|
||||
func TestInvalidFields(t *testing.T) {
|
||||
_, err := Load("testdata/invalid_config.yml")
|
||||
assert.EqualError(t, err, "unknown fields in the config file: invalid_root, archive.invalid_archive, archive.format_overrides[0].invalid_archive_fmtoverrides, brew.invalid_brew, brew.github.invalid_brew_github, builds[0].invalid_builds, builds[0].hooks.invalid_builds_hooks, builds[0].ignored_builds[0].invalid_builds_ignore, fpm.invalid_fpm, release.invalid_release, release.github.invalid_release_github, build.invalid_build, builds.hooks.invalid_build_hook, builds.ignored_builds[0].invalid_build_ignore, snapshot.invalid_snapshot, docker[0].invalid_docker, artifactory[0].invalid_artifactory, changelog.invalid_changelog, changelog.filters.invalid_filters")
|
||||
assert.EqualError(t, err, "yaml: unmarshal errors:\n line 2: field invalid_yaml not found in struct config.Build")
|
||||
}
|
||||
|
||||
func TestInvalidYaml(t *testing.T) {
|
||||
_, err := Load("testdata/invalid.yml")
|
||||
assert.EqualError(t, err, "yaml: line 1: did not find expected node content")
|
||||
}
|
||||
|
||||
func TestConfigWithAnchors(t *testing.T) {
|
||||
_, err := Load("testdata/anchor.yaml")
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
3
config/testdata/anchor.yaml
vendored
Normal file
3
config/testdata/anchor.yaml
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
project_name: &anchor_name This string will appear as the value of two keys.
|
||||
build:
|
||||
binary: *anchor_name
|
38
config/testdata/invalid_config.yml
vendored
38
config/testdata/invalid_config.yml
vendored
@ -1,37 +1,3 @@
|
||||
invalid_root: 1
|
||||
build:
|
||||
invalid_build: 1
|
||||
hooks:
|
||||
invalid_build_hook: 1
|
||||
ignore:
|
||||
- invalid_build_ignore: 1
|
||||
builds:
|
||||
- invalid_builds: 1
|
||||
hooks:
|
||||
invalid_builds_hooks: 1
|
||||
ignore:
|
||||
- invalid_builds_ignore: 1
|
||||
archive:
|
||||
invalid_archive: 1
|
||||
format_overrides:
|
||||
- invalid_archive_fmtoverrides: 1
|
||||
release:
|
||||
invalid_release: 1
|
||||
github:
|
||||
invalid_release_github: 1
|
||||
brew:
|
||||
invalid_brew: 1
|
||||
github:
|
||||
invalid_brew_github: 1
|
||||
fpm:
|
||||
invalid_fpm: 1
|
||||
snapshot:
|
||||
invalid_snapshot: 1
|
||||
dockers:
|
||||
- invalid_docker: 1
|
||||
artifactories:
|
||||
- invalid_artifactory: 1
|
||||
changelog:
|
||||
invalid_changelog: 1
|
||||
filters:
|
||||
invalid_filters: 1
|
||||
invalid_yaml: 1
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user