| package cfg | 
 |  | 
 | import ( | 
 | 	"fmt" | 
 | 	"path" | 
 | 	"reflect" | 
 | 	"strings" | 
 | 	"time" | 
 |  | 
 | 	"github.com/Masterminds/glide/util" | 
 | ) | 
 |  | 
 | // lConfig1 is a legacy Config file. | 
 | type lConfig1 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     lDependencies1 `yaml:"import"` | 
 | 	DevImports  lDependencies1 `yaml:"testImport,omitempty"` | 
 | } | 
 |  | 
 | func (c *lConfig1) UnmarshalYAML(unmarshal func(interface{}) error) error { | 
 | 	newConfig := &lcf1{} | 
 | 	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 | 
 |  | 
 | 	// Cleanup the Config object now that we have it. | 
 | 	err := c.DeDupe() | 
 |  | 
 | 	return err | 
 | } | 
 |  | 
 | func (c *lConfig1) Convert() (*Config, error) { | 
 | 	// This is probably already done, but do it just in case | 
 | 	err := c.DeDupe() | 
 | 	if err != nil { | 
 | 		return nil, err | 
 | 	} | 
 |  | 
 | 	// Pull over the easy values | 
 | 	c2 := &Config{ | 
 | 		Name:        c.Name, | 
 | 		Description: c.Description, | 
 | 		Home:        c.Home, | 
 | 		License:     c.License, | 
 | 		Owners:      c.Owners, | 
 | 		Ignore:      c.Ignore, | 
 | 	} | 
 |  | 
 | 	// _if_ the name is set, path-prepend it to exclude, and add that to ignore. | 
 | 	// Otherwise, we just skip excludes. Not that big a deal, since they're a | 
 | 	// root-only property anyway; the user can reasonably recreate. | 
 |  | 
 | 	if c.Name != "" { | 
 | 		for _, excl := range c.Exclude { | 
 | 			c.Ignore = append(c.Ignore, path.Join(c.Name, excl)) | 
 | 			// The trailing * is interpreted by gps as an ignore on that and all | 
 | 			// child paths (or, soon - https://github.com/sdboyer/gps/issues/88) | 
 | 			c.Ignore = append(c.Ignore, path.Join(c.Name, excl, "*")) | 
 | 		} | 
 | 	} | 
 |  | 
 | 	// Quitting early on this might seem risky, but a) all possible errs | 
 | 	// _should_ have already been surfaced in the earlier DeDupe(), and b) there | 
 | 	// are no new errs introduced by the conversion itself, so this doesn't | 
 | 	// actually increase the surface area for failures vis-a-vis pre-gps glide. | 
 | 	c2.Imports, err = c.Imports.Convert() | 
 | 	if err != nil { | 
 | 		return nil, err | 
 | 	} | 
 | 	c2.DevImports, err = c.DevImports.Convert() | 
 | 	if err != nil { | 
 | 		return nil, err | 
 | 	} | 
 |  | 
 | 	return c2, nil | 
 | } | 
 |  | 
 | // DeDupe consolidates duplicate dependencies on a Config instance | 
 | func (c *lConfig1) DeDupe() error { | 
 | 	// Remove duplicates in the imports | 
 | 	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 | 
 | 	} | 
 |  | 
 | 	// If the name on the config object is part of the imports remove it. | 
 | 	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:]...) | 
 | 	} | 
 |  | 
 | 	// If something is on the ignore list remove it from the imports. | 
 | 	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 | 
 | } | 
 |  | 
 | // Legacy representation of a glide.yaml file. | 
 | type lcf1 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     lDependencies1 `yaml:"import"` | 
 | 	DevImports  lDependencies1 `yaml:"testImport,omitempty"` | 
 | 	// these fields guarantee that this struct fails to unmarshal the new yamls | 
 | 	Compat  int `yaml:"dependencies,omitempty"` | 
 | 	Compat2 int `yaml:"testDependencies,omitempty"` | 
 | } | 
 |  | 
 | type lDependencies1 []*lDependency1 | 
 |  | 
 | func (ds lDependencies1) Convert() (Dependencies, error) { | 
 | 	dds, err := ds.DeDupe() | 
 | 	if err != nil { | 
 | 		return nil, err | 
 | 	} | 
 |  | 
 | 	var ds2 Dependencies | 
 | 	for _, d := range dds { | 
 | 		// If we have neither a repo nor a reference, then it's pointless to | 
 | 		// include this dep in the list (it will add no information to gps) | 
 | 		if d.Repository == "" && d.Reference == "" { | 
 | 			continue | 
 | 		} | 
 |  | 
 | 		d2 := &Dependency{ | 
 | 			Name:       d.Name, | 
 | 			Repository: d.Repository, | 
 | 			Version:    d.Reference, | 
 | 		} | 
 |  | 
 | 		// TODO(sdboyer) d.Reference doesn't disambiguate between branches and | 
 | 		// tags. Check the version list (via source manager) to convert most | 
 | 		// sanely? | 
 | 		ds2 = append(ds2, d2) | 
 | 	} | 
 |  | 
 | 	return ds2, nil | 
 | } | 
 |  | 
 | // DeDupe cleans up duplicates on a list of dependencies. | 
 | func (d lDependencies1) DeDupe() (lDependencies1, error) { | 
 | 	checked := map[string]int{} | 
 | 	imports := make(lDependencies1, 0, 1) | 
 | 	i := 0 | 
 | 	for _, dep := range d { | 
 | 		// The first time we encounter a dependency add it to the list | 
 | 		if val, ok := checked[dep.Name]; !ok { | 
 | 			checked[dep.Name] = i | 
 | 			imports = append(imports, dep) | 
 | 			i++ | 
 | 		} else { | 
 | 			// In here we've encountered a dependency for the second time. | 
 | 			// Make sure the details are the same or return an error. | 
 | 			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 lDependency1 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"` | 
 | } | 
 |  | 
 | // Legacy unmarshaler for dependency component of yaml files | 
 | func (d *lDependency1) UnmarshalYAML(unmarshal func(interface{}) error) error { | 
 | 	newDep := &ldep1{} | 
 | 	err := unmarshal(newDep) | 
 | 	if err != nil { | 
 | 		return err | 
 | 	} | 
 | 	d.Name = newDep.Name | 
 | 	d.Reference = newDep.Reference | 
 | 	d.Repository = newDep.Repository | 
 | 	d.VcsType = newDep.VcsType | 
 | 	d.Subpackages = newDep.Subpackages | 
 | 	d.Arch = newDep.Arch | 
 | 	d.Os = newDep.Os | 
 |  | 
 | 	if d.Reference == "" && newDep.Ref != "" { | 
 | 		d.Reference = newDep.Ref | 
 | 	} | 
 |  | 
 | 	// Make sure only legitimate VCS are listed. | 
 | 	d.VcsType = filterVcsType(d.VcsType) | 
 |  | 
 | 	// Get the root name for the package | 
 | 	tn, subpkg := util.NormalizeName(d.Name) | 
 | 	d.Name = tn | 
 | 	if subpkg != "" { | 
 | 		d.Subpackages = append(d.Subpackages, subpkg) | 
 | 	} | 
 |  | 
 | 	// Older versions of Glide had a / prefix on subpackages in some cases. | 
 | 	// Here that's cleaned up. Someday we should be able to remove this. | 
 | 	for k, v := range d.Subpackages { | 
 | 		d.Subpackages[k] = strings.TrimPrefix(v, "/") | 
 | 	} | 
 |  | 
 | 	return nil | 
 | } | 
 |  | 
 | // Legacy representation of a dep constraint | 
 | type ldep1 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"` | 
 | } | 
 |  | 
 | type lLockfile1 struct { | 
 | 	Hash       string    `yaml:"hash"` | 
 | 	Updated    time.Time `yaml:"updated"` | 
 | 	Imports    lLocks1   `yaml:"imports"` | 
 | 	DevImports lLocks1   `yaml:"testImports"` // TODO remove and fold in as prop | 
 | 	Compat     int       `yaml:"import,omitempty"` | 
 | 	Compat2    int       `yaml:"testImport,omitempty"` | 
 | } | 
 |  | 
 | func (l *lLockfile1) Convert() *Lockfile { | 
 | 	return &Lockfile{ | 
 | 		Hash:       l.Hash, | 
 | 		Updated:    l.Updated, | 
 | 		Imports:    l.Imports.Convert(), | 
 | 		DevImports: l.DevImports.Convert(), | 
 | 	} | 
 | } | 
 |  | 
 | type lLocks1 []*lLock1 | 
 |  | 
 | func (ll lLocks1) Convert() Locks { | 
 | 	var ll2 Locks | 
 | 	for _, l := range ll { | 
 | 		// If they have no rev, just drop them | 
 | 		if l.Version == "" { | 
 | 			continue | 
 | 		} | 
 |  | 
 | 		ll2 = append(ll2, &Lock{ | 
 | 			Name:       l.Name, | 
 | 			Repository: l.Repository, | 
 | 			Revision:   l.Version, | 
 | 		}) | 
 | 	} | 
 |  | 
 | 	return ll2 | 
 | } | 
 |  | 
 | type lLock1 struct { | 
 | 	Name        string   `yaml:"name"` | 
 | 	Version     string   `yaml:"version"` | 
 | 	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"` | 
 | } |