1
0
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:
Carlos Alexandro Becker 2018-01-26 16:31:35 -02:00 committed by GitHub
commit 41a09ea45a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 13 additions and 156 deletions

View File

@ -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
}

View File

@ -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
View File

@ -0,0 +1,3 @@
project_name: &anchor_name This string will appear as the value of two keys.
build:
binary: *anchor_name

View File

@ -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