fix: recursively search for packages. (#72)

This commit is contained in:
Ludovic Fernandez
2019-02-01 11:47:41 +01:00
committed by Marc Vertes
parent 1245e29a11
commit 27a338d84a
17 changed files with 384 additions and 3 deletions

View File

@@ -0,0 +1,17 @@
package pkg
import (
"fmt"
"guthib.com/containous/fromage"
)
func Here() string {
return "root"
}
func NewSample() func() string {
return func() string {
return fmt.Sprintf("%s %s", Here(), fromage.Hello())
}
}

View File

@@ -0,0 +1,11 @@
package cheese
import (
"fmt"
"guthib.com/containous/cheese/vin"
)
func Hello() string {
return fmt.Sprintf("Cheese %s", vin.Hello())
}

View File

@@ -0,0 +1,7 @@
package vin
import "fmt"
func Hello() string {
return fmt.Sprint("Vin!")
}

View File

@@ -0,0 +1,7 @@
package couteau
import "fmt"
func Hello() string {
return fmt.Sprint("Couteau")
}

View File

@@ -0,0 +1,12 @@
package fromage
import (
"fmt"
"guthib.com/containous/cheese"
"guthib.com/containous/fromage/couteau"
)
func Hello() string {
return fmt.Sprintf("Fromage %s %s", cheese.Hello(), couteau.Hello())
}

View File

@@ -0,0 +1,17 @@
package pkg
import (
"fmt"
"guthib.com/containous/fromage"
)
func Here() string {
return "root"
}
func NewSample() func() string {
return func() string {
return fmt.Sprintf("%s %s", Here(), fromage.Hello())
}
}

View File

@@ -0,0 +1,7 @@
package couteau
import "fmt"
func Hello() string {
return fmt.Sprint("Couteau")
}

View File

@@ -0,0 +1,12 @@
package fromage
import (
"fmt"
"guthib.com/containous/cheese"
"guthib.com/containous/fromage/couteau"
)
func Hello() string {
return fmt.Sprintf("Fromage %s %s", cheese.Hello(), couteau.Hello())
}

View File

@@ -0,0 +1,11 @@
package cheese
import (
"fmt"
"guthib.com/containous/cheese/vin"
)
func Hello() string {
return fmt.Sprintf("Cheese %s", vin.Hello())
}

View File

@@ -0,0 +1,7 @@
package vin
import "fmt"
func Hello() string {
return fmt.Sprint("Vin!")
}

View File

@@ -0,0 +1,17 @@
package pkg
import (
"fmt"
"guthib.com/containous/vin"
)
func Here() string {
return "root"
}
func NewSample() func() string {
return func() string {
return fmt.Sprintf("%s %s", Here(), vin.Hello())
}
}

View File

@@ -0,0 +1,7 @@
package fromage
import "fmt"
func Hello() string {
return fmt.Sprint("fromage")
}

View File

@@ -0,0 +1,11 @@
package cheese
import (
"fmt"
"guthib.com/containous/fromage"
)
func Hello() string {
return fmt.Sprintf("cheese %s", fromage.Hello())
}

View File

@@ -0,0 +1,11 @@
package vin
import (
"fmt"
"guthib.com/containous/cheese"
)
func Hello() string {
return fmt.Sprintf("vin %s", cheese.Hello())
}

View File

@@ -44,12 +44,26 @@ func TestPackages(t *testing.T) {
goPath: "./_pkg4/",
expected: "root Fromage Cheese Vin! Couteau",
},
{
desc: "vendor flat",
goPath: "./_pkg5/",
expected: "root Fromage Cheese Vin! Couteau",
},
{
desc: "fallback to GOPATH",
goPath: "./_pkg6/",
expected: "root Fromage Cheese Vin! Couteau",
},
{
desc: "recursive vendor",
goPath: "./_pkg7/",
expected: "root vin cheese fromage",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
// t.Parallel()
goPath, err := filepath.Abs(test.goPath)
if err != nil {

View File

@@ -1,6 +1,7 @@
package interp
import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
@@ -96,8 +97,34 @@ func pkgDir(goPath string, root, path string) (string, string, error) {
dir = filepath.Join(goPath, "src", effectivePkg(root, path))
_, err := os.Stat(dir)
return dir, root, err
if _, err := os.Stat(dir); err == nil {
return dir, root, nil // found!
}
if len(root) == 0 {
return "", "", fmt.Errorf("unable to find source related to: %q", path)
}
return pkgDir(goPath, previousRoot(root), path)
}
// Find the previous source root. (vendor > vendor > ... > GOPATH)
func previousRoot(root string) string {
splitRoot := strings.Split(root, string(filepath.Separator))
var index int
for i := len(splitRoot) - 1; i >= 0; i-- {
if splitRoot[i] == "vendor" {
index = i
break
}
}
if index == 0 {
return ""
}
return filepath.Join(splitRoot[:index]...)
}
func effectivePkg(root, path string) string {

View File

@@ -1,6 +1,9 @@
package interp
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)
@@ -38,3 +41,186 @@ func Test_effectivePkg(t *testing.T) {
})
}
}
func Test_pkgDir(t *testing.T) {
// create GOPATH
goPath, err := ioutil.TempDir("", "pkdir")
if err != nil {
t.Fatal(err)
}
defer func() {
_ = os.RemoveAll(goPath)
}()
// Create project
project := filepath.Join(goPath, "src", "guthib.com", "foo", "root")
if err := os.MkdirAll(project, 0700); err != nil {
t.Fatal(err)
}
type expected struct {
dir string
rpath string
}
testCases := []struct {
desc string
path string
root string
setup func() error
expected expected
}{
{
desc: "GOPATH only",
path: "guthib.com/foo/bar",
root: "",
setup: func() error {
return os.MkdirAll(filepath.Join(goPath, "src", "guthib.com", "foo", "bar"), 0700)
},
expected: expected{
dir: filepath.Join(goPath, "src", "guthib.com", "foo", "bar"),
rpath: "",
},
},
{
desc: "vendor",
path: "guthib.com/foo/bar",
root: filepath.Join("guthib.com", "foo", "root"),
setup: func() error {
return os.MkdirAll(filepath.Join(project, "vendor", "guthib.com", "foo", "bar"), 0700)
},
expected: expected{
dir: filepath.Join(goPath, "src", "guthib.com", "foo", "root", "vendor", "guthib.com", "foo", "bar"),
rpath: filepath.Join("guthib.com", "foo", "root", "vendor"),
},
},
{
desc: "GOPATH flat",
path: "guthib.com/foo/bar",
root: filepath.Join("guthib.com", "foo", "root"),
setup: func() error {
return os.MkdirAll(filepath.Join(goPath, "src", "guthib.com", "foo", "bar"), 0700)
},
expected: expected{
dir: filepath.Join(goPath, "src", "guthib.com", "foo", "bar"),
rpath: "",
},
},
{
desc: "vendor flat",
path: "guthib.com/foo/bar",
root: filepath.Join("guthib.com", "foo", "root", "vendor", "guthib.com", "foo", "bir"),
setup: func() error {
if err := os.MkdirAll(filepath.Join(project, "vendor", "guthib.com", "foo", "bar"), 0700); err != nil {
return err
}
return os.MkdirAll(filepath.Join(project, "vendor", "guthib.com", "foo", "bir"), 0700)
},
expected: expected{
dir: filepath.Join(goPath, "src", "guthib.com", "foo", "root", "vendor", "guthib.com", "foo", "bar"),
rpath: filepath.Join("guthib.com", "foo", "root", "vendor"),
},
},
{
desc: "fallback to GOPATH",
path: "guthib.com/foo/bar",
root: filepath.Join("guthib.com", "foo", "root", "vendor", "guthib.com", "foo", "bir"),
setup: func() error {
if err := os.MkdirAll(filepath.Join(goPath, "src", "guthib.com", "foo", "bar"), 0700); err != nil {
return err
}
return os.MkdirAll(filepath.Join(project, "vendor", "guthib.com", "foo", "bir"), 0700)
},
expected: expected{
dir: filepath.Join(goPath, "src", "guthib.com", "foo", "bar"),
rpath: "",
},
},
{
desc: "vendor recursive",
path: "guthib.com/foo/bar",
root: filepath.Join("guthib.com", "foo", "root", "vendor", "guthib.com", "foo", "bir", "vendor", "guthib.com", "foo", "bur"),
setup: func() error {
if err := os.MkdirAll(
filepath.Join(goPath, "src", "guthib.com", "foo", "root", "vendor", "guthib.com", "foo", "bir", "vendor", "guthib.com", "foo", "bur"),
0700); err != nil {
return err
}
return os.MkdirAll(filepath.Join(project, "vendor", "guthib.com", "foo", "bar"), 0700)
},
expected: expected{
dir: filepath.Join(project, "vendor", "guthib.com", "foo", "bar"),
rpath: filepath.Join("guthib.com", "foo", "root", "vendor"),
},
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
if err := os.RemoveAll(goPath); err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(goPath, 0700); err != nil {
t.Fatal(err)
}
if test.setup != nil {
err := test.setup()
if err != nil {
t.Fatal(err)
}
}
dir, rPath, err := pkgDir(goPath, test.root, test.path)
if err != nil {
t.Fatal(err)
}
if dir != test.expected.dir {
t.Errorf("[dir] got: %s, want: %s", dir, test.expected.dir)
}
if rPath != test.expected.rpath {
t.Errorf(" [rpath] got: %s, want: %s", rPath, test.expected.rpath)
}
})
}
}
func Test_previousRoot(t *testing.T) {
testCases := []struct {
desc string
root string
expected string
}{
{
desc: "GOPATH",
root: "github.com/foo/pkg/",
expected: "",
},
{
desc: "vendor level 1",
root: "github.com/foo/pkg/vendor/guthib.com/containous/fromage",
expected: "github.com/foo/pkg",
},
{
desc: "vendor level 2",
root: "github.com/foo/pkg/vendor/guthib.com/containous/fromage/vendor/guthib.com/containous/fuu",
expected: "github.com/foo/pkg/vendor/guthib.com/containous/fromage",
},
}
for _, test := range testCases {
test := test
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
p := previousRoot(test.root)
if p != test.expected {
t.Errorf("got: %s, want: %s", p, test.expected)
}
})
}
}