func DependencyFromLock(lock *Lock) *Dependency {
	return &Dependency{
		Name:        lock.Name,
		Reference:   lock.Version,
		Repository:  lock.Repository,
		VcsType:     lock.VcsType,
		Subpackages: lock.Subpackages,
		Arch:        lock.Arch,
		Os:          lock.Os,
	}
}
DependencyFromLock converts a Lock to a Dependency
package cfg
import (
	"crypto/sha256"
	"fmt"
	"io/ioutil"
	"reflect"
	"sort"
	"strings"
	"github.com/Masterminds/glide/mirrors"
	"github.com/Masterminds/glide/util"
	"github.com/Masterminds/vcs"
	"gopkg.in/yaml.v2"
)
type Config struct {
	Name string `yaml:"package"`
	Description string `json:"description,omitempty"`
	Home string `yaml:"homepage,omitempty"`
	License string `yaml:"license,omitempty"`
	Owners Owners `yaml:"owners,omitempty"`
	Ignore []string `yaml:"ignore,omitempty"`
	Exclude []string `yaml:"excludeDirs,omitempty"`
	Imports Dependencies `yaml:"import"`
	DevImports Dependencies `yaml:"testImport,omitempty"`
}
type cf struct {
	Name        string       `yaml:"package"`
	Description string       `yaml:"description,omitempty"`
	Home        string       `yaml:"homepage,omitempty"`
	License     string       `yaml:"license,omitempty"`
	Owners      Owners       `yaml:"owners,omitempty"`
	Ignore      []string     `yaml:"ignore,omitempty"`
	Exclude     []string     `yaml:"excludeDirs,omitempty"`
	Imports     Dependencies `yaml:"import"`
	DevImports  Dependencies `yaml:"testImport,omitempty"`
}
func ConfigFromYaml(yml []byte) (*Config, error) {
	cfg := &Config{}
	err := yaml.Unmarshal([]byte(yml), &cfg)
	return cfg, err
}
func (c *Config) Marshal() ([]byte, error) {
	yml, err := yaml.Marshal(&c)
	if err != nil {
		return []byte{}, err
	}
	return yml, nil
}
func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
	newConfig := &cf{}
	if err := unmarshal(&newConfig); err != nil {
		return err
	}
	c.Name = newConfig.Name
	c.Description = newConfig.Description
	c.Home = newConfig.Home
	c.License = newConfig.License
	c.Owners = newConfig.Owners
	c.Ignore = newConfig.Ignore
	c.Exclude = newConfig.Exclude
	c.Imports = newConfig.Imports
	c.DevImports = newConfig.DevImports
	err := c.DeDupe()
	return err
}
func (c *Config) MarshalYAML() (interface{}, error) {
	newConfig := &cf{
		Name:        c.Name,
		Description: c.Description,
		Home:        c.Home,
		License:     c.License,
		Owners:      c.Owners,
		Ignore:      c.Ignore,
		Exclude:     c.Exclude,
	}
	i, err := c.Imports.Clone().DeDupe()
	if err != nil {
		return newConfig, err
	}
	di, err := c.DevImports.Clone().DeDupe()
	if err != nil {
		return newConfig, err
	}
	newConfig.Imports = i
	newConfig.DevImports = di
	return newConfig, nil
}
func (c *Config) HasDependency(name string) bool {
	for _, d := range c.Imports {
		if d.Name == name {
			return true
		}
	}
	for _, d := range c.DevImports {
		if d.Name == name {
			return true
		}
	}
	return false
}
func (c *Config) HasIgnore(name string) bool {
	for _, v := range c.Ignore {
		if v == name || strings.HasPrefix(name, v+"/") {
			return true
		}
	}
	return false
}
func (c *Config) HasExclude(ex string) bool {
	ep := normalizeSlash(ex)
	for _, v := range c.Exclude {
		if vp := normalizeSlash(v); vp == ep {
			return true
		}
	}
	return false
}
func (c *Config) Clone() *Config {
	n := &Config{}
	n.Name = c.Name
	n.Description = c.Description
	n.Home = c.Home
	n.License = c.License
	n.Owners = c.Owners.Clone()
	n.Ignore = c.Ignore
	n.Exclude = c.Exclude
	n.Imports = c.Imports.Clone()
	n.DevImports = c.DevImports.Clone()
	return n
}
func (c *Config) WriteFile(glidepath string) error {
	o, err := c.Marshal()
	if err != nil {
		return err
	}
	return ioutil.WriteFile(glidepath, o, 0666)
}
func (c *Config) DeDupe() error {
	var err error
	c.Imports, err = c.Imports.DeDupe()
	if err != nil {
		return err
	}
	c.DevImports, err = c.DevImports.DeDupe()
	if err != nil {
		return err
	}
	found := -1
	for i, dep := range c.Imports {
		if dep.Name == c.Name {
			found = i
		}
	}
	if found >= 0 {
		c.Imports = append(c.Imports[:found], c.Imports[found+1:]...)
	}
	found = -1
	for i, dep := range c.DevImports {
		if dep.Name == c.Name {
			found = i
		}
	}
	if found >= 0 {
		c.DevImports = append(c.DevImports[:found], c.DevImports[found+1:]...)
	}
	for _, v := range c.Ignore {
		found = -1
		for k, d := range c.Imports {
			if v == d.Name {
				found = k
			}
		}
		if found >= 0 {
			c.Imports = append(c.Imports[:found], c.Imports[found+1:]...)
		}
		found = -1
		for k, d := range c.DevImports {
			if v == d.Name {
				found = k
			}
		}
		if found >= 0 {
			c.DevImports = append(c.DevImports[:found], c.DevImports[found+1:]...)
		}
	}
	return nil
}
func (c *Config) AddImport(deps ...*Dependency) error {
	t := c.Imports
	t = append(t, deps...)
	t, err := t.DeDupe()
	if err != nil {
		return err
	}
	c.Imports = t
	return nil
}
func (c *Config) Hash() (string, error) {
	yml, err := c.Marshal()
	if err != nil {
		return "", err
	}
	hash := sha256.New()
	hash.Write(yml)
	return fmt.Sprintf("%x", hash.Sum(nil)), nil
}
type Dependencies []*Dependency
func (d Dependencies) Get(name string) *Dependency {
	for _, dep := range d {
		if dep.Name == name {
			return dep
		}
	}
	return nil
}
func (d Dependencies) Has(name string) bool {
	for _, dep := range d {
		if dep.Name == name {
			return true
		}
	}
	return false
}
func (d Dependencies) Remove(name string) Dependencies {
	found := -1
	for i, dep := range d {
		if dep.Name == name {
			found = i
		}
	}
	if found >= 0 {
		copy(d[found:], d[found+1:])
		d[len(d)-1] = nil
		return d[:len(d)-1]
	}
	return d
}
func (d Dependencies) Clone() Dependencies {
	n := make(Dependencies, 0, len(d))
	for _, v := range d {
		n = append(n, v.Clone())
	}
	return n
}
func (d Dependencies) DeDupe() (Dependencies, error) {
	checked := map[string]int{}
	imports := make(Dependencies, 0, 1)
	i := 0
	for _, dep := range d {
		if val, ok := checked[dep.Name]; !ok {
			checked[dep.Name] = i
			imports = append(imports, dep)
			i++
		} else {
			v := imports[val]
			if dep.Reference != v.Reference {
				return d, fmt.Errorf("Import %s repeated with different versions '%s' and '%s'", dep.Name, dep.Reference, v.Reference)
			}
			if dep.Repository != v.Repository || dep.VcsType != v.VcsType {
				return d, fmt.Errorf("Import %s repeated with different Repository details", dep.Name)
			}
			if !reflect.DeepEqual(dep.Os, v.Os) || !reflect.DeepEqual(dep.Arch, v.Arch) {
				return d, fmt.Errorf("Import %s repeated with different OS or Architecture filtering", dep.Name)
			}
			imports[checked[dep.Name]].Subpackages = stringArrayDeDupe(v.Subpackages, dep.Subpackages...)
		}
	}
	return imports, nil
}
type Dependency struct {
	Name        string   `yaml:"package"`
	Reference   string   `yaml:"version,omitempty"`
	Pin         string   `yaml:"-"`
	Repository  string   `yaml:"repo,omitempty"`
	VcsType     string   `yaml:"vcs,omitempty"`
	Subpackages []string `yaml:"subpackages,omitempty"`
	Arch        []string `yaml:"arch,omitempty"`
	Os          []string `yaml:"os,omitempty"`
}
type dep struct {
	Name        string   `yaml:"package"`
	Reference   string   `yaml:"version,omitempty"`
	Ref         string   `yaml:"ref,omitempty"`
	Repository  string   `yaml:"repo,omitempty"`
	VcsType     string   `yaml:"vcs,omitempty"`
	Subpackages []string `yaml:"subpackages,omitempty"`
	Arch        []string `yaml:"arch,omitempty"`
	Os          []string `yaml:"os,omitempty"`
}