2 Commits

Author SHA1 Message Date
Serge Zaitsev
177b4914c5 add go mod download vcs provider 2019-10-02 09:41:39 +02:00
Serge Zaitsev
f906c8009a add module invalidation via DELETE request 2019-10-01 08:51:44 +02:00
14 changed files with 16 additions and 310 deletions

2
.gitignore vendored
View File

@@ -15,5 +15,3 @@
# Misc
_gopath
_gocache
dist/

View File

@@ -1,31 +0,0 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- darwin
main: ./cmd/gomodproxy/main.go
archives:
- replacements:
darwin: Darwin
linux: Linux
386: i386
amd64: x86_64
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'

View File

@@ -1,11 +0,0 @@
FROM golang:1.16.7 as build
ENV HOME /opt/app
COPY . $HOME
WORKDIR $HOME
RUN ls $HOME
RUN go build cmd/gomodproxy/main.go && \
go clean
FROM debian:buster
COPY --from=build /go/bin/ /go/bin/
ENTRYPOINT ["/go/bin/gomodproxy"]

View File

@@ -8,10 +8,6 @@ gomodproxy is a caching proxy for [Go modules].
Go 1.11 has introduced optional proxy support via GOPROXY environment variable. It is essential for use cases where you want to have better control over your dependencies and handle scenarios when GitHub is down or some open-source dependency has been removed.
## Releasing
See https://goreleaser.com/quick-start/
## Getting started
gomodproxy requires Go 1.11 or newer. There are no plans to support `vgo` or Go 1.11 beta versions.

View File

