Skip to content

Commit

Permalink
Use 'go list' to determine transitive dependencies for gomodules proj…
Browse files Browse the repository at this point in the history
…ects (#648)
  • Loading branch information
cnr committed Feb 10, 2021
1 parent 84818e9 commit 44d13b2
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 9 deletions.
34 changes: 25 additions & 9 deletions analyzers/golang/project.go
@@ -1,9 +1,12 @@
package golang

import (
"path/filepath"

"github.com/apex/log"

"github.com/fossas/fossa-cli/analyzers/golang/resolver"
"github.com/fossas/fossa-cli/buildtools/gomodules"
"github.com/fossas/fossa-cli/vcs"
)

Expand Down Expand Up @@ -73,16 +76,29 @@ func (a *Analyzer) Project(pkg string) (Project, error) {
return Project{}, err
}

// Find the nearest VCS repository.
_, repoRoot, err := vcs.Nearest(dir)
if err != nil {
return Project{}, err
}
var repoRoot string
var importPrefix string
if tool == "gomodules" {
// Gomodules forms its own "GOPATH root", so we use that for the project,
// instead of determining one from VCS + system GOPATH
repoRoot = dir
importPrefix, err = gomodules.ModulePath(filepath.Join(manifestDir, "go.mod"))

// Compute the project import path prefix.
importPrefix, err := ImportPath(repoRoot)
if err != nil {
return Project{}, err
if err != nil {
return Project{}, err
}
} else {
// Find the nearest VCS repository.
_, repoRoot, err = vcs.Nearest(dir)
if err != nil {
return Project{}, err
}

// Compute the project import path prefix.
importPrefix, err = ImportPath(repoRoot)
if err != nil {
return Project{}, err
}
}

// Cache the computed project.
Expand Down
28 changes: 28 additions & 0 deletions buildtools/gomodules/gomodules.go
Expand Up @@ -57,6 +57,34 @@ func New(dir string) (Resolver, error) {
return resolver, nil
}

// Return the "module path" from a go.mod file
//
// A file containing:
//
// module example.com/foo
//
// Returns "example.com/foo"
func ModulePath(modFile string) (string, error) {
mod, err := files.Read(modFile)
if err != nil {
return "", err
}

for _, line := range strings.Split(string(mod), "\n") {
trimLine := strings.TrimSpace(line)
splitLine := strings.Split(trimLine, " ")

if len(splitLine) < 2 {
continue
}

if splitLine[0] == "module" {
return splitLine[1], nil
}
}
return "", errors.New("no \"module\" directive found in go.mod")
}

// ModGraph returns the dependencies found in a `go.mod` file.
// We cannot resolve a graph so we make all dependencies direct.
func ModGraph(filename string) (graph.Deps, error) {
Expand Down
7 changes: 7 additions & 0 deletions buildtools/gomodules/gomodules_test.go
Expand Up @@ -54,6 +54,13 @@ func TestResolver(t *testing.T) {
assert.Equal(t, buildtools.ErrNoRevisionForPackage, err)
}

func TestModulePath(t *testing.T) {
modPath, err := gomodules.ModulePath("testdata/go.mod")
assert.NoError(t, err)

assert.Equal(t, "test/package", modPath)
}

func TestGoModGraph(t *testing.T) {
depGraph, err := gomodules.ModGraph("testdata/go.mod")
assert.NoError(t, err)
Expand Down

0 comments on commit 44d13b2

Please sign in to comment.