Skip to content

Commit

Permalink
Merge pull request #8 from erizocosmico/fix/gopath
Browse files Browse the repository at this point in the history
implement GoPath helper and prepare for multiple go paths
  • Loading branch information
Miguel Molina authored Apr 26, 2017
2 parents ce53c64 + cd0627f commit 9683a7e
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 18 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ matrix:
allow_failures:
- go: tip

env:
- GOPATH=/tmp/whatever:$GOPATH

install:
- rm -rf $GOPATH/src/gopkg.in/src-d
- mkdir -p $GOPATH/src/gopkg.in/src-d
Expand Down
8 changes: 6 additions & 2 deletions ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"go/ast"
"go/parser"
"go/token"
"path/filepath"
"strings"
)

Expand Down Expand Up @@ -33,7 +32,12 @@ type packageFilter func(string, *ast.Package) bool
// one left.
func parseAndFilterPackages(path string, filter packageFilter) (pkg *ast.Package, err error) {
fset := token.NewFileSet()
pkgs, err := parser.ParseDir(fset, filepath.Join(goSrc, path), nil, parser.ParseComments)
srcDir, err := DefaultGoPath.Abs(path)
if err != nil {
return nil, err
}

pkgs, err := parser.ParseDir(fset, srcDir, nil, parser.ParseComments)
if err != nil {
return nil, err
}
Expand Down
49 changes: 43 additions & 6 deletions importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,39 @@ import (
"sync"
)

var (
goPath = os.Getenv("GOPATH")
goSrc = filepath.Join(goPath, "src")
)
// ErrNotInGoPath is an error returned when a package is not in any of the
// possible go paths.
var ErrNotInGoPath = fmt.Errorf("parseutil: package is not in any of the go paths")

// GoPath is the collection of all go paths.
type GoPath []string

// Abs returns the absolute path to a package. The go path in the absolute path
// that will be returned is the first that contains the given package.
func (gp GoPath) Abs(pkg string) (string, error) {
path, err := gp.PathOf(pkg)
if err != nil {
return "", err
}

return filepath.Join(path, "src", pkg), nil
}

// PathOf returns the first go path that contains the given package.
func (gp GoPath) PathOf(pkg string) (string, error) {
for _, p := range gp {
if _, err := os.Stat(filepath.Join(p, "src", pkg)); err == nil {
return p, nil
} else if !os.IsNotExist(err) {
return "", err
}
}
return "", ErrNotInGoPath
}

// DefaultGoPath contains the default list of go paths provided either via
// GOPATH environment variable or the default value.
var DefaultGoPath = GoPath(filepath.SplitList(build.Default.GOPATH))

// FileFilter returns true if the given file needs to be kept.
type FileFilter func(pkgPath, file string, typ FileType) bool
Expand Down Expand Up @@ -86,7 +115,7 @@ func (i *Importer) Import(path string) (*types.Package, error) {
// ImportWithFilters works like Import but filtering the source files to parse using
// the passed FileFilters.
func (i *Importer) ImportWithFilters(path string, filters FileFilters) (*types.Package, error) {
return i.ImportFromWithFilters(path, goSrc, 0, filters)
return i.ImportFromWithFilters(path, "", 0, filters)
}

// ImportFrom returns the imported package for the given import
Expand Down Expand Up @@ -115,7 +144,15 @@ func (i *Importer) ImportFromWithFilters(path, srcDir string, mode types.ImportM
}

// If it's not on the GOPATH use the default importer instead
if !strings.HasPrefix(root, goPath) {
useDefaultImporter := true
for _, p := range DefaultGoPath {
if strings.HasPrefix(root, p) {
useDefaultImporter = false
break
}
}

if useDefaultImporter {
i.mut.Lock()
defer i.mut.Unlock()

Expand Down
23 changes: 13 additions & 10 deletions importer_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package parseutil_test

import (
"os"
"path/filepath"
"testing"

Expand All @@ -13,20 +12,24 @@ import (

const project = "gopkg.in/src-d/go-parse-utils.v1"

var (
goPath = os.Getenv("GOPATH")
goSrc = filepath.Join(goPath, "src")
)

var projectPath = filepath.Join(goSrc, project)
var projectPath = func() string {
path, err := parseutil.DefaultGoPath.Abs(project)
if err != nil {
panic(err)
}
return path
}()

func projectFile(path string) string {
return filepath.Join(projectPath, path)
}

func TestGetSourceFiles(t *testing.T) {
_, paths, err := parseutil.NewImporter().GetSourceFiles(project, goPath, parseutil.FileFilters{})
require.Nil(t, err)
projPath, err := parseutil.DefaultGoPath.PathOf(project)
require.NoError(t, err)
_, paths, err := parseutil.NewImporter().
GetSourceFiles(project, projPath, parseutil.FileFilters{})
require.NoError(t, err)
expected := []string{
projectFile("ast.go"),
projectFile("importer.go"),
Expand Down Expand Up @@ -72,7 +75,7 @@ func TestImportGoogleGrpc(t *testing.T) {

func TestImportFrom(t *testing.T) {
imp := parseutil.NewImporter()
pkg, err := imp.ImportFrom(project, goSrc, 0)
pkg, err := imp.ImportFrom(project, "", 0)
require.Nil(t, err)
require.Equal(t, "parseutil", pkg.Name())
}
Expand Down

0 comments on commit 9683a7e

Please sign in to comment.