modfetch

Imports

Imports #

"archive/zip"
"bytes"
"context"
"errors"
"fmt"
"io"
"io/fs"
"os"
"path"
"path/filepath"
"sort"
"strings"
"time"
"cmd/go/internal/gover"
"cmd/go/internal/modfetch/codehost"
"golang.org/x/mod/modfile"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
modzip "golang.org/x/mod/zip"
"bytes"
"errors"
"fmt"
"io"
"io/fs"
"net/url"
"os"
"path/filepath"
"strings"
"sync"
"time"
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/lockedfile"
"cmd/go/internal/web"
"golang.org/x/mod/module"
"golang.org/x/mod/sumdb"
"golang.org/x/mod/sumdb/note"
"context"
"fmt"
"io"
"sort"
"strings"
"cmd/go/internal/gover"
"cmd/go/internal/modfetch/codehost"
"golang.org/x/mod/module"
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/fs"
"math/rand"
"os"
"path/filepath"
"strconv"
"strings"
"sync"
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/gover"
"cmd/go/internal/lockedfile"
"cmd/go/internal/modfetch/codehost"
"cmd/internal/par"
"cmd/internal/robustio"
"cmd/internal/telemetry/counter"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
"archive/zip"
"bytes"
"context"
"crypto/sha256"
"encoding/base64"
"errors"
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"sort"
"strings"
"sync"
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/fsys"
"cmd/go/internal/gover"
"cmd/go/internal/lockedfile"
"cmd/go/internal/str"
"cmd/go/internal/trace"
"cmd/internal/par"
"cmd/internal/robustio"
"golang.org/x/mod/module"
"golang.org/x/mod/sumdb/dirhash"
modzip "golang.org/x/mod/zip"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/fs"
"net/url"
"path"
pathpkg "path"
"path/filepath"
"strings"
"sync"
"time"
"cmd/go/internal/base"
"cmd/go/internal/cfg"
"cmd/go/internal/modfetch/codehost"
"cmd/go/internal/web"
"golang.org/x/mod/module"
"golang.org/x/mod/semver"
"context"
"fmt"
"io"
"io/fs"
"os"
"strconv"
"time"
"cmd/go/internal/cfg"
"cmd/go/internal/modfetch/codehost"
"cmd/go/internal/vcs"
web "cmd/go/internal/web"
"cmd/internal/par"
"golang.org/x/mod/module"

Constants & Variables

ErrGoSumDirty var #

var ErrGoSumDirty = *ast.CallExpr

ErrToolchain var #

var ErrToolchain = *ast.CallExpr

GoSumFile var #

var GoSumFile string

HelpGoproxy var #

var HelpGoproxy = *ast.UnaryExpr

HelpModuleAuth var #

var HelpModuleAuth = *ast.UnaryExpr

HelpPrivate var #

var HelpPrivate = *ast.UnaryExpr

WorkspaceGoSumFiles var #

var WorkspaceGoSumFiles []string

counterErrorsGOMODCACHEEntryRelative var #

var counterErrorsGOMODCACHEEntryRelative = *ast.CallExpr

db var #

var db *sumdb.Client

dbErr var #

var dbErr error

dbName var #

var dbName string

dbOnce var #

var dbOnce sync.Once

downloadCache var #

var downloadCache *ast.IndexListExpr

downloadZipCache var #

var downloadZipCache *ast.IndexListExpr

emptyGoModHash const #

emptyGoModHash is the hash of a 1-file tree containing a 0-length go.mod. A bug caused us to write these into go.sum files for non-modules. We detect and remove them.

const emptyGoModHash = "h1:G7mAYYxgmS0lVkHyy2hEOLQCFB0DlQFTMLWggykrydY="

errLookupDisabled var #

var errLookupDisabled error = lookupDisabledError{...}

errNoproxy var #

var errNoproxy error = *ast.CallExpr

errNotCached var #

var errNotCached = *ast.CallExpr

errProxyOff var #

var errProxyOff = *ast.CallExpr

errProxyReuse var #

var errProxyReuse = *ast.CallExpr

errUseProxy var #

var errUseProxy error = *ast.CallExpr

goSum var #

var goSum struct{...}

goSumMismatch const #

