zip: add ErrUnrecognizedVCS error, allowing fallback behavior
Add ErrUnrecognizedVCS, which allows calling functions (such as gorelease) to
fallback: usually to CreateFromDir.
Updates golang/go#37413
Change-Id: I846f72b1ce22bfc699e8cd83b28ea4529e73d6e9
Reviewed-on: https://go-review.googlesource.com/c/mod/+/345730
Trust: Jean de Klerk <deklerk@google.com>
Run-TryBot: Jean de Klerk <deklerk@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
diff --git a/zip/zip.go b/zip/zip.go
index 40606d6..ca0f7ad 100644
--- a/zip/zip.go
+++ b/zip/zip.go
@@ -571,8 +571,8 @@
// CreateFromVCS creates a module zip file for module m from the contents of a
// VCS repository stored locally. The zip content is written to w.
//
-// repo must be an absolute path to the base of the repository, such as
-// "/Users/some-user/my-repo".
+// repoRoot must be an absolute path to the base of the repository, such as
+// "/Users/some-user/some-repo".
//
// revision is the revision of the repository to create the zip from. Examples
// include HEAD or SHA sums for git repositories.
@@ -580,32 +580,45 @@
// subdir must be the relative path from the base of the repository, such as
// "sub/dir". To create a zip from the base of the repository, pass an empty
// string.
-func CreateFromVCS(w io.Writer, m module.Version, repo, revision, subdir string) (err error) {
+//
+// If CreateFromVCS returns ErrUnrecognizedVCS, consider falling back to
+// CreateFromDir.
+func CreateFromVCS(w io.Writer, m module.Version, repoRoot, revision, subdir string) (err error) {
defer func() {
if zerr, ok := err.(*zipError); ok {
- zerr.path = repo
+ zerr.path = repoRoot
} else if err != nil {
- err = &zipError{verb: "create zip from version control system", path: repo, err: err}
+ err = &zipError{verb: "create zip from version control system", path: repoRoot, err: err}
}
}()
var filesToCreate []File
switch {
- case isGitRepo(repo):
- files, err := filesInGitRepo(repo, revision, subdir)
+ case isGitRepo(repoRoot):
+ files, err := filesInGitRepo(repoRoot, revision, subdir)
if err != nil {
return err
}
filesToCreate = files
default:
- return fmt.Errorf("%q does not use a recognised version control system", repo)
+ return &UnrecognizedVCSError{RepoRoot: repoRoot}
}
return Create(w, m, filesToCreate)
}
+// UnrecognizedVCSError indicates that no recognized version control system was
+// found in the given directory.
+type UnrecognizedVCSError struct {
+ RepoRoot string
+}
+
+func (e *UnrecognizedVCSError) Error() string {
+ return fmt.Sprintf("could not find a recognized version control system at %q", e.RepoRoot)
+}
+
// filterGitIgnored filters out any files that are git ignored in the directory.
func filesInGitRepo(dir, rev, subdir string) ([]File, error) {
stderr := bytes.Buffer{}
diff --git a/zip/zip_test.go b/zip/zip_test.go
index 93e60fb..810c07a 100644
--- a/zip/zip_test.go
+++ b/zip/zip_test.go
@@ -9,6 +9,7 @@
"bytes"
"crypto/sha256"
"encoding/hex"
+ "errors"
"fmt"
"io"
"io/ioutil"
@@ -1669,8 +1670,15 @@
m := module.Version{Path: "example.com/foo/bar", Version: "v0.0.1"}
- if err := modzip.CreateFromVCS(tmpZip, m, tmpDir, "HEAD", ""); err == nil {
- t.Error("CreateFromVCS: expected error, got nil")
+ err = modzip.CreateFromVCS(tmpZip, m, tmpDir, "HEAD", "")
+ if err == nil {
+ t.Fatal("CreateFromVCS: expected error, got nil")
+ }
+ var gotErr *modzip.UnrecognizedVCSError
+ if !errors.As(err, &gotErr) {
+ t.Errorf("CreateFromVCS: returned error does not unwrap to modzip.ErrUnrecognisedVCS, but expected it to. returned error: %v", err)
+ } else if gotErr.RepoRoot != tmpDir {
+ t.Errorf("CreateFromVCS: returned error has RepoRoot %q, but want %q. returned error: %v", gotErr.RepoRoot, tmpDir, err)
}
}