Get dependencies for go modules powered projects.
This commit is contained in:
		| @@ -2,9 +2,15 @@ package golang | ||||
|  | ||||
| import ( | ||||
| 	// stdlib | ||||
|  | ||||
| 	"bufio" | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
|  | ||||
| 	// local | ||||
| 	"go.dev.pztrn.name/glp/structs" | ||||
| ) | ||||
|  | ||||
| var goModulesFilesToCheck = []string{"go.mod", "go.sum"} | ||||
| @@ -25,3 +31,73 @@ func (gp *golangParser) detectModulesUsage(pkgPath string) bool { | ||||
|  | ||||
| 	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 { | ||||
| 	case packageManagerDep: | ||||
| 		deps = gp.getDependenciesFromDep(pkgPath) | ||||
| 	case packageManagerGoMod: | ||||
| 		deps = gp.getDependenciesFromModules(pkgPath) | ||||
| 	} | ||||
|  | ||||
| 	// Return early if no dependencies was found. | ||||
|   | ||||
| @@ -85,7 +85,7 @@ func (p *Project) process() { | ||||
| 	for _, dep := range p.deps { | ||||
| 		depDir, err := filer.FromDirectory(dep.LocalPath) | ||||
| 		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 | ||||
| 		} | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user