github.com/kngu9/glide@v0.0.0-20160505135211-e73500c73591/cfg/lock.go (about)

     1  package cfg
     2  
     3  import (
     4  	"io/ioutil"
     5  	"sort"
     6  	"strings"
     7  	"time"
     8  
     9  	"gopkg.in/yaml.v2"
    10  )
    11  
    12  // Lockfile represents a glide.lock file.
    13  type Lockfile struct {
    14  	Hash       string    `yaml:"hash"`
    15  	Updated    time.Time `yaml:"updated"`
    16  	Imports    Locks     `yaml:"imports"`
    17  	DevImports Locks     `yaml:"devImports"`
    18  }
    19  
    20  // LockfileFromYaml returns an instance of Lockfile from YAML
    21  func LockfileFromYaml(yml []byte) (*Lockfile, error) {
    22  	lock := &Lockfile{}
    23  	err := yaml.Unmarshal([]byte(yml), &lock)
    24  	return lock, err
    25  }
    26  
    27  // Marshal converts a Config instance to YAML
    28  func (lf *Lockfile) Marshal() ([]byte, error) {
    29  	yml, err := yaml.Marshal(&lf)
    30  	if err != nil {
    31  		return []byte{}, err
    32  	}
    33  	return yml, nil
    34  }
    35  
    36  // WriteFile writes a Glide lock file.
    37  //
    38  // This is a convenience function that marshals the YAML and then writes it to
    39  // the given file. If the file exists, it will be clobbered.
    40  func (lf *Lockfile) WriteFile(lockpath string) error {
    41  	o, err := lf.Marshal()
    42  	if err != nil {
    43  		return err
    44  	}
    45  	return ioutil.WriteFile(lockpath, o, 0666)
    46  }
    47  
    48  // Locks is a slice of locked dependencies.
    49  type Locks []*Lock
    50  
    51  // Len returns the length of the Locks. This is needed for sorting with
    52  // the sort package.
    53  func (l Locks) Len() int {
    54  	return len(l)
    55  }
    56  
    57  // Less is needed for the sort interface. It compares two locks based on
    58  // their name.
    59  func (l Locks) Less(i, j int) bool {
    60  
    61  	// Names are normalized to lowercase because case affects sorting order. For
    62  	// example, Masterminds comes before kylelemons. Making them lowercase
    63  	// causes kylelemons to come first which is what is expected.
    64  	return strings.ToLower(l[i].Name) < strings.ToLower(l[j].Name)
    65  }
    66  
    67  // Swap is needed for the sort interface. It swaps the position of two
    68  // locks.
    69  func (l Locks) Swap(i, j int) {
    70  	l[i], l[j] = l[j], l[i]
    71  }
    72  
    73  // Lock represents an individual locked dependency.
    74  type Lock struct {
    75  	Name        string   `yaml:"name"`
    76  	Version     string   `yaml:"version"`
    77  	Repository  string   `yaml:"repo,omitempty"`
    78  	VcsType     string   `yaml:"vcs,omitempty"`
    79  	Subpackages []string `yaml:"subpackages,omitempty"`
    80  	Arch        []string `yaml:"arch,omitempty"`
    81  	Os          []string `yaml:"os,omitempty"`
    82  }
    83  
    84  // NewLockfile is used to create an instance of Lockfile.
    85  func NewLockfile(ds Dependencies, hash string) *Lockfile {
    86  	lf := &Lockfile{
    87  		Hash:    hash,
    88  		Updated: time.Now(),
    89  		Imports: make([]*Lock, len(ds)),
    90  	}
    91  
    92  	for i := 0; i < len(ds); i++ {
    93  		lf.Imports[i] = &Lock{
    94  			Name:        ds[i].Name,
    95  			Version:     ds[i].Pin,
    96  			Repository:  ds[i].Repository,
    97  			VcsType:     ds[i].VcsType,
    98  			Subpackages: ds[i].Subpackages,
    99  			Arch:        ds[i].Arch,
   100  			Os:          ds[i].Os,
   101  		}
   102  	}
   103  
   104  	sort.Sort(lf.Imports)
   105  
   106  	return lf
   107  }
   108  
   109  // LockfileFromMap takes a map of dependencies and generates a lock Lockfile instance.
   110  func LockfileFromMap(ds map[string]*Dependency, hash string) *Lockfile {
   111  	lf := &Lockfile{
   112  		Hash:    hash,
   113  		Updated: time.Now(),
   114  		Imports: make([]*Lock, len(ds)),
   115  	}
   116  
   117  	i := 0
   118  	for name, dep := range ds {
   119  		lf.Imports[i] = &Lock{
   120  			Name:        name,
   121  			Version:     dep.Pin,
   122  			Repository:  dep.Repository,
   123  			VcsType:     dep.VcsType,
   124  			Subpackages: dep.Subpackages,
   125  			Arch:        dep.Arch,
   126  			Os:          dep.Os,
   127  		}
   128  		i++
   129  	}
   130  
   131  	sort.Sort(lf.Imports)
   132  
   133  	return lf
   134  }