| package mirrors | 
 |  | 
 | import ( | 
 | 	"io/ioutil" | 
 | 	"sort" | 
 | 	"strings" | 
 |  | 
 | 	"gopkg.in/yaml.v2" | 
 | ) | 
 |  | 
 | // Mirrors contains global mirrors to local configuration | 
 | type Mirrors struct { | 
 |  | 
 | 	// Repos contains repo mirror configuration | 
 | 	Repos MirrorRepos `yaml:"repos"` | 
 | } | 
 |  | 
 | // Marshal converts a Mirror instance to YAML | 
 | func (ov *Mirrors) Marshal() ([]byte, error) { | 
 | 	yml, err := yaml.Marshal(&ov) | 
 | 	if err != nil { | 
 | 		return []byte{}, err | 
 | 	} | 
 | 	return yml, nil | 
 | } | 
 |  | 
 | // WriteFile writes an mirrors.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 *Mirrors) WriteFile(opath string) error { | 
 | 	o, err := ov.Marshal() | 
 | 	if err != nil { | 
 | 		return err | 
 | 	} | 
 | 	return ioutil.WriteFile(opath, o, 0666) | 
 | } | 
 |  | 
 | // ReadMirrorsFile loads the contents of an mirrors.yaml file. | 
 | func ReadMirrorsFile(opath string) (*Mirrors, 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 Mirrors from YAML | 
 | func FromYaml(yml []byte) (*Mirrors, error) { | 
 | 	ov := &Mirrors{} | 
 | 	err := yaml.Unmarshal([]byte(yml), &ov) | 
 | 	return ov, err | 
 | } | 
 |  | 
 | // MarshalYAML is a hook for gopkg.in/yaml.v2. | 
 | // It sorts mirror repos lexicographically for reproducibility. | 
 | func (ov *Mirrors) MarshalYAML() (interface{}, error) { | 
 |  | 
 | 	sort.Sort(ov.Repos) | 
 |  | 
 | 	return ov, nil | 
 | } | 
 |  | 
 | // MirrorRepos is a slice of Mirror pointers | 
 | type MirrorRepos []*MirrorRepo | 
 |  | 
 | // Len returns the length of the MirrorRepos. This is needed for sorting with | 
 | // the sort package. | 
 | func (o MirrorRepos) Len() int { | 
 | 	return len(o) | 
 | } | 
 |  | 
 | // Less is needed for the sort interface. It compares two MirrorRepos based on | 
 | // their original value. | 
 | func (o MirrorRepos) 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 | 
 | // MirrorRepos. | 
 | func (o MirrorRepos) Swap(i, j int) { | 
 | 	o[i], o[j] = o[j], o[i] | 
 | } | 
 |  | 
 | // MirrorRepo represents a single repo mirror | 
 | type MirrorRepo struct { | 
 | 	Original string `yaml:"original"` | 
 | 	Repo     string `yaml:"repo"` | 
 | 	Vcs      string `yaml:"vcs,omitempty"` | 
 | } |