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"
}
}