blob: d79284ee1f8a8c5b2b19a7a667b6ac241fe8463c [file] [log] [blame]
package overrides
import (
"io/ioutil"
"sort"
"strings"
"gopkg.in/yaml.v2"
)
// Overrides contains global overrides to local configuration
type Overrides struct {
// Repos contains repo override configuration
Repos OverrideRepos `yaml:"repos"`
}
// Marshal converts an Overrides instance to YAML
func (ov *Overrides) Marshal() ([]byte, error) {
yml, err := yaml.Marshal(&ov)
if err != nil {
return []byte{}, err
}
return yml, nil
}
// WriteFile writes an overrides.yaml file
//
// This is a convenience function that marshals the YAML and then writes it to
// the given file. If the file exists, it will be clobbered.
func (ov *Overrides) WriteFile(opath string) error {
o, err := ov.Marshal()
if err != nil {
return err
}
return ioutil.WriteFile(opath, o, 0666)
}
// ReadOverridesFile loads the contents of an overrides.yaml file.
func ReadOverridesFile(opath string) (*Overrides, error) {
yml, err := ioutil.ReadFile(opath)
if err != nil {
return nil, err
}
ov, err := FromYaml(yml)
if err != nil {
return nil, err
}
return ov, nil
}
// FromYaml returns an instance of Overrides from YAML
func FromYaml(yml []byte) (*Overrides, error) {
ov := &Overrides{}
err := yaml.Unmarshal([]byte(yml), &ov)
return ov, err
}
// MarshalYAML is a hook for gopkg.in/yaml.v2.
// It sorts override repos lexicographically for reproducibility.
func (ov *Overrides) MarshalYAML() (interface{}, error) {
sort.Sort(ov.Repos)
return ov, nil
}
// OverrideRepos is a slice of Override pointers
type OverrideRepos []*OverrideRepo
// Len returns the length of the OverrideRepos. This is needed for sorting with
// the sort package.
func (o OverrideRepos) Len() int {
return len(o)
}
// Less is needed for the sort interface. It compares two OverrideRepos based on
// their original value.
func (o OverrideRepos) Less(i, j int) bool {
// Names are normalized to lowercase because case affects sorting order. For
// example, Masterminds comes before kylelemons. Making them lowercase
// causes kylelemons to come first which is what is expected.
return strings.ToLower(o[i].Original) < strings.ToLower(o[j].Original)
}
// Swap is needed for the sort interface. It swaps the position of two
// OverrideRepos.
func (o OverrideRepos) Swap(i, j int) {
o[i], o[j] = o[j], o[i]
}
// OverrideRepo represents a single repo override
type OverrideRepo struct {
Original string `yaml:"original"`
Repo string `yaml:"repo"`
Vcs string `yaml:"vcs,omitempty"`
}