Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
727 lines (694 sloc)
20 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Copyright 2018 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package modfetch | |
| import ( | |
| "archive/zip" | |
| "internal/testenv" | |
| "io/ioutil" | |
| "log" | |
| "os" | |
| "reflect" | |
| "strings" | |
| "testing" | |
| "time" | |
| "cmd/go/internal/cfg" | |
| "cmd/go/internal/modfetch/codehost" | |
| ) | |
| func TestMain(m *testing.M) { | |
| os.Exit(testMain(m)) | |
| } | |
| func testMain(m *testing.M) int { | |
| cfg.GOPROXY = "direct" | |
| // The sum database is populated using a released version of the go command, | |
| // but this test may include fixes for additional modules that previously | |
| // could not be fetched. Since this test isn't executing any of the resolved | |
| // code, bypass the sum database. | |
| cfg.GOSUMDB = "off" | |
| dir, err := ioutil.TempDir("", "gitrepo-test-") | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| defer os.RemoveAll(dir) | |
| codehost.WorkRoot = dir | |
| return m.Run() | |
| } | |
| const ( | |
| vgotest1git = "github.com/rsc/vgotest1" | |
| vgotest1hg = "vcs-test.golang.org/hg/vgotest1.hg" | |
| ) | |
| var altVgotests = map[string]string{ | |
| "hg": vgotest1hg, | |
| } | |
| type codeRepoTest struct { | |
| vcs string | |
| path string | |
| lookerr string | |
| mpath string | |
| rev string | |
| err string | |
| version string | |
| name string | |
| short string | |
| time time.Time | |
| gomod string | |
| gomoderr string | |
| zip []string | |
| ziperr string | |
| } | |
| var codeRepoTests = []codeRepoTest{ | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1", | |
| rev: "v0.0.0", | |
| version: "v0.0.0", | |
| name: "80d85c5d4d17598a0e9055e7c175a32b415d6128", | |
| short: "80d85c5d4d17", | |
| time: time.Date(2018, 2, 19, 23, 10, 6, 0, time.UTC), | |
| zip: []string{ | |
| "LICENSE", | |
| "README.md", | |
| "pkg/p.go", | |
| }, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1", | |
| rev: "v1.0.0", | |
| version: "v1.0.0", | |
| name: "80d85c5d4d17598a0e9055e7c175a32b415d6128", | |
| short: "80d85c5d4d17", | |
| time: time.Date(2018, 2, 19, 23, 10, 6, 0, time.UTC), | |
| zip: []string{ | |
| "LICENSE", | |
| "README.md", | |
| "pkg/p.go", | |
| }, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/v2", | |
| rev: "v2.0.0", | |
| version: "v2.0.0", | |
| name: "45f53230a74ad275c7127e117ac46914c8126160", | |
| short: "45f53230a74a", | |
| time: time.Date(2018, 7, 19, 1, 21, 27, 0, time.UTC), | |
| ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1", | |
| rev: "80d85c5", | |
| version: "v1.0.0", | |
| name: "80d85c5d4d17598a0e9055e7c175a32b415d6128", | |
| short: "80d85c5d4d17", | |
| time: time.Date(2018, 2, 19, 23, 10, 6, 0, time.UTC), | |
| zip: []string{ | |
| "LICENSE", | |
| "README.md", | |
| "pkg/p.go", | |
| }, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1", | |
| rev: "mytag", | |
| version: "v1.0.0", | |
| name: "80d85c5d4d17598a0e9055e7c175a32b415d6128", | |
| short: "80d85c5d4d17", | |
| time: time.Date(2018, 2, 19, 23, 10, 6, 0, time.UTC), | |
| zip: []string{ | |
| "LICENSE", | |
| "README.md", | |
| "pkg/p.go", | |
| }, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/v2", | |
| rev: "45f53230a", | |
| version: "v2.0.0", | |
| name: "45f53230a74ad275c7127e117ac46914c8126160", | |
| short: "45f53230a74a", | |
| time: time.Date(2018, 7, 19, 1, 21, 27, 0, time.UTC), | |
| gomoderr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", | |
| ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v2/go.mod at revision v2.0.0", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/v54321", | |
| rev: "80d85c5", | |
| version: "v54321.0.0-20180219231006-80d85c5d4d17", | |
| name: "80d85c5d4d17598a0e9055e7c175a32b415d6128", | |
| short: "80d85c5d4d17", | |
| time: time.Date(2018, 2, 19, 23, 10, 6, 0, time.UTC), | |
| ziperr: "missing github.com/rsc/vgotest1/go.mod and .../v54321/go.mod at revision 80d85c5d4d17", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/submod", | |
| rev: "v1.0.0", | |
| err: "unknown revision submod/v1.0.0", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/submod", | |
| rev: "v1.0.3", | |
| err: "unknown revision submod/v1.0.3", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/submod", | |
| rev: "v1.0.4", | |
| version: "v1.0.4", | |
| name: "8afe2b2efed96e0880ecd2a69b98a53b8c2738b6", | |
| short: "8afe2b2efed9", | |
| time: time.Date(2018, 2, 19, 23, 12, 7, 0, time.UTC), | |
| gomod: "module \"github.com/vgotest1/submod\" // submod/go.mod\n", | |
| zip: []string{ | |
| "go.mod", | |
| "pkg/p.go", | |
| "LICENSE", | |
| }, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1", | |
| rev: "v1.1.0", | |
| version: "v1.1.0", | |
| name: "b769f2de407a4db81af9c5de0a06016d60d2ea09", | |
| short: "b769f2de407a", | |
| time: time.Date(2018, 2, 19, 23, 13, 36, 0, time.UTC), | |
| gomod: "module \"github.com/rsc/vgotest1\" // root go.mod\nrequire \"github.com/rsc/vgotest1/submod\" v1.0.5\n", | |
| zip: []string{ | |
| "LICENSE", | |
| "README.md", | |
| "go.mod", | |
| "pkg/p.go", | |
| }, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/v2", | |
| rev: "v2.0.1", | |
| version: "v2.0.1", | |
| name: "ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9", | |
| short: "ea65f87c8f52", | |
| time: time.Date(2018, 2, 19, 23, 14, 23, 0, time.UTC), | |
| gomod: "module \"github.com/rsc/vgotest1/v2\" // root go.mod\n", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/v2", | |
| rev: "v2.0.3", | |
| version: "v2.0.3", | |
| name: "f18795870fb14388a21ef3ebc1d75911c8694f31", | |
| short: "f18795870fb1", | |
| time: time.Date(2018, 2, 19, 23, 16, 4, 0, time.UTC), | |
| gomoderr: "github.com/rsc/vgotest1/v2/go.mod has non-.../v2 module path \"github.com/rsc/vgotest\" at revision v2.0.3", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/v2", | |
| rev: "v2.0.4", | |
| version: "v2.0.4", | |
| name: "1f863feb76bc7029b78b21c5375644838962f88d", | |
| short: "1f863feb76bc", | |
| time: time.Date(2018, 2, 20, 0, 3, 38, 0, time.UTC), | |
| gomoderr: "github.com/rsc/vgotest1/go.mod and .../v2/go.mod both have .../v2 module paths at revision v2.0.4", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/v2", | |
| rev: "v2.0.5", | |
| version: "v2.0.5", | |
| name: "2f615117ce481c8efef46e0cc0b4b4dccfac8fea", | |
| short: "2f615117ce48", | |
| time: time.Date(2018, 2, 20, 0, 3, 59, 0, time.UTC), | |
| gomod: "module \"github.com/rsc/vgotest1/v2\" // v2/go.mod\n", | |
| }, | |
| { | |
| // redirect to github | |
| vcs: "git", | |
| path: "rsc.io/quote", | |
| rev: "v1.0.0", | |
| version: "v1.0.0", | |
| name: "f488df80bcdbd3e5bafdc24ad7d1e79e83edd7e6", | |
| short: "f488df80bcdb", | |
| time: time.Date(2018, 2, 14, 0, 45, 20, 0, time.UTC), | |
| gomod: "module \"rsc.io/quote\"\n", | |
| }, | |
| { | |
| // redirect to static hosting proxy | |
| vcs: "mod", | |
| path: "swtch.com/testmod", | |
| rev: "v1.0.0", | |
| version: "v1.0.0", | |
| // NO name or short - we intentionally ignore those in the proxy protocol | |
| time: time.Date(1972, 7, 18, 12, 34, 56, 0, time.UTC), | |
| gomod: "module \"swtch.com/testmod\"\n", | |
| }, | |
| { | |
| // redirect to googlesource | |
| vcs: "git", | |
| path: "golang.org/x/text", | |
| rev: "4e4a3210bb", | |
| version: "v0.3.1-0.20180208041248-4e4a3210bb54", | |
| name: "4e4a3210bb54bb31f6ab2cdca2edcc0b50c420c1", | |
| short: "4e4a3210bb54", | |
| time: time.Date(2018, 2, 8, 4, 12, 48, 0, time.UTC), | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/pkg/errors", | |
| rev: "v0.8.0", | |
| version: "v0.8.0", | |
| name: "645ef00459ed84a119197bfb8d8205042c6df63d", | |
| short: "645ef00459ed", | |
| time: time.Date(2016, 9, 29, 1, 48, 1, 0, time.UTC), | |
| }, | |
| { | |
| // package in subdirectory - custom domain | |
| // In general we can't reject these definitively in Lookup, | |
| // but gopkg.in is special. | |
| vcs: "git", | |
| path: "gopkg.in/yaml.v2/abc", | |
| lookerr: "invalid module path \"gopkg.in/yaml.v2/abc\"", | |
| }, | |
| { | |
| // package in subdirectory - github | |
| // Because it's a package, Stat should fail entirely. | |
| vcs: "git", | |
| path: "github.com/rsc/quote/buggy", | |
| rev: "c4d4236f", | |
| err: "missing github.com/rsc/quote/buggy/go.mod at revision c4d4236f9242", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "gopkg.in/yaml.v2", | |
| rev: "d670f940", | |
| version: "v2.0.0", | |
| name: "d670f9405373e636a5a2765eea47fac0c9bc91a4", | |
| short: "d670f9405373", | |
| time: time.Date(2018, 1, 9, 11, 43, 31, 0, time.UTC), | |
| gomod: "module gopkg.in/yaml.v2\n", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "gopkg.in/check.v1", | |
| rev: "20d25e280405", | |
| version: "v1.0.0-20161208181325-20d25e280405", | |
| name: "20d25e2804050c1cd24a7eea1e7a6447dd0e74ec", | |
| short: "20d25e280405", | |
| time: time.Date(2016, 12, 8, 18, 13, 25, 0, time.UTC), | |
| gomod: "module gopkg.in/check.v1\n", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "gopkg.in/yaml.v2", | |
| rev: "v2", | |
| version: "v2.2.3-0.20190319135612-7b8349ac747c", | |
| name: "7b8349ac747c6a24702b762d2c4fd9266cf4f1d6", | |
| short: "7b8349ac747c", | |
| time: time.Date(2019, 03, 19, 13, 56, 12, 0, time.UTC), | |
| gomod: "module \"gopkg.in/yaml.v2\"\n\nrequire (\n\t\"gopkg.in/check.v1\" v0.0.0-20161208181325-20d25e280405\n)\n", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "vcs-test.golang.org/go/mod/gitrepo1", | |
| rev: "master", | |
| version: "v1.2.4-annotated", | |
| name: "ede458df7cd0fdca520df19a33158086a8a68e81", | |
| short: "ede458df7cd0", | |
| time: time.Date(2018, 4, 17, 19, 43, 22, 0, time.UTC), | |
| gomod: "module vcs-test.golang.org/go/mod/gitrepo1\n", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "gopkg.in/natefinch/lumberjack.v2", | |
| rev: "latest", | |
| version: "v2.0.0-20170531160350-a96e63847dc3", | |
| name: "a96e63847dc3c67d17befa69c303767e2f84e54f", | |
| short: "a96e63847dc3", | |
| time: time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC), | |
| gomod: "module gopkg.in/natefinch/lumberjack.v2\n", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "gopkg.in/natefinch/lumberjack.v2", | |
| // This repo has a v2.1 tag. | |
| // We only allow semver references to tags that are fully qualified, as in v2.1.0. | |
| // Because we can't record v2.1.0 (the actual tag is v2.1), we record a pseudo-version | |
| // instead, same as if the tag were any other non-version-looking string. | |
| // We use a v2 pseudo-version here because of the .v2 in the path, not because | |
| // of the v2 in the rev. | |
| rev: "v2.1", // non-canonical semantic version turns into pseudo-version | |
| version: "v2.0.0-20170531160350-a96e63847dc3", | |
| name: "a96e63847dc3c67d17befa69c303767e2f84e54f", | |
| short: "a96e63847dc3", | |
| time: time.Date(2017, 5, 31, 16, 3, 50, 0, time.UTC), | |
| gomod: "module gopkg.in/natefinch/lumberjack.v2\n", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "vcs-test.golang.org/go/v2module/v2", | |
| rev: "v2.0.0", | |
| version: "v2.0.0", | |
| name: "203b91c896acd173aa719e4cdcb7d463c4b090fa", | |
| short: "203b91c896ac", | |
| time: time.Date(2019, 4, 3, 15, 52, 15, 0, time.UTC), | |
| gomod: "module vcs-test.golang.org/go/v2module/v2\n\ngo 1.12\n", | |
| }, | |
| } | |
| func TestCodeRepo(t *testing.T) { | |
| testenv.MustHaveExternalNetwork(t) | |
| tmpdir, err := ioutil.TempDir("", "modfetch-test-") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer os.RemoveAll(tmpdir) | |
| t.Run("parallel", func(t *testing.T) { | |
| for _, tt := range codeRepoTests { | |
| f := func(tt codeRepoTest) func(t *testing.T) { | |
| return func(t *testing.T) { | |
| t.Parallel() | |
| if tt.vcs != "mod" { | |
| testenv.MustHaveExecPath(t, tt.vcs) | |
| } | |
| repo, err := Lookup("direct", tt.path) | |
| if tt.lookerr != "" { | |
| if err != nil && err.Error() == tt.lookerr { | |
| return | |
| } | |
| t.Errorf("Lookup(%q): %v, want error %q", tt.path, err, tt.lookerr) | |
| } | |
| if err != nil { | |
| t.Fatalf("Lookup(%q): %v", tt.path, err) | |
| } | |
| if tt.mpath == "" { | |
| tt.mpath = tt.path | |
| } | |
| if mpath := repo.ModulePath(); mpath != tt.mpath { | |
| t.Errorf("repo.ModulePath() = %q, want %q", mpath, tt.mpath) | |
| } | |
| info, err := repo.Stat(tt.rev) | |
| if err != nil { | |
| if tt.err != "" { | |
| if !strings.Contains(err.Error(), tt.err) { | |
| t.Fatalf("repoStat(%q): %v, wanted %q", tt.rev, err, tt.err) | |
| } | |
| return | |
| } | |
| t.Fatalf("repo.Stat(%q): %v", tt.rev, err) | |
| } | |
| if tt.err != "" { | |
| t.Errorf("repo.Stat(%q): success, wanted error", tt.rev) | |
| } | |
| if info.Version != tt.version { | |
| t.Errorf("info.Version = %q, want %q", info.Version, tt.version) | |
| } | |
| if info.Name != tt.name { | |
| t.Errorf("info.Name = %q, want %q", info.Name, tt.name) | |
| } | |
| if info.Short != tt.short { | |
| t.Errorf("info.Short = %q, want %q", info.Short, tt.short) | |
| } | |
| if !info.Time.Equal(tt.time) { | |
| t.Errorf("info.Time = %v, want %v", info.Time, tt.time) | |
| } | |
| if tt.gomod != "" || tt.gomoderr != "" { | |
| data, err := repo.GoMod(tt.version) | |
| if err != nil && tt.gomoderr == "" { | |
| t.Errorf("repo.GoMod(%q): %v", tt.version, err) | |
| } else if err != nil && tt.gomoderr != "" { | |
| if err.Error() != tt.gomoderr { | |
| t.Errorf("repo.GoMod(%q): %v, want %q", tt.version, err, tt.gomoderr) | |
| } | |
| } else if tt.gomoderr != "" { | |
| t.Errorf("repo.GoMod(%q) = %q, want error %q", tt.version, data, tt.gomoderr) | |
| } else if string(data) != tt.gomod { | |
| t.Errorf("repo.GoMod(%q) = %q, want %q", tt.version, data, tt.gomod) | |
| } | |
| } | |
| if tt.zip != nil || tt.ziperr != "" { | |
| f, err := ioutil.TempFile(tmpdir, tt.version+".zip.") | |
| if err != nil { | |
| t.Fatalf("ioutil.TempFile: %v", err) | |
| } | |
| zipfile := f.Name() | |
| err = repo.Zip(f, tt.version) | |
| f.Close() | |
| if err != nil { | |
| if tt.ziperr != "" { | |
| if err.Error() == tt.ziperr { | |
| return | |
| } | |
| t.Fatalf("repo.Zip(%q): %v, want error %q", tt.version, err, tt.ziperr) | |
| } | |
| t.Fatalf("repo.Zip(%q): %v", tt.version, err) | |
| } | |
| if tt.ziperr != "" { | |
| t.Errorf("repo.Zip(%q): success, want error %q", tt.version, tt.ziperr) | |
| } | |
| prefix := tt.path + "@" + tt.version + "/" | |
| z, err := zip.OpenReader(zipfile) | |
| if err != nil { | |
| t.Fatalf("open zip %s: %v", zipfile, err) | |
| } | |
| var names []string | |
| for _, file := range z.File { | |
| if !strings.HasPrefix(file.Name, prefix) { | |
| t.Errorf("zip entry %v does not start with prefix %v", file.Name, prefix) | |
| continue | |
| } | |
| names = append(names, file.Name[len(prefix):]) | |
| } | |
| z.Close() | |
| if !reflect.DeepEqual(names, tt.zip) { | |
| t.Fatalf("zip = %v\nwant %v\n", names, tt.zip) | |
| } | |
| } | |
| } | |
| } | |
| t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt)) | |
| if strings.HasPrefix(tt.path, vgotest1git) { | |
| for vcs, alt := range altVgotests { | |
| // Note: Communicating with f through tt; should be cleaned up. | |
| old := tt | |
| tt.vcs = vcs | |
| tt.path = alt + strings.TrimPrefix(tt.path, vgotest1git) | |
| if strings.HasPrefix(tt.mpath, vgotest1git) { | |
| tt.mpath = alt + strings.TrimPrefix(tt.mpath, vgotest1git) | |
| } | |
| var m map[string]string | |
| if alt == vgotest1hg { | |
| m = hgmap | |
| } | |
| tt.version = remap(tt.version, m) | |
| tt.name = remap(tt.name, m) | |
| tt.short = remap(tt.short, m) | |
| tt.rev = remap(tt.rev, m) | |
| tt.gomoderr = remap(tt.gomoderr, m) | |
| tt.ziperr = remap(tt.ziperr, m) | |
| t.Run(strings.ReplaceAll(tt.path, "/", "_")+"/"+tt.rev, f(tt)) | |
| tt = old | |
| } | |
| } | |
| } | |
| }) | |
| } | |
| var hgmap = map[string]string{ | |
| "github.com/rsc/vgotest1/": "vcs-test.golang.org/hg/vgotest1.hg/", | |
| "f18795870fb14388a21ef3ebc1d75911c8694f31": "a9ad6d1d14eb544f459f446210c7eb3b009807c6", | |
| "ea65f87c8f52c15ea68f3bdd9925ef17e20d91e9": "f1fc0f22021b638d073d31c752847e7bf385def7", | |
| "b769f2de407a4db81af9c5de0a06016d60d2ea09": "92c7eb888b4fac17f1c6bd2e1060a1b881a3b832", | |
| "8afe2b2efed96e0880ecd2a69b98a53b8c2738b6": "4e58084d459ae7e79c8c2264d0e8e9a92eb5cd44", | |
| "2f615117ce481c8efef46e0cc0b4b4dccfac8fea": "879ea98f7743c8eff54f59a918f3a24123d1cf46", | |
| "80d85c5d4d17598a0e9055e7c175a32b415d6128": "e125018e286a4b09061079a81e7b537070b7ff71", | |
| "1f863feb76bc7029b78b21c5375644838962f88d": "bf63880162304a9337477f3858f5b7e255c75459", | |
| "45f53230a74ad275c7127e117ac46914c8126160": "814fce58e83abd5bf2a13892e0b0e1198abefcd4", | |
| } | |
| func remap(name string, m map[string]string) string { | |
| if m[name] != "" { | |
| return m[name] | |
| } | |
| if codehost.AllHex(name) { | |
| for k, v := range m { | |
| if strings.HasPrefix(k, name) { | |
| return v[:len(name)] | |
| } | |
| } | |
| } | |
| for k, v := range m { | |
| name = strings.ReplaceAll(name, k, v) | |
| if codehost.AllHex(k) { | |
| name = strings.ReplaceAll(name, k[:12], v[:12]) | |
| } | |
| } | |
| return name | |
| } | |
| var codeRepoVersionsTests = []struct { | |
| vcs string | |
| path string | |
| prefix string | |
| versions []string | |
| }{ | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1", | |
| versions: []string{"v0.0.0", "v0.0.1", "v1.0.0", "v1.0.1", "v1.0.2", "v1.0.3", "v1.1.0", "v2.0.0+incompatible"}, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1", | |
| prefix: "v1.0", | |
| versions: []string{"v1.0.0", "v1.0.1", "v1.0.2", "v1.0.3"}, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/v2", | |
| versions: []string{"v2.0.0", "v2.0.1", "v2.0.2", "v2.0.3", "v2.0.4", "v2.0.5", "v2.0.6"}, | |
| }, | |
| { | |
| vcs: "mod", | |
| path: "swtch.com/testmod", | |
| versions: []string{"v1.0.0", "v1.1.1"}, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "gopkg.in/russross/blackfriday.v2", | |
| versions: []string{"v2.0.0", "v2.0.1"}, | |
| }, | |
| { | |
| vcs: "git", | |
| path: "gopkg.in/natefinch/lumberjack.v2", | |
| versions: []string{"v2.0.0"}, | |
| }, | |
| } | |
| func TestCodeRepoVersions(t *testing.T) { | |
| testenv.MustHaveExternalNetwork(t) | |
| tmpdir, err := ioutil.TempDir("", "vgo-modfetch-test-") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer os.RemoveAll(tmpdir) | |
| t.Run("parallel", func(t *testing.T) { | |
| for _, tt := range codeRepoVersionsTests { | |
| t.Run(strings.ReplaceAll(tt.path, "/", "_"), func(t *testing.T) { | |
| tt := tt | |
| t.Parallel() | |
| if tt.vcs != "mod" { | |
| testenv.MustHaveExecPath(t, tt.vcs) | |
| } | |
| repo, err := Lookup("direct", tt.path) | |
| if err != nil { | |
| t.Fatalf("Lookup(%q): %v", tt.path, err) | |
| } | |
| list, err := repo.Versions(tt.prefix) | |
| if err != nil { | |
| t.Fatalf("Versions(%q): %v", tt.prefix, err) | |
| } | |
| if !reflect.DeepEqual(list, tt.versions) { | |
| t.Fatalf("Versions(%q):\nhave %v\nwant %v", tt.prefix, list, tt.versions) | |
| } | |
| }) | |
| } | |
| }) | |
| } | |
| var latestTests = []struct { | |
| vcs string | |
| path string | |
| version string | |
| err string | |
| }{ | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/empty", | |
| err: "no commits", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1", | |
| version: "v0.0.0-20180219223237-a08abb797a67", | |
| }, | |
| { | |
| vcs: "git", | |
| path: "github.com/rsc/vgotest1/subdir", | |
| err: "github.com/rsc/vgotest1/subdir@v0.0.0-20180219223237-a08abb797a67: invalid version: missing github.com/rsc/vgotest1/subdir/go.mod at revision a08abb797a67", | |
| }, | |
| { | |
| vcs: "mod", | |
| path: "swtch.com/testmod", | |
| version: "v1.1.1", | |
| }, | |
| } | |
| func TestLatest(t *testing.T) { | |
| testenv.MustHaveExternalNetwork(t) | |
| tmpdir, err := ioutil.TempDir("", "vgo-modfetch-test-") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| defer os.RemoveAll(tmpdir) | |
| t.Run("parallel", func(t *testing.T) { | |
| for _, tt := range latestTests { | |
| name := strings.ReplaceAll(tt.path, "/", "_") | |
| t.Run(name, func(t *testing.T) { | |
| tt := tt | |
| t.Parallel() | |
| if tt.vcs != "mod" { | |
| testenv.MustHaveExecPath(t, tt.vcs) | |
| } | |
| repo, err := Lookup("direct", tt.path) | |
| if err != nil { | |
| t.Fatalf("Lookup(%q): %v", tt.path, err) | |
| } | |
| info, err := repo.Latest() | |
| if err != nil { | |
| if tt.err != "" { | |
| if err.Error() == tt.err { | |
| return | |
| } | |
| t.Fatalf("Latest(): %v, want %q", err, tt.err) | |
| } | |
| t.Fatalf("Latest(): %v", err) | |
| } | |
| if tt.err != "" { | |
| t.Fatalf("Latest() = %v, want error %q", info.Version, tt.err) | |
| } | |
| if info.Version != tt.version { | |
| t.Fatalf("Latest() = %v, want %v", info.Version, tt.version) | |
| } | |
| }) | |
| } | |
| }) | |
| } | |
| // fixedTagsRepo is a fake codehost.Repo that returns a fixed list of tags | |
| type fixedTagsRepo struct { | |
| tags []string | |
| codehost.Repo | |
| } | |
| func (ch *fixedTagsRepo) Tags(string) ([]string, error) { return ch.tags, nil } | |
| func TestNonCanonicalSemver(t *testing.T) { | |
| root := "golang.org/x/issue24476" | |
| ch := &fixedTagsRepo{ | |
| tags: []string{ | |
| "", "huh?", "1.0.1", | |
| // what about "version 1 dot dogcow"? | |
| "v1.🐕.🐄", | |
| "v1", "v0.1", | |
| // and one normal one that should pass through | |
| "v1.0.1", | |
| }, | |
| } | |
| cr, err := newCodeRepo(ch, root, root) | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| v, err := cr.Versions("") | |
| if err != nil { | |
| t.Fatal(err) | |
| } | |
| if len(v) != 1 || v[0] != "v1.0.1" { | |
| t.Fatal("unexpected versions returned:", v) | |
| } | |
| } |