diff --git a/api/archive/testdata/sample_archive.zip b/api/archive/testdata/sample_archive.zip deleted file mode 100644 index de289247a..000000000 Binary files a/api/archive/testdata/sample_archive.zip and /dev/null differ diff --git a/api/archive/zip.go b/api/archive/zip.go index 2aaee5a4f..5952e98d0 100644 --- a/api/archive/zip.go +++ b/api/archive/zip.go @@ -3,13 +3,10 @@ package archive import ( "archive/zip" "bytes" - "fmt" - "github.com/pkg/errors" "io" "io/ioutil" "os" "path/filepath" - "strings" ) // UnzipArchive will unzip an archive from bytes into the dest destination folder on disk @@ -55,60 +52,3 @@ func extractFileFromArchive(file *zip.File, dest string) error { return outFile.Close() } - -// UnzipFile will decompress a zip archive, moving all files and folders -// within the zip file (parameter 1) to an output directory (parameter 2). -func UnzipFile(src string, dest string) error { - r, err := zip.OpenReader(src) - if err != nil { - return err - } - defer r.Close() - - for _, f := range r.File { - p := filepath.Join(dest, f.Name) - - // Check for ZipSlip. More Info: http://bit.ly/2MsjAWE - if !strings.HasPrefix(p, filepath.Clean(dest)+string(os.PathSeparator)) { - return fmt.Errorf("%s: illegal file path", p) - } - - if f.FileInfo().IsDir() { - // Make Folder - os.MkdirAll(p, os.ModePerm) - continue - } - - err = unzipFile(f, p) - if err != nil { - return err - } - } - - return nil -} - -func unzipFile(f *zip.File, p string) error { - // Make File - if err := os.MkdirAll(filepath.Dir(p), os.ModePerm); err != nil { - return errors.Wrapf(err, "unzipFile: can't make a path %s", p) - } - outFile, err := os.OpenFile(p, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) - if err != nil { - return errors.Wrapf(err, "unzipFile: can't create file %s", p) - } - defer outFile.Close() - rc, err := f.Open() - if err != nil { - return errors.Wrapf(err, "unzipFile: can't open zip file %s in the archive", f.Name) - } - defer rc.Close() - - _, err = io.Copy(outFile, rc) - - if err != nil { - return errors.Wrapf(err, "unzipFile: can't copy an archived file content") - } - - return nil -} diff --git a/api/archive/zip_test.go b/api/archive/zip_test.go deleted file mode 100644 index 01e398c3a..000000000 --- a/api/archive/zip_test.go +++ /dev/null @@ -1,32 +0,0 @@ -package archive - -import ( - "github.com/stretchr/testify/assert" - "io/ioutil" - "os" - "path/filepath" - "testing" -) - -func TestUnzipFile(t *testing.T) { - dir, err := ioutil.TempDir("", "unzip-test-") - assert.NoError(t, err) - defer os.RemoveAll(dir) - /* - Archive structure. - ├── 0 - │ ├── 1 - │ │ └── 2.txt - │ └── 1.txt - └── 0.txt - */ - - err = UnzipFile("./testdata/sample_archive.zip", dir) - - assert.NoError(t, err) - archiveDir := dir + "/sample_archive" - assert.FileExists(t, filepath.Join(archiveDir, "0.txt")) - assert.FileExists(t, filepath.Join(archiveDir, "0", "1.txt")) - assert.FileExists(t, filepath.Join(archiveDir, "0", "1", "2.txt")) - -} diff --git a/api/git/azure.go b/api/git/azure.go deleted file mode 100644 index cffcff521..000000000 --- a/api/git/azure.go +++ /dev/null @@ -1,154 +0,0 @@ -package git - -import ( - "context" - "fmt" - "github.com/pkg/errors" - "github.com/portainer/portainer/api/archive" - "io" - "io/ioutil" - "net/http" - "net/url" - "os" - "strings" -) - -func isAzureUrl(s string) bool { - return strings.Contains(s, "dev.azure.com") -} - -type azureOptions struct { - organisation, project, repository string -} - -type azureDownloader struct { - client *http.Client -} - -func (a *azureDownloader) download(ctx context.Context, destination string, options cloneOptions) error { - zipFilepath, err := a.downloadZipFromAzureDevOps(ctx, options) - if err != nil { - return errors.Wrap(err, "failed to download a zip file from Azure DevOps") - } - defer os.Remove(zipFilepath) - - err = archive.UnzipFile(zipFilepath, destination) - if err != nil { - return errors.Wrap(err,"failed to unzip file") - } - - return nil -} - -func (a *azureDownloader) downloadZipFromAzureDevOps(ctx context.Context, options cloneOptions) (string, error) { - config, err := parseUrl(options.repositoryUrl) - if err != nil { - return "", errors.WithMessage(err, "failed to parse url") - } - downloadUrl, err := buildDownloadUrl(config, options.referenceName) - if err != nil { - return "", errors.WithMessage(err, "failed to build download url") - } - zipFile, err := ioutil.TempFile("", "azure-git-repo-*.zip") - if err != nil { - return "", errors.WithMessage(err, "failed to create temp file") - } - defer zipFile.Close() - - req, err := http.NewRequestWithContext(ctx, "GET", downloadUrl, nil) - req.SetBasicAuth(options.username, options.password) - if err != nil { - return "", errors.WithMessage(err, "failed to create new context") - } - - res, err := a.client.Do(req) - if err != nil { - return "", errors.WithMessage(err, "failed to make an HTTP request") - } - defer res.Body.Close() - - if res.StatusCode != http.StatusOK { - return "", fmt.Errorf("failed to download zip with a status \"%v\"", res.Status) - } - - _, err = io.Copy(zipFile, res.Body) - if err != nil { - return "", errors.WithMessage(err, "failed to save HTTP response to a file") - } - return zipFile.Name(), nil -} - -func parseUrl(rawUrl string) (*azureOptions, error) { - if strings.HasPrefix(rawUrl, "https://") { - return parseHttpUrl(rawUrl) - } - if strings.HasPrefix(rawUrl, "git@ssh") { - return parseSshUrl(rawUrl) - } - if strings.HasPrefix(rawUrl, "ssh://") { - r := []rune(rawUrl) - return parseSshUrl(string(r[6:])) // remove the prefix - } - - return nil, errors.Errorf("supported url schemes are https and ssh; recevied URL %s rawUrl", rawUrl) -} - -var expectedSshUrl = "git@ssh.dev.azure.com:v3/Organisation/Project/Repository" - -func parseSshUrl(rawUrl string) (*azureOptions, error) { - path := strings.Split(rawUrl, "/") - - unexpectedUrlErr := errors.Errorf("want url %s, got %s", expectedSshUrl, rawUrl) - if len(path) != 4 { - return nil, unexpectedUrlErr - } - return &azureOptions{ - organisation: path[1], - project: path[2], - repository: path[3], - }, nil -} - -var expectedHttpUrl = "https://Organisation@dev.azure.com/Organisation/Project/_git/Repository" - -func parseHttpUrl(rawUrl string) (*azureOptions, error) { - u, err := url.Parse(rawUrl) - if err != nil { - return nil, errors.Wrap(err, "failed to parse HTTP url") - } - - path := strings.Split(u.Path, "/") - - unexpectedUrlErr := errors.Errorf("want url %s, got %s", expectedHttpUrl, u) - if len(path) != 5 { - return nil, unexpectedUrlErr - } - return &azureOptions{ - organisation: path[1], - project: path[2], - repository: path[4], - }, nil -} - -func buildDownloadUrl(config *azureOptions, referenceName string) (string, error) { - rawUrl := fmt.Sprintf("https://dev.azure.com/%s/%s/_apis/git/repositories/%s/items", - url.PathEscape(config.organisation), - url.PathEscape(config.project), - url.PathEscape(config.repository)) - u, err := url.Parse(rawUrl) - - if err != nil { - return "", errors.Wrapf(err, "failed to parse download url path %s", rawUrl) - } - q := u.Query() - // scopePath=/&download=true&versionDescriptor.version=feture&$format=zip&recursionLevel=full&api-version=6.0 - q.Set("scopePath", "/") - q.Set("download", "true") - q.Set("versionDescriptor.version", referenceName) - q.Set("$format", "zip") - q.Set("recursionLevel", "full") - q.Set("api-version", "6.0") - u.RawQuery = q.Encode() - - return u.String(), nil -} diff --git a/api/git/azure_test.go b/api/git/azure_test.go deleted file mode 100644 index a71a88578..000000000 --- a/api/git/azure_test.go +++ /dev/null @@ -1,128 +0,0 @@ -package git - -import ( - "github.com/stretchr/testify/assert" - "net/url" - "testing" -) - -func Test_buildDownloadUrl(t *testing.T) { - u, err := buildDownloadUrl(&azureOptions{ - organisation: "organisation", - project: "project", - repository: "repository", - }, "refs/heads/main") - - expectedUrl, _ := url.Parse("https://dev.azure.com/organisation/project/_apis/git/repositories/repository/items?scopePath=/&download=true&versionDescriptor.version=refs/heads/main&$format=zip&recursionLevel=full&api-version=6.0") - actualUrl, _ := url.Parse(u) - if assert.NoError(t, err) { - assert.Equal(t, expectedUrl.Host, actualUrl.Host) - assert.Equal(t, expectedUrl.Scheme, actualUrl.Scheme) - assert.Equal(t, expectedUrl.Path, actualUrl.Path) - assert.Equal(t, expectedUrl.Query(), actualUrl.Query()) - } -} - -func Test_parseAzureUrl(t *testing.T) { - type args struct { - url string - } - tests := []struct { - name string - args args - want *azureOptions - wantErr bool - }{ - { - name: "Expected SSH URL format starting with ssh://", - args: args{ - url: "ssh://git@ssh.dev.azure.com:v3/Organisation/Project/Repository", - }, - want: &azureOptions{ - organisation: "Organisation", - project: "Project", - repository: "Repository", - }, - wantErr: false, - }, - { - name: "Expected SSH URL format starting with git@ssh", - args: args{ - url: "git@ssh.dev.azure.com:v3/Organisation/Project/Repository", - }, - want: &azureOptions{ - organisation: "Organisation", - project: "Project", - repository: "Repository", - }, - wantErr: false, - }, - { - name: "Unexpected SSH URL format", - args: args{ - url: "git@ssh.dev.azure.com:v3/Organisation/Repository", - }, - wantErr: true, - }, - { - name: "Expected HTTPS URL format", - args: args{ - url: "https://Organisation@dev.azure.com/Organisation/Project/_git/Repository", - }, - want: &azureOptions{ - organisation: "Organisation", - project: "Project", - repository: "Repository", - }, - wantErr: false, - }, - { - name: "Unexpected HTTPS URL format", - args: args{ - url: "https://Organisation@dev.azure.com/Project/_git/Repository", - }, - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := parseUrl(tt.args.url) - if (err != nil) != tt.wantErr { - t.Errorf("parseUrl() error = %v, wantErr %v", err, tt.wantErr) - return - } - assert.Equal(t, tt.want, got) - }) - } -} - -func Test_isAzureUrl(t *testing.T) { - type args struct { - s string - } - tests := []struct { - name string - args args - want bool - }{ - { - name: "Is Azure url", - args: args{ - s: "https://Organisation@dev.azure.com/Organisation/Project/_git/Repository", - }, - want: true, - }, - { - name: "Is NOT Azure url", - args: args{ - s: "https://github.com/Organisation/Repository", - }, - want: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, isAzureUrl(tt.args.s)) - }) - } -} \ No newline at end of file diff --git a/api/git/git.go b/api/git/git.go index 96beae003..116a5f113 100644 --- a/api/git/git.go +++ b/api/git/git.go @@ -1,71 +1,21 @@ package git import ( - "context" "crypto/tls" - "github.com/pkg/errors" "net/http" - "os" - "path/filepath" + "net/url" + "strings" "time" - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing" - "github.com/go-git/go-git/v5/plumbing/transport/client" - githttp "github.com/go-git/go-git/v5/plumbing/transport/http" + "gopkg.in/src-d/go-git.v4" + "gopkg.in/src-d/go-git.v4/plumbing" + "gopkg.in/src-d/go-git.v4/plumbing/transport/client" + githttp "gopkg.in/src-d/go-git.v4/plumbing/transport/http" ) -type cloneOptions struct { - repositoryUrl string - username string - password string - referenceName string - depth int -} - -type downloader interface { - download(ctx context.Context, dst string, opt cloneOptions) error -} - -type gitClient struct{ - preserveGitDirectory bool -} - -func (c gitClient) download(ctx context.Context, dst string, opt cloneOptions) error { - gitOptions := git.CloneOptions{ - URL: opt.repositoryUrl, - Depth: opt.depth, - } - - if opt.password != "" || opt.username != "" { - gitOptions.Auth = &githttp.BasicAuth{ - Username: opt.username, - Password: opt.password, - } - } - - if opt.referenceName != "" { - gitOptions.ReferenceName = plumbing.ReferenceName(opt.referenceName) - } - - _, err := git.PlainCloneContext(ctx, dst, false, &gitOptions) - - if err != nil { - return errors.Wrap(err, "failed to clone git repository") - } - - if !c.preserveGitDirectory { - os.RemoveAll(filepath.Join(dst, ".git")) - } - - return nil -} - // Service represents a service for managing Git. type Service struct { httpsCli *http.Client - azure downloader - git downloader } // NewService initializes a new service. @@ -81,37 +31,32 @@ func NewService() *Service { return &Service{ httpsCli: httpsCli, - azure: &azureDownloader{client: httpsCli}, - git: gitClient{}, } } // ClonePublicRepository clones a public git repository using the specified URL in the specified // destination folder. -func (service *Service) ClonePublicRepository(repositoryURL, referenceName, destination string) error { - return service.cloneRepository(destination, cloneOptions{ - repositoryUrl: repositoryURL, - referenceName: referenceName, - depth: 1, - }) +func (service *Service) ClonePublicRepository(repositoryURL, referenceName string, destination string) error { + return cloneRepository(repositoryURL, referenceName, destination) } // ClonePrivateRepositoryWithBasicAuth clones a private git repository using the specified URL in the specified -// destination folder. It will use the specified Username and Password for basic HTTP authentication. -func (service *Service) ClonePrivateRepositoryWithBasicAuth(repositoryURL, referenceName, destination, username, password string) error { - return service.cloneRepository(destination, cloneOptions{ - repositoryUrl: repositoryURL, - username: username, - password: password, - referenceName: referenceName, - depth: 1, - }) +// destination folder. It will use the specified username and password for basic HTTP authentication. +func (service *Service) ClonePrivateRepositoryWithBasicAuth(repositoryURL, referenceName string, destination, username, password string) error { + credentials := username + ":" + url.PathEscape(password) + repositoryURL = strings.Replace(repositoryURL, "://", "://"+credentials+"@", 1) + return cloneRepository(repositoryURL, referenceName, destination) } -func (service *Service) cloneRepository(destination string, options cloneOptions) error { - if isAzureUrl(options.repositoryUrl) { - return service.azure.download(context.TODO(), destination, options) +func cloneRepository(repositoryURL, referenceName, destination string) error { + options := &git.CloneOptions{ + URL: repositoryURL, } - return service.git.download(context.TODO(), destination, options) + if referenceName != "" { + options.ReferenceName = plumbing.ReferenceName(referenceName) + } + + _, err := git.PlainClone(destination, false, options) + return err } diff --git a/api/git/git_test.go b/api/git/git_test.go deleted file mode 100644 index 8276a0925..000000000 --- a/api/git/git_test.go +++ /dev/null @@ -1,173 +0,0 @@ -package git - -import ( - "context" - "github.com/go-git/go-git/v5" - "github.com/go-git/go-git/v5/plumbing/object" - "github.com/pkg/errors" - "github.com/portainer/portainer/api/archive" - "github.com/stretchr/testify/assert" - "io/ioutil" - "log" - "os" - "path/filepath" - "testing" -) - -var bareRepoDir string - -func TestMain(m *testing.M) { - if err := testMain(m); err != nil { - log.Fatal(err) - } -} - -// testMain does extra setup/teardown before/after testing. -// The function is separated from TestMain due to necessity to call os.Exit/log.Fatal in the latter. -func testMain(m *testing.M) error { - dir, err := ioutil.TempDir("", "git-repo-") - if err != nil { - return errors.Wrap(err, "failed to create a temp dir") - } - defer os.RemoveAll(dir) - - bareRepoDir = filepath.Join(dir, "test-clone.git") - - file, err := os.OpenFile("./testdata/test-clone-git-repo.tar.gz", os.O_RDONLY, 0755) - if err != nil { - return errors.Wrap(err, "failed to open an archive") - } - err = archive.ExtractTarGz(file, dir) - if err != nil { - return errors.Wrapf(err, "failed to extract file from the archive to a folder %s\n", dir) - } - - m.Run() - - return nil -} - -func Test_ClonePublicRepository_Shallow(t *testing.T) { - service := Service{git: gitClient{preserveGitDirectory: true}} // no need for http client since the test access the repo via file system. - repositoryURL := bareRepoDir - referenceName := "refs/heads/main" - destination := "shallow" - - dir, err := ioutil.TempDir("", destination) - if err != nil { - t.Fatalf("failed to create a temp dir") - } - defer os.RemoveAll(dir) - t.Logf("Cloning into %s", dir) - err = service.ClonePublicRepository(repositoryURL, referenceName, dir) - assert.NoError(t, err) - assert.Equal(t, 1, getCommitHistoryLength(t, err, dir), "cloned repo has incorrect depth") -} - -func Test_ClonePublicRepository_NoGitDirectory(t *testing.T) { - service := Service{git: gitClient{preserveGitDirectory: false}} // no need for http client since the test access the repo via file system. - repositoryURL := bareRepoDir - referenceName := "refs/heads/main" - destination := "shallow" - - dir, err := ioutil.TempDir("", destination) - if err != nil { - t.Fatalf("failed to create a temp dir") - } - defer os.RemoveAll(dir) - t.Logf("Cloning into %s", dir) - err = service.ClonePublicRepository(repositoryURL, referenceName, dir) - assert.NoError(t, err) - assert.NoDirExists(t, filepath.Join(dir, ".git")) -} - -func Test_cloneRepository(t *testing.T) { - service := Service{git: gitClient{preserveGitDirectory: true}} // no need for http client since the test access the repo via file system. - - repositoryURL := bareRepoDir - referenceName := "refs/heads/main" - destination := "shallow" - - dir, err := ioutil.TempDir("", destination) - if err != nil { - t.Fatalf("failed to create a temp dir") - } - defer os.RemoveAll(dir) - t.Logf("Cloning into %s", dir) - - err = service.cloneRepository(dir, cloneOptions{ - repositoryUrl: repositoryURL, - referenceName: referenceName, - depth: 10, - }) - - assert.NoError(t, err) - assert.Equal(t, 3, getCommitHistoryLength(t, err, dir), "cloned repo has incorrect depth") -} - -func getCommitHistoryLength(t *testing.T, err error, dir string) int { - repo, err := git.PlainOpen(dir) - if err != nil { - t.Fatalf("can't open a git repo at %s with error %v", dir, err) - } - iter, err := repo.Log(&git.LogOptions{All: true}) - if err != nil { - t.Fatalf("can't get a commit history iterator with error %v", err) - } - count := 0 - err = iter.ForEach(func(_ *object.Commit) error { - count++ - return nil - }) - if err != nil { - t.Fatalf("can't iterate over the commit history with error %v", err) - } - return count -} - -type testDownloader struct { - called bool -} - -func (t *testDownloader) download(_ context.Context, _ string, _ cloneOptions) error { - t.called = true - return nil -} - -func Test_cloneRepository_azure(t *testing.T) { - tests := []struct { - name string - url string - called bool - }{ - { - name: "Azure HTTP URL", - url: "https://Organisation@dev.azure.com/Organisation/Project/_git/Repository", - called: true, - }, - { - name: "Azure SSH URL", - url: "git@ssh.dev.azure.com:v3/Organisation/Project/Repository", - called: true, - }, - { - name: "Something else", - url: "https://example.com", - called: false, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - azure := &testDownloader{} - git := &testDownloader{} - - s := &Service{azure: azure, git: git} - s.cloneRepository("", cloneOptions{repositoryUrl: tt.url, depth: 1}) - - // if azure API is called, git isn't and vice versa - assert.Equal(t, tt.called, azure.called) - assert.Equal(t, tt.called, !git.called) - }) - } -} diff --git a/api/git/testdata/azure-repo.zip b/api/git/testdata/azure-repo.zip deleted file mode 100644 index d4b53d0b8..000000000 Binary files a/api/git/testdata/azure-repo.zip and /dev/null differ diff --git a/api/git/testdata/test-clone-git-repo.tar.gz b/api/git/testdata/test-clone-git-repo.tar.gz deleted file mode 100644 index ca63d337c..000000000 Binary files a/api/git/testdata/test-clone-git-repo.tar.gz and /dev/null differ diff --git a/api/go.mod b/api/go.mod index f241c431c..c6243456f 100644 --- a/api/go.mod +++ b/api/go.mod @@ -3,7 +3,7 @@ module github.com/portainer/portainer/api go 1.13 require ( - github.com/Microsoft/go-winio v0.4.16 + github.com/Microsoft/go-winio v0.4.14 github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a github.com/asdine/storm/v3 v3.2.1 github.com/aws/aws-sdk-go v1.38.3 @@ -15,12 +15,12 @@ require ( github.com/docker/cli v0.0.0-20191126203649-54d085b857e9 github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0 github.com/g07cha/defender v0.0.0-20180505193036-5665c627c814 - github.com/go-git/go-git/v5 v5.3.0 github.com/go-ldap/ldap/v3 v3.1.8 github.com/gofrs/uuid v3.2.0+incompatible github.com/gorilla/mux v1.7.3 github.com/gorilla/securecookie v1.1.1 github.com/gorilla/websocket v1.4.1 + github.com/imdario/mergo v0.3.8 // indirect github.com/jpillora/chisel v0.0.0-20190724232113-f3a8df20e389 github.com/json-iterator/go v1.1.10 github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c @@ -36,9 +36,11 @@ require ( github.com/robfig/cron/v3 v3.0.1 github.com/stretchr/testify v1.7.0 go.etcd.io/bbolt v1.3.5 // indirect - golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 + golang.org/x/sys v0.0.0-20210301091718-77cc2087c03b // indirect gopkg.in/alecthomas/kingpin.v2 v2.2.6 + gopkg.in/src-d/go-git.v4 v4.13.1 k8s.io/api v0.17.2 k8s.io/apimachinery v0.17.2 k8s.io/client-go v0.17.2 diff --git a/api/go.sum b/api/go.sum index ac8019037..7e337fb2d 100644 --- a/api/go.sum +++ b/api/go.sum @@ -14,9 +14,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/DataDog/zstd v1.4.1 h1:3oxKN3wbHibqx897utPC2LTQU4J+IHWWJO+glkAkpFM= github.com/DataDog/zstd v1.4.1/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Microsoft/go-winio v0.3.8/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -55,7 +54,7 @@ github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVl github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -100,15 +99,6 @@ 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-asn1-ber/asn1-ber v1.3.1 h1:gvPdv/Hr++TRFCl0UbPFHC54P9N9jgsRPnmnr419Uck= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -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/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-billy/v5 v5.1.0 h1:4pl5BV4o7ZG/lterP4S6WzJ6xr49Ba5ET9ygheTYahk= -github.com/go-git/go-billy/v5 v5.1.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.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc= -github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-ldap/ldap/v3 v3.1.8 h1:5vU/2jOh9HqprwXp8aF915s9p6Z8wmbSEVF7/gdTFhM= github.com/go-ldap/ldap/v3 v3.1.8/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q= @@ -165,11 +155,11 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ= +github.com/imdario/mergo v0.3.8/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.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= @@ -191,8 +181,8 @@ github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +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.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c h1:N7A4JCA2G+j5fuFxCsJqjFU/sZe0mj8H0sSoSwbaikw= @@ -200,14 +190,13 @@ github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c/go.mod h1:Nn github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v0.0.0-20150511174710-5cf931ef8f76/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 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/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mattn/go-shellwords v1.0.6 h1:9Jok5pILi5S1MnDirGVTufYGtksUs/V2BWUP3ZkeUUI= github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= @@ -229,7 +218,6 @@ github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5 github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -243,6 +231,7 @@ github.com/opencontainers/runc v0.0.0-20161109192122-51371867a01c h1:iOMba/KmaXg github.com/opencontainers/runc v0.0.0-20161109192122-51371867a01c/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6 h1:lNCW6THrCKBiJBpz8kbVGjC7MgdCGKwuvBgc7LoD6sw= github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= +github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -251,6 +240,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/portainer/docker-compose-wrapper v0.0.0-20210415231937-2c60ce1d9fc1 h1:wo86z2M4+d5NCpkefIVSPzH93l9kSiR8GWlOevoenJQ= +github.com/portainer/docker-compose-wrapper v0.0.0-20210415231937-2c60ce1d9fc1/go.mod h1:No8p8iZt9N2HOtDS9aWkh1ILxmQVoOTZZjHGlOij/ec= github.com/portainer/docker-compose-wrapper v0.0.0-20210415235931-d457f9aba1cc h1:MvSEkOvhW3m2D3L0/Ymrjgg0t3CpHlHwpZfpgpIGNiw= github.com/portainer/docker-compose-wrapper v0.0.0-20210415235931-d457f9aba1cc/go.mod h1:No8p8iZt9N2HOtDS9aWkh1ILxmQVoOTZZjHGlOij/ec= github.com/portainer/libcompose v0.5.3 h1:tE4WcPuGvo+NKeDkDWpwNavNLZ5GHIJ4RvuZXsI9uI8= @@ -277,8 +268,8 @@ github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURm github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -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/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -286,8 +277,11 @@ github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/src-d/gcfg v1.4.0 h1:xXbNR5AlLSA315x2UO+fTSSAXCDf+Ar38/6oyGbDKQ4= +github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -299,8 +293,8 @@ github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoi github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= -github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= +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/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -316,10 +310,10 @@ golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -337,12 +331,12 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191105084925-a882066a44e0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs= -golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= @@ -355,8 +349,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEha golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -374,6 +366,7 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -391,22 +384,25 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/src-d/go-billy.v4 v4.3.2 h1:0SQA1pRztfTFx2miS8sA97XvooFeNOmvUenF4o0EcVg= +gopkg.in/src-d/go-billy.v4 v4.3.2/go.mod h1:nDjArDMp+XMs1aFAESLRjfGSgfvoYN0hDfzEk0GjC98= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0 h1:ivZFOIltbce2Mo8IjzUHAFoq/IylO9WHhNOAJK+LsJg= +gopkg.in/src-d/go-git-fixtures.v3 v3.5.0/go.mod h1:dLBcvytrw/TYZsNTWCnkNF2DSIlzWYqTe3rJR56Ac7g= +gopkg.in/src-d/go-git.v4 v4.13.1 h1:SRtFyV8Kxc0UP7aCHcijOMQGPxHSmMOPrzulQWolkYE= +gopkg.in/src-d/go-git.v4 v4.13.1/go.mod h1:nx5NYcxdKxq5fpltdHnPa2Exj4Sx0EclMWZQbYDu2z8= 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= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=