const goSumMismatch = `

SECURITY ERROR
This download does NOT match an earlier download recorded in go.sum.
The bits may have been replaced on the origin server, or an attacker may
have intercepted the download attempt.

For more information, see 'go help module-auth'.
`

hashVersionMismatch const #

const hashVersionMismatch = `

SECURITY WARNING
This download is listed in go.sum, but using an unknown hash algorithm.
The download cannot be verified.

For more information, see 'go help module-auth'.

`

knownGOSUMDB var #

var knownGOSUMDB = map[string]string{...}

lookupCache var #

var lookupCache *ast.IndexListExpr

lookupLocalCache var #

var lookupLocalCache *ast.IndexListExpr

oldVgoPrefix var #

oldVgoPrefix is the prefix in the old auto-generated cached go.mod files. We stopped trying to auto-generate the go.mod files. Now we use a trivial go.mod with only a module line, and we've dropped the version prefix entirely. If we see a version prefix, that means we're looking at an old copy and should ignore it.

var oldVgoPrefix = *ast.CallExpr

proxyOnce var #

var proxyOnce struct{...}

statCacheErr var #

var statCacheErr error

statCacheOnce var #

var statCacheOnce sync.Once

sumdbMismatch const #

const sumdbMismatch = `

SECURITY ERROR
This download does NOT match the one reported by the checksum server.
The bits may have been replaced on the origin server, or an attacker may
have intercepted the download attempt.

For more information, see 'go help module-auth'.
`

traceRepo const #

const traceRepo = false

Interfaces

Repo interface #

A Repo represents a repository storing all versions of a single module. It must be safe for simultaneous use by multiple goroutines.

type Repo interface {
ModulePath() string
CheckReuse(ctx context.Context, old *codehost.Origin) error
Versions(ctx context.Context, prefix string) (*Versions, error)
Stat(ctx context.Context, rev string) (*RevInfo, error)
Latest(ctx context.Context) (*RevInfo, error)
GoMod(ctx context.Context, version string) (data []byte, err error)
Zip(ctx context.Context, dst io.Writer, version string) error
}

Structs

DownloadDirPartialError struct #

DownloadDirPartialError is returned by DownloadDir if a module directory exists but was not completely populated. DownloadDirPartialError is equivalent to fs.ErrNotExist.

type DownloadDirPartialError struct {
Dir string
Err error
}

RevInfo struct #

A RevInfo describes a single revision in a module repository.

type RevInfo struct {
Version string
Time time.Time
Name string `json:"-"`
Short string `json:"-"`
Origin *codehost.Origin `json:",omitempty"`
}

Versions struct #

A Versions describes the available versions in a module repository.

type Versions struct {
Origin *codehost.Origin `json:",omitempty"`
List []string
}

cachedInfo struct #

type cachedInfo struct {
info *RevInfo
err error
}

cachingRepo struct #

A cachingRepo is a cache around an underlying Repo, avoiding redundant calls to ModulePath, Versions, Stat, Latest, and GoMod (but not CheckReuse or Zip). It is also safe for simultaneous use by multiple goroutines (so that it can be returned from Lookup multiple times). It serializes calls to the underlying Repo.

type cachingRepo struct {
path string
versionsCache *ast.IndexListExpr
statCache *ast.IndexListExpr
latestCache *ast.IndexListExpr
gomodCache *ast.IndexListExpr
once sync.Once
initRepo func(context.Context) (Repo, error)
r Repo
}

codeRepo struct #

A codeRepo implements modfetch.Repo using an underlying codehost.Repo.

type codeRepo struct {
modPath string
code codehost.Repo
codeRoot string
codeDir string
pathMajor string
pathPrefix string
pseudoMajor string
}

dataFile struct #

type dataFile struct {
name string
data []byte
}

dataFileInfo struct #

type dataFileInfo struct {
f dataFile
}

dbClient struct #

type dbClient struct {
key string
name string
direct *url.URL
once sync.Once
base *url.URL
baseErr error
}

errRepo struct #

errRepo is a Repo that returns the same error for all operations. It is useful in conjunction with caching, since cache hits will not attempt the prohibited operations.

type errRepo struct {
modulePath string
err error
}

loggingRepo struct #

