github.com/joey-fossa/fossa-cli@v0.7.34-0.20190708193710-569f1e8679f0/buildtools/glide/glide.go (about) 1 // Package glide provides functions for working with the glide tool. 2 package glide 3 4 import ( 5 "errors" 6 "path" 7 "path/filepath" 8 "time" 9 10 "github.com/fossas/fossa-cli/buildtools" 11 "github.com/fossas/fossa-cli/files" 12 "github.com/fossas/fossa-cli/pkg" 13 ) 14 15 // ErrNoLockfile is returned if a glide manifest is found without an accompanying lockfile. 16 var ErrNoLockfile = errors.New("found glide.yaml but not glide.lock") 17 18 // An Import is a single imported repository within a glide project. 19 type Import struct { 20 Name string 21 Version string 22 Subpackages []string 23 Repo string 24 } 25 26 // A Lockfile contains the contents of a glide lockfile. Lockfiles are resolvers. 27 type Lockfile struct { 28 Hash string 29 Updated time.Time 30 Imports []Import 31 TestImports []Import 32 33 normalized map[string]pkg.Import // A normalized map of package import paths to revisions. 34 } 35 36 // Resolve returns the revision of an imported Go package contained within the 37 // lockfile. If the package is not found, buildtools.ErrNoRevisionForPackage is 38 // returned. If the revision has an aliased location, that is returned in place of the 39 // existing name. 40 func (l Lockfile) Resolve(importpath string) (pkg.Import, error) { 41 rev, ok := l.normalized[importpath] 42 if !ok { 43 return pkg.Import{}, buildtools.ErrNoRevisionForPackage 44 } 45 46 if rev.Resolved.Location != "" { 47 rev.Resolved.Name = rev.Resolved.Location 48 } 49 return rev, nil 50 } 51 52 // New constructs a golang.Resolver 53 func New(dirname string) (Lockfile, error) { 54 ok, err := UsedIn(dirname) 55 if err != nil { 56 return Lockfile{}, err 57 } 58 if !ok { 59 return Lockfile{}, errors.New("directory does not use glide") 60 } 61 lockfile, err := FromFile(filepath.Join(dirname, "glide.lock")) 62 if err != nil { 63 return Lockfile{}, err 64 } 65 normalized := make(map[string]pkg.Import) 66 for _, project := range lockfile.Imports { 67 for _, subpkg := range project.Subpackages { 68 importpath := path.Join(project.Name, subpkg) 69 normalized[importpath] = pkg.Import{ 70 Target: project.Version, 71 Resolved: pkg.ID{ 72 Type: pkg.Go, 73 Name: importpath, 74 Revision: project.Version, 75 Location: project.Repo, 76 }, 77 } 78 } 79 // The repository in glide lockfiles might also be a package, but it won't 80 // be listed as a _subpackage_. 81 normalized[project.Name] = pkg.Import{ 82 Target: project.Version, 83 Resolved: pkg.ID{ 84 Type: pkg.Go, 85 Name: project.Name, 86 Revision: project.Version, 87 Location: project.Repo, 88 }, 89 } 90 } 91 92 lockfile.normalized = normalized 93 return lockfile, nil 94 } 95 96 // UsedIn checks whether glide is used correctly within a project folder. 97 func UsedIn(dirname string) (bool, error) { 98 // Check whether there exists a manifest. 99 ok, err := files.Exists(dirname, "glide.yaml") 100 if err != nil { 101 return false, err 102 } 103 104 if ok { 105 // Check whether there exists a lockfile. 106 ok, err := files.Exists(dirname, "glide.lock") 107 if err != nil { 108 return false, err 109 } 110 // If both exist, then glide is being used correctly. 111 if ok { 112 return true, nil 113 } 114 // If only a manifest exists, then return ErrNoLockfile. 115 return true, ErrNoLockfile 116 } 117 // If there is no manifest, then glide is not being used. 118 return false, nil 119 } 120 121 // FromFile reads a raw Lockfile from a glide.lock file. 122 func FromFile(filename string) (Lockfile, error) { 123 var lockfile Lockfile 124 err := files.ReadYAML(&lockfile, filename) 125 if err != nil { 126 return Lockfile{}, err 127 } 128 return lockfile, nil 129 }