Get dependencies for go modules powered projects.
This commit is contained in:
parent
633aa28ef1
commit
f423fb9ac7
@ -2,9 +2,15 @@ package golang
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
// stdlib
|
// stdlib
|
||||||
|
|
||||||
|
"bufio"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
// local
|
||||||
|
"go.dev.pztrn.name/glp/structs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var goModulesFilesToCheck = []string{"go.mod", "go.sum"}
|
var goModulesFilesToCheck = []string{"go.mod", "go.sum"}
|
||||||
@ -25,3 +31,73 @@ func (gp *golangParser) detectModulesUsage(pkgPath string) bool {
|
|||||||
|
|
||||||
return goModulesFileFound
|
return goModulesFileFound
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Gets dependencies from go.mod/go.sum files.
|
||||||
|
func (gp *golangParser) getDependenciesFromModules(pkgPath string) []*structs.Dependency {
|
||||||
|
deps := make([]*structs.Dependency, 0)
|
||||||
|
|
||||||
|
// Try to figure out parent package name for all dependencies.
|
||||||
|
parent := gp.getParentForDep(pkgPath)
|
||||||
|
|
||||||
|
// Get GOPATH for future dependency path composing.
|
||||||
|
gopath, found := os.LookupEnv("GOPATH")
|
||||||
|
if !found {
|
||||||
|
log.Fatalln("Go modules project found but no GOPATH environment variable defined. Cannot continue.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// To get really all dependencies we should use go.sum file.
|
||||||
|
filePath := filepath.Join(pkgPath, "go.sum")
|
||||||
|
|
||||||
|
f, err := os.Open(filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("Failed to open go.sum file for reading:", err.Error())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// We do not need multiple lines of dependencies in reports which
|
||||||
|
// describes same name and version.
|
||||||
|
createdDeps := make(map[string]bool)
|
||||||
|
|
||||||
|
// Read file data line by line.
|
||||||
|
gosum := bufio.NewScanner(f)
|
||||||
|
gosum.Split(bufio.ScanLines)
|
||||||
|
|
||||||
|
for gosum.Scan() {
|
||||||
|
depLine := strings.Split(gosum.Text(), " ")
|
||||||
|
|
||||||
|
// Version should be cleared out from possible "/go.mod"
|
||||||
|
// substring.
|
||||||
|
version := strings.Split(depLine[1], "/")[0]
|
||||||
|
|
||||||
|
// Check if we've already processed that dependency.
|
||||||
|
_, processed := createdDeps[depLine[0]+"@"+version]
|
||||||
|
if processed {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go modules present on disk either in vendor or in GOPATH/pkg
|
||||||
|
// directory. But vendor here should not be trusted because it
|
||||||
|
// might contain old versions.
|
||||||
|
dependencyPath := filepath.Join(gopath, "pkg", "mod", depLine[0]+"@"+version)
|
||||||
|
|
||||||
|
// Check if this module exists on disk. Absence means that it
|
||||||
|
// isn't actually used and just pollute go.sum.
|
||||||
|
if _, err := os.Stat(dependencyPath); err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
dependency := &structs.Dependency{
|
||||||
|
LocalPath: dependencyPath,
|
||||||
|
Name: depLine[0],
|
||||||
|
Parent: parent,
|
||||||
|
Version: version,
|
||||||
|
}
|
||||||
|
|
||||||
|
deps = append(deps, dependency)
|
||||||
|
|
||||||
|
// Mark dependency as processed.
|
||||||
|
createdDeps[depLine[0]+"@"+version] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return deps
|
||||||
|
}
|
||||||
|
@ -42,6 +42,8 @@ func (gp *golangParser) GetDependencies(flavor string, pkgPath string) []*struct
|
|||||||
switch flavor {
|
switch flavor {
|
||||||
case packageManagerDep:
|
case packageManagerDep:
|
||||||
deps = gp.getDependenciesFromDep(pkgPath)
|
deps = gp.getDependenciesFromDep(pkgPath)
|
||||||
|
case packageManagerGoMod:
|
||||||
|
deps = gp.getDependenciesFromModules(pkgPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return early if no dependencies was found.
|
// Return early if no dependencies was found.
|
||||||
|
@ -85,7 +85,7 @@ func (p *Project) process() {
|
|||||||
for _, dep := range p.deps {
|
for _, dep := range p.deps {
|
||||||
depDir, err := filer.FromDirectory(dep.LocalPath)
|
depDir, err := filer.FromDirectory(dep.LocalPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Failed to prepare directory path for depencendy license scan:", err.Error())
|
log.Println("Failed to prepare directory path for dependency license scan:", err.Error())
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user