From db604c9497fa34ac5beeec2a52fc0f1d4bf51ead Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 18 Oct 2016 10:53:59 -0400 Subject: [PATCH 1/2] Add funcs for finding the project root Project root inference is done by searching for an appropriately-named file (currently manifest.json). Search should generally proceed from the cwd upwards towards root. --- main.go | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/main.go b/main.go index 0a550a0b31..2b945006c5 100644 --- a/main.go +++ b/main.go @@ -8,8 +8,12 @@ import ( "flag" "fmt" "os" + "path/filepath" ) +const ManifestName = "manifest.json" +const LockName = "lock.json" + func main() { flag.Parse() @@ -186,3 +190,41 @@ var getCmd = &command{ -vendor (?) get to workspace or vendor directory `, } + +func findProjectRootFromWD() (string, error) { + path, err := os.Getwd() + if err != nil { + return "", fmt.Errorf("could not get working directory: %s", err) + } + return findProjectRoot(path) +} + +func findProjectRoot(from string) (string, error) { + var f func(string) (string, error) + f = func(dir string) (string, error) { + + fullpath := filepath.Join(dir, ManifestName) + + if _, err := os.Stat(fullpath); err == nil { + return dir, nil + } else if !os.IsNotExist(err) { + // Some err other than non-existence - return that out + return "", err + } + + base := filepath.Dir(dir) + if base == dir { + return "", fmt.Errorf("cannot resolve parent of %s", base) + } + + return f(base) + } + + path, err := f(from) + if err != nil { + return "", fmt.Errorf("error while searching for manifest: %s", err) + } else if path == "" { + return "", fmt.Errorf("could not find manifest in any parent of %s", from) + } + return path, nil +} From ce9692f3839e7db320694d763548a85b93dd49a8 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 18 Oct 2016 11:05:34 -0400 Subject: [PATCH 2/2] Basic tests for root finding --- _testdata/rootfind/manifest.json | 0 _testdata/rootfind/subdir/.gitkeep | 0 main_test.go | 42 ++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 _testdata/rootfind/manifest.json create mode 100644 _testdata/rootfind/subdir/.gitkeep create mode 100644 main_test.go diff --git a/_testdata/rootfind/manifest.json b/_testdata/rootfind/manifest.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/_testdata/rootfind/subdir/.gitkeep b/_testdata/rootfind/subdir/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000000..fc65cb8a2e --- /dev/null +++ b/main_test.go @@ -0,0 +1,42 @@ +package main + +import ( + "os" + "path/filepath" + "testing" +) + +func TestFindRoot(t *testing.T) { + wd, err := os.Getwd() + if err != nil { + t.Fatal(err) + } + + expect := filepath.Join(wd, "_testdata", "rootfind") + + got1, err := findProjectRoot(expect) + if err != nil { + t.Errorf("Unexpected error while finding root: %s", err) + } else if expect != got1 { + t.Errorf("findProjectRoot directly on root dir should have found %s, got %s", expect, got1) + } + + got2, err := findProjectRoot(filepath.Join(expect, "subdir")) + if err != nil { + t.Errorf("Unexpected error while finding root: %s", err) + } else if expect != got2 { + t.Errorf("findProjectRoot on subdir should have found %s, got %s", expect, got2) + } + + got3, err := findProjectRoot(filepath.Join(expect, "nonexistent")) + if err != nil { + t.Errorf("Unexpected error while finding root: %s", err) + } else if expect != got3 { + t.Errorf("findProjectRoot on nonexistent subdir should still work and give %s, got %s", expect, got3) + } + + got4, err := findProjectRoot(filepath.Join(expect, ManifestName)) + if err == nil { + t.Errorf("Should have err'd when trying subdir of file, but returned %s", got4) + } +}