Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

Commit b3bd16e

Browse files
authored
Merge pull request #528 from darkowlzz/506-add-metadata-warn-unknown-manifest-fields
Add metadata to manifest & warn on unknown fields
2 parents a919470 + c588d9e commit b3bd16e

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

manifest.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@ package dep
66

77
import (
88
"bytes"
9+
"fmt"
910
"io"
11+
"reflect"
1012
"sort"
1113

1214
"github.com/golang/dep/gps"
15+
"github.com/golang/dep/internal"
1316
"github.com/pelletier/go-toml"
1417
"github.com/pkg/errors"
1518
)
@@ -38,13 +41,74 @@ type rawProject struct {
3841
Source string `toml:"source,omitempty"`
3942
}
4043

44+
func validateManifest(s string) ([]error, error) {
45+
var errs []error
46+
// Load the TomlTree from string
47+
tree, err := toml.Load(s)
48+
if err != nil {
49+
return errs, errors.Wrap(err, "Unable to load TomlTree from string")
50+
}
51+
// Convert tree to a map
52+
manifest := tree.ToMap()
53+
54+
// Look for unknown fields and collect errors
55+
for prop, val := range manifest {
56+
switch prop {
57+
case "metadata":
58+
// Check if metadata is of Map type
59+
if reflect.TypeOf(val).Kind() != reflect.Map {
60+
errs = append(errs, errors.New("metadata should be a TOML table"))
61+
}
62+
case "dependencies", "overrides":
63+
// Invalid if type assertion fails. Not a TOML array of tables.
64+
if rawProj, ok := val.([]interface{}); ok {
65+
// Iterate through each array of tables
66+
for _, v := range rawProj {
67+
// Check the individual field's key to be valid
68+
for key, value := range v.(map[string]interface{}) {
69+
// Check if the key is valid
70+
switch key {
71+
case "name", "branch", "revision", "version", "source":
72+
// valid key
73+
case "metadata":
74+
// Check if metadata is of Map type
75+
if reflect.TypeOf(value).Kind() != reflect.Map {
76+
errs = append(errs, fmt.Errorf("metadata in %q should be a TOML table", prop))
77+
}
78+
default:
79+
// unknown/invalid key
80+
errs = append(errs, fmt.Errorf("Invalid key %q in %q", key, prop))
81+
}
82+
}
83+
}
84+
} else {
85+
errs = append(errs, fmt.Errorf("%v should be a TOML array of tables", prop))
86+
}
87+
case "ignored", "required":
88+
default:
89+
errs = append(errs, fmt.Errorf("Unknown field in manifest: %v", prop))
90+
}
91+
}
92+
93+
return errs, nil
94+
}
95+
4196
func readManifest(r io.Reader) (*Manifest, error) {
4297
buf := &bytes.Buffer{}
4398
_, err := buf.ReadFrom(r)
4499
if err != nil {
45100
return nil, errors.Wrap(err, "Unable to read byte stream")
46101
}
47102

103+
// Validate manifest and log warnings
104+
errs, err := validateManifest(buf.String())
105+
if err != nil {
106+
return nil, errors.Wrap(err, "Manifest validation failed")
107+
}
108+
for _, e := range errs {
109+
internal.Logf("WARNING: %v", e)
110+
}
111+
48112
raw := rawManifest{}
49113
err = toml.Unmarshal(buf.Bytes(), &raw)
50114
if err != nil {

manifest_test.go

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package dep
66

77
import (
8+
"errors"
89
"reflect"
910
"strings"
1011
"testing"
@@ -119,3 +120,120 @@ func TestReadManifestErrors(t *testing.T) {
119120
}
120121
}
121122
}
123+
124+
func TestValidateManifest(t *testing.T) {
125+
cases := []struct {
126+
tomlString string
127+
want []error
128+
}{
129+
{
130+
tomlString: `
131+
[[dependencies]]
132+
name = "github.com/foo/bar"
133+
`,
134+
want: []error{},
135+
},
136+
{
137+
tomlString: `
138+
[metadata]
139+
authors = "foo"
140+
version = "1.0.0"
141+
`,
142+
want: []error{},
143+
},
144+
{
145+
tomlString: `
146+
foo = "some-value"
147+
version = 14
148+
149+
[[bar]]
150+
author = "xyz"
151+
152+
[[dependencies]]
153+
name = "github.com/foo/bar"
154+
version = ""
155+
`,
156+
want: []error{
157+
errors.New("Unknown field in manifest: foo"),
158+
errors.New("Unknown field in manifest: bar"),
159+
errors.New("Unknown field in manifest: version"),
160+
},
161+
},
162+
{
163+
tomlString: `
164+
metadata = "project-name"
165+
166+
[[dependencies]]
167+
name = "github.com/foo/bar"
168+
`,
169+
want: []error{errors.New("metadata should be a TOML table")},
170+
},
171+
{
172+
tomlString: `
173+
dependencies = "foo"
174+
overrides = "bar"
175+
`,
176+
want: []error{
177+
errors.New("dependencies should be a TOML array of tables"),
178+
errors.New("overrides should be a TOML array of tables"),
179+
},
180+
},
181+
{
182+
tomlString: `
183+
[[dependencies]]
184+
name = "github.com/foo/bar"
185+
location = "some-value"
186+
link = "some-other-value"
187+
metadata = "foo"
188+
189+
[[overrides]]
190+
nick = "foo"
191+
`,
192+
want: []error{
193+
errors.New("Invalid key \"location\" in \"dependencies\""),
194+
errors.New("Invalid key \"link\" in \"dependencies\""),
195+
errors.New("Invalid key \"nick\" in \"overrides\""),
196+
errors.New("metadata in \"dependencies\" should be a TOML table"),
197+
},
198+
},
199+
{
200+
tomlString: `
201+
[[dependencies]]
202+
name = "github.com/foo/bar"
203+
204+
[dependencies.metadata]
205+
color = "blue"
206+
`,
207+
want: []error{},
208+
},
209+
}
210+
211+
// constains for error
212+
contains := func(s []error, e error) bool {
213+
for _, a := range s {
214+
if a.Error() == e.Error() {
215+
return true
216+
}
217+
}
218+
return false
219+
}
220+
221+
for _, c := range cases {
222+
errs, err := validateManifest(c.tomlString)
223+
if err != nil {
224+
t.Fatal(err)
225+
}
226+
227+
// compare length of error slice
228+
if len(errs) != len(c.want) {
229+
t.Fatalf("Number of manifest errors are not as expected: \n\t(GOT) %v errors(%v)\n\t(WNT) %v errors(%v).", len(errs), errs, len(c.want), c.want)
230+
}
231+
232+
// check if the expected errors exist in actual errors slice
233+
for _, er := range errs {
234+
if !contains(c.want, er) {
235+
t.Fatalf("Manifest errors are not as expected: \n\t(MISSING) %v\n\t(FROM) %v", er, c.want)
236+
}
237+
}
238+
}
239+
}

0 commit comments

Comments
 (0)