Skip to content
This repository has been archived by the owner on Feb 26, 2019. It is now read-only.

Commit

Permalink
Replace go get, further fix up error handling/reporting
Browse files Browse the repository at this point in the history
Fixes another issue reported in #186 where an entire package is missing.

Don't bother restoring/downloading if already done.
  • Loading branch information
Edward Muller committed Dec 16, 2015
1 parent 03595ab commit 4154dbb
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 32 deletions.
6 changes: 6 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# v38 2015/12/16

* Replace `go get`, further fix up restore error handling/reporting.
* Fixes #186
* Don't bother restoring/downloading if already done.

# v37 2015/12/15

* Change up how download/restore works a little
Expand Down
110 changes: 79 additions & 31 deletions restore.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package main

import (
"errors"
"go/build"
"log"
"os"
"strings"
"path/filepath"

"github.com/tools/godep/Godeps/_workspace/src/golang.org/x/tools/go/vcs"
)

var cmdRestore = &Command{
Expand All @@ -26,8 +29,9 @@ If -d is given, debug output is enabled (you probably don't want this, see -v ab
// 3. Attempt to load all deps as a simple consistency check
func runRestore(cmd *Command, args []string) {
var hadError bool
checkErr := func() {
checkErr := func(s string) {
if hadError {
log.Println(s)
os.Exit(1)
}
}
Expand All @@ -45,7 +49,7 @@ func runRestore(cmd *Command, args []string) {
}
g.Deps[i] = dep
}
checkErr()
checkErr("Error downloading some deps. Aborting restore and check.")
for _, dep := range g.Deps {
verboseln("Restoring dependency (if needed):", dep.ImportPath)
err := restore(dep)
Expand All @@ -54,7 +58,7 @@ func runRestore(cmd *Command, args []string) {
hadError = true
}
}
checkErr()
checkErr("Error restoring some deps. Aborting check.")
for _, dep := range g.Deps {
verboseln("Checking dependency:", dep.ImportPath)
_, err := LoadPackages(dep.ImportPath)
Expand All @@ -67,60 +71,104 @@ func runRestore(cmd *Command, args []string) {
hadError = true
}
}
checkErr()
checkErr("Error checking some deps.")
}

var downloaded = make(map[string]bool)

// download downloads the given dependency.
// 2 Passes: 1) go get -d <pkg>, 2) git pull (if necessary)
func download(dep *Dependency) error {
// make sure pkg exists somewhere in GOPATH

args := []string{"get", "-d"}
if debug {
args = append(args, "-v")
rr, err := vcs.RepoRootForImportPath(dep.ImportPath, debug)
if err != nil {
debugln("Error determining repo root for", dep.ImportPath)
return err
}
ppln("rr", rr)

o, err := runInWithOutput(".", "go", append(args, dep.ImportPath)...)
if strings.Contains(o, "no buildable Go source files") {
// We were able to fetch the repo, but didn't find any code to build
// this can happen when a repo has changed structure or if the dep won't normally
// be built on the current architecture until we implement our own fetcher this
// may be the "best"" we can do.
// TODO: replace go get
err = nil
dep.vcs = cmd[rr.VCS]

// try to find an existing directory in the GOPATHs
for _, gp := range filepath.SplitList(build.Default.GOPATH) {
t := filepath.Join(gp, "src", rr.Root)
fi, err := os.Stat(t)
if err != nil {
continue
}
if fi.IsDir() {
dep.root = t
break
}
}

pkg, err := build.Import(dep.ImportPath, ".", build.FindOnly)
if err != nil {
debugln("Error finding package "+dep.ImportPath+" after go get:", err)
return err
// If none found, just pick the first GOPATH entry (AFAICT that's what go get does)
if dep.root == "" {
dep.root = filepath.Join(filepath.SplitList(build.Default.GOPATH)[0], "src", rr.Root)
}
ppln("dep", dep)

if downloaded[rr.Repo] {
verboseln("Skipping already downloaded repo", rr.Repo)
return nil
}

dep.vcs, err = VCSForImportPath(dep.ImportPath)
fi, err := os.Stat(dep.root)
if err != nil {
dep.vcs, _, err = VCSFromDir(pkg.Dir, pkg.Root)
if err != nil {
return err
if os.IsNotExist(err) {
err := rr.VCS.CreateAtRev(dep.root, rr.Repo, dep.Rev)
debugln("CreatedAtRev", dep.root, rr.Repo, dep.Rev)
if err != nil {
debugln("CreateAtRev error", err)
return err
}
downloaded[rr.Repo] = true
return nil
}
debugln("Error checking repo root for", dep.ImportPath, "at", dep.root, ":", err)
return err
}

if !dep.vcs.exists(pkg.Dir, dep.Rev) {
dep.vcs.vcs.Download(pkg.Dir)
if !fi.IsDir() {
return errors.New("repo root src dir exists, but isn't a directory for " + dep.ImportPath + " at " + dep.root)
}

if !dep.vcs.exists(dep.root, dep.Rev) {
debugln("Updating existing", dep.root)
dep.vcs.vcs.Download(dep.root)
downloaded[rr.Repo] = true
}

debugln("Nothing to download")
return nil
}

var restored = make(map[string]string) // dep.root -> dep.Rev

// restore checks out the given revision.
func restore(dep Dependency) error {
debugln("Restoring:", dep.ImportPath, dep.Rev)
rev, ok := restored[dep.root]
debugln(rev)
debugln(ok)
debugln(dep.root)
if ok {
if rev != dep.Rev {
return errors.New("Wanted to restore rev " + dep.Rev + ", already restored rev " + rev + " for another package in the repo")
}
verboseln("Skipping already restored repo")
return nil
}

debugln("Restoring:", dep.ImportPath, dep.Rev)
pkg, err := build.Import(dep.ImportPath, ".", build.FindOnly)
if err != nil {
// THi should never happen
// This should never happen
debugln("Error finding package "+dep.ImportPath+" on restore:", err)
return err
}

return dep.vcs.RevSync(pkg.Dir, dep.Rev)
err = dep.vcs.RevSync(pkg.Dir, dep.Rev)
if err == nil {
restored[dep.root] = dep.Rev
}
return err
}
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"runtime"
)

const version = 37
const version = 38

var cmdVersion = &Command{
Name: "version",
Expand Down

0 comments on commit 4154dbb

Please sign in to comment.