Involved Source Files
Package module defines the module.Version type along with support code.
The module.Version type is a simple Path, Version pair:
type Version struct {
Path string
Version string
}
There are no restrictions imposed directly by use of this structure,
but additional checking functions, most notably Check, verify that
a particular path, version pair is valid.
Escaped Paths
Module paths appear as substrings of file system paths
(in the download cache) and of web server URLs in the proxy protocol.
In general we cannot rely on file systems to be case-sensitive,
nor can we rely on web servers, since they read from file systems.
That is, we cannot rely on the file system to keep rsc.io/QUOTE
and rsc.io/quote separate. Windows and macOS don't.
Instead, we must never require two different casings of a file path.
Because we want the download cache to match the proxy protocol,
and because we want the proxy protocol to be possible to serve
from a tree of static files (which might be stored on a case-insensitive
file system), the proxy protocol must never require two different casings
of a URL path either.
One possibility would be to make the escaped form be the lowercase
hexadecimal encoding of the actual path bytes. This would avoid ever
needing different casings of a file path, but it would be fairly illegible
to most programmers when those paths appeared in the file system
(including in file paths in compiler errors and stack traces)
in web server logs, and so on. Instead, we want a safe escaped form that
leaves most paths unaltered.
The safe escaped form is to replace every uppercase letter
with an exclamation mark followed by the letter's lowercase equivalent.
For example,
github.com/Azure/azure-sdk-for-go -> github.com/!azure/azure-sdk-for-go.
github.com/GoogleCloudPlatform/cloudsql-proxy -> github.com/!google!cloud!platform/cloudsql-proxy
github.com/Sirupsen/logrus -> github.com/!sirupsen/logrus.
Import paths that avoid upper-case letters are left unchanged.
Note that because import paths are ASCII-only and avoid various
problematic punctuation (like : < and >), the escaped form is also ASCII-only
and avoids the same problematic punctuation.
Import paths have never allowed exclamation marks, so there is no
need to define how to escape a literal !.
Unicode Restrictions
Today, paths are disallowed from using Unicode.
Although paths are currently disallowed from using Unicode,
we would like at some point to allow Unicode letters as well, to assume that
file systems and URLs are Unicode-safe (storing UTF-8), and apply
the !-for-uppercase convention for escaping them in the file system.
But there are at least two subtle considerations.
First, note that not all case-fold equivalent distinct runes
form an upper/lower pair.
For example, U+004B ('K'), U+006B ('k'), and U+212A ('K' for Kelvin)
are three distinct runes that case-fold to each other.
When we do add Unicode letters, we must not assume that upper/lower
are the only case-equivalent pairs.
Perhaps the Kelvin symbol would be disallowed entirely, for example.
Or perhaps it would escape as "!!k", or perhaps as "(212A)".
Second, it would be nice to allow Unicode marks as well as letters,
but marks include combining marks, and then we must deal not
only with case folding but also normalization: both U+00E9 ('é')
and U+0065 U+0301 ('e' followed by combining acute accent)
look the same on the page and are treated by some file systems
as the same path. If we do allow Unicode marks in paths, there
must be some kind of normalization to allow only one canonical
encoding of any character used in an import path.
Package-Level Type Names (total 3, all are exported)
/* sort exporteds by: | */
An InvalidVersionError indicates an error specific to a version, with the
module path unknown or specified externally.
A ModuleError may wrap an InvalidVersionError, but an InvalidVersionError
must not wrap a ModuleError.
ErrerrorPseudoboolVersionstring(*T) Error() string(*T) Unwrap() error
noun returns either "version" or "pseudo-version", depending on whether
e.Version is a pseudo-version.
*T : golang.org/x/xerrors.Wrapper
*T : error
A Version (for clients, a module.Version) is defined by a module path and version pair.
These are stored in their plain (unescaped) form.
Path is a module path, like "golang.org/x/text" or "rsc.io/quote/v2".
Version is usually a semantic version in canonical form.
There are three exceptions to this general rule.
First, the top-level target of a build has no specific version
and uses Version = "".
Second, during MVS calculations the version "none" is used
to represent the decision to take no version of a given module.
Third, filesystem paths found in "replace" directives are
represented by a path with an empty version.
String returns a representation of the Version suitable for logging
(Path@Version, or just Path if Version is empty).
T : expvar.Var
T : fmt.Stringer
T : context.stringer
T : runtime.stringer
func Sort(list []Version)
func VersionError(v Version, err error) error
func golang.org/x/mod/zip.CheckZip(m Version, zipFile string) (zip.CheckedFiles, error)
func golang.org/x/mod/zip.Create(w io.Writer, m Version, files []zip.File) (err error)
func golang.org/x/mod/zip.CreateFromDir(w io.Writer, m Version, dir string) (err error)
func golang.org/x/mod/zip.Unzip(dir string, m Version, zipFile string) (err error)
func golang.org/x/mod/zip.checkZip(m Version, f *os.File) (*zip.Reader, zip.CheckedFiles, error)
Package-Level Functions (total 24, in which 16 are exported)
CanonicalVersion returns the canonical form of the version string v.
It is the same as semver.Canonical(v) except that it preserves the special build suffix "+incompatible".
Check checks that a given module path, version pair is valid.
In addition to the path being a valid module path
and the version being a valid semantic version,
the two must correspond.
For example, the path "yaml/v2" only corresponds to
semantic versions beginning with "v2.".
CheckFilePath checks that a slash-separated file path is valid.
The definition of a valid file path is the same as the definition
of a valid import path except that the set of allowed characters is larger:
all Unicode letters, ASCII digits, the ASCII space character (U+0020),
and the ASCII punctuation characters
“!#$%&()+,-.=@[]^_{}~”.
(The excluded punctuation characters, " * < > ? ` ' | / \ and :,
have special meanings in certain shells or operating systems.)
CheckFilePath may be less restrictive in the future, but see the
top-level package documentation for additional information about
subtleties of Unicode.
CheckImportPath checks that an import path is valid.
A valid import path consists of one or more valid path elements
separated by slashes (U+002F). (It must not begin with nor end in a slash.)
A valid path element is a non-empty string made up of
ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
It must not begin or end with a dot (U+002E), nor contain two dots in a row.
The element prefix up to the first dot must not be a reserved file name
on Windows, regardless of case (CON, com1, NuL, and so on). The element
must not have a suffix of a tilde followed by one or more ASCII digits
(to exclude paths elements that look like Windows short-names).
CheckImportPath may be less restrictive in the future, but see the
top-level package documentation for additional information about
subtleties of Unicode.
CheckPath checks that a module path is valid.
A valid module path is a valid import path, as checked by CheckImportPath,
with two additional constraints.
First, the leading path element (up to the first slash, if any),
by convention a domain name, must contain only lower-case ASCII letters,
ASCII digits, dots (U+002E), and dashes (U+002D);
it must contain at least one dot and cannot start with a dash.
Second, for a final path element of the form /vN, where N looks numeric
(ASCII digits and dots) must not begin with a leading zero, must not be /v1,
and must not contain any dots. For paths beginning with "gopkg.in/",
this second requirement is replaced by a requirement that the path
follow the gopkg.in server's conventions.
CheckPathMajor returns a non-nil error if the semantic version v
does not match the path major version pathMajor.
EscapePath returns the escaped form of the given module path.
It fails if the module path is invalid.
EscapeVersion returns the escaped form of the given module version.
Versions are allowed to be in non-semver form but must be valid file names
and not contain exclamation marks.
MatchPathMajor reports whether the semantic version v
matches the path major version pathMajor.
MatchPathMajor returns true if and only if CheckPathMajor returns nil.
MatchPrefixPatterns reports whether any path prefix of target matches one of
the glob patterns (as defined by path.Match) in the comma-separated globs
list. This implements the algorithm used when matching a module path to the
GOPRIVATE environment variable, as described by 'go help module-private'.
It ignores any empty or malformed patterns in the list.
PathMajorPrefix returns the major-version tag prefix implied by pathMajor.
An empty PathMajorPrefix allows either v0 or v1.
Note that MatchPathMajor may accept some versions that do not actually begin
with this prefix: namely, it accepts a 'v0.0.0-' prefix for a '.v1'
pathMajor, even though that pathMajor implies 'v1' tagging.
Sort sorts the list by Path, breaking ties by comparing Version fields.
The Version fields are interpreted as semantic versions (using semver.Compare)
optionally followed by a tie-breaking suffix introduced by a slash character,
like in "v0.0.1/go.mod".
SplitPathVersion returns prefix and major version such that prefix+pathMajor == path
and version is either empty or "/vN" for N >= 2.
As a special case, gopkg.in paths are recognized directly;
they require ".vN" instead of "/vN", and for all N, not just N >= 2.
SplitPathVersion returns with ok = false when presented with
a path whose last path element does not satisfy the constraints
applied by CheckPath, such as "example.com/pkg/v1" or "example.com/pkg/v1.2".
UnescapePath returns the module path for the given escaped path.
It fails if the escaped path is invalid or describes an invalid path.
UnescapeVersion returns the version string for the given escaped version.
It fails if the escaped form is invalid or describes an invalid version.
Versions are allowed to be in non-semver form but must be valid file names
and not contain exclamation marks.
VersionError returns a ModuleError derived from a Version and error,
or err itself if it is already such an error.
checkElem checks whether an individual path element is valid.
fileName indicates whether the element is a file name (not a directory name).
checkPath checks that a general path is valid.
It returns an error describing why but not mentioning path.
Because these checks apply to both module paths and import paths,
the caller is expected to add the "malformed ___ path %q: " prefix.
fileName indicates whether the final element of the path is a file name
(as opposed to a directory name).
fileNameOK reports whether r can appear in a file name.
For now we allow all Unicode letters but otherwise limit to pathOK plus a few more punctuation characters.
If we expand the set of allowed characters here, we have to
work harder at detecting potential case-folding and normalization collisions.
See note about "escaped paths" above.
firstPathOK reports whether r can appear in the first element of a module path.
The first element of the path must be an LDH domain name, at least for now.
To avoid case ambiguity, the domain name must be entirely lower case.
pathOK reports whether r can appear in an import path element.
Paths can be ASCII letters, ASCII digits, and limited ASCII punctuation: - . _ and ~.
This matches what "go get" has historically recognized in import paths.
TODO(rsc): We would like to allow Unicode letters, but that requires additional
care in the safe encoding (see "escaped paths" above).
splitGopkgIn is like SplitPathVersion but only for gopkg.in paths.
Package-Level Variables (only one, which is unexported)
badWindowsNames are the reserved file path elements on Windows.
See https://docs.microsoft.com/en-us/windows/desktop/fileio/naming-a-file
The pages are generated with Goldsv0.3.2-preview. (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.