diff --git a/cobra/cmd/helpers.go b/cobra/cmd/helpers.go index 6989bd78..db03dd2a 100644 --- a/cobra/cmd/helpers.go +++ b/cobra/cmd/helpers.go @@ -97,13 +97,27 @@ func guessCmdDir() string { func guessImportPath() string { guessProjectPath() - if !strings.HasPrefix(projectPath, getSrcPath()) { + if !inPath(getSrcPath(), projectPath) { er("Cobra only supports project within $GOPATH") } return filepath.ToSlash(filepath.Clean(strings.TrimPrefix(projectPath, getSrcPath()))) } +func inPath(srcPath, projectPath string) bool { + relPath, err := filepath.Rel(srcPath, projectPath) + if err != nil { + return false + } + + splitRelPath := filepath.SplitList(relPath) + if splitRelPath[0] == ".." || splitRelPath[0] == "." { + return false + } + + return true +} + func getSrcPath() string { return filepath.Join(os.Getenv("GOPATH"), "src") + string(os.PathSeparator) } diff --git a/cobra/cmd/helpers_test.go b/cobra/cmd/helpers_test.go index bce94719..bf8789b5 100644 --- a/cobra/cmd/helpers_test.go +++ b/cobra/cmd/helpers_test.go @@ -2,6 +2,7 @@ package cmd import ( "path/filepath" + "runtime" "testing" ) @@ -33,3 +34,37 @@ func TestProjectPath(t *testing.T) { checkGuess(t, "/bar/foo/commands", "", filepath.Join("/", "bar", "foo")) checkGuess(t, "github.com/spf13/hugo/../hugo", "", filepath.Join("github.com", "spf13", "hugo")) } + +type inPathTestCase struct { + Src string + Prj string + InPath bool +} + +func TestInPath(t *testing.T) { + cases := []inPathTestCase{ + {"/bar/foo", "/bar/foo", false}, + {"/bar/foo", "/bar/foo/baz", true}, + {"/bar/foo/baz", "/bar/foo", false}, + {"/bar/foo", "/bar/foo/.wierd..dirname/", true}, + } + if runtime.GOOS == "windows" { + cases = append( + cases, + inPathTestCase{"C:/Bar/foo", "c:/bar/foo/baz", true}, + inPathTestCase{"c:\\bar\\foo", "C:\\bar\\foo", false}, + inPathTestCase{"c:\\bar\\..\\bar\\foo", "C:\\bar\\foo\\baz", true}, + ) + } + + for _, tc := range cases { + ip := inPath(tc.Src, tc.Prj) + if tc.InPath != ip { + if ip { + t.Errorf("Unexpected %s determined as not inside %s", tc.Prj, tc.Src) + } else { + t.Errorf("Unexpected %s determined as inside %s", tc.Prj, tc.Src) + } + } + } +}