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>
This commit is contained in:
Jean de Klerk 2021-08-27 16:35:50 -06:00
Родитель 4029241eb1
Коммит 1b1db11ec8
2 изменённых файлов: 31 добавлений и 10 удалений

Просмотреть файл

@ -571,8 +571,8 @@ func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) {
// 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 @@ func CreateFromDir(w io.Writer, m module.Version, dir string) (err error) {
// 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{}

Просмотреть файл

@ -9,6 +9,7 @@ import (
"bytes"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"io"
"io/ioutil"
@ -1669,8 +1670,15 @@ var A = 5
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)
}
}