|  | package gom | 
|  |  | 
|  | import ( | 
|  | "errors" | 
|  | "os" | 
|  | "path/filepath" | 
|  |  | 
|  | "github.com/Masterminds/glide/cfg" | 
|  | "github.com/Masterminds/glide/msg" | 
|  | gpath "github.com/Masterminds/glide/path" | 
|  | "github.com/Masterminds/glide/util" | 
|  | "github.com/sdboyer/gps" | 
|  | ) | 
|  |  | 
|  | // Has returns true if this dir has a Gomfile. | 
|  | func Has(dir string) bool { | 
|  | path := filepath.Join(dir, "Gomfile") | 
|  | fi, err := os.Stat(path) | 
|  | return err == nil && !fi.IsDir() | 
|  | } | 
|  |  | 
|  | // Parse parses a Gomfile. | 
|  | func Parse(dir string) ([]*cfg.Dependency, error) { | 
|  | path := filepath.Join(dir, "Gomfile") | 
|  | if fi, err := os.Stat(path); err != nil || fi.IsDir() { | 
|  | return []*cfg.Dependency{}, nil | 
|  | } | 
|  |  | 
|  | msg.Info("Found Gomfile in %s", gpath.StripBasepath(dir)) | 
|  | msg.Info("--> Parsing Gomfile metadata...") | 
|  | buf := []*cfg.Dependency{} | 
|  |  | 
|  | goms, err := parseGomfile(path) | 
|  | if err != nil { | 
|  | return []*cfg.Dependency{}, err | 
|  | } | 
|  |  | 
|  | for _, gom := range goms { | 
|  | // Do we need to skip this dependency? | 
|  | if val, ok := gom.options["skipdep"]; ok && val.(string) == "true" { | 
|  | continue | 
|  | } | 
|  |  | 
|  | // Check for custom cloning command | 
|  | if _, ok := gom.options["command"]; ok { | 
|  | return []*cfg.Dependency{}, errors.New("Glide does not support custom Gomfile commands") | 
|  | } | 
|  |  | 
|  | // Check for groups/environments | 
|  | if val, ok := gom.options["group"]; ok { | 
|  | groups := toStringSlice(val) | 
|  | if !stringsContain(groups, "development") && !stringsContain(groups, "production") { | 
|  | // right now we only support development and production | 
|  | msg.Info("Skipping dependency '%s' because it isn't in the development or production group", gom.name) | 
|  | continue | 
|  | } | 
|  | } | 
|  |  | 
|  | pkg, _ := util.NormalizeName(gom.name) | 
|  |  | 
|  | dep := &cfg.Dependency{ | 
|  | Name: pkg, | 
|  | } | 
|  |  | 
|  | // Check for a specific revision | 
|  | if val, ok := gom.options["commit"]; ok { | 
|  | dep.Version = val.(string) | 
|  | } | 
|  | if val, ok := gom.options["tag"]; ok { | 
|  | dep.Version = val.(string) | 
|  | } | 
|  | if val, ok := gom.options["branch"]; ok { | 
|  | dep.Branch = val.(string) | 
|  | } | 
|  |  | 
|  | buf = append(buf, dep) | 
|  | } | 
|  |  | 
|  | return buf, nil | 
|  | } | 
|  |  | 
|  | // AsMetadataPair attempts to extract manifest and lock data from gom metadata. | 
|  | func AsMetadataPair(dir string) (gps.Manifest, gps.Lock, error) { | 
|  | path := filepath.Join(dir, "Gomfile") | 
|  | if _, err := os.Stat(path); err != nil { | 
|  | return nil, nil, err | 
|  | } | 
|  |  | 
|  | goms, err := parseGomfile(path) | 
|  | if err != nil { | 
|  | return nil, nil, err | 
|  | } | 
|  |  | 
|  | var l gps.SimpleLock | 
|  | m := gps.SimpleManifest{} | 
|  |  | 
|  | for _, gom := range goms { | 
|  | // Do we need to skip this dependency? | 
|  | if val, ok := gom.options["skipdep"]; ok && val.(string) == "true" { | 
|  | continue | 
|  | } | 
|  |  | 
|  | // Check for custom cloning command | 
|  | if _, ok := gom.options["command"]; ok { | 
|  | return nil, nil, errors.New("Glide does not support custom Gomfile commands") | 
|  | } | 
|  |  | 
|  | // Check for groups/environments | 
|  | if val, ok := gom.options["group"]; ok { | 
|  | groups := toStringSlice(val) | 
|  | if !stringsContain(groups, "development") && !stringsContain(groups, "production") { | 
|  | // right now we only support development and production | 
|  | continue | 
|  | } | 
|  | } | 
|  |  | 
|  | pkg, _ := util.NormalizeName(gom.name) | 
|  |  | 
|  | dep := gps.ProjectConstraint{ | 
|  | Ident: gps.ProjectIdentifier{ | 
|  | ProjectRoot: gps.ProjectRoot(pkg), | 
|  | }, | 
|  | } | 
|  |  | 
|  | // Our order of preference for things to put in the manifest are | 
|  | //   - Semver | 
|  | //   - Version | 
|  | //   - Branch | 
|  | //   - Revision | 
|  |  | 
|  | var v gps.UnpairedVersion | 
|  | if val, ok := gom.options["tag"]; ok { | 
|  | body := val.(string) | 
|  | v = gps.NewVersion(body) | 
|  | c, err := gps.NewSemverConstraint(body) | 
|  | if err != nil { | 
|  | c = gps.NewVersion(body) | 
|  | } | 
|  | dep.Constraint = c | 
|  | } else if val, ok := gom.options["branch"]; ok { | 
|  | body := val.(string) | 
|  | v = gps.NewBranch(body) | 
|  | dep.Constraint = gps.NewBranch(body) | 
|  | } | 
|  |  | 
|  | id := gps.ProjectIdentifier{ | 
|  | ProjectRoot: gps.ProjectRoot(dir), | 
|  | } | 
|  | var version gps.Version | 
|  | if val, ok := gom.options["commit"]; ok { | 
|  | body := val.(string) | 
|  | if v != nil { | 
|  | version = v.Is(gps.Revision(body)) | 
|  | } else { | 
|  | // As with the other third-party system integrations, we're | 
|  | // going to choose not to put revisions into a manifest, even | 
|  | // though gom has a lot more information than most and the | 
|  | // argument could be made for it. | 
|  | dep.Constraint = gps.Any() | 
|  | version = gps.Revision(body) | 
|  | } | 
|  | } else if v != nil { | 
|  | // This is kinda uncomfortable - lock w/no immut - but OK | 
|  | version = v | 
|  | } | 
|  | l = append(l, gps.NewLockedProject(id, version, nil)) | 
|  |  | 
|  | // TODO We ignore GOOS, GOARCH for now | 
|  | } | 
|  |  | 
|  | return m, l, nil | 
|  | } | 
|  |  | 
|  | func stringsContain(v []string, key string) bool { | 
|  | for _, s := range v { | 
|  | if s == key { | 
|  | return true | 
|  | } | 
|  | } | 
|  | return false | 
|  | } | 
|  |  | 
|  | func toStringSlice(v interface{}) []string { | 
|  | if v, ok := v.(string); ok { | 
|  | return []string{v} | 
|  | } | 
|  |  | 
|  | if v, ok := v.([]string); ok { | 
|  | return v | 
|  | } | 
|  |  | 
|  | return []string{} | 
|  | } |