A loggingRepo is a wrapper around an underlying Repo that prints a log message at the start and end of each call. It can be inserted when debugging.

type loggingRepo struct {
r Repo
}

lookupCacheKey struct #

type lookupCacheKey struct {
proxy string
path string
}

lookupDisabledError struct #

type lookupDisabledError struct {

}

modSum struct #

type modSum struct {
mod module.Version
sum string
}

modSumStatus struct #

type modSumStatus struct {
used bool
dirty bool
}

notExistError struct #

A notExistError is like fs.ErrNotExist, but with a custom message

type notExistError struct {
err error
}

proxyRepo struct #

type proxyRepo struct {
url *url.URL
path string
redactedBase string
listLatestOnce sync.Once
listLatest *RevInfo
listLatestErr error
}

proxySpec struct #

type proxySpec struct {
url string
fallBackOnError bool
}

toolchainRepo struct #

A toolchainRepo is a synthesized repository reporting Go toolchain versions. It has path "go" or "toolchain". The "go" repo reports versions like "1.2". The "toolchain" repo reports versions like "go1.2". Note that the repo ONLY reports versions. It does not actually support downloading of the actual toolchains. Instead, that is done using the regular repo code with "golang.org/toolchain". The naming conflict is unfortunate: "golang.org/toolchain" should perhaps have been "go.dev/dl", but it's too late. For clarity, this file refers to golang.org/toolchain as the "DL" repo, the one you can actually download.

type toolchainRepo struct {
path string
repo Repo
}

zipFile struct #

type zipFile struct {
name string
f *zip.File
}

Functions

CachePath function #

func CachePath(ctx context.Context, m module.Version, suffix string) (string, error)

CheckReuse method #

func (r *cachingRepo) CheckReuse(ctx context.Context, old *codehost.Origin) error

CheckReuse method #

func (r *codeRepo) CheckReuse(ctx context.Context, old *codehost.Origin) error

CheckReuse method #

func (p *proxyRepo) CheckReuse(ctx context.Context, old *codehost.Origin) error

CheckReuse method #

func (r *toolchainRepo) CheckReuse(ctx context.Context, old *codehost.Origin) error

CheckReuse method #

func (r errRepo) CheckReuse(ctx context.Context, old *codehost.Origin) error

CheckReuse method #

func (l *loggingRepo) CheckReuse(ctx context.Context, old *codehost.Origin) (err error)

Download function #

Download downloads the specific module version to the local download cache and returns the name of the directory corresponding to the root of the module's file tree.

func Download(ctx context.Context, mod module.Version) (dir string, err error)

DownloadDir function #

DownloadDir returns the directory to which m should have been downloaded. An error will be returned if the module path or version cannot be escaped. An error satisfying errors.Is(err, fs.ErrNotExist) will be returned along with the directory if the directory does not exist or if the directory is not completely populated.

func DownloadDir(ctx context.Context, m module.Version) (string, error)

DownloadZip function #

DownloadZip downloads the specific module version to the local zip cache and returns the name of the zip file.

func DownloadZip(ctx context.Context, mod module.Version) (zipfile string, err error)

Error method #

func (e *DownloadDirPartialError) Error() string

Error method #

func (e notExistError) Error() string

Error method #

func (lookupDisabledError) Error() string

GoMod method #

func (l *loggingRepo) GoMod(ctx context.Context, version string) ([]byte, error)

GoMod method #

func (r *codeRepo) GoMod(ctx context.Context, version string) (data []byte, err error)

GoMod function #

GoMod is like Lookup(ctx, path).GoMod(rev) but avoids the repository path resolution in Lookup if the result is already cached on local disk.

func GoMod(ctx context.Context, path string, rev string) ([]byte, error)

GoMod method #

func (r *cachingRepo) GoMod(ctx context.Context, version string) ([]byte, error)

GoMod method #

func (p *proxyRepo) GoMod(ctx context.Context, version string) ([]byte, error)

GoMod method #

func (r *toolchainRepo) GoMod(ctx context.Context, version string) (data []byte, err error)

GoMod method #

func (r errRepo) GoMod(ctx context.Context, version string) ([]byte, error)

GoModFile function #

GoModFile is like GoMod but returns the name of the file containing the cached information.

func GoModFile(ctx context.Context, path string, version string) (string, error)

