diff --git a/Makefile b/Makefile index 4d727e412..389c3eb0b 100644 --- a/Makefile +++ b/Makefile @@ -103,6 +103,7 @@ test-unit-go: cd sdk/v3 && \ go test \ -v \ + -tags testUnit \ -timeout=60s \ -race \ -coverprofile=coverage.txt \ @@ -111,6 +112,7 @@ test-unit-go: cd ../../v2 && \ go test \ -v \ + -tags testUnit \ -timeout=60s \ -race \ -coverprofile=coverage.txt \ diff --git a/golangci.yaml b/golangci.yaml index 33b75f62c..0bd0c3f4a 100644 --- a/golangci.yaml +++ b/golangci.yaml @@ -1,7 +1,8 @@ run: concurrency: 1 deadline: 10m - skip-files: + build-tags: + - lint linters: disable-all: true diff --git a/v2/git-initializer-windows/Dockerfile b/v2/git-initializer-windows/Dockerfile index 717a6924a..ba3acd4e0 100644 --- a/v2/git-initializer-windows/Dockerfile +++ b/v2/git-initializer-windows/Dockerfile @@ -1,24 +1,59 @@ -FROM golang:1.17.2-windowsservercore-1809 as builder +# escape=` -ARG VERSION -ARG COMMIT -ENV CGO_ENABLED=0 +FROM brigadecore/win-go-tools:v0.2.0 as builder -WORKDIR /src -COPY sdk/ sdk/ -WORKDIR /src/v2 -COPY v2/git-initializer/ git-initializer/ -COPY v2/internal/ internal/ -COPY v2/go.mod go.mod -COPY v2/go.sum go.sum +# As of this writing, pacman installs a newer libgit2 than we are able to use. +# Here, we download and install an older version. +RUN curl ` + -L ` + https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-libgit2-1.2.0-3-any.pkg.tar.zst ` + -o C:\windows\temp/libgit2.pkg.tar.zst ` + && bash -l -c "pacman --noconfirm -U /c/windows/temp/libgit2.pkg.tar.zst" -RUN go build \ - -o ../bin/git-initializer.exe \ - -ldflags \"-w -X github.com/brigadecore/brigade-foundations/version.version=$env:VERSION -X github.com/brigadecore/brigade-foundations/version.commit=$env:COMMIT\" \ - ./git-initializer +WORKDIR C:\\msys64\\brigade +COPY sdk\\ sdk\\ +WORKDIR C:\\msys64\\brigade\\v2 +COPY v2\\go.mod go.mod +COPY v2\\go.sum go.sum +RUN bash -l -c " ` + cd /brigade/v2 ` + && PATH=$PATH:/mingw64/bin ` + GOROOT=/mingw64/lib/go ` + go mod download ` + " +COPY v2\\git-initializer\\ git-initializer\\ +COPY v2\\internal\\ internal\\ -FROM mcr.microsoft.com/windows/nanoserver:1809 +# The `-tags static,system_libgit2` specified below instruct git2go on how to +# locate libgit2. It does NOT imply our binary is statically linked -- in fact, +# it is not. In theory, that can be accomplished by including +# `-extldflags 'static'` in the `-ldflags`, but we've had no luck getting that +# to work. +RUN bash -l -c " ` + cd /brigade/v2 ` + && PATH=$PATH:/mingw64/bin ` + GOROOT=/mingw64/lib/go ` + go build ` + -tags static,system_libgit2 ` + -ldflags \"-w -X github.com/brigadecore/brigade-foundations/version.version=$VERSION -X github.com/brigadecore/brigade-foundations/version.commit=$COMMIT\" ` + -o ../bin/git-initializer.exe ` + ./git-initializer ` + " -COPY --from=builder /src/bin/ /brigade/bin/ +ENTRYPOINT [ "C:\\msys64\\brigade\\bin\\git-initializer.exe" ] -ENTRYPOINT ["/brigade/bin/git-initializer.exe"] +FROM mcr.microsoft.com/windows/nanoserver:1809 AS final + +USER ContainerAdministrator + +# Note that because we were unable to produce a statically-linked binary, we +# depend on a number of .dlls from the builder image, so we just copy them +# all over and add them to the path. +COPY --from=builder C:\\msys64\\mingw64\\bin\\ C:\\mingw64\\bin\\ +RUN setx /M PATH "%PATH%;C:\mingw64\bin" + +COPY --from=builder C:\\msys64\\brigade\\bin\\ C:\\brigade\\bin\\ + +USER ContainerUser + +ENTRYPOINT ["C:\\brigade\\bin\\git-initializer.exe"] diff --git a/v2/git-initializer/Dockerfile b/v2/git-initializer/Dockerfile index c04f60e3d..c3a6c934f 100644 --- a/v2/git-initializer/Dockerfile +++ b/v2/git-initializer/Dockerfile @@ -1,10 +1,7 @@ -FROM --platform=$BUILDPLATFORM brigadecore/go-tools:v0.9.0 as builder +FROM brigadecore/go-libgit2:v0.1.0 as builder ARG VERSION ARG COMMIT -ARG TARGETOS -ARG TARGETARCH -ENV CGO_ENABLED=0 WORKDIR /src COPY sdk/ sdk/ @@ -15,12 +12,15 @@ RUN go mod download COPY v2/git-initializer/ git-initializer/ COPY v2/internal/ internal/ -RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go build \ +# Despite CGO being involved, this builds a statically linked binary +RUN go build \ + -tags static,system_libgit2 \ -o ../bin/git-initializer \ - -ldflags "-w -X github.com/brigadecore/brigade-foundations/version.version=$VERSION -X github.com/brigadecore/brigade-foundations/version.commit=$COMMIT" \ + -ldflags "-extldflags '-static -lgcrypt -lgpg-error' -w -X github.com/brigadecore/brigade-foundations/version.version=$VERSION -X github.com/brigadecore/brigade-foundations/version.commit=$COMMIT" \ ./git-initializer -FROM gcr.io/distroless/static:nonroot as final +# Note: Cannot use gcr.io/distroless/static:nonroot because we still need glibc +FROM gcr.io/distroless/base:nonroot as final COPY --from=builder /src/bin/ /brigade/bin/ diff --git a/v2/git-initializer/credentials.go b/v2/git-initializer/credentials.go new file mode 100644 index 000000000..fd22ff0ee --- /dev/null +++ b/v2/git-initializer/credentials.go @@ -0,0 +1,82 @@ +//go:build !testUnit && !lint +// +build !testUnit,!lint + +// We exclude this file from unit tests and linting because it cannot be +// compiled without CGO and a specific version of libgit2 pre-installed. To keep +// our linting and unit tests lightweight, those are complications we'd like to +// avoid. We'll live without the linting and test this well with integration +// tests. + +package main + +import ( + git "github.com/libgit2/git2go/v32" + "github.com/pkg/errors" + "golang.org/x/crypto/ssh" +) + +// getCredentialsCallback extracts credentials, if any, from project secrets in +// the provided map and returns a callback function. If no credentials are found +// in the secrets, a nil function pointer is returned. +func getCredentialsCallback( + secrets map[string]string, +) (git.CredentialsCallback, error) { + // We'll check the project's secrets first for a well-known key that we could + // expect contains a private SSH key. If we find that, we'll use it. + if privateKey, ok := secrets["gitSSHKey"]; ok { + var signer ssh.Signer + var err error + // The private key may or may not be protected by a passphrase... + if keyPassStr, ok := secrets["gitSSHKeyPassword"]; ok { + // Auth using key and passphrase + signer, err = ssh.ParsePrivateKeyWithPassphrase( + []byte(privateKey), + []byte(keyPassStr), + ) + } else { + // Auth using a key without a passphrase + signer, err = ssh.ParsePrivateKey([]byte(privateKey)) + } + if err != nil { + return nil, errors.Wrap( + err, + `error parsing private SSH key specified by secret "gitSSHKey"`, + ) + } + return func( + string, + string, + git.CredentialType, + ) (*git.Credential, error) { + return git.NewCredentialSSHKeyFromSigner("git", signer) + }, nil + } + + // Check the project's secrets for a well-known key that we could expect + // contains a password or token. + if password, ok := secrets["gitPassword"]; ok { + // There may or may not be a username associated with the password. It + // really depends on who hosts the repository we're cloning from. GitHub, + // for instance, expects the username to be any non-empty string (and the + // password to be a personal access token), while Bitbucket expects a valid + // username (and the password to be an app password). + username := secrets["gitUsername"] + // Ultimately, the username and password are used with basic auth and an + // empty username isn't allowed, so if no username was specified (e.g. for a + // repo hosted on GitHub), just use the string "git" as the username. + if username == "" { + username = "git" + } + return func( + string, + string, + git.CredentialType, + ) (*git.Credential, error) { + // Basic auth + return git.NewCredentialUserpassPlaintext(username, password) + }, nil + } + + // No credentials found + return nil, nil +} diff --git a/v2/git-initializer/events.go b/v2/git-initializer/events.go new file mode 100644 index 000000000..03d79b30b --- /dev/null +++ b/v2/git-initializer/events.go @@ -0,0 +1,36 @@ +package main + +import ( + "encoding/json" + "io/ioutil" + + "github.com/brigadecore/brigade/sdk/v3" + "github.com/pkg/errors" +) + +// event is a custom representation of a Brigade event that matches what the +// API server provides to the git-initializer. +type event struct { + Project struct { + Secrets map[string]string `json:"secrets"` + } `json:"project"` + Worker struct { + Git *sdk.GitConfig `json:"git"` + } `json:"worker"` +} + +// getEvent loads an event from the indicated path on the file system. +func getEvent(path string) (event, error) { + evt := event{} + eventPath := "/var/event/event.json" + data, err := ioutil.ReadFile(eventPath) + if err != nil { + return evt, + errors.Wrapf(err, "error reading event from file %q", eventPath) + } + return evt, errors.Wrapf( + json.Unmarshal(data, &evt), + "error reading event from file %q", + eventPath, + ) +} diff --git a/v2/git-initializer/main.go b/v2/git-initializer/main.go index 0206d1680..1ec0f566a 100644 --- a/v2/git-initializer/main.go +++ b/v2/git-initializer/main.go @@ -1,35 +1,19 @@ +//go:build !testUnit && !lint +// +build !testUnit,!lint + +// We exclude this file from unit tests and linting because it cannot be +// compiled without CGO and a specific version of libgit2 pre-installed. To keep +// our linting and unit tests lightweight, those are complications we'd like to +// avoid. We'll live without the linting and test this well with integration +// tests. + package main import ( - "context" - "encoding/json" - "fmt" - "io/ioutil" "log" - "os" - "path/filepath" - "time" - "github.com/brigadecore/brigade-foundations/retries" "github.com/brigadecore/brigade-foundations/version" - "github.com/brigadecore/brigade/sdk/v3" - "github.com/go-git/go-billy/v5/osfs" - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/config" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/cache" - "github.com/go-git/go-git/v5/plumbing/transport" - "github.com/go-git/go-git/v5/plumbing/transport/http" - gitssh "github.com/go-git/go-git/v5/plumbing/transport/ssh" - "github.com/go-git/go-git/v5/storage/filesystem" - "github.com/pkg/errors" - "golang.org/x/crypto/ssh" -) - -const ( - workspace = "/var/vcs" - maxRetryCount = 5 - maxBackoff = 5 * time.Second + git "github.com/libgit2/git2go/v32" ) func main() { @@ -39,333 +23,56 @@ func main() { version.Commit(), ) - if err := gitCheckout(); err != nil { - fmt.Printf("\n%s\n\n", err) - os.Exit(1) - } -} - -// nolint: gocyclo -func gitCheckout() error { - eventPath := "/var/event/event.json" - data, err := ioutil.ReadFile(eventPath) + event, err := getEvent("/var/event/event.json") if err != nil { - return errors.Wrapf(err, "unable read the event file %q", eventPath) + log.Fatal(err) } - - var event struct { - Project struct { - Secrets map[string]string `json:"secrets"` - } `json:"project"` - Worker struct { - Git *sdk.GitConfig `json:"git"` - } `json:"worker"` - } - err = json.Unmarshal(data, &event) - if err != nil { - return errors.Wrap(err, "error unmarshaling the event") - } - - // Extract git config gitConfig := event.Worker.Git if gitConfig == nil { - return fmt.Errorf("git config from %q is empty", eventPath) - } - - // Setup Auth - var auth transport.AuthMethod - - // TODO: Check for SSH Cert - // (see https://github.com/brigadecore/brigade/pull/1008) - - // Check for SSH Key - if privateKey, ok := event.Project.Secrets["gitSSHKey"]; ok { - var publicKeys *gitssh.PublicKeys - publicKeys, err = gitssh.NewPublicKeys( - "git", - []byte(privateKey), - event.Project.Secrets["gitSSHKeyPassword"], - ) - if err != nil { - return errors.Wrapf( - err, - "error configuring authentication for remote with URL %s", - event.Worker.Git.CloneURL, - ) - } - // The following avoids: - // "unable to find any valid known_hosts file, - // set SSH_KNOWN_HOSTS env variable" - publicKeys.HostKeyCallback = ssh.InsecureIgnoreHostKey() // nolint: gosec - auth = publicKeys - } else if password, ok := event.Project.Secrets["gitPassword"]; ok { - username := event.Project.Secrets["gitUsername"] - if username == "" { - username = "git" - } - auth = &http.BasicAuth{ - Username: username, - Password: password, - } + log.Fatal("event has no git config") } - var worktree *git.Worktree - if event.Worker.Git.Commit == "" && event.Worker.Git.Ref == "" { - worktree, err = simpleCheckout(gitConfig.CloneURL, auth) - } else { - worktree, err = complexCheckout( - gitConfig.CloneURL, - event.Worker.Git.Commit, - event.Worker.Git.Ref, - auth, - ) - } + credentialsCallback, err := getCredentialsCallback(event.Project.Secrets) if err != nil { - return err - } - - // Initialize submodules if configured to do so - if event.Worker.Git.InitSubmodules { - err = initSubmodules(worktree) + log.Fatal(err) } - return err -} -func simpleCheckout( - cloneURL string, - auth transport.AuthMethod, -) (*git.Worktree, error) { - // This will reliably get whichever branch is designated as the default. - repo, err := git.PlainClone( - workspace, - false, + const workspacePath = "/var/vcs" + log.Printf("cloning repository from %q into %q", + gitConfig.CloneURL, + workspacePath, + ) + repo, err := git.Clone( + event.Worker.Git.CloneURL, + workspacePath, &git.CloneOptions{ - URL: cloneURL, - Auth: auth, - Progress: os.Stdout, + FetchOptions: git.FetchOptions{ + RemoteCallbacks: git.RemoteCallbacks{ + CertificateCheckCallback: func(*git.Certificate, bool, string) error { + return nil + }, + CredentialsCallback: credentialsCallback, + }, + }, }, ) if err != nil { - return nil, errors.Wrapf(err, "error cloning repository at %s", cloneURL) - } - worktree, err := repo.Worktree() - return worktree, errors.Wrapf( - err, - "error getting worktree from repository cloned from %s", - cloneURL, - ) -} - -func complexCheckout( - cloneURL string, - commit string, - ref string, - auth transport.AuthMethod, -) (*git.Worktree, error) { - // Prioritize using Commit; alternatively try Ref - commitRef := commit - if commitRef == "" { - commitRef = ref // This will never be empty - } - fullRef := plumbing.NewReferenceFromStrings(commitRef, commitRef) - refSpec := config.RefSpec( - fmt.Sprintf("+%s:%s", fullRef.Name(), fullRef.Name())) - - // Initialize an empty repository with an empty working tree - gitStorage := filesystem.NewStorage( - osfs.New(filepath.Join(workspace, ".git")), - cache.NewObjectLRUDefault(), - ) - - repo, err := git.Init(gitStorage, osfs.New(workspace)) - if err != nil { - return nil, errors.Wrapf( + log.Fatalf( + "error cloning repository from %q into %q: %s", + gitConfig.CloneURL, + workspacePath, err, - "error initializing git repository at %s", - workspace, ) } + defer repo.Free() - const remoteName = "origin" - // If we're not dealing with an exact commit, and we don't already have a - // full reference, list the remote refs to build out a full, updated refspec - // - // For example, we might be supplied with the tag "v0.1.0", but if we use - // this directly, we'll get: couldn't find remote ref "v0.1.0" - // So we need to find the full remote ref; in this case, "refs/tags/v0.1.0" - if commit == "" && !isFullReference(fullRef.Name()) { - // Create a new remote for the purposes of listing remote refs and finding - // the full ref we want - remoteConfig := &config.RemoteConfig{ - Name: remoteName, - URLs: []string{cloneURL}, - Fetch: []config.RefSpec{refSpec}, - } - rem := git.NewRemote(gitStorage, remoteConfig) - - // List remote refs - var refs []*plumbing.Reference - refs, err = rem.List(&git.ListOptions{Auth: auth}) - if err != nil { - return nil, errors.Wrap(err, "error listing remotes") - } - - // Filter the list of refs and only keep the full ref matching our commitRef - matches := make([]*plumbing.Reference, 0) - for _, ref := range refs { - // Ignore the HEAD symbolic reference - // e.g. [HEAD ref: refs/heads/main] - if ref.Type() == plumbing.SymbolicReference { - continue - } - - // Compare the short names of both refs, - // where the short name of e.g. '/refs/heads/main' is 'main' - // Alternatively, match on ref hash - if ref.Name().Short() == fullRef.Name().Short() || - ref.Hash() == fullRef.Hash() { - matches = append(matches, ref) - } - } - - if len(matches) == 0 { - return nil, fmt.Errorf( - "reference %q not found in repo %q", - fullRef.Name(), - cloneURL, - ) - } - if len(matches) > 1 { - return nil, fmt.Errorf( - "found more than one match for reference %q: %+v", - fullRef.Name(), - matches, - ) - } - fullRef = matches[0] - - // Create refspec with the updated ref - refSpec = config.RefSpec(fmt.Sprintf("+%s:%s", - fullRef.Name(), fullRef.Name())) - } - - // Create the remote that we'll use to fetch, using the updated/full refspec - remoteConfig := &config.RemoteConfig{ - Name: remoteName, - URLs: []string{cloneURL}, - Fetch: []config.RefSpec{refSpec}, - } - remote, err := repo.CreateRemote(remoteConfig) - if err != nil { - return nil, errors.Wrap(err, "error creating remote") - } - - // Create a FETCH_HEAD reference pointing to our ref hash - // The go-git library doesn't appear to support adding this, though the - // git CLI does. This is for parity with v1 functionality. - // - // From https://git-scm.com/docs/gitrevisions: - // "FETCH_HEAD records the branch which you fetched from a remote repository - // with your last git fetch invocation." - newRef := plumbing.NewReferenceFromStrings("FETCH_HEAD", - fullRef.Hash().String()) - err = repo.Storer.SetReference(newRef) - if err != nil { - return nil, errors.Wrap(err, "unable to set ref") - } - - // Fetch the ref specs we are interested in - fetchOpts := &git.FetchOptions{ - RemoteName: remoteName, - RefSpecs: []config.RefSpec{refSpec}, - Force: true, - Auth: auth, - Progress: os.Stdout, - } - if retryErr := retries.ManageRetries( - context.Background(), - "git fetch", - maxRetryCount, - maxBackoff, - func() (bool, error) { - err = remote.Fetch(fetchOpts) - if err != nil { - return true, errors.Wrap(err, "error fetching refs from the remote") - } - return false, nil - }, - ); retryErr != nil { - return nil, retryErr - } - - // Get the repository's working tree - worktree, err := repo.Worktree() - if err != nil { - return nil, errors.Wrap(err, "unable to access the repo worktree") - } - - // Check out whatever we're interested in into the working tree - if retryErr := retries.ManageRetries( - context.Background(), - "git checkout", - maxRetryCount, - maxBackoff, - func() (bool, error) { - err := worktree.Checkout( - &git.CheckoutOptions{ - Branch: fullRef.Name(), - Force: true, - }, - ) - if err != nil { - return true, errors.Wrapf( - err, - "unable to checkout using %q", - commitRef, - ) - } - return false, nil - }, - ); retryErr != nil { - return nil, retryErr + if err = checkout(repo, gitConfig.Commit, gitConfig.Ref); err != nil { + log.Fatal(err) } - return worktree, nil -} - -func initSubmodules(worktree *git.Worktree) error { - submodules, err := worktree.Submodules() - if err != nil { - return errors.Wrap(err, "error retrieving submodules: %s") - } - if retryErr := retries.ManageRetries( - context.Background(), - "update submodules", - maxRetryCount, - maxBackoff, - func() (bool, error) { - for _, submodule := range submodules { - if err = submodule.Update( - &git.SubmoduleUpdateOptions{ - Init: true, - RecurseSubmodules: git.DefaultSubmoduleRecursionDepth, - }, - ); err != nil { - return true, errors.Wrapf( - err, - "error updating submodule %q", - submodule.Config().Name, - ) - } - } - return false, nil - }, - ); retryErr != nil { - return retryErr + if gitConfig.InitSubmodules { + if err = initSubmodules(repo); err != nil { + log.Fatal(err) + } } - return nil -} - -func isFullReference(name plumbing.ReferenceName) bool { - return name.IsBranch() || name.IsNote() || name.IsRemote() || name.IsTag() } diff --git a/v2/git-initializer/main_test.go b/v2/git-initializer/main_test.go deleted file mode 100644 index 2a582e1d4..000000000 --- a/v2/git-initializer/main_test.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "testing" - - "github.com/go-git/go-git/v5/plumbing" - "github.com/stretchr/testify/require" -) - -func Test_isFullReference(t *testing.T) { - t.Run("full branch reference", func(t *testing.T) { - ref := plumbing.ReferenceName("refs/heads/foo") - require.True(t, isFullReference(ref)) - }) - - t.Run("full tag reference", func(t *testing.T) { - ref := plumbing.ReferenceName("refs/tags/foo") - require.True(t, isFullReference(ref)) - }) - - t.Run("full remote reference", func(t *testing.T) { - ref := plumbing.ReferenceName("refs/remotes/foo") - require.True(t, isFullReference(ref)) - }) - - t.Run("full note reference", func(t *testing.T) { - ref := plumbing.ReferenceName("refs/notes/foo") - require.True(t, isFullReference(ref)) - }) - - t.Run("short reference", func(t *testing.T) { - ref := plumbing.ReferenceName("foo") - require.False(t, isFullReference(ref)) - }) - - t.Run("tasty reference", func(t *testing.T) { - ref := plumbing.ReferenceName("refs/tacos/carnitas") - require.False(t, isFullReference(ref)) - }) -} diff --git a/v2/git-initializer/refs.go b/v2/git-initializer/refs.go new file mode 100644 index 000000000..aafc7b44e --- /dev/null +++ b/v2/git-initializer/refs.go @@ -0,0 +1,52 @@ +//go:build !testUnit && !lint +// +build !testUnit,!lint + +// We exclude this file from unit tests and linting because it cannot be +// compiled without CGO and a specific version of libgit2 pre-installed. To keep +// our linting and unit tests lightweight, those are complications we'd like to +// avoid. We'll live without the linting and test this well with integration +// tests. + +package main + +import ( + "fmt" + "strings" + + git "github.com/libgit2/git2go/v32" + "github.com/pkg/errors" +) + +// resolveRef resolves refStr, which could be very specific and unambiguous +// (like "refs/heads/my-branch" -- which is clearly a branch) or relatively +// vague and ambiguous (like "foo" -- which could be a branch or a tag). This is +// the magic that makes the git-initializer DWIM (Do What I Mean). +func resolveRef(repo *git.Repository, refStr string) (*git.Reference, error) { + if strings.HasPrefix(refStr, "refs/tags/") { + // This refStr is very specific about what it is. Just look it up and return + // whatever result we get. + return repo.References.Lookup(refStr) + } + if strings.HasPrefix(refStr, "refs/heads/") { + // This refStr is very specific about what it is. We need to factor the + // remote name into the lookup, but then we can just return whatever result + // we get. + shortName := strings.SplitN(refStr, "/", 3)[2] + return repo.References.Lookup( + fmt.Sprintf("refs/remotes/origin/%s", shortName), + ) + } + // If we get to here, the refStr was a bit more vague about what it is. + // Is it a tag? + tagRefStr := fmt.Sprintf("refs/tags/%s", refStr) + if ref, err := repo.References.Lookup(tagRefStr); err == nil { + return ref, nil // No error. It WAS a tag! + } + // Is it a branch? + branchRefStr := fmt.Sprintf("refs/remotes/origin/%s", refStr) + if ref, err := repo.References.Lookup(branchRefStr); err == nil { + return ref, nil // No error. It WAS a branch! + } + return nil, + errors.Errorf("neither reference %q nor %q found", tagRefStr, branchRefStr) +} diff --git a/v2/git-initializer/repos.go b/v2/git-initializer/repos.go new file mode 100644 index 000000000..ec7f8749d --- /dev/null +++ b/v2/git-initializer/repos.go @@ -0,0 +1,171 @@ +//go:build !testUnit && !lint +// +build !testUnit,!lint + +// We exclude this file from unit tests and linting because it cannot be +// compiled without CGO and a specific version of libgit2 pre-installed. To keep +// our linting and unit tests lightweight, those are complications we'd like to +// avoid. We'll live without the linting and test this well with integration +// tests. + +package main + +import ( + "log" + "strings" + + git "github.com/libgit2/git2go/v32" + "github.com/pkg/errors" +) + +// checkout checks out a specific commit, branch, or tag from the provided repo. +// Precedence is given to a specific commit, identified by the provided sha. If +// that value is empty, the provided reference will be used instead. If both are +// empty, the repository's default branch is checked out. +func checkout(repo *git.Repository, sha string, refStr string) error { + // Our first concern is finding the commit in question and while we're at it + // we'll create a local branch to check out into, if necessary. + var commit *git.Commit + var tagRef *git.Reference + var localBranch *git.Branch + var checkingOutDefaultBranch bool + if sha != "" { // Specific commit identified by SHA takes precedence + oid, err := git.NewOid(sha) + if err != nil { + return errors.Wrapf(err, "error getting oid from sha %q", sha) + } + if commit, err = repo.LookupCommit(oid); err != nil { + return errors.Wrapf(err, "error getting commit %q", sha) + } + defer commit.Free() + log.Printf("checking out commit %q", commit.Id().String()) + } else if refStr != "" { // Next in order of precedence is a specific ref + ref, err := resolveRef(repo, refStr) + if err != nil { + return errors.Wrapf(err, "error resolving ref %q", refStr) + } + defer ref.Free() + if commit, err = repo.LookupCommit(ref.Target()); err != nil { + return errors.Wrapf( + err, + "error getting commit from ref %q", + ref.Shorthand(), + ) + } + defer commit.Free() + if ref.IsRemote() { // i.e. Not a tag + headRef, err := repo.Head() + if err != nil { + return errors.Wrap(err, "error getting ref from default branch") + } + defer headRef.Free() + if ref.Target().String() == headRef.Target().String() { + // This ref points to the default branch, which we already have locally, + // so we'll bypass creating a new local branch. + checkingOutDefaultBranch = true + log.Printf("checking out branch %q", headRef.Shorthand()) + } else { // We need to make a new local branch. + // ref.Shorthand() will be like "origin/" and we + // want JUST the branch or tag name. + shortName := strings.SplitN(ref.Shorthand(), "/", 2)[1] + if localBranch, err = repo.CreateBranch(shortName, commit, false); err != nil { + return errors.Wrapf( + err, + "error creating branch %q from commit %q", + shortName, + commit.Id().String(), + ) + } + defer localBranch.Free() + log.Printf("checking out branch %q", shortName) + } + } else { + tagRef = ref + log.Printf("checking out tag %q", ref.Shorthand()) + } + } else { // Last in order of precedence is the default branch + checkingOutDefaultBranch = true + ref, err := repo.Head() + if err != nil { + return errors.Wrap(err, "error getting ref from default branch") + } + defer ref.Free() + if commit, err = repo.LookupCommit(ref.Target()); err != nil { + return errors.Wrap( + err, + "error getting commit from HEAD of default branch", + ) + } + log.Printf("checking out branch %q", ref.Shorthand()) + } + + // This is where we actually perform the checkout + tree, err := repo.LookupTree(commit.TreeId()) + if err != nil { + return errors.Wrapf( + err, + "error finding tree for commit %q", + commit.Id().String(), + ) + } + defer tree.Free() + if err = repo.CheckoutTree( + tree, + &git.CheckoutOptions{ + Strategy: git.CheckoutSafe | + git.CheckoutRecreateMissing | + git.CheckoutAllowConflicts | + git.CheckoutUseTheirs, + }, + ); err != nil { + return errors.Wrapf( + err, + "error checking out tree for commit %q", + commit.Id().String(), + ) + } + + // If we just checked out the default branch, we're done. + if checkingOutDefaultBranch { + return nil + } + + // If we checked out some other branch, set HEAD to point to the local branch. + if localBranch != nil { + return errors.Wrapf( + repo.SetHead(localBranch.Reference.Name()), + "error setting HEAD to %q", + localBranch.Reference.Name(), + ) + } + + // If we checked out a tag, we want HEAD detached at the name of the tag. + if tagRef != nil { + return errors.Wrapf( + repo.SetHead(tagRef.Name()), + "error setting detached HEAD to %q", + tagRef.Name(), + ) + } + + // We must have checked out a specific commit by SHA. We want HEAD detached + // at the SHA. + return errors.Wrapf( + repo.SetHeadDetached(commit.Id()), + "error setting detached HEAD to %q", + commit.Id().String(), + ) +} + +// initSubmodules iterates over all of the provided repositories submodules and +// initializes and updates each. +func initSubmodules(repo *git.Repository) error { + return repo.Submodules.Foreach( + func(submodule *git.Submodule, name string) error { + return errors.Wrapf( + submodule.Update(true, nil), + "error initializing submodule %q", + name, + ) + }, + ) +} diff --git a/v2/go.mod b/v2/go.mod index a001fe67d..4cfccb08c 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -15,11 +15,10 @@ require ( github.com/coreos/go-oidc v2.2.1+incompatible github.com/gdamore/tcell/v2 v2.3.3 github.com/ghodss/yaml v1.0.0 - github.com/go-git/go-billy/v5 v5.0.0 - github.com/go-git/go-git/v5 v5.2.0 github.com/google/go-github/v33 v33.0.0 github.com/gorilla/mux v1.8.0 github.com/gosuri/uitable v0.0.4 + github.com/libgit2/git2go/v32 v32.1.9 github.com/mitchellh/go-homedir v1.1.0 github.com/pkg/errors v0.9.1 github.com/rivo/tview v0.0.0-20210624165335-29d673af0ce2 @@ -41,11 +40,9 @@ require ( github.com/Masterminds/semver v1.5.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emirpasic/gods v1.12.0 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect github.com/fatih/color v1.9.0 // indirect github.com/gdamore/encoding v1.0.0 // indirect - github.com/go-git/gcfg v1.5.0 // indirect github.com/go-logr/logr v1.2.0 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -60,10 +57,8 @@ require ( github.com/hashicorp/go-retryablehttp v0.6.7 // indirect github.com/huandu/xstrings v1.3.2 // indirect github.com/imdario/mergo v0.3.9 // indirect - github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect - github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd // indirect github.com/klauspost/compress v1.13.6 // indirect github.com/kr/pty v1.1.8 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect @@ -79,10 +74,8 @@ require ( github.com/pquerna/cachecontrol v0.0.0-20200921180117-858c6e7e6b7e // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect - github.com/sergi/go-diff v1.1.0 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/xanzy/ssh-agent v0.2.1 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.0.2 // indirect github.com/xdg-go/stringprep v1.0.2 // indirect @@ -99,7 +92,6 @@ require ( google.golang.org/protobuf v1.27.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect - gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect k8s.io/klog/v2 v2.30.0 // indirect diff --git a/v2/go.sum b/v2/go.sum index 68577c94b..ede45bcdf 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -60,14 +60,8 @@ github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nB github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs= -github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2 h1:7Ip0wMmLHLRJdrloDxZfhMm0xrLXZS8+COSu2bXmEQs= github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/bacongobbler/browser v1.1.0 h1:6YTctUlzcApit1vpWgh+myjh8lQUyQRD2Ltoyvy2EoM= github.com/bacongobbler/browser v1.1.0/go.mod h1:T9AaY4DSJ61FNgVTlCP/FWPrJ36TMRwI0Z18eLZ3IKI= @@ -94,8 +88,6 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -106,7 +98,6 @@ github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= @@ -121,16 +112,6 @@ github.com/gdamore/tcell/v2 v2.3.3/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6o github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.0.0 h1:7NQHvd9FVid8VL4qVUMm8XifBK+2xCoZ2lSk0agRrHM= -github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbKy9zOy4aAKrJ5pibIRpVO2BXnK1Tlcg+caKI7Ox5M= -github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw= -github.com/go-git/go-git/v5 v5.2.0 h1:YPBLG/3UK1we1ohRkncLjaXWLW+HKp5QNM/jTli2JgI= -github.com/go-git/go-git/v5 v5.2.0/go.mod h1:kh02eMX+wdqqxgNMEyq8YgwlIOsDOa9homkUq1PoTMs= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -216,6 +197,8 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -247,9 +230,6 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= @@ -257,8 +237,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v2wtGp9Gmz1Ze3eVRAWJMLokvN3QjdzCHLY= -github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= @@ -272,6 +250,8 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/libgit2/git2go/v32 v32.1.9 h1:RjHicBhR3vi7u86cU6Km912rQunjf6PCGbQa8g1x+hQ= +github.com/libgit2/git2go/v32 v32.1.9/go.mod h1:FAA2ePV5PlLjw1ccncFIvu2v8hJSZVN5IzEn4lo/vwo= github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= @@ -318,7 +298,6 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -338,8 +317,6 @@ github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= -github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -359,8 +336,6 @@ github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= -github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70= -github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2 h1:akYIkZ28e6A96dkWNJQu3nmCzH3YfwMPQExUYDaRv7w= @@ -389,15 +364,14 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -502,7 +476,6 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -537,6 +510,7 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -741,8 +715,6 @@ gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/v2/tests/testcases_test.go b/v2/tests/testcases_test.go index f6cef0d80..5d14445a0 100644 --- a/v2/tests/testcases_test.go +++ b/v2/tests/testcases_test.go @@ -320,8 +320,7 @@ var testCases = []struct { ctx, event.ID, &sdk.LogsSelector{Container: "vcs"}, - `reference "non-existent" not found in repo `+ - `"https://github.com/brigadecore/empty-testbed.git"`, + `error resolving ref "non-existent"`, ) }, },