func (l Locks) Len() int {
	return len(l)
}
Len returns the length of the Locks. This is needed for sorting with
the sort package.
package cfg
import (
	"crypto/sha256"
	"fmt"
	"io/ioutil"
	"sort"
	"strings"
	"time"
	"gopkg.in/yaml.v2"
)
type Lockfile struct {
	Hash       string    `yaml:"hash"`
	Updated    time.Time `yaml:"updated"`
	Imports    Locks     `yaml:"imports"`
	DevImports Locks     `yaml:"testImports"`
}
func LockfileFromYaml(yml []byte) (*Lockfile, error) {
	lock := &Lockfile{}
	err := yaml.Unmarshal([]byte(yml), &lock)
	return lock, err
}
func (lf *Lockfile) Marshal() ([]byte, error) {
	yml, err := yaml.Marshal(&lf)
	if err != nil {
		return []byte{}, err
	}
	return yml, nil
}
func (lf *Lockfile) MarshalYAML() (interface{}, error) {
	for _, imp := range lf.Imports {
		sort.Strings(imp.Subpackages)
	}
	var newDI Locks
	var found bool
	for _, imp := range lf.DevImports {
		found = false
		for i := 0; i < len(lf.Imports); i++ {
			if lf.Imports[i].Name == imp.Name {
				found = true
				if lf.Imports[i].Version != imp.Version {
					return lf, fmt.Errorf("Generating lock YAML produced conflicting versions of %s. import (%s), testImport (%s)", imp.Name, lf.Imports[i].Version, imp.Version)
				}
			}
		}
		if !found {
			newDI = append(newDI, imp)
		}
	}
	lf.DevImports = newDI
	for _, imp := range lf.DevImports {
		sort.Strings(imp.Subpackages)
	}
	return lf, nil
}
func (lf *Lockfile) WriteFile(lockpath string) error {
	o, err := lf.Marshal()
	if err != nil {
		return err
	}
	return ioutil.WriteFile(lockpath, o, 0666)
}
func (lf *Lockfile) Clone() *Lockfile {
	n := &Lockfile{}
	n.Hash = lf.Hash
	n.Updated = lf.Updated
	n.Imports = lf.Imports.Clone()
	n.DevImports = lf.DevImports.Clone()
	return n
}
func (lf *Lockfile) Fingerprint() ([32]byte, error) {
	c := lf.Clone()
	c.Updated = time.Time{}  
	sort.Sort(c.Imports)
	sort.Sort(c.DevImports)
	yml, err := c.Marshal()
	if err != nil {
		return [32]byte{}, err
	}
	return sha256.Sum256(yml), nil
}
func ReadLockFile(lockpath string) (*Lockfile, error) {
	yml, err := ioutil.ReadFile(lockpath)
	if err != nil {
		return nil, err
	}
	lock, err := LockfileFromYaml(yml)
	if err != nil {
		return nil, err
	}
	return lock, nil
}
type Locks []*Lock
func (l Locks) Clone() Locks {
	n := make(Locks, 0, len(l))
	for _, v := range l {
		n = append(n, v.Clone())
	}
	return n
}