GoModSum function #

GoModSum returns the go.sum entry for the module version's go.mod file. (That is, it returns the entry listed in go.sum as "path version/go.mod".)

func GoModSum(ctx context.Context, path string, version string) (string, error)

HaveSum function #

HaveSum returns true if the go.sum file contains an entry for mod. The entry's hash must be generated with a known hash algorithm. mod.Version may have a "/go.mod" suffix to distinguish sums for .mod and .zip files.

func HaveSum(mod module.Version) bool

InfoFile function #

InfoFile is like Lookup(ctx, path).Stat(version) but also returns the name of the file containing the cached information.

func InfoFile(ctx context.Context, path string, version string) (*RevInfo, string, error)

Is method #

func (notExistError) Is(target error) bool

Is method #

func (e *DownloadDirPartialError) Is(err error) bool

IsDir method #

func (fi dataFileInfo) IsDir() bool

Latest method #

func (r *toolchainRepo) Latest(ctx context.Context) (*RevInfo, error)

Latest method #

func (r *cachingRepo) Latest(ctx context.Context) (*RevInfo, error)

Latest method #

func (p *proxyRepo) Latest(ctx context.Context) (*RevInfo, error)

Latest method #

func (r *codeRepo) Latest(ctx context.Context) (*RevInfo, error)

Latest method #

func (r errRepo) Latest(ctx context.Context) (*RevInfo, error)

Latest method #

func (l *loggingRepo) Latest(ctx context.Context) (*RevInfo, error)

LegacyGoMod function #

LegacyGoMod generates a fake go.mod file for a module that doesn't have one. The go.mod file contains a module directive and nothing else: no go version, no requirements. We used to try to build a go.mod reflecting pre-existing package management metadata files, but the conversion was inherently imperfect (because those files don't have exactly the same semantics as go.mod) and, when done for dependencies in the middle of a build, impossible to correct. So we stopped.

func LegacyGoMod(modPath string) []byte

Log method #

func (*dbClient) Log(msg string)

Lookup function #

Lookup returns the module with the given module path, fetched through the given proxy. The distinguished proxy "direct" indicates that the path should be fetched from its origin, and "noproxy" indicates that the patch should be fetched directly only if GONOPROXY matches the given path. For the distinguished proxy "off", Lookup always returns a Repo that returns a non-nil error for every method call. A successful return does not guarantee that the module has any defined versions.

func Lookup(ctx context.Context, proxy string, path string) Repo

LookupLocal function #

LookupLocal will only use local VCS information to fetch the Repo.

func LookupLocal(ctx context.Context, path string) Repo

Lstat method #

func (f zipFile) Lstat() (fs.FileInfo, error)

Lstat method #

func (f dataFile) Lstat() (fs.FileInfo, error)

ModTime method #

func (fi dataFileInfo) ModTime() time.Time

Mode method #

func (fi dataFileInfo) Mode() fs.FileMode

ModulePath method #

func (r *cachingRepo) ModulePath() string

ModulePath method #

func (l *loggingRepo) ModulePath() string

ModulePath method #

func (r *toolchainRepo) ModulePath() string

ModulePath method #

func (r errRepo) ModulePath() string

ModulePath method #

func (p *proxyRepo) ModulePath() string

ModulePath method #

func (r *codeRepo) ModulePath() string

Name method #

func (fi dataFileInfo) Name() string

Open method #

func (f dataFile) Open() (io.ReadCloser, error)

Open method #

func (f zipFile) Open() (io.ReadCloser, error)

Path method #

func (f zipFile) Path() string

Path method #

func (f dataFile) Path() string

ReadCache method #

ReadCache reads cached lookups or tiles from GOPATH/pkg/mod/cache/download/sumdb, which will be deleted by "go clean -modcache".

func (*dbClient) ReadCache(file string) ([]byte, error)

ReadConfig method #

ReadConfig reads the key from c.key and otherwise reads the config (a latest tree head) from GOPATH/pkg/sumdb/.

func (c *dbClient) ReadConfig(file string) (data []byte, err error)

ReadRemote method #

func (c *dbClient) ReadRemote(path string) ([]byte, error)

RecordedSum function #

