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  }