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

Simplify findProjectRoot #17

Merged
merged 1 commit into from
Nov 30, 2016
Merged
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
2 changes: 1 addition & 1 deletion init.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func runInit(args []string) error {

func isStdLib(i string) bool {
switch i {
case "bytes", "encoding/hex", "encoding/json", "flag", "fmt", "io", "os", "path/filepath", "strings", "text/tabwriter":
case "bytes", "encoding/hex", "errors", "sort", "encoding/json", "flag", "fmt", "io", "os", "path/filepath", "strings", "text/tabwriter":
return true
}
return false
Expand Down
49 changes: 25 additions & 24 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 @@ -57,6 +58,10 @@ var commands = []*command{
// help added here at init time.
}

var (
errProjectNotFound = errors.New("no project could be found")
)

func init() {
// Defeat circular declarations by appending
// this to the list at init time.
Expand Down Expand Up @@ -134,34 +139,27 @@ func findProjectRootFromWD() (string, error) {
return findProjectRoot(path)
}

// search upwards looking for a manifest file until we get to the root of the
// filesystem
func findProjectRoot(from string) (string, error) {
var f func(string) (string, error)
f = func(dir string) (string, error) {

fullpath := filepath.Join(dir, manifestName)
for {
mp := filepath.Join(from, manifestName)

if _, err := os.Stat(fullpath); err == nil {
return dir, nil
} else if !os.IsNotExist(err) {
_, err := os.Stat(mp)
if err == nil {
return from, nil
}
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)
parent := filepath.Dir(from)
if parent == from {
return "", errProjectNotFound
}

return f(base)
from = 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 @@ -210,12 +208,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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is it standard practice to use %v for string placeholders? It works, ofc; I've just always tended to %s.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm interested in hearing what @adg says about this, but %v == "default format", so I generally use it for most things unless I need more control over the format.

}
// Unable to read the manifest file
return nil, err
}
defer mf.Close()

Expand Down