RecordedSum returns the sum if the go.sum file contains an entry for mod. The boolean reports true if an entry was found or false if no entry found or two conflicting sums are found. The entry's hash must be generated with a known hash algorithm. mod.Version may have a "/go.mod" suffix to distinguish sums for .mod and .zip files.

func RecordedSum(mod module.Version) (sum string, ok bool)

RemoveAll function #

RemoveAll removes a directory written by Download or Unzip, first applying any permission changes needed to do so.

func RemoveAll(dir string) error

Reset function #

Reset resets globals in the modfetch package, so previous loads don't affect contents of go.sum files.

func Reset()

SecurityError method #

func (*dbClient) SecurityError(msg string)

SideLock function #

SideLock locks a file within the module cache that previously guarded edits to files outside the cache, such as go.sum and go.mod files in the user's working directory. If err is nil, the caller MUST eventually call the unlock function.

func SideLock(ctx context.Context) (unlock func(), err error)

Size method #

func (fi dataFileInfo) Size() int64

Stat method #

func (r *toolchainRepo) Stat(ctx context.Context, rev string) (*RevInfo, error)

Stat method #

func (r errRepo) Stat(ctx context.Context, rev string) (*RevInfo, error)

Stat method #

func (p *proxyRepo) Stat(ctx context.Context, rev string) (*RevInfo, error)

Stat method #

func (r *cachingRepo) Stat(ctx context.Context, rev string) (*RevInfo, error)

Stat method #

func (l *loggingRepo) Stat(ctx context.Context, rev string) (*RevInfo, error)

Stat method #

func (r *codeRepo) Stat(ctx context.Context, rev string) (*RevInfo, error)

String method #

func (fi dataFileInfo) String() string

Sum function #

Sum returns the checksum for the downloaded copy of the given module, if present in the download cache.

func Sum(ctx context.Context, mod module.Version) string

Sys method #

func (fi dataFileInfo) Sys() any

TidyGoSum function #

TidyGoSum returns a tidy version of the go.sum file. A missing go.sum file is treated as if empty.

func TidyGoSum(keep map[module.Version]bool) (before []byte, after []byte)

TrimGoSum function #

TrimGoSum trims go.sum to contain only the modules needed for reproducible builds. keep is used to check whether a sum should be retained in go.mod. It should have entries for both module content sums and go.mod sums (version ends with "/go.mod").

func TrimGoSum(keep map[module.Version]bool)

TryProxies function #

TryProxies iterates f over each configured proxy (including "noproxy" and "direct" if applicable) until f returns no error or until f returns an error that is not equivalent to fs.ErrNotExist on a proxy configured not to fall back on errors. TryProxies then returns that final error. If GOPROXY is set to "off", TryProxies invokes f once with the argument "off".

func TryProxies(f func(proxy string) error) error

Unwrap method #

func (e notExistError) Unwrap() error

Unzip function #

Unzip is like Download but is given the explicit zip file to use, rather than downloading it. This is used for the GOFIPS140 zip files, which ship in the Go distribution itself.

func Unzip(ctx context.Context, mod module.Version, zipfile string) (dir string, err error)

Versions method #

func (r errRepo) Versions(ctx context.Context, prefix string) (*Versions, error)

Versions method #

func (l *loggingRepo) Versions(ctx context.Context, prefix string) (*Versions, error)

Versions method #

func (r *cachingRepo) Versions(ctx context.Context, prefix string) (*Versions, error)

Versions method #

func (r *codeRepo) Versions(ctx context.Context, prefix string) (*Versions, error)

Versions method #

func (r *toolchainRepo) Versions(ctx context.Context, prefix string) (*Versions, error)

Versions method #

func (p *proxyRepo) Versions(ctx context.Context, prefix string) (*Versions, error)

WriteCache method #

WriteCache updates cached lookups or tiles.

func (*dbClient) WriteCache(file string, data []byte)

WriteConfig method #

WriteConfig rewrites the latest tree head.

func (*dbClient) WriteConfig(file string, old []byte, new []byte) error

WriteGoSum function #

WriteGoSum writes the go.sum file if it needs to be updated. keep is used to check whether a newly added sum should be saved in go.sum. It should have entries for both module content sums and go.mod sums (version ends with "/go.mod"). Existing sums will be preserved unless they have been marked for deletion with TrimGoSum.

