Skip to content

Commit 9683a7e

Browse files
author
Miguel Molina
authored
Merge pull request #8 from erizocosmico/fix/gopath
implement GoPath helper and prepare for multiple go paths
2 parents ce53c64 + cd0627f commit 9683a7e

File tree

4 files changed

+65
-18
lines changed

4 files changed

+65
-18
lines changed

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ matrix:
88
allow_failures:
99
- go: tip
1010

11+
env:
12+
- GOPATH=/tmp/whatever:$GOPATH
13+
1114
install:
1215
- rm -rf $GOPATH/src/gopkg.in/src-d
1316
- mkdir -p $GOPATH/src/gopkg.in/src-d

ast.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import (
55
"go/ast"
66
"go/parser"
77
"go/token"
8-
"path/filepath"
98
"strings"
109
)
1110

@@ -33,7 +32,12 @@ type packageFilter func(string, *ast.Package) bool
3332
// one left.
3433
func parseAndFilterPackages(path string, filter packageFilter) (pkg *ast.Package, err error) {
3534
fset := token.NewFileSet()
36-
pkgs, err := parser.ParseDir(fset, filepath.Join(goSrc, path), nil, parser.ParseComments)
35+
srcDir, err := DefaultGoPath.Abs(path)
36+
if err != nil {
37+
return nil, err
38+
}
39+
40+
pkgs, err := parser.ParseDir(fset, srcDir, nil, parser.ParseComments)
3741
if err != nil {
3842
return nil, err
3943
}

importer.go

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,39 @@ import (
1414
"sync"
1515
)
1616

17-
var (
18-
goPath = os.Getenv("GOPATH")
19-
goSrc = filepath.Join(goPath, "src")
20-
)
17+
// ErrNotInGoPath is an error returned when a package is not in any of the
18+
// possible go paths.
19+
var ErrNotInGoPath = fmt.Errorf("parseutil: package is not in any of the go paths")
20+
21+
// GoPath is the collection of all go paths.
22+
type GoPath []string
23+
24+
// Abs returns the absolute path to a package. The go path in the absolute path
25+
// that will be returned is the first that contains the given package.
26+
func (gp GoPath) Abs(pkg string) (string, error) {
27+
path, err := gp.PathOf(pkg)
28+
if err != nil {
29+
return "", err
30+
}
31+
32+
return filepath.Join(path, "src", pkg), nil
33+
}
34+
35+
// PathOf returns the first go path that contains the given package.
36+
func (gp GoPath) PathOf(pkg string) (string, error) {
37+
for _, p := range gp {
38+
if _, err := os.Stat(filepath.Join(p, "src", pkg)); err == nil {
39+
return p, nil
40+
} else if !os.IsNotExist(err) {
41+
return "", err
42+
}
43+
}
44+
return "", ErrNotInGoPath
45+
}
46+
47+
// DefaultGoPath contains the default list of go paths provided either via
48+
// GOPATH environment variable or the default value.
49+
var DefaultGoPath = GoPath(filepath.SplitList(build.Default.GOPATH))
2150

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

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

117146
// If it's not on the GOPATH use the default importer instead
118-
if !strings.HasPrefix(root, goPath) {
147+
useDefaultImporter := true
148+
for _, p := range DefaultGoPath {
149+
if strings.HasPrefix(root, p) {
150+
useDefaultImporter = false
151+
break
152+
}
153+
}
154+
155+
if useDefaultImporter {
119156
i.mut.Lock()
120157
defer i.mut.Unlock()
121158

importer_test.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package parseutil_test
22

33
import (
4-
"os"
54
"path/filepath"
65
"testing"
76

@@ -13,20 +12,24 @@ import (
1312

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

16-
var (
17-
goPath = os.Getenv("GOPATH")
18-
goSrc = filepath.Join(goPath, "src")
19-
)
20-
21-
var projectPath = filepath.Join(goSrc, project)
15+
var projectPath = func() string {
16+
path, err := parseutil.DefaultGoPath.Abs(project)
17+
if err != nil {
18+
panic(err)
19+
}
20+
return path
21+
}()
2222

2323
func projectFile(path string) string {
2424
return filepath.Join(projectPath, path)
2525
}
2626

2727
func TestGetSourceFiles(t *testing.T) {
28-
_, paths, err := parseutil.NewImporter().GetSourceFiles(project, goPath, parseutil.FileFilters{})
29-
require.Nil(t, err)
28+
projPath, err := parseutil.DefaultGoPath.PathOf(project)
29+
require.NoError(t, err)
30+
_, paths, err := parseutil.NewImporter().
31+
GetSourceFiles(project, projPath, parseutil.FileFilters{})
32+
require.NoError(t, err)
3033
expected := []string{
3134
projectFile("ast.go"),
3235
projectFile("importer.go"),
@@ -72,7 +75,7 @@ func TestImportGoogleGrpc(t *testing.T) {
7275

7376
func TestImportFrom(t *testing.T) {
7477
imp := parseutil.NewImporter()
75-
pkg, err := imp.ImportFrom(project, goSrc, 0)
78+
pkg, err := imp.ImportFrom(project, "", 0)
7679
require.Nil(t, err)
7780
require.Equal(t, "parseutil", pkg.Name())
7881
}

0 commit comments

Comments
 (0)