refactor: use a map instead of a slice

Packages are unique anyways so it makes sense to use a map to avoid having
duplicates.

For compatibility reasons custom json (un)marshallers hide this change from the
end user
This commit is contained in:
sh0rez 2019-10-16 17:36:25 +02:00
parent 4b6e2d89e9
commit 6e3e7b2fdd
No known key found for this signature in database
GPG key ID: 87C71DF9F8181FF1
4 changed files with 52 additions and 17 deletions

View file

@ -34,15 +34,15 @@ func installCommand(dir, jsonnetHome string, uris []string) int {
} }
kingpin.FatalIfError( kingpin.FatalIfError(
os.MkdirAll(filepath.Join(dir, "vendor", ".tmp"), os.ModePerm), os.MkdirAll(filepath.Join(dir, jsonnetHome, ".tmp"), os.ModePerm),
"creating vendor/ folder") "creating vendor folder")
jsonnetFile, err := jsonnetfile.Load(filepath.Join(dir, jsonnetfile.File)) jsonnetFile, err := jsonnetfile.Load(filepath.Join(dir, jsonnetfile.File))
kingpin.FatalIfError(err, "failed to load jsonnetfile") kingpin.FatalIfError(err, "failed to load jsonnetfile")
for _, u := range uris { for _, u := range uris {
d := parseDependency(dir, u) d := parseDependency(dir, u)
jsonnetFile.Dependencies = append(jsonnetFile.Dependencies, *d) jsonnetFile.Dependencies[d.Name] = *d
} }
lockFile, err := jsonnetfile.Load(filepath.Join(dir, jsonnetfile.LockFile)) lockFile, err := jsonnetfile.Load(filepath.Join(dir, jsonnetfile.LockFile))
@ -50,12 +50,7 @@ func installCommand(dir, jsonnetHome string, uris []string) int {
kingpin.FatalIfError(err, "failed to load lockfile") kingpin.FatalIfError(err, "failed to load lockfile")
} }
locks := make(map[string]spec.Dependency) locked, err := pkg.Ensure(jsonnetFile, jsonnetHome, lockFile.Dependencies)
for _, d := range lockFile.Dependencies {
locks[d.Name] = d
}
locked, err := pkg.Ensure(jsonnetFile, jsonnetHome, locks)
kingpin.FatalIfError(err, "failed to install packages") kingpin.FatalIfError(err, "failed to install packages")
kingpin.FatalIfError( kingpin.FatalIfError(

View file

@ -66,6 +66,9 @@ func Load(filepath string) (spec.JsonnetFile, error) {
if err := json.Unmarshal(bytes, &m); err != nil { if err := json.Unmarshal(bytes, &m); err != nil {
return m, errors.Wrap(err, "failed to unmarshal file") return m, errors.Wrap(err, "failed to unmarshal file")
} }
if m.Dependencies == nil {
m.Dependencies = make(map[string]spec.Dependency)
}
return m, nil return m, nil
} }

View file

@ -33,14 +33,15 @@ var (
VersionMismatch = errors.New("multiple colliding versions specified") VersionMismatch = errors.New("multiple colliding versions specified")
) )
func Ensure(want spec.JsonnetFile, vendorDir string, locks map[string]spec.Dependency) ([]spec.Dependency, error) { func Ensure(want spec.JsonnetFile, vendorDir string, locks map[string]spec.Dependency) (map[string]spec.Dependency, error) {
var list []spec.Dependency deps := make(map[string]spec.Dependency)
for _, d := range want.Dependencies { for _, d := range want.Dependencies {
l, present := locks[d.Name] l, present := locks[d.Name]
// already locked and the integrity is intact // already locked and the integrity is intact
if present && check(l, vendorDir) { if present && check(l, vendorDir) {
list = append(list, l) deps[d.Name] = l
continue continue
} }
expectedSum := d.Sum expectedSum := d.Sum
@ -54,12 +55,12 @@ func Ensure(want spec.JsonnetFile, vendorDir string, locks map[string]spec.Depen
return nil, errors.Wrap(err, "downloading") return nil, errors.Wrap(err, "downloading")
} }
if expectedSum != "" && d.Sum != expectedSum { if expectedSum != "" && d.Sum != expectedSum {
return fmt.Errorf("checksum mismatch for %s. Expected %s but got %s", d.Name, expectedSum, d.Sum) return nil, fmt.Errorf("checksum mismatch for %s. Expected %s but got %s", d.Name, expectedSum, d.Sum)
} }
list = append(list, *locked) deps[d.Name] = *locked
} }
for _, d := range list { for _, d := range deps {
f, err := jsonnetfile.Load(filepath.Join(vendorDir, d.Name, jsonnetfile.File)) f, err := jsonnetfile.Load(filepath.Join(vendorDir, d.Name, jsonnetfile.File))
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
@ -73,10 +74,14 @@ func Ensure(want spec.JsonnetFile, vendorDir string, locks map[string]spec.Depen
return nil, err return nil, err
} }
list = append(list, nested...) for _, d := range nested {
if _, ok := deps[d.Name]; !ok {
deps[d.Name] = d
}
}
} }
return list, nil return deps, nil
} }
func download(d spec.Dependency, vendorDir string) (*spec.Dependency, error) { func download(d spec.Dependency, vendorDir string) (*spec.Dependency, error) {

View file

@ -14,10 +14,42 @@
package spec package spec
import (
"encoding/json"
"sort"
)
type JsonnetFile struct { type JsonnetFile struct {
Dependencies map[string]Dependency
}
type jsonFile struct {
Dependencies []Dependency `json:"dependencies"` Dependencies []Dependency `json:"dependencies"`
} }
func (jf *JsonnetFile) UnmarshalJSON(data []byte) error {
var s jsonFile
if err := json.Unmarshal(data, &s); err != nil {
return err
}
jf.Dependencies = make(map[string]Dependency)
for _, d := range s.Dependencies {
jf.Dependencies[d.Name] = d
}
return nil
}
func (jf JsonnetFile) MarshalJSON() ([]byte, error) {
var s jsonFile
for _, d := range jf.Dependencies {
s.Dependencies = append(s.Dependencies, d)
}
return json.Marshal(s)
}
type Dependency struct { type Dependency struct {
Name string `json:"name"` Name string `json:"name"`
Source Source `json:"source"` Source Source `json:"source"`