github.com/joey-fossa/fossa-cli@v0.7.34-0.20190708193710-569f1e8679f0/analyzers/ruby/bundler.go (about)

     1  package ruby
     2  
     3  import (
     4  	"github.com/fossas/fossa-cli/buildtools/bundler"
     5  	"github.com/fossas/fossa-cli/pkg"
     6  )
     7  
     8  func FromGems(gems []bundler.Gem) ([]pkg.Import, map[pkg.ID]pkg.Package) {
     9  	var imports []pkg.Import
    10  	graph := make(map[pkg.ID]pkg.Package)
    11  	for _, gem := range gems {
    12  		id := pkg.ID{
    13  			Type:     pkg.Ruby,
    14  			Name:     gem.Name,
    15  			Revision: gem.Revision,
    16  		}
    17  		imports = append(imports, pkg.Import{
    18  			Resolved: id,
    19  		})
    20  		graph[id] = pkg.Package{
    21  			ID:       id,
    22  			Strategy: "bundler-list",
    23  		}
    24  	}
    25  	return imports, graph
    26  }
    27  
    28  func FromLockfile(lockfile bundler.Lockfile) ([]pkg.Import, map[pkg.ID]pkg.Package) {
    29  	// Construct a map of all dependencies.
    30  	nameToID := make(map[string]pkg.ID)
    31  
    32  	AddSpecs(nameToID, lockfile.Git)
    33  	AddSpecs(nameToID, lockfile.Path)
    34  	AddSpecs(nameToID, lockfile.Gem)
    35  
    36  	// Build the dependency graph.
    37  	graph := make(map[pkg.ID]pkg.Package)
    38  
    39  	AddToGraph(graph, nameToID, lockfile.Git)
    40  	AddToGraph(graph, nameToID, lockfile.Path)
    41  	AddToGraph(graph, nameToID, lockfile.Gem)
    42  
    43  	var imports []pkg.Import
    44  	for _, dep := range lockfile.Dependencies {
    45  		imports = append(imports, pkg.Import{
    46  			Target:   dep.String(),
    47  			Resolved: nameToID[dep.Name],
    48  		})
    49  	}
    50  
    51  	return imports, graph
    52  }
    53  
    54  func AddSpecs(lookup map[string]pkg.ID, sections []bundler.Section) {
    55  	for _, section := range sections {
    56  		for _, spec := range section.Specs {
    57  			location := section.Remote
    58  			if section.Type == "GIT" {
    59  				location = section.Remote + "@" + section.Revision
    60  			}
    61  			lookup[spec.Name] = pkg.ID{
    62  				Type:     pkg.Ruby,
    63  				Name:     spec.Name,
    64  				Revision: spec.Version,
    65  				Location: location,
    66  			}
    67  		}
    68  	}
    69  }
    70  
    71  func AddToGraph(graph map[pkg.ID]pkg.Package, lookup map[string]pkg.ID, sections []bundler.Section) {
    72  	for _, section := range sections {
    73  		for _, spec := range section.Specs {
    74  			var imports []pkg.Import
    75  			for _, dep := range spec.Dependencies {
    76  				imports = append(imports, pkg.Import{
    77  					Target:   dep.String(),
    78  					Resolved: lookup[dep.Name],
    79  				})
    80  			}
    81  
    82  			id := lookup[spec.Name]
    83  			graph[id] = pkg.Package{
    84  				ID:      id,
    85  				Imports: imports,
    86  			}
    87  		}
    88  	}
    89  }
    90  
    91  func FilteredLockfile(gems []bundler.Gem, lockfile bundler.Lockfile) ([]pkg.Import, map[pkg.ID]pkg.Package) {
    92  	// Construct set of allowed gems.
    93  	gemSet := make(map[string]bool)
    94  	for _, gem := range gems {
    95  		gemSet[gem.Name] = true
    96  	}
    97  
    98  	// Filter lockfile results.
    99  	imports, graph := FromLockfile(lockfile)
   100  
   101  	var filteredImports []pkg.Import
   102  	filteredGraph := make(map[pkg.ID]pkg.Package)
   103  
   104  	for _, dep := range imports {
   105  		if _, ok := gemSet[dep.Resolved.Name]; ok {
   106  			filteredImports = append(filteredImports, dep)
   107  		}
   108  	}
   109  
   110  	for id, pkg := range graph {
   111  		if _, ok := gemSet[id.Name]; ok {
   112  			filteredGraph[id] = pkg
   113  		}
   114  	}
   115  
   116  	return filteredImports, filteredGraph
   117  }