func WriteGoSum(ctx context.Context, keep map[module.Version]bool, readonly bool) error

Zip method #

func (r *cachingRepo) Zip(ctx context.Context, dst io.Writer, version string) error

Zip method #

func (p *proxyRepo) Zip(ctx context.Context, dst io.Writer, version string) error

Zip method #

func (r *codeRepo) Zip(ctx context.Context, dst io.Writer, version string) error

Zip method #

func (l *loggingRepo) Zip(ctx context.Context, dst io.Writer, version string) error

Zip method #

func (r *toolchainRepo) Zip(ctx context.Context, dst io.Writer, version string) error

Zip method #

func (r errRepo) Zip(ctx context.Context, dst io.Writer, version string) error

addModSumLocked function #

addModSumLocked adds the pair mod,h to go.sum. goSum.mu must be locked.

func addModSumLocked(mod module.Version, h string)

appendIncompatibleVersions method #

appendIncompatibleVersions appends "+incompatible" versions to list if appropriate, returning the final list. The incompatible list contains candidate versions without the '+incompatible' prefix. Both list and incompatible must be sorted in semantic order.

func (r *codeRepo) appendIncompatibleVersions(ctx context.Context, origin *codehost.Origin, list []string, incompatible []string) (*Versions, error)

cacheDir function #

func cacheDir(ctx context.Context, path string) (string, error)

canReplaceMismatchedVersionDueToBug method #

canReplaceMismatchedVersionDueToBug reports whether versions of r could replace versions of mpath with otherwise-mismatched major versions due to a historical bug in the Go command (golang.org/issue/34254).

func (r *codeRepo) canReplaceMismatchedVersionDueToBug(mpath string) bool

checkCacheDir function #

checkCacheDir checks if the directory specified by GOMODCACHE exists. An error is returned if it does not.

func checkCacheDir(ctx context.Context) error

checkGoMod function #

checkGoMod checks the given module's go.mod checksum; data is the go.mod content.

func checkGoMod(path string, version string, data []byte) error

checkMod function #

checkMod checks the given module's checksum and Go version.

func checkMod(ctx context.Context, mod module.Version)

checkModSum function #

checkModSum checks that the recorded checksum for mod is h. mod.Version may have the additional suffix "/go.mod" to request the checksum for the module's go.mod file only.

func checkModSum(mod module.Version, h string) error

checkSumDB function #

checkSumDB checks the mod, h pair against the Go checksum database. It calls base.Fatalf if the hash is to be rejected.

func checkSumDB(mod module.Version, h string) error

convert method #

convert converts a version as reported by the code host to a version as interpreted by the module system. If statVers is a valid module version, it is used for the Version field. Otherwise, the Version is derived from the passed-in info and recent tags.

func (r *codeRepo) convert(ctx context.Context, info *codehost.RevInfo, statVers string) (revInfo *RevInfo, err error)

dbDial function #

func dbDial() (dbName string, db *sumdb.Client, err error)

dlToGo function #

dlToGo converts a DL module version like "v0.0.1-go1.2.linux-amd64" to a Go version like "1.2".

func dlToGo(v string) (string, bool)

download function #

func download(ctx context.Context, mod module.Version) (dir string, err error)

downloadZip function #

func downloadZip(ctx context.Context, mod module.Version, zipfile string) (err error)

findDir method #

findDir locates the directory within the repo containing the module. If r.pathMajor is non-empty, this can be either r.codeDir or — if a go.mod file exists — r.codeDir/r.pathMajor[1:].

func (r *codeRepo) findDir(ctx context.Context, version string) (rev string, dir string, gomod []byte, err error)

getBody method #

func (p *proxyRepo) getBody(ctx context.Context, path string) (r io.ReadCloser, redactedURL string, err error)

getBytes method #

func (p *proxyRepo) getBytes(ctx context.Context, path string) ([]byte, error)

goModSum function #

goModSum returns the checksum for the go.mod contents.

func goModSum(data []byte) (string, error)

goToDL function #

goToDL converts a Go version like "1.2" to a DL module version like "v0.0.1-go1.2.linux-amd64".

func goToDL(v string, goos string, goarch string) string

hasPathPrefix function #

