Skip to content
This repository was archived by the owner on Sep 9, 2020. It is now read-only.

dep: locate project by VCS root instead of manifest file #11

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 31 additions & 28 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package main

import (
"errors"
"flag"
"fmt"
"os"
Expand Down Expand Up @@ -151,34 +152,33 @@ func findProjectRootFromWD() (string, error) {
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)
var (
errProjectNotFound = errors.New("no project could be found")
vcsDirs = []string{".git"} // TODO: add others
)

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
// findProjectRoot walks up the file system tree from the given directory to
// the file system root looking for a known VCS metadata directory (.git, .hg,
// etc). If none found, it returns errProjectNotFound.
func findProjectRoot(dir string) (string, error) {
for {
for _, vcsDir := range vcsDirs {
vcsMeta := filepath.Join(dir, vcsDir)
if _, err := os.Stat(vcsMeta); err == nil {
return dir, nil
} else if !os.IsNotExist(err) {
// Something went wrong trying to read the directory,
// the user should be told of this.
return "", err
}
}

base := filepath.Dir(dir)
if base == dir {
return "", fmt.Errorf("cannot resolve parent of %s", base)
parent := filepath.Dir(dir)
if parent == dir {
// We've hit the root without finding anything.
return "", errProjectNotFound
}

return f(base)
dir = parent
}

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
}

type project struct {
Expand Down Expand Up @@ -227,12 +227,15 @@ func loadProject(path string) (*project, error) {
return nil, fmt.Errorf("could not determine project root - not on GOPATH")
}

mp := filepath.Join(path, manifestName)
mp := filepath.Join(p.absroot, manifestName)
mf, err := os.Open(mp)
if err != nil {
// Should be impossible at this point for the manifest file not to
// exist, so this is some other kind of err
return nil, fmt.Errorf("could not open %s: %s", mp, err)
if os.IsNotExist(err) {
// TODO: list possible solutions? (dep init, cd $project)
return nil, fmt.Errorf("no %v found in project root %v", manifestName, p.absroot)
}
// Unable to read the manifest file.
return nil, err
}
defer mf.Close()

Expand Down
11 changes: 11 additions & 0 deletions main_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"io/ioutil"
"os"
"path/filepath"
"testing"
Expand All @@ -14,6 +15,16 @@ func TestFindRoot(t *testing.T) {

expect := filepath.Join(wd, "_testdata", "rootfind")

// Drop a .git file in the project root.
// We would commit a file named .git,
// but that would confuse git. Silly git.
gitFile := filepath.Join(expect, ".git")
err = ioutil.WriteFile(gitFile, []byte("not really a .git directory"), 0644)
if err != nil {
t.Fatal(err)
}
defer os.Remove(gitFile)

got1, err := findProjectRoot(expect)
if err != nil {
t.Errorf("Unexpected error while finding root: %s", err)
Expand Down
8 changes: 4 additions & 4 deletions manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/sdboyer/gps"
)

func TestReadManifest(t *testing.T) {
func TestreadManifest(t *testing.T) {
const je = `{
"dependencies": {
"github.com/sdboyer/gps": {
Expand Down Expand Up @@ -55,20 +55,20 @@ func TestReadManifest(t *testing.T) {
]
}`

_, err := ReadManifest(strings.NewReader(je))
_, err := readManifest(strings.NewReader(je))
if err == nil {
t.Error("Reading manifest with invalid props should have caused error, but did not")
} else if !strings.Contains(err.Error(), "multiple constraints") {
t.Errorf("Unexpected error %q; expected multiple constraint error", err)
}

m2, err := ReadManifest(strings.NewReader(jg))
m2, err := readManifest(strings.NewReader(jg))
if err != nil {
t.Fatalf("Should have read Manifest correctly, but got err %q", err)
}

c, _ := gps.NewSemverConstraint("^v0.12.0")
em := Manifest{
em := manifest{
Dependencies: map[gps.ProjectRoot]gps.ProjectProperties{
gps.ProjectRoot("github.com/sdboyer/gps"): {
Constraint: c,
Expand Down