1
0
mirror of https://github.com/goreleaser/goreleaser.git synced 2025-03-17 20:47:50 +02:00

breaking on invalid config files

This commit is contained in:
Carlos Alexandro Becker 2017-07-08 12:05:57 -03:00
parent 4e150b2e5a
commit cec34b91d5
No known key found for this signature in database
GPG Key ID: E61E2F7DC14AB940
8 changed files with 154 additions and 25 deletions

View File

@ -1,7 +1,6 @@
homepage: &homepage http://goreleaser.github.io
description: &description Deliver Go binaries as fast and easily as possible
nnnnnnnn: a
builds:
-
- y: 1
env:
- CGO_ENABLED=0
goos:
@ -14,6 +13,7 @@ builds:
- arm
- arm64
archive:
s: 1
name_template: '{{ .Binary }}_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}'
replacements:
darwin: Darwin
@ -24,18 +24,22 @@ archive:
format_overrides:
- goos: windows
format: zip
- asd: as
brew:
a: 1
github:
bb: a
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
fff: 444
homepage: http://goreleaser.github.io
description: Deliver Go binaries as fast and easily as possible
maintainer: Carlos Alexandro Becker <root@carlosbecker.com>
license: MIT
vendor: GoReleaser

20
Gopkg.lock generated
View File

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

View File

@ -97,5 +97,5 @@
name = "golang.org/x/sync"
[[constraint]]
branch = "v1"
name = "gopkg.in/yaml.v1"
branch = "v2"
name = "gopkg.in/yaml.v2"

View File

@ -3,18 +3,24 @@
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 +39,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 +73,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 +94,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 +118,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 +146,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 +169,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, ", "),
)
}

View File

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

30
config/testdata/invalid_config.yml vendored Normal file
View File

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

View File

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

View File

@ -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() {