hasPathPrefix reports whether the path s begins with the elements in prefix.

func hasPathPrefix(s string, prefix string) bool

hashZip function #

hashZip reads the zip file opened in f, then writes the hash to ziphashfile, overwriting that file if it exists. If the hash does not match go.sum (or the sumdb if enabled), hashZip returns an error and does not write ziphashfile.

func hashZip(mod module.Version, zipfile string, ziphashfile string) (err error)

haveModSumLocked function #

haveModSumLocked reports whether the pair mod,h is already listed in go.sum. If it finds a conflicting pair instead, it calls base.Fatalf. goSum.mu must be locked.

func haveModSumLocked(mod module.Version, h string) bool

initBase method #

initBase determines the base URL for connecting to the database. Determining the URL requires sending network traffic to proxies, so this work is delayed until we need to download something from the database. If everything we need is in the local cache and c.ReadRemote is never called, we will never do this work.

func (c *dbClient) initBase()

initGoSum function #

initGoSum initializes the go.sum data. The boolean it returns reports whether the use of go.sum is now enabled. The goSum lock must be held.

func initGoSum() (bool, error)

isMajor function #

isMajor reports whether the versions allowed for mpath are compatible with the major version(s) implied by pathMajor, or false if mpath has an invalid version suffix.

func isMajor(mpath string, pathMajor string) bool

isValidSum function #

isValidSum returns true if data is the valid contents of a zip hash file. Certain critical files are written to disk by first truncating then writing the actual bytes, so that if the write fails the corrupt file should contain at least one of the null bytes written by the truncate operation.

func isValidSum(data []byte) bool

latest method #

func (p *proxyRepo) latest(ctx context.Context) (*RevInfo, error)

latestFromList method #

func (p *proxyRepo) latestFromList(ctx context.Context, allLine []string) (*RevInfo, error)

lockVersion function #

lockVersion locks a file within the module cache that guards the downloading and extraction of the zipfile for the given module version.

func lockVersion(ctx context.Context, mod module.Version) (unlock func(), err error)

logCall function #

logCall prints a log message using format and args and then also returns a function that will print the same message again, along with the elapsed time. Typical usage is: defer logCall("hello %s", arg)() Note the final ().

func logCall(format string, args ...any) func()

lookup function #

lookup returns the module with the given module path.

func lookup(ctx context.Context, proxy string, path string) (r Repo, err error)

lookupCodeRepo function #

func lookupCodeRepo(ctx context.Context, rr *vcs.RepoRoot, local bool) (codehost.Repo, error)

lookupDirect function #

func lookupDirect(ctx context.Context, path string) (Repo, error)

lookupSumDB function #

lookupSumDB returns the Go checksum database's go.sum lines for the given module, along with the name of the database.

func lookupSumDB(mod module.Version) (dbname string, lines []string, err error)

lookupSumDB function #

func lookupSumDB(mod module.Version) (string, []string, error)

makeDirsReadOnly function #

makeDirsReadOnly makes a best-effort attempt to remove write permissions for dir and its transitive contents.

func makeDirsReadOnly(dir string)

modPrefix method #

func (r *codeRepo) modPrefix(rev string) string

newCachingRepo function #

func newCachingRepo(ctx context.Context, path string, initRepo func(context.Context) (Repo, error)) *cachingRepo

newCodeRepo function #

newCodeRepo returns a Repo that reads the source code for the module with the given path, from the repo stored in code, with the root of the repo containing the path given by codeRoot.

func newCodeRepo(code codehost.Repo, codeRoot string, path string) (Repo, error)

newLoggingRepo function #

func newLoggingRepo(r Repo) *loggingRepo

newProxyRepo function #

func newProxyRepo(baseURL string, path string) (Repo, error)

notExistErrorf function #

func notExistErrorf(format string, args ...any) error

pathEscape function #

pathEscape escapes s so it can be used in a path. That is, it escapes things like ? and # (which really shouldn't appear anyway). It does not escape / to %2F: our REST API is designed so that / can be left as is.

func pathEscape(s string) string

proxyList function #

func proxyList() ([]proxySpec, error)

readDiskCache function #