@@ -16,7 +16,7 @@ import (
"time"
"unicode"
"github.com/bilus/gomodproxy/pkg/api"
"github.com/sixt/gomodproxy/pkg/api"
"expvar"
_ "net/http/pprof"
@@ -137,7 +137,7 @@ func main() {
if len(kv) != 2 {
log.Fatal("bad git path:", path)
}
options = append(options, api.GitWithEphemeralTags(kv[0], kv[1]))
options = append(options, api.Git(kv[0], kv[1]))
}
for _, path := range vcsPaths {

4
go.mod
View File

@@ -1,5 +1,5 @@
module github.com/bilus/gomodproxy
module github.com/sixt/gomodproxy
go 1.16
go 1.13
require gopkg.in/src-d/go-git.v4 v4.13.1

14
go.sum
View File

@@ -1,37 +1,27 @@
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/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/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
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=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
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/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/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
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/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
@@ -39,7 +29,6 @@ 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.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
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=
@@ -58,15 +47,12 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e h1:D5TXcfTk7xF7hvieo4QErS3qqCB4teTffacDWr7CI+0=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190729092621-ff9f1409240a/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
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=

View File

@@ -15,8 +15,8 @@ import (
"time"
"unicode"
"github.com/bilus/gomodproxy/pkg/store"
"github.com/bilus/gomodproxy/pkg/vcs"
"github.com/sixt/gomodproxy/pkg/store"
"github.com/sixt/gomodproxy/pkg/vcs"
)
type logger = func(v ...interface{})
@@ -27,8 +27,6 @@ type api struct {
vcsPaths []vcsPath
stores []store.Store
semc chan struct{}
ephemeralTagStorage *vcs.EphemeralTagStorage
}
type vcsPath struct {
@@ -44,7 +42,6 @@ var (
apiInfo = regexp.MustCompile(`^/(?P<module>.*)/@v/(?P<version>.*).info$`)
apiMod = regexp.MustCompile(`^/(?P<module>.*)/@v/(?P<version>.*).mod$`)
apiZip = regexp.MustCompile(`^/(?P<module>.*)/@v/(?P<version>.*).zip$`)
apiTag = regexp.MustCompile(`^/tags/(?P<module>.*)/@v/(?P<version>.*)$`)
)
var (
@@ -89,28 +86,6 @@ func Git(prefix string, auth string) Option {
}
}
// GitWithEphemeralTags configures API to use a specific git client when trying
// to download a repository with the given prefix. Auth string can be a path to
// the SSK key, or a colon-separated username:password string.
func GitWithEphemeralTags(prefix string, auth string) Option {
storage := vcs.NewEphemeralTagStorage()
a := vcs.Key(auth)
if creds := strings.SplitN(auth, ":", 2); len(creds) == 2 {
a = vcs.Password(creds[0], creds[1])
}
return func(api *api) {
api.ephemeralTagStorage = storage
api.vcsPaths = append(api.vcsPaths, vcsPath{
prefix: prefix,
vcs: func(module string) vcs.VCS {
return vcs.NewGitWithEphemeralTags(api.log, api.gitdir, module, a, storage)
},
})
}
}
func CustomVCS(prefix string, cmd string) Option {
return func(api *api) {
api.vcsPaths = append(api.vcsPaths, vcsPath{
@@ -176,7 +151,6 @@ func (api *api) ServeHTTP(w http.ResponseWriter, r *http.Request) {
{"info", apiInfo, api.info},
{"api", apiMod, api.mod},
{"zip", apiZip, api.zip},
{"tag", apiTag, api.tag},
} {
if m := route.regexp.FindStringSubmatch(r.URL.Path); m != nil {
module, version := m[1], ""
@@ -327,35 +301,3 @@ func (api *api) delete(w http.ResponseWriter, r *http.Request, module, version s
}
}
}
func (api *api) tag(w http.ResponseWriter, r *http.Request, module, version string) {
api.log("api.tag", "module", module, "version", version)
taggable, ok := api.vcs(r.Context(), module).(vcs.Taggable)
if !ok {
err := fmt.Errorf("repository for module %v is not taggable", module)
api.log("api.tag", "module", module, "version", version, "error", err)
httpErrors.Add(module, 1)
http.Error(w, err.Error(), http.StatusNotFound)
return
}
defer r.Body.Close()
req := struct {
Short string `json:"short"`
}{}
err := json.NewDecoder(r.Body).Decode(&req)
if err != nil {
api.log("api.tag", "module", module, "version", version, "error", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
err = taggable.Tag(r.Context(), vcs.Version(version), req.Short)
if err != nil {
api.log("api.tag", "module", module, "version", version, "error", err)
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}

View File

@@ -6,7 +6,7 @@ import (
"os"
"path/filepath"
"github.com/bilus/gomodproxy/pkg/vcs"
"github.com/sixt/gomodproxy/pkg/vcs"
)
type disk string

View File

@@ -5,7 +5,7 @@ import (
"errors"
"sync"
"github.com/bilus/gomodproxy/pkg/vcs"
"github.com/sixt/gomodproxy/pkg/vcs"
)
type memory struct {

View File

@@ -4,7 +4,7 @@ import (
"context"
"time"
"github.com/bilus/gomodproxy/pkg/vcs"
"github.com/sixt/gomodproxy/pkg/vcs"
)
type logger = func(...interface{})

View File

@@ -63,7 +63,7 @@ func (g *gitVCS) List(ctx context.Context) ([]Version, error) {
}
list := []Version{}
var masterHash plumbing.Hash
masterHash := ""
tagPrefix := ""
if g.prefix != "" {
tagPrefix = g.prefix + "/"
@@ -71,33 +71,17 @@ func (g *gitVCS) List(ctx context.Context) ([]Version, error) {
for _, ref := range refs {
name := ref.Name()
if name == plumbing.Master {
masterHash = ref.Hash()
masterHash = ref.Hash().String()
} else if name.IsTag() && strings.HasPrefix(name.String(), "refs/tags/"+tagPrefix+"v") {
list = append(list, Version(strings.TrimPrefix(name.String(), "refs/tags/"+tagPrefix)))
}
}
if len(list) == 0 {
if masterHash.IsZero() {
if masterHash == "" {
return nil, errors.New("no tags and no master branch found")
}
masterCommit, err := repo.CommitObject(masterHash)
if err != nil {
return nil, err
}
tree, err := masterCommit.Tree()
if err != nil {
return nil, err
}
if g.isModule(tree) {
return nil, errors.New("no matching versions")
}
hashStr := masterHash.String()
short := hashStr[:12]
short := masterHash[:12]
t, err := g.Timestamp(ctx, Version("v0.0.0-20060102150405-"+short))
if err != nil {
return nil, err
@@ -109,17 +93,6 @@ func (g *gitVCS) List(ctx context.Context) ([]Version, error) {
return list, nil
}
func (g *gitVCS) isModule(tree *object.Tree) bool {
mod := "go.mod"
for path := g.prefix; path != "."; path = filepath.Dir(path) {
_, err := tree.FindEntry(filepath.Join(path, mod))
if err == nil {
return true
}
}
return false
}
func (g *gitVCS) Timestamp(ctx context.Context, version Version) (time.Time, error) {
g.log("gitVCS.Timestamp", "module", g.module, "version", version)
ci, err := g.commit(ctx, version)
@@ -143,11 +116,6 @@ func isVendoredPackage(name string) bool {
}
func (g *gitVCS) Zip(ctx context.Context, version Version) (io.ReadCloser, error) {
dirName := g.module + "@" + string(version)
return g.zipAs(ctx, version, dirName)
}
func (g *gitVCS) zipAs(ctx context.Context, version Version, dirName string) (io.ReadCloser, error) {
g.log("gitVCS.Zip", "module", g.module, "version", version)
ci, err := g.commit(ctx, version)
if err != nil {
@@ -208,7 +176,7 @@ func (g *gitVCS) zipAs(ctx context.Context, version Version, dirName string) (io
} else {
continue
}
w, err := zw.Create(filepath.Join(dirName, name))
w, err := zw.Create(filepath.Join(g.module+"@"+string(version), name))
if err != nil {
return nil, err
}
@@ -272,10 +240,6 @@ func (g *gitVCS) commit(ctx context.Context, version Version) (*object.Commit, e
if err != nil && err != git.NoErrAlreadyUpToDate {
return nil, err
}
tagPrefix := ""
if g.prefix != "" {
tagPrefix = g.prefix + "/"
}
version = Version(strings.TrimSuffix(string(version), "+incompatible"))
hash := version.Hash()
@@ -285,7 +249,7 @@ func (g *gitVCS) commit(ctx context.Context, version Version) (*object.Commit, e
return nil, err
}
tags.ForEach(func(t *plumbing.Reference) error {
if t.Name().String() == path.Join("refs/tags", tagPrefix, string(version)) {
if t.Name().String() == "refs/tags/"+string(version) {
hash = t.Hash().String()
annotated, err := repo.TagObject(t.Hash())
if err == nil {

View File

@@ -82,6 +82,6 @@ func (g *goVCS) download(ctx context.Context, version string) error {
}
func (g *goVCS) file(name string) ([]byte, error) {
path := filepath.Join(g.dir, "pkg", "mod", "cache", "download", encodeBangs(g.module), "@v", name)
path := filepath.Join(g.dir, "pkg", "mod", "cache", "download", g.module, "@v", name)
return ioutil.ReadFile(path)
}

View File

@@ -1,138 +0,0 @@
package vcs
import (
"context"
"fmt"
"io"
"time"
)
type ephemeralTag struct {
semVer Version
short string
}
type EphemeralTagStorage struct {
tagsByModule map[moduleName][]ephemeralTag
}
func NewEphemeralTagStorage() *EphemeralTagStorage {
return &EphemeralTagStorage{
tagsByModule: make(map[moduleName][]ephemeralTag),
}
}
func (s *EphemeralTagStorage) Tag(module string, semVer Version, short string) error {
tags := s.tagsByModule[module]
tmp := tags[:0]
for _, t := range tags {
if t.semVer != semVer {
tmp = append(tmp, t)
}
}
s.tagsByModule[module] = append(tmp, ephemeralTag{semVer, short})
return nil
}
func (s *EphemeralTagStorage) tags(module string) []ephemeralTag {
return s.tagsByModule[module]
}
type moduleName = string
type taggableVCS struct {
wrapped *gitVCS
module string
storage *EphemeralTagStorage
}
type Taggable interface {
Tag(ctx context.Context, semVer Version, short string) error
}
// NewGitWithEphemeralTags return a go-git VCS client implementation that
// provides information about the specific module using the given
// authentication mechanism while adding support to ephemeral tags.
func NewGitWithEphemeralTags(l logger, dir string, module string, auth Auth, storage *EphemeralTagStorage) VCS {
git := NewGit(l, dir, module, auth).(*gitVCS)
return &taggableVCS{
wrapped: git,
module: module,
storage: storage,
}
}
func (v *taggableVCS) Tag(ctx context.Context, semVer Version, short string) error {
remoteVersions, err := v.wrapped.List(ctx)
if err != nil {
return err
}
if versionExists(remoteVersions, semVer) {
return fmt.Errorf("remote version %s already exists for module %s", semVer, v.module)
}
return v.storage.Tag(v.module, semVer, short)
}
func (v *taggableVCS) List(ctx context.Context) ([]Version, error) {
remoteVersions, err := v.wrapped.List(ctx)
if err != nil {
return nil, err
}
tags := v.storage.tags(v.module)
// Remote versions win.
return appendEphemeralVersion(remoteVersions, tags...), nil
}
func appendEphemeralVersion(versions []Version, tags ...ephemeralTag) []Version {
ephemeral := make([]Version, 0)
for _, tag := range tags {
if !versionExists(versions, tag.semVer) {
ephemeral = append(ephemeral, tag.semVer)
}
}
return append(versions, ephemeral...)
}
func versionExists(versions []Version, v Version) bool {
for _, v2 := range versions {
if v == v2 {
return true
}
}
return false
}
func (v *taggableVCS) Timestamp(ctx context.Context, version Version) (time.Time, error) {
version2, err := v.resolveVersion(ctx, version)
if err != nil {
return time.Time{}, err
}
return v.wrapped.Timestamp(ctx, version2)
}
func (v *taggableVCS) Zip(ctx context.Context, version Version) (io.ReadCloser, error) {
version2, err := v.resolveVersion(ctx, version)
if err != nil {
return nil, err
}
// Zip must contain the ephemeral version.
dirName := v.module + "@" + string(version)
return v.wrapped.zipAs(ctx, version2, dirName)
}
func (v *taggableVCS) resolveVersion(ctx context.Context, version Version) (Version, error) {
for _, tag := range v.storage.tags(v.module) {
if tag.semVer == version {
// TODO(bilus): Duplicated in git.go.
t, err := v.wrapped.Timestamp(ctx, Version("v0.0.0-20060102150405-"+tag.short))
if err != nil {
return Version(""), err
}
version2 := Version(fmt.Sprintf("v0.0.0-%s-%s", t.Format("20060102150405"), tag.short))
return version2, nil
}
}
return version, nil
}