cmd/go/internal/modfetch/codehost: merge gitrepo

Preparation for implementing other access mechanisms,
which share enough functionality to live in package codehost.
Git will still be a special, somewhat more optimized, case
compared to the other repository types, but they might as well
all be in a single package.

Change-Id: I82cfaa8843daf2c07b558b9ae10901f72b4ad1e2
Reviewed-on: https://go-review.googlesource.com/120997
Reviewed-by: Bryan C. Mills <bcmills@google.com>
diff --git a/vendor/cmd/go/internal/modfetch/gitrepo/fetch.go b/vendor/cmd/go/internal/modfetch/codehost/git.go
similarity index 77%
rename from vendor/cmd/go/internal/modfetch/gitrepo/fetch.go
rename to vendor/cmd/go/internal/modfetch/codehost/git.go
index a4ee7fc..ee616b2 100644
--- a/vendor/cmd/go/internal/modfetch/gitrepo/fetch.go
+++ b/vendor/cmd/go/internal/modfetch/codehost/git.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package gitrepo provides a Git-based implementation of codehost.Repo.
-package gitrepo
+package codehost
 
 import (
 	"bytes"
@@ -18,54 +17,53 @@
 	"sync"
 	"time"
 
-	"cmd/go/internal/modfetch/codehost"
 	"cmd/go/internal/par"
 )
 
