| package cmd |
| |
| import ( |
| "os" |
| "path/filepath" |
| "sort" |
| "strings" |
| |
| "github.com/Masterminds/cookoo" |
| "github.com/Masterminds/glide/cfg" |
| "github.com/Masterminds/glide/dependency" |
| "github.com/Masterminds/glide/util" |
| ) |
| |
| // GuessDeps tries to get the dependencies for the current directory. |
| // |
| // Params |
| // - dirname (string): Directory to use as the base. Default: "." |
| // - skipImport (book): Whether to skip importing from Godep, GPM, and gb |
| func GuessDeps(c cookoo.Context, p *cookoo.Params) (interface{}, cookoo.Interrupt) { |
| buildContext, err := util.GetBuildContext() |
| if err != nil { |
| return nil, err |
| } |
| base := p.Get("dirname", ".").(string) |
| skipImport := p.Get("skipImport", false).(bool) |
| name := guessPackageName(buildContext, base) |
| |
| Info("Generating a YAML configuration file and guessing the dependencies") |
| |
| config := new(cfg.Config) |
| |
| // Get the name of the top level package |
| config.Name = name |
| |
| // Import by looking at other package managers and looking over the |
| // entire directory structure. |
| |
| // Attempt to import from other package managers. |
| if !skipImport { |
| Info("Attempting to import from other package managers (use --skip-import to skip)") |
| deps := []*cfg.Dependency{} |
| absBase, err := filepath.Abs(base) |
| if err != nil { |
| return nil, err |
| } |
| |
| if d, ok := guessImportGodep(absBase); ok { |
| Info("Importing Godep configuration") |
| Warn("Godep uses commit id versions. Consider using Semantic Versions with Glide") |
| deps = d |
| } else if d, ok := guessImportGPM(absBase); ok { |
| Info("Importing GPM configuration") |
| deps = d |
| } else if d, ok := guessImportGB(absBase); ok { |
| Info("Importing GB configuration") |
| deps = d |
| } |
| |
| for _, i := range deps { |
| Info("Found imported reference to %s\n", i.Name) |
| config.Imports = append(config.Imports, i) |
| } |
| } |
| |
| // Resolve dependencies by looking at the tree. |
| r, err := dependency.NewResolver(base) |
| if err != nil { |
| return nil, err |
| } |
| |
| h := &dependency.DefaultMissingPackageHandler{Missing: []string{}, Gopath: []string{}} |
| r.Handler = h |
| |
| sortable, err := r.ResolveLocal(false) |
| if err != nil { |
| return nil, err |
| } |
| |
| sort.Strings(sortable) |
| |
| vpath := r.VendorDir |
| if !strings.HasSuffix(vpath, "/") { |
| vpath = vpath + string(os.PathSeparator) |
| } |
| |
| for _, pa := range sortable { |
| n := strings.TrimPrefix(pa, vpath) |
| root := util.GetRootFromPackage(n) |
| |
| if !config.HasDependency(root) { |
| Info("Found reference to %s\n", n) |
| d := &cfg.Dependency{ |
| Name: root, |
| } |
| subpkg := strings.TrimPrefix(n, root) |
| if len(subpkg) > 0 && subpkg != "/" { |
| d.Subpackages = []string{subpkg} |
| } |
| config.Imports = append(config.Imports, d) |
| } else { |
| subpkg := strings.TrimPrefix(n, root) |
| if len(subpkg) > 0 && subpkg != "/" { |
| subpkg = strings.TrimPrefix(subpkg, "/") |
| d := config.Imports.Get(root) |
| f := false |
| for _, v := range d.Subpackages { |
| if v == subpkg { |
| f = true |
| } |
| } |
| if !f { |
| Info("Adding sub-package %s to %s\n", subpkg, root) |
| d.Subpackages = append(d.Subpackages, subpkg) |
| } |
| } |
| } |
| } |
| |
| return config, nil |
| } |
| |
| // Attempt to guess at the package name at the top level. When unable to detect |
| // a name goes to default of "main". |
| func guessPackageName(b *util.BuildCtxt, base string) string { |
| cwd, err := os.Getwd() |
| if err != nil { |
| return "main" |
| } |
| |
| pkg, err := b.Import(base, cwd, 0) |
| if err != nil { |
| // There may not be any top level Go source files but the project may |
| // still be within the GOPATH. |
| if strings.HasPrefix(base, b.GOPATH) { |
| p := strings.TrimPrefix(base, b.GOPATH) |
| return strings.Trim(p, string(os.PathSeparator)) |
| } |
| } |
| |
| return pkg.ImportPath |
| } |
| |
| func guessImportGodep(dir string) ([]*cfg.Dependency, bool) { |
| d, err := parseGodepGodeps(dir) |
| if err != nil || len(d) == 0 { |
| return []*cfg.Dependency{}, false |
| } |
| |
| return d, true |
| } |
| |
| func guessImportGPM(dir string) ([]*cfg.Dependency, bool) { |
| d, err := parseGPMGodeps(dir) |
| if err != nil || len(d) == 0 { |
| return []*cfg.Dependency{}, false |
| } |
| |
| return d, true |
| } |
| |
| func guessImportGB(dir string) ([]*cfg.Dependency, bool) { |
| d, err := parseGbManifest(dir) |
| if err != nil || len(d) == 0 { |
| return []*cfg.Dependency{}, false |
| } |
| |
| return d, true |
| } |