readDiskCache is the generic "read from a cache file" implementation. It takes the revision and an identifying suffix for the kind of data being cached. It returns the name of the cache file and the content of the file. If the read fails, the caller can use writeDiskCache(file, data) to write a new cache entry.

func readDiskCache(ctx context.Context, path string, rev string, suffix string) (file string, data []byte, err error)

readDiskGoMod function #

readDiskGoMod reads a cached go.mod file from disk, returning the name of the cache file and the result. If the read fails, the caller can use writeDiskGoMod(file, data) to write a new cache entry.

func readDiskGoMod(ctx context.Context, path string, rev string) (file string, data []byte, err error)

readDiskStat function #

readDiskStat reads a cached stat result from disk, returning the name of the cache file and the result. If the read fails, the caller can use writeDiskStat(file, info) to write a new cache entry.

func readDiskStat(ctx context.Context, path string, rev string) (file string, info *RevInfo, err error)

readDiskStatByHash function #

readDiskStatByHash is a fallback for readDiskStat for the case where rev is a commit hash instead of a proper semantic version. In that case, we look for a cached pseudo-version that matches the commit hash. If we find one, we use it. This matters most for converting legacy package management configs, when we are often looking up commits by full hash. Without this check we'd be doing network I/O to the remote repo just to find out about a commit we already know about (and have cached under its pseudo-version).

func readDiskStatByHash(ctx context.Context, path string, rev string) (file string, info *RevInfo, err error)

readGoSum function #

readGoSum parses data, which is the content of file, and adds it to goSum.m. The goSum lock must be held.

func readGoSum(dst map[module.Version][]string, file string, data []byte)

readGoSumFile function #

func readGoSumFile(dst map[module.Version][]string, file string) (bool, error)

repo method #

func (r *cachingRepo) repo(ctx context.Context) Repo

retractedVersions method #

func (r *codeRepo) retractedVersions(ctx context.Context) (func(string) bool, error)

revToRev method #

func (r *codeRepo) revToRev(rev string) string

rewriteVersionList function #

rewriteVersionList rewrites the version list in dir after a new *.mod file has been written.

func rewriteVersionList(ctx context.Context, dir string) (err error)

sumInWorkspaceModulesLocked function #

func sumInWorkspaceModulesLocked(m module.Version) bool

tempFile function #

tempFile creates a new temporary file with given permission bits.

func tempFile(ctx context.Context, dir string, prefix string, perm fs.FileMode) (f *os.File, err error)

tidyGoSum function #

tidyGoSum returns a tidy version of the go.sum file. The goSum lock must be held.

func tidyGoSum(data []byte, keep map[module.Version]bool) []byte

unzip function #

func unzip(ctx context.Context, mod module.Version, zipfile string) (dir string, err error)

useSumDB function #

useSumDB reports whether to use the Go checksum database for the given module.

func useSumDB(mod module.Version) bool

useSumDB function #

func useSumDB(mod module.Version) bool

validatePseudoVersion method #

validatePseudoVersion checks that version has a major version compatible with r.modPath and encodes a base version and commit metadata that agrees with info. Note that verifying a nontrivial base version in particular may be somewhat expensive: in order to do so, r.code.DescendsFrom will need to fetch at least enough of the commit history to find a path between version and its base. Fortunately, many pseudo-versions — such as those for untagged repositories — have trivial bases!

func (r *codeRepo) validatePseudoVersion(ctx context.Context, info *codehost.RevInfo, version string) (err error)

versionError method #

versionError returns err wrapped in a ModuleError for p.path.

func (p *proxyRepo) versionError(version string, err error) error

versionToRev method #

func (r *codeRepo) versionToRev(version string) (rev string, err error)

writeDiskCache function #

writeDiskCache is the generic "write to a cache file" implementation. The file must have been returned by a previous call to readDiskCache.

func writeDiskCache(ctx context.Context, file string, data []byte) error

writeDiskGoMod function #

writeDiskGoMod writes a go.mod cache entry. The file name must have been returned by a previous call to readDiskGoMod.

func writeDiskGoMod(ctx context.Context, file string, text []byte) error

writeDiskStat function #

writeDiskStat writes a stat result cache entry. The file name must have been returned by a previous call to readDiskStat.

func writeDiskStat(ctx context.Context, file string, info *RevInfo) error

Generated with Arrow