diff --git a/.goreleaser.yml b/.goreleaser.yml index 01c8b5844..921ec808b 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,5 +1,3 @@ -homepage: &homepage http://goreleaser.github.io -description: &description Deliver Go binaries as fast and easily as possible builds: - env: @@ -29,13 +27,13 @@ brew: owner: goreleaser name: homebrew-tap folder: Formula - homepage: *homepage - description: *description + homepage: http://goreleaser.github.io + description: Deliver Go binaries as fast and easily as possible dependencies: - git fpm: - homepage: *homepage - description: *description + homepage: http://goreleaser.github.io + description: Deliver Go binaries as fast and easily as possible maintainer: Carlos Alexandro Becker license: MIT vendor: GoReleaser diff --git a/Gopkg.lock b/Gopkg.lock index 93ed8b013..61e2727f4 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -17,13 +17,13 @@ branch = "master" name = "github.com/golang/protobuf" packages = ["proto"] - revision = "5a0f697c9ed9d68fef0116532c6e05cfeae00e55" + revision = "6a1fa9404c0aebf36c879bc50152edcc953910d2" [[projects]] branch = "master" name = "github.com/google/go-github" packages = ["github"] - revision = "ebfec748347a9af6793c723f8859afcd906860fb" + revision = "fe7d11f8add400587b6718d9f39a62e42cb04c28" [[projects]] branch = "master" @@ -70,20 +70,20 @@ [[projects]] branch = "master" name = "golang.org/x/net" - packages = ["context"] - revision = "3da985ce5951d99de868be4385f21ea6c2b22f24" + packages = ["context","context/ctxhttp"] + revision = "054b33e6527139ad5b1ec2f6232c3b175bd9a30c" [[projects]] branch = "master" name = "golang.org/x/oauth2" packages = [".","internal"] - revision = "f047394b6d14284165300fd82dad67edb3a4d7f6" + revision = "cce311a261e6fcf29de72ca96827bdb0b7d9c9e6" [[projects]] branch = "master" name = "golang.org/x/sync" packages = ["errgroup"] - revision = "57af736625aaa69dfa099432bb67e0808eef3bcc" + revision = "f52d1811a62927559de87708c8913c1650ce4f26" [[projects]] name = "google.golang.org/appengine" @@ -92,14 +92,14 @@ version = "v1.0.0" [[projects]] - branch = "v1" - name = "gopkg.in/yaml.v1" + branch = "v2" + name = "gopkg.in/yaml.v2" packages = ["."] - revision = "9f9df34309c04878acc86042b16630b0f696e1de" + revision = "cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "15a60b1efa147cc2507589fd45e4b767e118c6853c6ae2e2728a6ba01b818fe4" + inputs-digest = "d3f68b6665e34ba913718b1ea7bbe0dbb185290b5209146133ca8d70615c09ac" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml index 8d27120ca..b5eba4eb3 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -97,5 +97,5 @@ name = "golang.org/x/sync" [[constraint]] - branch = "v1" - name = "gopkg.in/yaml.v1" + branch = "v2" + name = "gopkg.in/yaml.v2" diff --git a/config/config.go b/config/config.go index ae138434d..39335eb2a 100644 --- a/config/config.go +++ b/config/config.go @@ -3,18 +3,23 @@ package config import ( + "fmt" "io" "io/ioutil" "os" + "strings" "github.com/apex/log" - yaml "gopkg.in/yaml.v1" + yaml "gopkg.in/yaml.v2" ) // Repo represents any kind of repo (github, gitlab, etc) 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 @@ -33,17 +38,26 @@ type Homebrew struct { Conflicts []string `yaml:",omitempty"` Description string `yaml:",omitempty"` Homepage string `yaml:",omitempty"` + + // Capture all undefined fields and should be empty after loading + XXX map[string]interface{} `yaml:",inline"` } // Hooks define actions to run before and/or after something 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 @@ -58,12 +72,18 @@ 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 @@ -73,12 +93,18 @@ type Archive struct { NameTemplate string `yaml:"name_template,omitempty"` Replacements map[string]string `yaml:",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 type Release struct { GitHub Repo `yaml:",omitempty"` Draft bool `yaml:",omitempty"` + + // Capture all undefined fields and should be empty after loading + XXX map[string]interface{} `yaml:",inline"` } // FPM config @@ -91,11 +117,17 @@ type FPM struct { Maintainer string `yaml:",omitempty"` Description string `yaml:",omitempty"` License string `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"` } // Project includes all project configuration @@ -113,6 +145,9 @@ type Project struct { // test only property indicating the path to the dist folder Dist string `yaml:"-"` + + // Capture all undefined fields and should be empty after loading + XXX map[string]interface{} `yaml:",inline"` } // Load config file @@ -133,5 +168,59 @@ func LoadReader(fd io.Reader) (config Project, err error) { } err = yaml.Unmarshal(data, &config) log.WithField("config", config).Debug("loaded config file") + + err = checkOverflows(config) return } + +func checkOverflows(config Project) error { + var checker = &overflowChecker{} + checker.check(config.XXX, "") + checker.check(config.Archive.XXX, "archive") + for i, ov := range config.Archive.FormatOverrides { + checker.check(ov.XXX, fmt.Sprintf("archive.format_overrides[%d]", i)) + } + checker.check(config.Brew.XXX, "brew") + checker.check(config.Brew.GitHub.XXX, "brew.github") + for i, build := range config.Builds { + checker.check(build.XXX, fmt.Sprintf("builds[%d]", i)) + checker.check(build.Hooks.XXX, fmt.Sprintf("builds[%d].hooks", i)) + for j, ignored := range build.Ignore { + checker.check(ignored.XXX, fmt.Sprintf("builds[%d].ignored_builds[%d]", i, j)) + } + } + checker.check(config.FPM.XXX, "fpm") + checker.check(config.Release.XXX, "release") + checker.check(config.Release.GitHub.XXX, "release.github") + checker.check(config.SingleBuild.XXX, "build") + checker.check(config.SingleBuild.Hooks.XXX, "builds.hooks") + for i, ignored := range config.SingleBuild.Ignore { + checker.check(ignored.XXX, fmt.Sprintf("builds.ignored_builds[%d]", i)) + } + checker.check(config.Snapshot.XXX, "snapshot") + return checker.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, ", "), + ) +} diff --git a/config/config_test.go b/config/config_test.go index c3ee5af24..370fc5ad3 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -13,15 +13,14 @@ import ( func TestRepo(t *testing.T) { var assert = assert.New(t) - r := Repo{"goreleaser", "godownloader"} + r := Repo{Owner: "goreleaser", Name: "godownloader"} assert.Equal("goreleaser/godownloader", r.String(), "not equal") } func TestLoadReader(t *testing.T) { var conf = ` -homepage: &homepage http://goreleaser.github.io fpm: - homepage: *homepage + homepage: http://goreleaser.github.io ` var assert = assert.New(t) buf := strings.NewReader(conf) @@ -55,3 +54,9 @@ func TestFileNotFound(t *testing.T) { _, err := Load("/nope/no-way.yml") assert.Error(err) } + +func TestInvalidFields(t *testing.T) { + var assert = assert.New(t) + _, err := Load("testdata/invalid_config.yml") + assert.EqualError(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") +} diff --git a/config/testdata/invalid_config.yml b/config/testdata/invalid_config.yml new file mode 100644 index 000000000..c8b0223bb --- /dev/null +++ b/config/testdata/invalid_config.yml @@ -0,0 +1,30 @@ +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 + diff --git a/goreleaserlib/goreleaser.go b/goreleaserlib/goreleaser.go index fdd03a94c..19b220482 100644 --- a/goreleaserlib/goreleaser.go +++ b/goreleaserlib/goreleaser.go @@ -20,7 +20,7 @@ import ( "github.com/goreleaser/goreleaser/pipeline/fpm" "github.com/goreleaser/goreleaser/pipeline/git" "github.com/goreleaser/goreleaser/pipeline/release" - yaml "gopkg.in/yaml.v1" + yaml "gopkg.in/yaml.v2" ) var pipes = []pipeline.Pipe{ diff --git a/goreleaserlib/goreleaser_test.go b/goreleaserlib/goreleaser_test.go index 3270f2165..b632102df 100644 --- a/goreleaserlib/goreleaser_test.go +++ b/goreleaserlib/goreleaser_test.go @@ -9,7 +9,7 @@ import ( "github.com/goreleaser/goreleaser/config" "github.com/stretchr/testify/assert" - yaml "gopkg.in/yaml.v1" + yaml "gopkg.in/yaml.v2" ) func init() {