-// Repo returns the code repository at the given Git remote reference.
-func Repo(remote string) (codehost.Repo, error) {
-	return newRepoCached(remote, false)
+// GitRepo returns the code repository at the given Git remote reference.
+func GitRepo(remote string) (Repo, error) {
+	return newGitRepoCached(remote, false)
 }
 
-// LocalRepo is like Repo but accepts both Git remote references
+// LocalGitRepo is like Repo but accepts both Git remote references
 // and paths to repositories on the local file system.
-func LocalRepo(remote string) (codehost.Repo, error) {
-	return newRepoCached(remote, true)
+func LocalGitRepo(remote string) (Repo, error) {
+	return newGitRepoCached(remote, true)
 }
 
-const workDirType = "git2"
+const gitWorkDirType = "git2"
 
-var repoCache par.Cache
+var gitRepoCache par.Cache
 
-func newRepoCached(remote string, localOK bool) (codehost.Repo, error) {
+func newGitRepoCached(remote string, localOK bool) (Repo, error) {
 	type key struct {
 		remote  string
 		localOK bool
 	}
 	type cached struct {
-		repo codehost.Repo
+		repo Repo
 		err  error
 	}
 
-	c := repoCache.Do(key{remote, localOK}, func() interface{} {
-		repo, err := newRepo(remote, localOK)
+	c := gitRepoCache.Do(key{remote, localOK}, func() interface{} {
+		repo, err := newGitRepo(remote, localOK)
 		return cached{repo, err}
 	}).(cached)
 
 	return c.repo, c.err
 }
 
-func newRepo(remote string, localOK bool) (codehost.Repo, error) {
-	r := &repo{remote: remote}
+func newGitRepo(remote string, localOK bool) (Repo, error) {
+	r := &gitRepo{remote: remote}
 	if strings.Contains(remote, "://") {
 		// This is a remote path.
-		dir, err := codehost.WorkDir(workDirType, r.remote)
+		dir, err := WorkDir(gitWorkDirType, r.remote)
 		if err != nil {
 			return nil, err
 		}
 		r.dir = dir
 		if _, err := os.Stat(filepath.Join(dir, "objects")); err != nil {
-			if _, err := codehost.Run(dir, "git", "init", "--bare"); err != nil {
+			if _, err := Run(dir, "git", "init", "--bare"); err != nil {
 				os.RemoveAll(dir)
 				return nil, err
 			}
@@ -73,7 +71,7 @@
 			// but this lets us say git fetch origin instead, which
 			// is a little nicer. More importantly, using a named remote
 			// avoids a problem with Git LFS. See golang.org/issue/25605.
-			if _, err := codehost.Run(dir, "git", "remote", "add", "origin", r.remote); err != nil {
+			if _, err := Run(dir, "git", "remote", "add", "origin", r.remote); err != nil {
 				os.RemoveAll(dir)
 				return nil, err
 			}
@@ -103,7 +101,7 @@
 	return r, nil
 }
 
-type repo struct {
+type gitRepo struct {
 	remote string
 	local  bool
 	dir    string
@@ -131,11 +129,11 @@
 // loadLocalTags loads tag references from the local git cache
 // into the map r.localTags.
 // Should only be called as r.localTagsOnce.Do(r.loadLocalTags).
-func (r *repo) loadLocalTags() {
+func (r *gitRepo) loadLocalTags() {
 	// The git protocol sends all known refs and ls-remote filters them on the client side,
 	// so we might as well record both heads and tags in one shot.
 	// Most of the time we only care about tags but sometimes we care about heads too.
-	out, err := codehost.Run(r.dir, "git", "tag", "-l")
+	out, err := Run(r.dir, "git", "tag", "-l")
 	if err != nil {
 		return
 	}
@@ -150,11 +148,11 @@
 
 // loadRefs loads heads and tags references from the remote into the map r.refs.
 // Should only be called as r.refsOnce.Do(r.loadRefs).
-func (r *repo) loadRefs() {
+func (r *gitRepo) loadRefs() {
 	// The git protocol sends all known refs and ls-remote filters them on the client side,
 	// so we might as well record both heads and tags in one shot.
 	// Most of the time we only care about tags but sometimes we care about heads too.
-	out, err := codehost.Run(r.dir, "git", "ls-remote", "-q", r.remote)
+	out, err := Run(r.dir, "git", "ls-remote", "-q", r.remote)
 	if err != nil {
 		r.refsErr = err
 		return
@@ -178,7 +176,7 @@
 	}
 }
 
-func (r *repo) Tags(prefix string) ([]string, error) {
+func (r *gitRepo) Tags(prefix string) ([]string, error) {
 	r.refsOnce.Do(r.loadRefs)
 	if r.refsErr != nil {
 		return nil, r.refsErr
@@ -199,7 +197,7 @@
 	return tags, nil
 }
 
-func (r *repo) Latest() (*codehost.RevInfo, error) {
+func (r *gitRepo) Latest() (*RevInfo, error) {
 	r.refsOnce.Do(r.loadRefs)
 	if r.refsErr != nil {
 		return nil, r.refsErr
@@ -214,7 +212,7 @@
 // for use when the server requires giving a ref instead of a hash.
 // There may be multiple ref names for a given hash,
 // in which case this returns some name - it doesn't matter which.
-func (r *repo) findRef(hash string) (ref string, ok bool) {
+func (r *gitRepo) findRef(hash string) (ref string, ok bool) {
 	r.refsOnce.Do(r.loadRefs)
 	for ref, h := range r.refs {
 		if h == hash {
@@ -241,13 +239,13 @@
 
 // stat stats the given rev in the local repository,
 // or else it fetches more info from the remote repository and tries again.
-func (r *repo) stat(rev string) (*codehost.RevInfo, error) {
+func (r *gitRepo) stat(rev string) (*RevInfo, error) {
 	if r.local {
 		return r.statLocal(rev, rev)
 	}
 
 	// Fast path: maybe rev is a hash we already have locally.
-	if len(rev) >= minHashDigits && len(rev) <= 40 && codehost.AllHex(rev) {
+	if len(rev) >= minHashDigits && len(rev) <= 40 && AllHex(rev) {
 		if info, err := r.statLocal(rev, rev); err == nil {
 			return info, nil
 		}
@@ -277,7 +275,7 @@
 		ref = "HEAD"
 		hash = r.refs[ref]
 		rev = hash // Replace rev, because meaning of HEAD can change.
-	} else if len(rev) >= minHashDigits && len(rev) <= 40 && codehost.AllHex(rev) {
+	} else if len(rev) >= minHashDigits && len(rev) <= 40 && AllHex(rev) {
 		// At the least, we have a hash prefix we can look up after the fetch below.
 		// Maybe we can map it to a full hash using the known refs.
 		prefix := rev
@@ -304,7 +302,7 @@
 	}
 
 	// Protect r.fetchLevel and the "fetch more and more" sequence.
-	// TODO(rsc): Add codehost.LockDir and use it for protecting that
+	// TODO(rsc): Add LockDir and use it for protecting that
 	// sequence, so that multiple processes don't collide in their
 	// git commands.
 	r.mu.Lock()
@@ -324,7 +322,7 @@
 			ref = hash
 			refspec = hash
 		}
-		_, err := codehost.Run(r.dir, "git", "fetch", "-f", "--depth=1", r.remote, refspec)
+		_, err := Run(r.dir, "git", "fetch", "-f", "--depth=1", r.remote, refspec)
 		if err == nil {
 			return r.statLocal(rev, ref)
 		}
@@ -348,7 +346,7 @@
 		if len(unshallowFlag) > 0 {
 			protoFlag = []string{"-c", "protocol.version=0"}
 		}
-		if _, err := codehost.Run(r.dir, "git", protoFlag, "fetch", unshallowFlag, "-f", r.remote, "refs/heads/*:refs/heads/*", "refs/tags/*:refs/tags/*"); err != nil {
+		if _, err := Run(r.dir, "git", protoFlag, "fetch", unshallowFlag, "-f", r.remote, "refs/heads/*:refs/heads/*", "refs/tags/*:refs/tags/*"); err != nil {
 			return nil, err
 		}
 	}
@@ -356,12 +354,12 @@
 	return r.statLocal(rev, rev)
 }
 
-// statLocal returns a codehost.RevInfo describing rev in the local git repository.
+// statLocal returns a RevInfo describing rev in the local git repository.
 // It uses version as info.Version.
-func (r *repo) statLocal(version, rev string) (*codehost.RevInfo, error) {
-	out, err := codehost.Run(r.dir, "git", "log", "-n1", "--format=format:%H %ct", rev)
+func (r *gitRepo) statLocal(version, rev string) (*RevInfo, error) {
+	out, err := Run(r.dir, "git", "log", "-n1", "--format=format:%H %ct", rev)
 	if err != nil {
-		if codehost.AllHex(rev) {
+		if AllHex(rev) {
 			return nil, fmt.Errorf("unknown hash %s", rev)
 		}
 		return nil, fmt.Errorf("unknown revision %s", rev)
@@ -379,18 +377,18 @@
 		return nil, fmt.Errorf("invalid time from git log: %q", out)
 	}
 
-	info := &codehost.RevInfo{
+	info := &RevInfo{
 		Name:    hash,
-		Short:   codehost.ShortenSHA1(hash),
+		Short:   ShortenSHA1(hash),
 		Time:    time.Unix(t, 0).UTC(),
 		Version: version,
 	}
 	return info, nil
 }
 
-func (r *repo) Stat(rev string) (*codehost.RevInfo, error) {
+func (r *gitRepo) Stat(rev string) (*RevInfo, error) {
 	type cached struct {
-		info *codehost.RevInfo
+		info *RevInfo
 		err  error
 	}
 	c := r.statCache.Do(rev, func() interface{} {
@@ -400,20 +398,20 @@
 	return c.info, c.err
 }
 
-func (r *repo) ReadFile(rev, file string, maxSize int64) ([]byte, error) {
+func (r *gitRepo) ReadFile(rev, file string, maxSize int64) ([]byte, error) {
 	// TODO: Could use git cat-file --batch.
 	info, err := r.Stat(rev) // download rev into local git repo
 	if err != nil {
 		return nil, err
 	}
-	out, err := codehost.Run(r.dir, "git", "cat-file", "blob", info.Name+":"+file)
+	out, err := Run(r.dir, "git", "cat-file", "blob", info.Name+":"+file)
 	if err != nil {
 		return nil, os.ErrNotExist
 	}
 	return out, nil
 }
 
-func (r *repo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, actualSubdir string, err error) {
+func (r *gitRepo) ReadZip(rev, subdir string, maxSize int64) (zip io.ReadCloser, actualSubdir string, err error) {
 	// TODO: Use maxSize or drop it.
 	args := []string{}
 	if subdir != "" {
@@ -423,9 +421,9 @@
 	if err != nil {
 		return nil, "", err
 	}
-	archive, err := codehost.Run(r.dir, "git", "archive", "--format=zip", "--prefix=prefix/", info.Name, args)
+	archive, err := Run(r.dir, "git", "archive", "--format=zip", "--prefix=prefix/", info.Name, args)
 	if err != nil {
-		if bytes.Contains(err.(*codehost.RunError).Stderr, []byte("did not match any files")) {
+		if bytes.Contains(err.(*RunError).Stderr, []byte("did not match any files")) {
 			return nil, "", os.ErrNotExist
 		}
 		return nil, "", err
diff --git a/vendor/cmd/go/internal/modfetch/gitrepo/fetch_test.go b/vendor/cmd/go/internal/modfetch/codehost/git_test.go
similarity index 91%
rename from vendor/cmd/go/internal/modfetch/gitrepo/fetch_test.go
rename to vendor/cmd/go/internal/modfetch/codehost/git_test.go
index 99af883..a2faa8e 100644
--- a/vendor/cmd/go/internal/modfetch/gitrepo/fetch_test.go
+++ b/vendor/cmd/go/internal/modfetch/codehost/git_test.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package gitrepo
+package codehost
 
 import (
 	"archive/zip"
@@ -18,8 +18,6 @@
 	"strings"
 	"testing"
 	"time"
-
-	"cmd/go/internal/modfetch/codehost"
 )
 
 func TestMain(m *testing.M) {
@@ -43,7 +41,7 @@
 		log.Fatal(err)
 	}
 	defer os.RemoveAll(dir)
-	codehost.WorkRoot = dir
+	WorkRoot = dir
 
 	if testenv.HasExternalNetwork() && testenv.HasExec() {
 		// Clone gitrepo1 into a local directory.
@@ -51,10 +49,10 @@
 		// then git starts up all the usual protocol machinery,
 		// which will let us test remote git archive invocations.
 		localGitRepo = filepath.Join(dir, "gitrepo2")
-		if _, err := codehost.Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
+		if _, err := Run("", "git", "clone", "--mirror", gitrepo1, localGitRepo); err != nil {
 			log.Fatal(err)
 		}
-		if _, err := codehost.Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
+		if _, err := Run(localGitRepo, "git", "config", "daemon.uploadarch", "true"); err != nil {
 			log.Fatal(err)
 		}
 	}
@@ -62,11 +60,11 @@
 	return m.Run()
 }
 
-func testRepo(remote string) (codehost.Repo, error) {
+func testGitRepo(remote string) (Repo, error) {
 	if remote == "localGitRepo" {
 		remote = "file://" + filepath.ToSlash(localGitRepo)
 	}
-	return LocalRepo(remote)
+	return LocalGitRepo(remote)
 }
 
 var tagsTests = []struct {
@@ -81,13 +79,13 @@
 	{gitrepo1, "2", []string{}},
 }
 
-func TestTags(t *testing.T) {
+func TestGitTags(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
 
 	for _, tt := range tagsTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testGitRepo(tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -109,11 +107,11 @@
 
 var latestTests = []struct {
 	repo string
-	info *codehost.RevInfo
+	info *RevInfo
 }{
 	{
 		gitrepo1,
-		&codehost.RevInfo{
+		&RevInfo{
 			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
 			Short:   "ede458df7cd0",
 			Version: "ede458df7cd0fdca520df19a33158086a8a68e81",
@@ -122,13 +120,13 @@
 	},
 }
 
-func TestLatest(t *testing.T) {
+func TestGitLatest(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
 
 	for _, tt := range latestTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testGitRepo(tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -175,13 +173,13 @@
 	},
 }
 
-func TestReadFile(t *testing.T) {
+func TestGitReadFile(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
 
 	for _, tt := range readFileTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testGitRepo(tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -305,13 +303,13 @@
 	size int64
 }
 
-func TestReadZip(t *testing.T) {
+func TestGitReadZip(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
 
 	for _, tt := range readZipTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testGitRepo(tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
@@ -373,12 +371,12 @@
 	repo string
 	rev  string
 	err  string
-	info *codehost.RevInfo
+	info *RevInfo
 }{
 	{
 		repo: gitrepo1,
 		rev:  "HEAD",
-		info: &codehost.RevInfo{
+		info: &RevInfo{
 			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
 			Short:   "ede458df7cd0",
 			Version: "ede458df7cd0fdca520df19a33158086a8a68e81",
@@ -388,7 +386,7 @@
 	{
 		repo: gitrepo1,
 		rev:  "v2", // branch
-		info: &codehost.RevInfo{
+		info: &RevInfo{
 			Name:    "9d02800338b8a55be062c838d1f02e0c5780b9eb",
 			Short:   "9d02800338b8",
 			Version: "9d02800338b8a55be062c838d1f02e0c5780b9eb",
@@ -398,7 +396,7 @@
 	{
 		repo: gitrepo1,
 		rev:  "v2.3.4", // badly-named branch (semver should be a tag)
-		info: &codehost.RevInfo{
+		info: &RevInfo{
 			Name:    "76a00fb249b7f93091bc2c89a789dab1fc1bc26f",
 			Short:   "76a00fb249b7",
 			Version: "76a00fb249b7f93091bc2c89a789dab1fc1bc26f",
@@ -408,7 +406,7 @@
 	{
 		repo: gitrepo1,
 		rev:  "v2.3", // badly-named tag (we only respect full semver v2.3.0)
-		info: &codehost.RevInfo{
+		info: &RevInfo{
 			Name:    "76a00fb249b7f93091bc2c89a789dab1fc1bc26f",
 			Short:   "76a00fb249b7",
 			Version: "v2.3",
@@ -418,7 +416,7 @@
 	{
 		repo: gitrepo1,
 		rev:  "v1.2.3", // tag
-		info: &codehost.RevInfo{
+		info: &RevInfo{
 			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
 			Short:   "ede458df7cd0",
 			Version: "v1.2.3",
@@ -428,7 +426,7 @@
 	{
 		repo: gitrepo1,
 		rev:  "ede458df", // hash prefix in refs
-		info: &codehost.RevInfo{
+		info: &RevInfo{
 			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
 			Short:   "ede458df7cd0",
 			Version: "ede458df7cd0fdca520df19a33158086a8a68e81",
@@ -438,7 +436,7 @@
 	{
 		repo: gitrepo1,
 		rev:  "97f6aa59", // hash prefix not in refs
-		info: &codehost.RevInfo{
+		info: &RevInfo{
 			Name:    "97f6aa59c81c623494825b43d39e445566e429a4",
 			Short:   "97f6aa59c81c",
 			Version: "97f6aa59c81c623494825b43d39e445566e429a4",
@@ -448,7 +446,7 @@
 	{
 		repo: gitrepo1,
 		rev:  "v1.2.4-annotated", // annotated tag uses unwrapped commit hash
-		info: &codehost.RevInfo{
+		info: &RevInfo{
 			Name:    "ede458df7cd0fdca520df19a33158086a8a68e81",
 			Short:   "ede458df7cd0",
 			Version: "v1.2.4-annotated",
@@ -462,13 +460,13 @@
 	},
 }
 
-func TestStat(t *testing.T) {
+func TestGitStat(t *testing.T) {
 	testenv.MustHaveExternalNetwork(t)
 	testenv.MustHaveExec(t)
 
 	for _, tt := range statTests {
 		f := func(t *testing.T) {
-			r, err := testRepo(tt.repo)
+			r, err := testGitRepo(tt.repo)
 			if err != nil {
 				t.Fatal(err)
 			}
diff --git a/vendor/cmd/go/internal/modfetch/repo.go b/vendor/cmd/go/internal/modfetch/repo.go
index 2de9225..b91790c 100644
--- a/vendor/cmd/go/internal/modfetch/repo.go
+++ b/vendor/cmd/go/internal/modfetch/repo.go
@@ -14,7 +14,6 @@
 	"cmd/go/internal/cfg"
 	"cmd/go/internal/get"
 	"cmd/go/internal/modfetch/codehost"
-	"cmd/go/internal/modfetch/gitrepo"
 	"cmd/go/internal/module"
 	"cmd/go/internal/par"
 	"cmd/go/internal/semver"
@@ -236,7 +235,7 @@
 	default:
 		return nil, fmt.Errorf("lookup %s: unknown VCS %s %s", rr.Root, rr.VCS, rr.Repo)
 	case "git":
-		return gitrepo.Repo(rr.Repo)
+		return codehost.GitRepo(rr.Repo)
 		// TODO: "hg", "svn", "bzr", "fossil"
 	}
 }