From 78f796a291b64302415ef52ab3c9a77a1fef8cd0 Mon Sep 17 00:00:00 2001 From: damnever Date: Sat, 6 May 2017 10:16:11 +0800 Subject: [PATCH] Fix couldn't load package bug, if multiple GOPATH exists and target code is not in first GOPATH --- .travis.yml | 3 +-- parser/parser.go | 11 +++++---- parser/parser_test.go | 52 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 parser/parser_test.go diff --git a/.travis.yml b/.travis.yml index 5b2fbc1..b2bb328 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,5 +5,4 @@ go: - 1.8 - master script: - - go test ./... - + - GOPATH="$GOPATH:/tmp/jsonenums-test/go1:/tmp/jsonenums-test/go2" go test ./... diff --git a/parser/parser.go b/parser/parser.go index 5598362..4d7110a 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -23,7 +23,6 @@ import ( "go/token" "go/types" "log" - "path/filepath" "strings" "golang.org/x/tools/go/loader" @@ -39,20 +38,20 @@ type Package struct { // ParsePackage parses the package in the given directory and returns it. func ParsePackage(directory string) (*Package, error) { - relDir, err := filepath.Rel(filepath.Join(build.Default.GOPATH, "src"), directory) + p, err := build.ImportDir(directory, build.FindOnly) if err != nil { - return nil, fmt.Errorf("provided directory not under GOPATH (%s): %v", - build.Default.GOPATH, err) + return nil, fmt.Errorf("provided directory (%s) may not under GOPATH (%s): %v", + directory, build.Default.GOPATH, err) } conf := loader.Config{TypeChecker: types.Config{FakeImportC: true}} - conf.Import(relDir) + conf.Import(p.ImportPath) program, err := conf.Load() if err != nil { return nil, fmt.Errorf("couldn't load package: %v", err) } - pkgInfo := program.Package(relDir) + pkgInfo := program.Package(p.ImportPath) return &Package{ Name: pkgInfo.Pkg.Name(), files: pkgInfo.Files, diff --git a/parser/parser_test.go b/parser/parser_test.go new file mode 100644 index 0000000..e14221e --- /dev/null +++ b/parser/parser_test.go @@ -0,0 +1,52 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to writing, software distributed +// under the License is distributed on a "AS IS" BASIS, WITHOUT WARRANTIES OR +// CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. + +package parser + +import ( + "go/build" + "io/ioutil" + "os" + "path/filepath" + "testing" +) + +func must(t *testing.T, err error) { + if err != nil { + t.Fatal(err) + } +} + +var fakeCode = ` +package main +import "fmt" +func main() { + fmt.Println("Hello world!") +} +` + +func TestParseFromMultipleGopath(t *testing.T) { + gopaths := filepath.SplitList(build.Default.GOPATH) + if len(gopaths) < 2 { + t.Skipf("No multiple GOPATH (%s) exists, skiping..", build.Default.GOPATH) + } + gopath := gopaths[len(gopaths)-1] + dir := filepath.Join(gopath, "src", "foo") + defer must(t, os.RemoveAll(dir)) + must(t, os.MkdirAll(dir, 0755)) + must(t, ioutil.WriteFile(filepath.Join(dir, "main.go"), []byte(fakeCode), 0644)) + + if _, err := ParsePackage(dir); err != nil { + t.Fatalf("Parse package (%v): %v", dir, err) + } +}