mirror of
https://github.com/golang/go.git
synced 2024-09-21 10:28:27 +00:00
[dev.regabi] all: merge master (dab3e5a
) into dev.regabi
This merge had two conflicts to resolve: 1. The embed code on master had somewhat substantially diverged, so this CL tediously backported the changes to dev.regabi. In particular, I went through all of the embed changes to gc/{embed,noder,syntax}.go and made sure the analogous code on dev.regabi in noder/noder.go and staticdata/embed.go mirrors it. 2. The init-cycle reporting code on master was extended slightly to track already visited declarations to avoid exponential behavior. The same fix is applied on dev.regabi, just using ir.NameSet instead of map[ir.Node]bool. Conflicts: - src/cmd/compile/internal/gc/embed.go - src/cmd/compile/internal/gc/noder.go - src/cmd/compile/internal/gc/syntax.go - src/cmd/compile/internal/pkginit/initorder.go - src/embed/internal/embedtest/embed_test.go - src/go/types/stdlib_test.go Merge List: + 2021-01-22dab3e5affe
runtime: switch runtime to libc for openbsd/amd64 + 2021-01-22a1b53d85da
cmd/go: add documentation for test and xtest fields output by go list + 2021-01-22b268b60774
runtime: remove pthread_kill/pthread_self for openbsd + 2021-01-22ec4051763d
runtime: fix typo in mgcscavenge.go + 2021-01-227ece3a7b17
net/http: fix flaky TestDisableKeepAliveUpgrade + 2021-01-2250cba0506f
time: clarify Timer.Reset behavior on AfterFunc Timers + 2021-01-22cf10e69f17
doc/go1.16: mention net/http.Transport.GetProxyConnectHeader + 2021-01-22ec1b945265
doc/go1.16: mention path/filepath.WalkDir + 2021-01-2211def3d40b
doc/go1.16: mention syscall.AllThreadsSyscall + 2021-01-2107b0235609
doc/go1.16: add notes about package-specific fs.FS changes + 2021-01-21e2b4f1fea5
doc/go1.16: minor formatting fix + 2021-01-219f43a9e07b
doc/go1.16: mention new debug/elf constants + 2021-01-213c2f11ba5b
cmd/go: overwrite program name with full path + 2021-01-21953d1feca9
all: introduce and use internal/execabs + 2021-01-21b186e4d70d
cmd/go: add test case for cgo CC setting + 2021-01-215a8a2265fb
cmd/cgo: report exec errors a bit more clearly + 2021-01-2146e2e2e9d9
cmd/go: pass resolved CC, GCCGO to cgo + 2021-01-213d40895e36
runtime: switch openbsd/arm64 to pthreads + 2021-01-21d95ca91380
crypto/elliptic: fix P-224 field reduction + 2021-01-20ecf4ebf100
cmd/internal/moddeps: check content of all modules in GOROOT + 2021-01-20d2d155d1ae
runtime: don't adjust timer pp field in timerWaiting status + 2021-01-20803d18fc6c
cmd/go: set Incomplete field on go list output if no files match embed + 2021-01-206e243ce71d
cmd/go: have go mod vendor copy embedded files in subdirs + 2021-01-20be28e5abc5
cmd/go: fix mod_get_fallback test + 2021-01-20928bda4f4a
runtime: convert openbsd/amd64 locking to libc + 2021-01-19824f2d635c
cmd/go: allow go fmt to complete when embedded file is missing + 2021-01-190575e35e50
cmd/compile: require 'go 1.16' go.mod line for //go:embed + 2021-01-19ccb2e90688
cmd/link: exit before Asmb2 if error + 2021-01-19ca5774a5a5
embed: treat uninitialized FS as empty + 2021-01-19d047c91a6c
cmd/link,runtime: switch openbsd/amd64 to pthreads + 2021-01-1961debffd97
runtime: factor out usesLibcall + 2021-01-199fed39d281
runtime: factor out mStackIsSystemAllocated + 2021-01-18dbab079835
runtime: free Windows event handles after last lock is dropped + 2021-01-185a8fbb0d2d
os: do not close syscall.Stdin in TestReadStdin + 2021-01-15682a1d2176
runtime: detect errors in DuplicateHandle + 2021-01-159f83418b83
cmd/link: remove GOROOT write in TestBuildForTvOS + 2021-01-15ec9470162f
cmd/compile: allow embed into any string or byte slice type + 2021-01-1554198b04db
cmd/compile: disallow embed of var inside func + 2021-01-15b386c735e7
cmd/go: fix go generate docs + 2021-01-15bb5075a525
syscall: remove RtlGenRandom and move it into internal/syscall + 2021-01-151deae0b597
os: invoke processKiller synchronously in testKillProcess + 2021-01-15ff196c3e84
crypto/x509: update iOS bundled roots to version 55188.40.9 + 2021-01-14e125ccd10e
cmd/go: in 'go mod edit', validate versions given to -retract and -exclude + 2021-01-14eb330020dc
cmd/dist, cmd/go: pass -arch for C compilation on Darwin + 2021-01-1484e8a06f62
cmd/cgo: remove unnecessary space in cgo export header + 2021-01-140c86b999c3
cmd/test2json: document passing -test.paniconexit0 + 2021-01-149135795891
cmd/go/internal/load: report positions for embed errors + 2021-01-14d9b79e53bb
cmd/compile: fix wrong complement for arm64 floating-point comparisons + 2021-01-14c73232d08f
cmd/go/internal/load: refactor setErrorPos to PackageError.setPos + 2021-01-146aa28d3e06
go/build: report positions for go:embed directives + 2021-01-137eb31d999c
cmd/go: add hints to more missing sum error messages + 2021-01-12ba76567bc2
cmd/go/internal/modload: delete unused *mvsReqs.next method + 2021-01-12665def2c11
encoding/asn1: document unmarshaling behavior for IMPLICIT string fields + 2021-01-1181ea89adf3
cmd/go: fix non-script staleness checks interacting badly with GOFLAGS + 2021-01-11759309029f
doc: update editors.html for Go 1.16 + 2021-01-11c3b4c7093a
cmd/internal/objfile: don't require runtime.symtab symbol for XCOFF + 2021-01-0859bfc18e34
cmd/go: add hint to read 'go help vcs' to GOVCS errors + 2021-01-08cd6f3a54e4
cmd/go: revise 'go help' documentation for modules + 2021-01-086192b98751
cmd/go: make hints in error messages more consistent + 2021-01-0825886cf4bd
cmd/go: preserve sums for indirect deps fetched by 'go mod download' + 2021-01-086250833911
runtime/metrics: mark histogram metrics as cumulative + 2021-01-088f6a9acbb3
runtime/metrics: remove unused StopTheWorld Description field + 2021-01-086598c65646
cmd/compile: fix exponential-time init-cycle reporting + 2021-01-08fefad1dc85
test: fix timeout code for invoking compiler + 2021-01-086728118e0a
cmd/go: pass signals forward during "go tool" + 2021-01-08e65c543f3c
go/build/constraint: add parser for build tag constraint expressions + 2021-01-080c5afc4fb7
testing/fstest,os: clarify racy behavior of TestFS + 2021-01-0832afcc9436
runtime/metrics: change unit on *-by-size metrics to match bucket unit + 2021-01-08c6513bca5a
io/fs: minor corrections to Glob doc + 2021-01-08304f769ffc
cmd/compile: don't short-circuit copies whose source is volatile + 2021-01-08ae97717133
runtime,runtime/metrics: use explicit histogram boundaries + 2021-01-08a9ccd2d795
go/build: skip string literal while findEmbed + 2021-01-08d92f8add32
archive/tar: fix typo in comment + 2021-01-08cab1202183
cmd/link: accept extra blocks in TestFallocate + 2021-01-08ee4d32249b
io/fs: minor corrections to Glob release date + 2021-01-0854bd1ccce2
cmd: update to latest golang.org/x/tools + 2021-01-079ec21a8f34
Revert "reflect: support multiple keys in struct tags" + 2021-01-07091414b5b7
io/fs: correct WalkDirFunc documentation + 2021-01-079b55088d6b
doc/go1.16: add release note for disallowing non-ASCII import paths + 2021-01-07fa90aaca7d
cmd/compile: fix late expand_calls leaf type for OpStructSelect/OpArraySelect + 2021-01-077cee66d4cb
cmd/go: add documentation for Embed fields in go list output + 2021-01-07e60cffa4ca
html/template: attach functions to namespace + 2021-01-076da2d3b7d7
cmd/link: fix typo in asm.go + 2021-01-07df81a15819
runtime: check mips64 VDSO clock_gettime return code + 2021-01-064787e906cf
crypto/x509: rollback new CertificateRequest fields + 2021-01-06c9658bee93
cmd/go: make module suggestion more friendly + 2021-01-064c668b25c6
runtime/metrics: fix panic message for Float64Histogram + 2021-01-06d2131704a6
net/http/httputil: fix deadlock in DumpRequestOut + 2021-01-053e1e13ce6d
cmd/go: set cfg.BuildMod to "readonly" by default with no module root + 2021-01-050b0d004983
cmd/go: pass embedcfg to gccgo if supported + 2021-01-051b85e7c057
cmd/go: don't scan gccgo standard library packages for imports + 2021-01-056b37b15d95
runtime: don't take allglock in tracebackothers + 2021-01-049eef49cfa6
math/rand: fix typo in comment + 2021-01-04b01fb2af9e
testing/fstest: fix typo in error message + 2021-01-013dd5867605
doc: 2021 is the Year of the Gopher + 2020-12-3195ce805d14
io/fs: remove darwin/arm64 special condition + 2020-12-3020d0991b86
lib/time, time/tzdata: update tzdata to 2020f + 2020-12-30ed301733bb
misc/cgo/testcarchive: remove special flags for Darwin/ARM + 2020-12-300ae2e032f2
misc/cgo/test: enable TestCrossPackageTests on darwin/arm64 + 2020-12-29780b4de16b
misc/ios: fix wording for command line instructions + 2020-12-29b4a71c95d2
doc/go1.16: reference misc/ios/README for how to build iOS programs + 2020-12-29f83e0f6616
misc/ios: add to README how to build ios executables + 2020-12-284fd9455882
io/fs: fix typo in comment Change-Id: I2f257bbc5fbb05f15c2d959f8cfe0ce13b083538
This commit is contained in:
commit
7e0a81d280
@ -1,15 +1,6 @@
|
||||
pkg archive/zip, method (*ReadCloser) Open(string) (fs.File, error)
|
||||
pkg archive/zip, method (*Reader) Open(string) (fs.File, error)
|
||||
pkg crypto/x509, method (SystemRootsError) Unwrap() error
|
||||
pkg crypto/x509, type CertificateRequest struct, BasicConstraintsValid bool
|
||||
pkg crypto/x509, type CertificateRequest struct, ExtKeyUsage []ExtKeyUsage
|
||||
pkg crypto/x509, type CertificateRequest struct, IsCA bool
|
||||
pkg crypto/x509, type CertificateRequest struct, KeyUsage KeyUsage
|
||||
pkg crypto/x509, type CertificateRequest struct, MaxPathLen int
|
||||
pkg crypto/x509, type CertificateRequest struct, MaxPathLenZero bool
|
||||
pkg crypto/x509, type CertificateRequest struct, PolicyIdentifiers []asn1.ObjectIdentifier
|
||||
pkg crypto/x509, type CertificateRequest struct, SubjectKeyId []uint8
|
||||
pkg crypto/x509, type CertificateRequest struct, UnknownExtKeyUsage []asn1.ObjectIdentifier
|
||||
pkg debug/elf, const DT_ADDRRNGHI = 1879047935
|
||||
pkg debug/elf, const DT_ADDRRNGHI DynTag
|
||||
pkg debug/elf, const DT_ADDRRNGLO = 1879047680
|
||||
@ -235,9 +226,12 @@ pkg embed, type FS struct
|
||||
pkg flag, func Func(string, string, func(string) error)
|
||||
pkg flag, method (*FlagSet) Func(string, string, func(string) error)
|
||||
pkg go/build, type Package struct, EmbedPatterns []string
|
||||
pkg go/build, type Package struct, EmbedPatternPos map[string][]token.Position
|
||||
pkg go/build, type Package struct, IgnoredOtherFiles []string
|
||||
pkg go/build, type Package struct, TestEmbedPatterns []string
|
||||
pkg go/build, type Package struct, TestEmbedPatternPos map[string][]token.Position
|
||||
pkg go/build, type Package struct, XTestEmbedPatterns []string
|
||||
pkg go/build, type Package struct, XTestEmbedPatternPos map[string][]token.Position
|
||||
pkg html/template, func ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg html/template, method (*Template) ParseFS(fs.FS, ...string) (*Template, error)
|
||||
pkg io, func NopCloser(Reader) ReadCloser
|
||||
@ -404,7 +398,6 @@ pkg runtime/metrics, type Description struct, Cumulative bool
|
||||
pkg runtime/metrics, type Description struct, Description string
|
||||
pkg runtime/metrics, type Description struct, Kind ValueKind
|
||||
pkg runtime/metrics, type Description struct, Name string
|
||||
pkg runtime/metrics, type Description struct, StopTheWorld bool
|
||||
pkg runtime/metrics, type Float64Histogram struct
|
||||
pkg runtime/metrics, type Float64Histogram struct, Buckets []float64
|
||||
pkg runtime/metrics, type Float64Histogram struct, Counts []uint64
|
||||
@ -437,10 +430,8 @@ pkg syscall (linux-arm-cgo), func AllThreadsSyscall(uintptr, uintptr, uintptr, u
|
||||
pkg syscall (linux-arm-cgo), func AllThreadsSyscall6(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) (uintptr, uintptr, Errno)
|
||||
pkg syscall (linux-arm-cgo), func Setegid(int) error
|
||||
pkg syscall (linux-arm-cgo), func Seteuid(int) error
|
||||
pkg syscall (windows-386), func RtlGenRandom(*uint8, uint32) error
|
||||
pkg syscall (windows-386), method (*DLLError) Unwrap() error
|
||||
pkg syscall (windows-386), type SysProcAttr struct, NoInheritHandles bool
|
||||
pkg syscall (windows-amd64), func RtlGenRandom(*uint8, uint32) error
|
||||
pkg syscall (windows-amd64), method (*DLLError) Unwrap() error
|
||||
pkg syscall (windows-amd64), type SysProcAttr struct, NoInheritHandles bool
|
||||
pkg testing/fstest, func TestFS(fs.FS, ...string) error
|
||||
|
@ -1023,13 +1023,13 @@ New files that you contribute should use the standard copyright header:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Copyright 2021 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.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
(Use the current year if you're reading this in 2021 or beyond.)
|
||||
(Use the current year if you're reading this in 2022 or beyond.)
|
||||
Files in the repository are copyrighted the year they are added.
|
||||
Do not update the copyright year on files that you change.
|
||||
</p>
|
||||
|
@ -19,13 +19,11 @@ editing, navigation, testing, and debugging experience.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/fatih/vim-go">vim</a>: vim-go plugin provides Go programming language support</li>
|
||||
<li><a href="https://marketplace.visualstudio.com/items?itemName=golang.go">Visual Studio Code</a>:
|
||||
Go extension provides support for the Go programming language</li>
|
||||
<li><a href="https://www.jetbrains.com/go">GoLand</a>: GoLand is distributed either as a standalone IDE
|
||||
or as a plugin for IntelliJ IDEA Ultimate</li>
|
||||
<li><a href="https://atom.io/packages/go-plus">Atom</a>: Go-Plus is an Atom package that provides enhanced Go support</li>
|
||||
</ul>
|
||||
<li><a href="https://github.com/fatih/vim-go">vim</a>: vim-go plugin provides Go programming language support</li>
|
||||
|
||||
<p>
|
||||
Note that these are only a few top solutions; a more comprehensive
|
||||
|
117
doc/go1.16.html
117
doc/go1.16.html
@ -55,7 +55,9 @@ Do not send CLs removing the interior tags from such phrases.
|
||||
Go 1.16 adds an <code>ios/amd64</code> port, which targets the iOS
|
||||
simulator running on AMD64-based macOS. Previously this was
|
||||
unofficially supported through <code>darwin/amd64</code> with
|
||||
the <code>ios</code> build tag set.
|
||||
the <code>ios</code> build tag set. See also
|
||||
<a href="/misc/ios/README"><code>misc/ios/README</code></a> for
|
||||
details about how to build programs for iOS and iOS simulator.
|
||||
</p>
|
||||
|
||||
<p><!-- golang.org/issue/23011 -->
|
||||
@ -162,6 +164,12 @@ Do not send CLs removing the interior tags from such phrases.
|
||||
non-reproducible builds.
|
||||
</p>
|
||||
|
||||
<p><!-- golang.org/issue/43052 -->
|
||||
The <code>go</code> command now disallows non-ASCII import paths in module
|
||||
mode. Non-ASCII module paths have already been disallowed so this change
|
||||
affects module subdirectory paths that contain non-ASCII characters.
|
||||
</p>
|
||||
|
||||
<h4 id="embed">Embedding Files</h4>
|
||||
|
||||
<p>
|
||||
@ -504,6 +512,16 @@ func TestFoo(t *testing.T) {
|
||||
in mind.
|
||||
</p>
|
||||
|
||||
<dl id="archive/zip"><dt><a href="/pkg/archive/zip/">archive/zip</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 243937 -->
|
||||
The new <a href="/pkg/archive/zip/#Reader.Open"><code>Reader.Open</code></a>
|
||||
method implements the <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a>
|
||||
interface.
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl id="crypto/dsa"><dt><a href="/pkg/crypto/dsa/">crypto/dsa</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 257939 -->
|
||||
@ -588,14 +606,6 @@ func TestFoo(t *testing.T) {
|
||||
a malformed certificate.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 233163 -->
|
||||
A number of additional fields have been added to the
|
||||
<a href="/pkg/crypto/x509/#CertificateRequest"><code>CertificateRequest</code></a> type.
|
||||
These fields are now parsed in <a href="/pkg/crypto/x509/#ParseCertificateRequest">
|
||||
<code>ParseCertificateRequest</code></a> and marshalled in
|
||||
<a href="/pkg/crypto/x509/#CreateCertificateRequest"><code>CreateCertificateRequest</code></a>.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 257939 -->
|
||||
DSA signature verification is no longer supported. Note that DSA signature
|
||||
generation was never supported.
|
||||
@ -616,6 +626,16 @@ func TestFoo(t *testing.T) {
|
||||
</dd>
|
||||
</dl><!-- crypto/x509 -->
|
||||
|
||||
<dl id="debug/elf"><dt><a href="/pkg/debug/elf/">debug/elf</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 255138 -->
|
||||
More <a href="/pkg/debug/elf/#DT_NULL"><code>DT</code></a>
|
||||
and <a href="/pkg/debug/elf/#PT_NULL"><code>PT</code></a>
|
||||
constants have been added.
|
||||
</p>
|
||||
</dd>
|
||||
</dl><!-- debug/elf -->
|
||||
|
||||
<dl id="encoding/asn1"><dt><a href="/pkg/encoding/asn1">encoding/asn1</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 255881 -->
|
||||
@ -665,6 +685,18 @@ func TestFoo(t *testing.T) {
|
||||
</dd>
|
||||
</dl><!-- flag -->
|
||||
|
||||
<dl id="html/template"><dt><a href="/pkg/html/template/">html/template</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 243938 -->
|
||||
The new <a href="/pkg/html/template/#ParseFS"><code>template.ParseFS</code></a>
|
||||
function and <a href="/pkg/html/template/#Template.ParseFS"><code>template.Template.ParseFS</code></a>
|
||||
method are like <a href="/pkg/html/template/#ParseGlob"><code>template.ParseGlob</code></a>
|
||||
and <a href="/pkg/html/template/#Template.ParseGlob"><code>template.Template.ParseGlob</code></a>,
|
||||
but read the templates from an <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a>.
|
||||
</p>
|
||||
</dd>
|
||||
</dl><!-- html/template -->
|
||||
|
||||
<dl id="io"><dt><a href="/pkg/io/">io</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 261577 -->
|
||||
@ -774,6 +806,25 @@ func TestFoo(t *testing.T) {
|
||||
environment variable for <code>https://</code> URLs when
|
||||
<code>HTTPS_PROXY</code> is unset.
|
||||
</p>
|
||||
|
||||
<p><!-- 259917 -->
|
||||
The <a href="/pkg/net/http/#Transport"><code>Transport</code></a>
|
||||
type has a new field
|
||||
<a href="/pkg/net/http/#Transport.GetProxyConnectHeader"><code>GetProxyConnectHeader</code></a>
|
||||
which may be set to a function that returns headers to send to a
|
||||
proxy during a <code>CONNECT</code> request.
|
||||
In effect <code>GetProxyConnectHeader</code> is a dynamic
|
||||
version of the existing field
|
||||
<a href="/pkg/net/http/#Transport.ProxyConnectHeader"><code>ProxyConnectHeader</code></a>;
|
||||
if <code>GetProxyConnectHeader</code> is not <code>nil</code>,
|
||||
then <code>ProxyConnectHeader</code> is ignored.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 243939 -->
|
||||
The new <a href="/pkg/net/http/#FS"><code>http.FS</code></a>
|
||||
function converts an <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a>
|
||||
to an <a href="/pkg/net/http/#Handler"><code>http.Handler</code></a>.
|
||||
</p>
|
||||
</dd>
|
||||
</dl><!-- net/http -->
|
||||
|
||||
@ -834,6 +885,21 @@ func TestFoo(t *testing.T) {
|
||||
|
||||
<dl id="path/filepath"><dt><a href="/pkg/path/filepath/">path/filepath</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 267887 -->
|
||||
The new function
|
||||
<a href="/pkg/path/filepath/WalkDir"><code>WalkDir</code></a>
|
||||
is similar to
|
||||
<a href="/pkg/path/filepath/Walk"><code>Walk</code></a>,
|
||||
but is typically more efficient.
|
||||
The function passed to <code>WalkDir</code> receives a
|
||||
<a href="/pkg/io/fs/#DirEntry"><code>fs.DirEntry</code></a>
|
||||
instead of a
|
||||
<a href="/pkg/io/fs/#FileInfo"><code>fs.FileInfo</code></a>.
|
||||
(To clarify for those who recall the <code>Walk</code> function
|
||||
as taking an <a href="/pkg/os/#FileInfo"><code>os.FileInfo</code></a>,
|
||||
<code>os.FileInfo</code> is now an alias for <code>fs.FileInfo</code>.)
|
||||
</p>
|
||||
|
||||
<p><!-- CL 264397, golang.org/issues/28614 -->
|
||||
The <a href="/pkg/path/filepath#Match"><code>Match</code></a> and
|
||||
<a href="/pkg/path/filepath#Glob"><code>Glob</code></a> functions now
|
||||
@ -845,17 +911,6 @@ func TestFoo(t *testing.T) {
|
||||
</dd>
|
||||
</dl><!-- path/filepath -->
|
||||
|
||||
<dl id="reflect"><dt><a href="/pkg/reflect/">reflect</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 248341, golang.org/issues/40281 -->
|
||||
<a href="/pkg/reflect/#StructTag"><code>StructTag</code></a>
|
||||
now allows multiple space-separated keys in key:value pairs,
|
||||
as in <code>`json xml:"field1"`</code> (equivalent to
|
||||
<code>`json:"field1" xml:"field1"`</code>).
|
||||
</p>
|
||||
</dd>
|
||||
</dl><!-- reflect -->
|
||||
|
||||
<dl id="runtime/debug"><dt><a href="/pkg/runtime/debug/">runtime/debug</a></dt>
|
||||
<dd>
|
||||
<p><!-- CL 249677 -->
|
||||
@ -893,11 +948,11 @@ func TestFoo(t *testing.T) {
|
||||
</p>
|
||||
|
||||
<p><!-- CL 261917 -->
|
||||
<a href="/pkg/syscall/?GOOS=windows#SysProcAttr"><code>SysProcAttr</code></a> on Windows has a new NoInheritHandles field that disables inheriting handles when creating a new process.
|
||||
<a href="/pkg/syscall/?GOOS=windows#SysProcAttr"><code>SysProcAttr</code></a> on Windows has a new <code>NoInheritHandles</code> field that disables inheriting handles when creating a new process.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 269761, golang.org/issue/42584 -->
|
||||
<a href="/pkg/syscall/?GOOS=windows#DLLError"><code>DLLError</code></a> on Windows now has an Unwrap function for unwrapping its underlying error.
|
||||
<a href="/pkg/syscall/?GOOS=windows#DLLError"><code>DLLError</code></a> on Windows now has an <code>Unwrap</code> method for unwrapping its underlying error.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 210639 -->
|
||||
@ -907,6 +962,16 @@ func TestFoo(t *testing.T) {
|
||||
and related calls are now implemented.
|
||||
Previously, they returned an <code>syscall.EOPNOTSUPP</code> error.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 210639 -->
|
||||
On Linux, the new functions
|
||||
<a href="/pkg/syscall/#AllThreadsSyscall"><code>AllThreadsSyscall</code></a>
|
||||
and <a href="/pkg/syscall/#AllThreadsSyscall6"><code>AllThreadsSyscall6</code></a>
|
||||
may be used to make a system call on all Go threads in the process.
|
||||
These functions may only be used by programs that do not use cgo;
|
||||
if a program uses cgo, they will always return
|
||||
<a href="/pkg/syscall/#ENOTSUP"><code>syscall.ENOTSUP</code></a>.
|
||||
</p>
|
||||
</dd>
|
||||
</dl><!-- syscall -->
|
||||
|
||||
@ -916,6 +981,14 @@ func TestFoo(t *testing.T) {
|
||||
Newlines characters are now allowed inside action delimiters,
|
||||
permitting actions to span multiple lines.
|
||||
</p>
|
||||
|
||||
<p><!-- CL 243938 -->
|
||||
The new <a href="/pkg/text/template/#ParseFS"><code>template.ParseFS</code></a>
|
||||
function and <a href="/pkg/text/template/#Template.ParseFS"><code>template.Template.ParseFS</code></a>
|
||||
method are like <a href="/pkg/text/template/#ParseGlob"><code>template.ParseGlob</code></a>
|
||||
and <a href="/pkg/text/template/#Template.ParseGlob"><code>template.Template.ParseGlob</code></a>,
|
||||
but read the templates from an <a href="/pkg/io/fs/#FS"><code>fs.FS</code></a>.
|
||||
</p>
|
||||
</dd>
|
||||
</dl><!-- text/template -->
|
||||
|
||||
|
@ -8,8 +8,8 @@
|
||||
# Consult https://www.iana.org/time-zones for the latest versions.
|
||||
|
||||
# Versions to use.
|
||||
CODE=2020e
|
||||
DATA=2020e
|
||||
CODE=2020f
|
||||
DATA=2020f
|
||||
|
||||
set -e
|
||||
rm -rf work
|
||||
|
Binary file not shown.
@ -30,7 +30,7 @@ func TestCrossPackageTests(t *testing.T) {
|
||||
switch runtime.GOOS {
|
||||
case "android":
|
||||
t.Skip("Can't exec cmd/go subprocess on Android.")
|
||||
case "darwin", "ios":
|
||||
case "ios":
|
||||
switch runtime.GOARCH {
|
||||
case "arm64":
|
||||
t.Skip("Can't exec cmd/go subprocess on iOS.")
|
||||
|
@ -118,11 +118,6 @@ func testMain(m *testing.M) int {
|
||||
cc = append(cc, s[start:])
|
||||
}
|
||||
|
||||
if GOOS == "darwin" || GOOS == "ios" {
|
||||
// For Darwin/ARM.
|
||||
// TODO: do we still need this?
|
||||
cc = append(cc, []string{"-framework", "CoreFoundation", "-framework", "Foundation"}...)
|
||||
}
|
||||
if GOOS == "aix" {
|
||||
// -Wl,-bnoobjreorder is mandatory to keep the same layout
|
||||
// in .text section.
|
||||
|
@ -7,6 +7,13 @@ set to the clang wrapper that invokes clang for iOS. For example, this command r
|
||||
|
||||
GOOS=ios GOARCH=amd64 CGO_ENABLED=1 CC_FOR_TARGET=$(pwd)/../misc/ios/clangwrap.sh ./all.bash
|
||||
|
||||
If CC_FOR_TARGET is not set when the toolchain is built (make.bash or all.bash), CC
|
||||
can be set on the command line. For example,
|
||||
|
||||
GOOS=ios GOARCH=amd64 CGO_ENABLED=1 CC=$(go env GOROOT)/misc/ios/clangwrap.sh go build
|
||||
|
||||
Setting CC is not necessary if the toolchain is built with CC_FOR_TARGET set.
|
||||
|
||||
To use the go tool to run individual programs and tests, put $GOROOT/bin into PATH to ensure
|
||||
the go_ios_$GOARCH_exec wrapper is found. For example, to run the archive/tar tests:
|
||||
|
||||
|
@ -28,7 +28,7 @@ func isASCII(s string) bool {
|
||||
}
|
||||
|
||||
// toASCII converts the input to an ASCII C-style string.
|
||||
// This a best effort conversion, so invalid characters are dropped.
|
||||
// This is a best effort conversion, so invalid characters are dropped.
|
||||
func toASCII(s string) string {
|
||||
if isASCII(s) {
|
||||
return s
|
||||
|
@ -16,10 +16,10 @@ import (
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"go/types"
|
||||
exec "internal/execabs"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
|
@ -10,9 +10,9 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
@ -1549,7 +1549,14 @@ func (p *Package) gccBaseCmd() []string {
|
||||
func (p *Package) gccMachine() []string {
|
||||
switch goarch {
|
||||
case "amd64":
|
||||
if goos == "darwin" {
|
||||
return []string{"-arch", "x86_64", "-m64"}
|
||||
}
|
||||
return []string{"-m64"}
|
||||
case "arm64":
|
||||
if goos == "darwin" {
|
||||
return []string{"-arch", "arm64"}
|
||||
}
|
||||
case "386":
|
||||
return []string{"-m32"}
|
||||
case "arm":
|
||||
|
@ -14,10 +14,10 @@ import (
|
||||
"go/ast"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
exec "internal/execabs"
|
||||
"internal/xcoff"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
@ -953,9 +953,9 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
|
||||
// Build the wrapper function compiled by gcc.
|
||||
gccExport := ""
|
||||
if goos == "windows" {
|
||||
gccExport = "__declspec(dllexport)"
|
||||
gccExport = "__declspec(dllexport) "
|
||||
}
|
||||
s := fmt.Sprintf("%s %s %s(", gccExport, gccResult, exp.ExpName)
|
||||
s := fmt.Sprintf("%s%s %s(", gccExport, gccResult, exp.ExpName)
|
||||
if fn.Recv != nil {
|
||||
s += p.cgoType(fn.Recv.List[0].Type).C.String()
|
||||
s += " recv"
|
||||
|
@ -8,9 +8,9 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"go/token"
|
||||
exec "internal/execabs"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
)
|
||||
|
||||
// run runs the command argv, feeding in stdin on standard input.
|
||||
@ -63,7 +63,7 @@ func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
|
||||
p.Env = append(os.Environ(), "TERM=dumb")
|
||||
err := p.Run()
|
||||
if _, ok := err.(*exec.ExitError); err != nil && !ok {
|
||||
fatalf("%s", err)
|
||||
fatalf("exec %s: %s", argv[0], err)
|
||||
}
|
||||
ok = p.ProcessState.Success()
|
||||
stdout, stderr = bout.Bytes(), berr.Bytes()
|
||||
@ -88,7 +88,7 @@ func fatalf(msg string, args ...interface{}) {
|
||||
// If we've already printed other errors, they might have
|
||||
// caused the fatal condition. Assume they're enough.
|
||||
if nerrors == 0 {
|
||||
fmt.Fprintf(os.Stderr, msg+"\n", args...)
|
||||
fmt.Fprintf(os.Stderr, "cgo: "+msg+"\n", args...)
|
||||
}
|
||||
os.Exit(2)
|
||||
}
|
||||
|
@ -1056,7 +1056,11 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
||||
ssa.OpARM64LessThanF,
|
||||
ssa.OpARM64LessEqualF,
|
||||
ssa.OpARM64GreaterThanF,
|
||||
ssa.OpARM64GreaterEqualF:
|
||||
ssa.OpARM64GreaterEqualF,
|
||||
ssa.OpARM64NotLessThanF,
|
||||
ssa.OpARM64NotLessEqualF,
|
||||
ssa.OpARM64NotGreaterThanF,
|
||||
ssa.OpARM64NotGreaterEqualF:
|
||||
// generate boolean values using CSET
|
||||
p := s.Prog(arm64.ACSET)
|
||||
p.From.Type = obj.TYPE_REG // assembler encodes conditional bits in Reg
|
||||
@ -1100,10 +1104,16 @@ var condBits = map[ssa.Op]int16{
|
||||
ssa.OpARM64GreaterThanU: arm64.COND_HI,
|
||||
ssa.OpARM64GreaterEqual: arm64.COND_GE,
|
||||
ssa.OpARM64GreaterEqualU: arm64.COND_HS,
|
||||
ssa.OpARM64LessThanF: arm64.COND_MI,
|
||||
ssa.OpARM64LessEqualF: arm64.COND_LS,
|
||||
ssa.OpARM64GreaterThanF: arm64.COND_GT,
|
||||
ssa.OpARM64GreaterEqualF: arm64.COND_GE,
|
||||
ssa.OpARM64LessThanF: arm64.COND_MI, // Less than
|
||||
ssa.OpARM64LessEqualF: arm64.COND_LS, // Less than or equal to
|
||||
ssa.OpARM64GreaterThanF: arm64.COND_GT, // Greater than
|
||||
ssa.OpARM64GreaterEqualF: arm64.COND_GE, // Greater than or equal to
|
||||
|
||||
// The following condition codes have unordered to handle comparisons related to NaN.
|
||||
ssa.OpARM64NotLessThanF: arm64.COND_PL, // Greater than, equal to, or unordered
|
||||
ssa.OpARM64NotLessEqualF: arm64.COND_HI, // Greater than or unordered
|
||||
ssa.OpARM64NotGreaterThanF: arm64.COND_LE, // Less than, equal to or unordered
|
||||
ssa.OpARM64NotGreaterEqualF: arm64.COND_LT, // Less than or unordered
|
||||
}
|
||||
|
||||
var blockJump = map[ssa.BlockKind]struct {
|
||||
|
@ -475,7 +475,7 @@ func (p *noder) varDecl(decl *syntax.VarDecl) []ir.Node {
|
||||
p.errorAt(e.Pos, "//go:embed only allowed in Go files that import \"embed\"")
|
||||
}
|
||||
} else {
|
||||
exprs = varEmbed(p, names, typ, exprs, pragma.Embeds)
|
||||
varEmbed(p, names, typ, exprs, pragma.Embeds)
|
||||
}
|
||||
pragma.Embeds = nil
|
||||
}
|
||||
@ -1923,7 +1923,7 @@ func oldname(s *types.Sym) ir.Node {
|
||||
return n
|
||||
}
|
||||
|
||||
func varEmbed(p *noder, names []*ir.Name, typ ir.Ntype, exprs []ir.Node, embeds []pragmaEmbed) (newExprs []ir.Node) {
|
||||
func varEmbed(p *noder, names []*ir.Name, typ ir.Ntype, exprs []ir.Node, embeds []pragmaEmbed) {
|
||||
haveEmbed := false
|
||||
for _, decl := range p.file.DeclList {
|
||||
imp, ok := decl.(*syntax.ImportDecl)
|
||||
@ -1941,28 +1941,24 @@ func varEmbed(p *noder, names []*ir.Name, typ ir.Ntype, exprs []ir.Node, embeds
|
||||
pos := embeds[0].Pos
|
||||
if !haveEmbed {
|
||||
p.errorAt(pos, "invalid go:embed: missing import \"embed\"")
|
||||
return exprs
|
||||
}
|
||||
if base.Flag.Cfg.Embed.Patterns == nil {
|
||||
p.errorAt(pos, "invalid go:embed: build system did not supply embed configuration")
|
||||
return exprs
|
||||
return
|
||||
}
|
||||
if len(names) > 1 {
|
||||
p.errorAt(pos, "go:embed cannot apply to multiple vars")
|
||||
return exprs
|
||||
return
|
||||
}
|
||||
if len(exprs) > 0 {
|
||||
p.errorAt(pos, "go:embed cannot apply to var with initializer")
|
||||
return exprs
|
||||
return
|
||||
}
|
||||
if typ == nil {
|
||||
// Should not happen, since len(exprs) == 0 now.
|
||||
p.errorAt(pos, "go:embed cannot apply to var without type")
|
||||
return exprs
|
||||
return
|
||||
}
|
||||
if typecheck.DeclContext != ir.PEXTERN {
|
||||
p.errorAt(pos, "go:embed cannot apply to var inside func")
|
||||
return exprs
|
||||
return
|
||||
}
|
||||
|
||||
v := names[0]
|
||||
@ -1971,5 +1967,4 @@ func varEmbed(p *noder, names []*ir.Name, typ ir.Ntype, exprs []ir.Node, embeds
|
||||
for _, e := range embeds {
|
||||
*v.Embed = append(*v.Embed, ir.Embed{Pos: p.makeXPos(e.Pos), Patterns: e.Patterns})
|
||||
}
|
||||
return exprs
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ func initOrder(l []ir.Node) []ir.Node {
|
||||
// first.
|
||||
base.ExitIfErrors()
|
||||
|
||||
o.findInitLoopAndExit(firstLHS(n), new([]*ir.Name))
|
||||
o.findInitLoopAndExit(firstLHS(n), new([]*ir.Name), new(ir.NameSet))
|
||||
base.Fatalf("initialization unfinished, but failed to identify loop")
|
||||
}
|
||||
}
|
||||
@ -184,10 +184,7 @@ func (o *InitOrder) flushReady(initialize func(ir.Node)) {
|
||||
// path points to a slice used for tracking the sequence of
|
||||
// variables/functions visited. Using a pointer to a slice allows the
|
||||
// slice capacity to grow and limit reallocations.
|
||||
func (o *InitOrder) findInitLoopAndExit(n *ir.Name, path *[]*ir.Name) {
|
||||
// We implement a simple DFS loop-finding algorithm. This
|
||||
// could be faster, but initialization cycles are rare.
|
||||
|
||||
func (o *InitOrder) findInitLoopAndExit(n *ir.Name, path *[]*ir.Name, ok *ir.NameSet) {
|
||||
for i, x := range *path {
|
||||
if x == n {
|
||||
reportInitLoopAndExit((*path)[i:])
|
||||
@ -204,12 +201,19 @@ func (o *InitOrder) findInitLoopAndExit(n *ir.Name, path *[]*ir.Name) {
|
||||
*path = append(*path, n)
|
||||
for _, ref := range refers {
|
||||
// Short-circuit variables that were initialized.
|
||||
if ref.Class == ir.PEXTERN && o.order[ref.Defn] == orderDone {
|
||||
if ref.Class == ir.PEXTERN && o.order[ref.Defn] == orderDone || ok.Has(ref) {
|
||||
continue
|
||||
}
|
||||
|
||||
o.findInitLoopAndExit(ref, path)
|
||||
o.findInitLoopAndExit(ref, path, ok)
|
||||
}
|
||||
|
||||
// n is not involved in a cycle.
|
||||
// Record that fact to avoid checking it again when reached another way,
|
||||
// or else this traversal will take exponential time traversing all paths
|
||||
// through the part of the package's call graph implicated in the cycle.
|
||||
ok.Add(n)
|
||||
|
||||
*path = (*path)[:len(*path)-1]
|
||||
}
|
||||
|
||||
|
@ -198,7 +198,8 @@ func expandCalls(f *Func) {
|
||||
}
|
||||
break
|
||||
}
|
||||
if leaf.Op == OpIData {
|
||||
switch leaf.Op {
|
||||
case OpIData, OpStructSelect, OpArraySelect:
|
||||
leafType = removeTrivialWrapperTypes(leaf.Type)
|
||||
}
|
||||
aux := selector.Aux
|
||||
|
@ -478,20 +478,24 @@ func init() {
|
||||
// pseudo-ops
|
||||
{name: "LoweredNilCheck", argLength: 2, reg: regInfo{inputs: []regMask{gpg}}, nilCheck: true, faultOnNilArg0: true}, // panic if arg0 is nil. arg1=mem.
|
||||
|
||||
{name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise.
|
||||
{name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise.
|
||||
{name: "LessThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x<y false otherwise.
|
||||
{name: "LessEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x<=y false otherwise.
|
||||
{name: "GreaterThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x>y false otherwise.
|
||||
{name: "GreaterEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x>=y false otherwise.
|
||||
{name: "LessThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<y false otherwise.
|
||||
{name: "LessEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<=y false otherwise.
|
||||
{name: "GreaterThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>y false otherwise.
|
||||
{name: "GreaterEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>=y false otherwise.
|
||||
{name: "LessThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<y false otherwise.
|
||||
{name: "LessEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<=y false otherwise.
|
||||
{name: "GreaterThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>y false otherwise.
|
||||
{name: "GreaterEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>=y false otherwise.
|
||||
{name: "Equal", argLength: 1, reg: readflags}, // bool, true flags encode x==y false otherwise.
|
||||
{name: "NotEqual", argLength: 1, reg: readflags}, // bool, true flags encode x!=y false otherwise.
|
||||
{name: "LessThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x<y false otherwise.
|
||||
{name: "LessEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x<=y false otherwise.
|
||||
{name: "GreaterThan", argLength: 1, reg: readflags}, // bool, true flags encode signed x>y false otherwise.
|
||||
{name: "GreaterEqual", argLength: 1, reg: readflags}, // bool, true flags encode signed x>=y false otherwise.
|
||||
{name: "LessThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<y false otherwise.
|
||||
{name: "LessEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x<=y false otherwise.
|
||||
{name: "GreaterThanU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>y false otherwise.
|
||||
{name: "GreaterEqualU", argLength: 1, reg: readflags}, // bool, true flags encode unsigned x>=y false otherwise.
|
||||
{name: "LessThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<y false otherwise.
|
||||
{name: "LessEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<=y false otherwise.
|
||||
{name: "GreaterThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>y false otherwise.
|
||||
{name: "GreaterEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>=y false otherwise.
|
||||
{name: "NotLessThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>=y || x is unordered with y, false otherwise.
|
||||
{name: "NotLessEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x>y || x is unordered with y, false otherwise.
|
||||
{name: "NotGreaterThanF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<=y || x is unordered with y, false otherwise.
|
||||
{name: "NotGreaterEqualF", argLength: 1, reg: readflags}, // bool, true flags encode floating-point x<y || x is unordered with y, false otherwise.
|
||||
// duffzero
|
||||
// arg0 = address of memory to zero
|
||||
// arg1 = mem
|
||||
|
@ -2512,7 +2512,7 @@
|
||||
(Move {t1} [s] dst tmp1 midmem:(Move {t2} [s] tmp2 src _))
|
||||
&& t1.Compare(t2) == types.CMPeq
|
||||
&& isSamePtr(tmp1, tmp2)
|
||||
&& isStackPtr(src)
|
||||
&& isStackPtr(src) && !isVolatile(src)
|
||||
&& disjoint(src, s, tmp2, s)
|
||||
&& (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
|
||||
=> (Move {t1} [s] dst src midmem)
|
||||
@ -2521,7 +2521,7 @@
|
||||
(Move {t1} [s] dst tmp1 midmem:(VarDef (Move {t2} [s] tmp2 src _)))
|
||||
&& t1.Compare(t2) == types.CMPeq
|
||||
&& isSamePtr(tmp1, tmp2)
|
||||
&& isStackPtr(src)
|
||||
&& isStackPtr(src) && !isVolatile(src)
|
||||
&& disjoint(src, s, tmp2, s)
|
||||
&& (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
|
||||
=> (Move {t1} [s] dst src midmem)
|
||||
|
@ -9,9 +9,9 @@ import (
|
||||
"cmd/internal/src"
|
||||
"fmt"
|
||||
"html"
|
||||
exec "internal/execabs"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -1564,6 +1564,10 @@ const (
|
||||
OpARM64LessEqualF
|
||||
OpARM64GreaterThanF
|
||||
OpARM64GreaterEqualF
|
||||
OpARM64NotLessThanF
|
||||
OpARM64NotLessEqualF
|
||||
OpARM64NotGreaterThanF
|
||||
OpARM64NotGreaterEqualF
|
||||
OpARM64DUFFZERO
|
||||
OpARM64LoweredZero
|
||||
OpARM64DUFFCOPY
|
||||
@ -20798,6 +20802,42 @@ var opcodeTable = [...]opInfo{
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NotLessThanF",
|
||||
argLen: 1,
|
||||
reg: regInfo{
|
||||
outputs: []outputInfo{
|
||||
{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NotLessEqualF",
|
||||
argLen: 1,
|
||||
reg: regInfo{
|
||||
outputs: []outputInfo{
|
||||
{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NotGreaterThanF",
|
||||
argLen: 1,
|
||||
reg: regInfo{
|
||||
outputs: []outputInfo{
|
||||
{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NotGreaterEqualF",
|
||||
argLen: 1,
|
||||
reg: regInfo{
|
||||
outputs: []outputInfo{
|
||||
{0, 670826495}, // R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R19 R20 R21 R22 R23 R24 R25 R26 R30
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DUFFZERO",
|
||||
auxType: auxInt64,
|
||||
|
@ -996,9 +996,10 @@ func flagArg(v *Value) *Value {
|
||||
}
|
||||
|
||||
// arm64Negate finds the complement to an ARM64 condition code,
|
||||
// for example Equal -> NotEqual or LessThan -> GreaterEqual
|
||||
// for example !Equal -> NotEqual or !LessThan -> GreaterEqual
|
||||
//
|
||||
// TODO: add floating-point conditions
|
||||
// For floating point, it's more subtle because NaN is unordered. We do
|
||||
// !LessThanF -> NotLessThanF, the latter takes care of NaNs.
|
||||
func arm64Negate(op Op) Op {
|
||||
switch op {
|
||||
case OpARM64LessThan:
|
||||
@ -1022,13 +1023,21 @@ func arm64Negate(op Op) Op {
|
||||
case OpARM64NotEqual:
|
||||
return OpARM64Equal
|
||||
case OpARM64LessThanF:
|
||||
return OpARM64GreaterEqualF
|
||||
case OpARM64GreaterThanF:
|
||||
return OpARM64LessEqualF
|
||||
return OpARM64NotLessThanF
|
||||
case OpARM64NotLessThanF:
|
||||
return OpARM64LessThanF
|
||||
case OpARM64LessEqualF:
|
||||
return OpARM64NotLessEqualF
|
||||
case OpARM64NotLessEqualF:
|
||||
return OpARM64LessEqualF
|
||||
case OpARM64GreaterThanF:
|
||||
return OpARM64NotGreaterThanF
|
||||
case OpARM64NotGreaterThanF:
|
||||
return OpARM64GreaterThanF
|
||||
case OpARM64GreaterEqualF:
|
||||
return OpARM64LessThanF
|
||||
return OpARM64NotGreaterEqualF
|
||||
case OpARM64NotGreaterEqualF:
|
||||
return OpARM64GreaterEqualF
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
@ -1039,8 +1048,6 @@ func arm64Negate(op Op) Op {
|
||||
// that the same result would be produced if the arguments
|
||||
// to the flag-generating instruction were reversed, e.g.
|
||||
// (InvertFlags (CMP x y)) -> (CMP y x)
|
||||
//
|
||||
// TODO: add floating-point conditions
|
||||
func arm64Invert(op Op) Op {
|
||||
switch op {
|
||||
case OpARM64LessThan:
|
||||
@ -1069,6 +1076,14 @@ func arm64Invert(op Op) Op {
|
||||
return OpARM64GreaterEqualF
|
||||
case OpARM64GreaterEqualF:
|
||||
return OpARM64LessEqualF
|
||||
case OpARM64NotLessThanF:
|
||||
return OpARM64NotGreaterThanF
|
||||
case OpARM64NotGreaterThanF:
|
||||
return OpARM64NotLessThanF
|
||||
case OpARM64NotLessEqualF:
|
||||
return OpARM64NotGreaterEqualF
|
||||
case OpARM64NotGreaterEqualF:
|
||||
return OpARM64NotLessEqualF
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
|
@ -13637,7 +13637,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
// match: (Move {t1} [s] dst tmp1 midmem:(Move {t2} [s] tmp2 src _))
|
||||
// cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
|
||||
// cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
|
||||
// result: (Move {t1} [s] dst src midmem)
|
||||
for {
|
||||
s := auxIntToInt64(v.AuxInt)
|
||||
@ -13651,7 +13651,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
|
||||
t2 := auxToType(midmem.Aux)
|
||||
src := midmem.Args[1]
|
||||
tmp2 := midmem.Args[0]
|
||||
if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
|
||||
if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpMove)
|
||||
@ -13661,7 +13661,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
|
||||
return true
|
||||
}
|
||||
// match: (Move {t1} [s] dst tmp1 midmem:(VarDef (Move {t2} [s] tmp2 src _)))
|
||||
// cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
|
||||
// cond: t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))
|
||||
// result: (Move {t1} [s] dst src midmem)
|
||||
for {
|
||||
s := auxIntToInt64(v.AuxInt)
|
||||
@ -13679,7 +13679,7 @@ func rewriteValuegeneric_OpMove(v *Value) bool {
|
||||
t2 := auxToType(midmem_0.Aux)
|
||||
src := midmem_0.Args[1]
|
||||
tmp2 := midmem_0.Args[0]
|
||||
if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
|
||||
if !(t1.Compare(t2) == types.CMPeq && isSamePtr(tmp1, tmp2) && isStackPtr(src) && !isVolatile(src) && disjoint(src, s, tmp2, s) && (disjoint(src, s, dst, s) || isInlinableMemmove(dst, src, s, config))) {
|
||||
break
|
||||
}
|
||||
v.reset(OpMove)
|
||||
|
@ -23,13 +23,7 @@ const (
|
||||
embedFiles
|
||||
)
|
||||
|
||||
func embedFileList(v *ir.Name) []string {
|
||||
kind := embedKind(v.Type())
|
||||
if kind == embedUnknown {
|
||||
base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
|
||||
return nil
|
||||
}
|
||||
|
||||
func embedFileList(v *ir.Name, kind int) []string {
|
||||
// Build list of files to store.
|
||||
have := make(map[string]bool)
|
||||
var list []string
|
||||
@ -71,38 +65,15 @@ func embedFileList(v *ir.Name) []string {
|
||||
return list
|
||||
}
|
||||
|
||||
// embedKindApprox determines the kind of embedding variable, approximately.
|
||||
// The match is approximate because we haven't done scope resolution yet and
|
||||
// can't tell whether "string" and "byte" really mean "string" and "byte".
|
||||
// The result must be confirmed later, after type checking, using embedKind.
|
||||
func embedKindApprox(typ ir.Node) int {
|
||||
if typ.Sym() != nil && typ.Sym().Name == "FS" && (typ.Sym().Pkg.Path == "embed" || (typ.Sym().Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "embed")) {
|
||||
return embedFiles
|
||||
}
|
||||
// These are not guaranteed to match only string and []byte -
|
||||
// maybe the local package has redefined one of those words.
|
||||
// But it's the best we can do now during the noder.
|
||||
// The stricter check happens later, in WriteEmbed calling embedKind.
|
||||
if typ.Sym() != nil && typ.Sym().Name == "string" && typ.Sym().Pkg == types.LocalPkg {
|
||||
return embedString
|
||||
}
|
||||
if typ, ok := typ.(*ir.SliceType); ok {
|
||||
if sym := typ.Elem.Sym(); sym != nil && sym.Name == "byte" && sym.Pkg == types.LocalPkg {
|
||||
return embedBytes
|
||||
}
|
||||
}
|
||||
return embedUnknown
|
||||
}
|
||||
|
||||
// embedKind determines the kind of embedding variable.
|
||||
func embedKind(typ *types.Type) int {
|
||||
if typ.Sym() != nil && typ.Sym().Name == "FS" && (typ.Sym().Pkg.Path == "embed" || (typ.Sym().Pkg == types.LocalPkg && base.Ctxt.Pkgpath == "embed")) {
|
||||
return embedFiles
|
||||
}
|
||||
if typ == types.Types[types.TSTRING] {
|
||||
if typ.Kind() == types.TSTRING {
|
||||
return embedString
|
||||
}
|
||||
if typ.Sym() == nil && typ.IsSlice() && typ.Elem() == types.ByteType {
|
||||
if typ.Sym() == nil && typ.IsSlice() && typ.Elem().Kind() == types.TUINT8 {
|
||||
return embedBytes
|
||||
}
|
||||
return embedUnknown
|
||||
@ -134,11 +105,28 @@ func embedFileLess(x, y string) bool {
|
||||
// WriteEmbed emits the init data for a //go:embed variable,
|
||||
// which is either a string, a []byte, or an embed.FS.
|
||||
func WriteEmbed(v *ir.Name) {
|
||||
files := embedFileList(v)
|
||||
switch kind := embedKind(v.Type()); kind {
|
||||
case embedUnknown:
|
||||
base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
|
||||
// TODO(mdempsky): User errors should be reported by the frontend.
|
||||
|
||||
commentPos := (*v.Embed)[0].Pos
|
||||
if !types.AllowsGoVersion(types.LocalPkg, 1, 16) {
|
||||
prevPos := base.Pos
|
||||
base.Pos = commentPos
|
||||
base.ErrorfVers("go1.16", "go:embed")
|
||||
base.Pos = prevPos
|
||||
return
|
||||
}
|
||||
if base.Flag.Cfg.Embed.Patterns == nil {
|
||||
base.ErrorfAt(commentPos, "invalid go:embed: build system did not supply embed configuration")
|
||||
return
|
||||
}
|
||||
kind := embedKind(v.Type())
|
||||
if kind == embedUnknown {
|
||||
base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
|
||||
return
|
||||
}
|
||||
|
||||
files := embedFileList(v, kind)
|
||||
switch kind {
|
||||
case embedString, embedBytes:
|
||||
file := files[0]
|
||||
fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], kind == embedString, nil)
|
||||
|
@ -15,9 +15,9 @@ import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
exec "internal/execabs"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
|
2
src/cmd/cover/testdata/toolexec.go
vendored
2
src/cmd/cover/testdata/toolexec.go
vendored
@ -16,7 +16,7 @@ package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
exec "internal/execabs"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
4
src/cmd/dist/buildtool.go
vendored
4
src/cmd/dist/buildtool.go
vendored
@ -285,8 +285,10 @@ func bootstrapFixImports(srcFile string) string {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(line, `import "`) || strings.HasPrefix(line, `import . "`) ||
|
||||
inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"")) {
|
||||
inBlock && (strings.HasPrefix(line, "\t\"") || strings.HasPrefix(line, "\t. \"") || strings.HasPrefix(line, "\texec \"")) {
|
||||
line = strings.Replace(line, `"cmd/`, `"bootstrap/cmd/`, -1)
|
||||
// During bootstrap, must use plain os/exec.
|
||||
line = strings.Replace(line, `exec "internal/execabs"`, `"os/exec"`, -1)
|
||||
for _, dir := range bootstrapDirs {
|
||||
if strings.HasPrefix(dir, "cmd/") {
|
||||
continue
|
||||
|
@ -7,9 +7,9 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
@ -9,8 +9,8 @@ import (
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
exec "internal/execabs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
|
@ -6,7 +6,7 @@ require (
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2
|
||||
golang.org/x/arch v0.0.0-20201008161808-52c3e6f60cff
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897
|
||||
golang.org/x/mod v0.4.0
|
||||
golang.org/x/mod v0.4.1
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88 // indirect
|
||||
golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11
|
||||
golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff
|
||||
)
|
||||
|
@ -14,8 +14,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897 h1:pLI5jrR7OSLijeIDcmRxNmw2api+jEfxLoykJVice/E=
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
@ -31,8 +31,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11 h1:9j/upNXDRpADUw2RpUfJ7E7GHtfhDih62kX6JM8vs2c=
|
||||
golang.org/x/tools v0.0.0-20201211025543-abf6a1d87e11/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff h1:6EkB024TP1fu6cmQqeCNw685zYDVt5g8N1BXh755SQM=
|
||||
golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -216,6 +216,7 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
// Don't let these environment variables confuse the test.
|
||||
os.Setenv("GOENV", "off")
|
||||
os.Unsetenv("GOFLAGS")
|
||||
os.Unsetenv("GOBIN")
|
||||
os.Unsetenv("GOPATH")
|
||||
os.Unsetenv("GIT_ALLOW_PROTOCOL")
|
||||
@ -2655,12 +2656,12 @@ func TestBadCommandLines(t *testing.T) {
|
||||
tg.tempFile("src/@x/x.go", "package x\n")
|
||||
tg.setenv("GOPATH", tg.path("."))
|
||||
tg.runFail("build", "@x")
|
||||
tg.grepStderr("invalid input directory name \"@x\"|cannot use path@version syntax", "did not reject @x directory")
|
||||
tg.grepStderr("invalid input directory name \"@x\"|can only use path@version syntax with 'go get' and 'go install' in module-aware mode", "did not reject @x directory")
|
||||
|
||||
tg.tempFile("src/@x/y/y.go", "package y\n")
|
||||
tg.setenv("GOPATH", tg.path("."))
|
||||
tg.runFail("build", "@x/y")
|
||||
tg.grepStderr("invalid import path \"@x/y\"|cannot use path@version syntax", "did not reject @x/y import path")
|
||||
tg.grepStderr("invalid import path \"@x/y\"|can only use path@version syntax with 'go get' and 'go install' in module-aware mode", "did not reject @x/y import path")
|
||||
|
||||
tg.tempFile("src/-x/x.go", "package x\n")
|
||||
tg.setenv("GOPATH", tg.path("."))
|
||||
|
@ -10,9 +10,9 @@ import (
|
||||
"context"
|
||||
"flag"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
|
@ -9,10 +9,10 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"io"
|
||||
urlpkg "net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
|
@ -75,7 +75,8 @@ func runFmt(ctx context.Context, cmd *base.Command, args []string) {
|
||||
}
|
||||
if pkg.Error != nil {
|
||||
var nogo *load.NoGoError
|
||||
if errors.As(pkg.Error, &nogo) && len(pkg.InternalAllGoFiles()) > 0 {
|
||||
var embed *load.EmbedError
|
||||
if (errors.As(pkg.Error, &nogo) || errors.As(pkg.Error, &embed)) && len(pkg.InternalAllGoFiles()) > 0 {
|
||||
// Skip this error, as we will format
|
||||
// all files regardless.
|
||||
} else {
|
||||
|
@ -12,10 +12,10 @@ import (
|
||||
"fmt"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
exec "internal/execabs"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@ -52,15 +52,6 @@ that can be run locally. It must either be in the shell path
|
||||
(gofmt), a fully qualified path (/usr/you/bin/mytool), or a
|
||||
command alias, described below.
|
||||
|
||||
To convey to humans and machine tools that code is generated,
|
||||
generated source should have a line that matches the following
|
||||
regular expression (in Go syntax):
|
||||
|
||||
^// Code generated .* DO NOT EDIT\.$
|
||||
|
||||
The line may appear anywhere in the file, but is typically
|
||||
placed near the beginning so it is easy to find.
|
||||
|
||||
Note that go generate does not parse the file, so lines that look
|
||||
like directives in comments or multiline strings will be treated
|
||||
as directives.
|
||||
@ -72,6 +63,15 @@ arguments when it is run.
|
||||
Quoted strings use Go syntax and are evaluated before execution; a
|
||||
quoted string appears as a single argument to the generator.
|
||||
|
||||
To convey to humans and machine tools that code is generated,
|
||||
generated source should have a line that matches the following
|
||||
regular expression (in Go syntax):
|
||||
|
||||
^// Code generated .* DO NOT EDIT\.$
|
||||
|
||||
This line must appear before the first non-comment, non-blank
|
||||
text in the file.
|
||||
|
||||
Go generate sets several variables when it runs the generator:
|
||||
|
||||
$GOARCH
|
||||
|
@ -202,7 +202,7 @@ func runGet(ctx context.Context, cmd *base.Command, args []string) {
|
||||
func downloadPaths(patterns []string) []string {
|
||||
for _, arg := range patterns {
|
||||
if strings.Contains(arg, "@") {
|
||||
base.Fatalf("go: cannot use path@version syntax in GOPATH mode")
|
||||
base.Fatalf("go: can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -266,7 +266,7 @@ listed in the GOPATH environment variable.
|
||||
(See 'go help gopath-get' and 'go help gopath'.)
|
||||
|
||||
When using modules, downloaded packages are stored in the module cache.
|
||||
(See 'go help module-get' and 'go help goproxy'.)
|
||||
See https://golang.org/ref/mod#module-cache.
|
||||
|
||||
When using modules, an additional variant of the go-import meta tag is
|
||||
recognized and is preferred over those listing version control systems.
|
||||
@ -276,7 +276,8 @@ That variant uses "mod" as the vcs in the content value, as in:
|
||||
|
||||
This tag means to fetch modules with paths beginning with example.org
|
||||
from the module proxy available at the URL https://code.org/moduleproxy.
|
||||
See 'go help goproxy' for details about the proxy protocol.
|
||||
See https://golang.org/ref/mod#goproxy-protocol for details about the
|
||||
proxy protocol.
|
||||
|
||||
Import path checking
|
||||
|
||||
@ -483,6 +484,10 @@ See 'go help env' for details.
|
||||
|
||||
General-purpose environment variables:
|
||||
|
||||
GO111MODULE
|
||||
Controls whether the go command runs in module-aware mode or GOPATH mode.
|
||||
May be "off", "on", or "auto".
|
||||
See https://golang.org/ref/mod#mod-commands.
|
||||
GCCGO
|
||||
The gccgo command to run for 'go build -compiler=gccgo'.
|
||||
GOARCH
|
||||
@ -521,20 +526,24 @@ General-purpose environment variables:
|
||||
GOPATH
|
||||
For more details see: 'go help gopath'.
|
||||
GOPROXY
|
||||
URL of Go module proxy. See 'go help modules'.
|
||||
URL of Go module proxy. See https://golang.org/ref/mod#environment-variables
|
||||
and https://golang.org/ref/mod#module-proxy for details.
|
||||
GOPRIVATE, GONOPROXY, GONOSUMDB
|
||||
Comma-separated list of glob patterns (in the syntax of Go's path.Match)
|
||||
of module path prefixes that should always be fetched directly
|
||||
or that should not be compared against the checksum database.
|
||||
See 'go help private'.
|
||||
See https://golang.org/ref/mod#private-modules.
|
||||
GOROOT
|
||||
The root of the go tree.
|
||||
GOSUMDB
|
||||
The name of checksum database to use and optionally its public key and
|
||||
URL. See 'go help module-auth'.
|
||||
URL. See https://golang.org/ref/mod#authenticating.
|
||||
GOTMPDIR
|
||||
The directory where the go command will write
|
||||
temporary source files, packages, and binaries.
|
||||
GOVCS
|
||||
Lists version control commands that may be used with matching servers.
|
||||
See 'go help vcs'.
|
||||
|
||||
Environment variables for use with cgo:
|
||||
|
||||
|
@ -89,6 +89,14 @@ to -f '{{.ImportPath}}'. The struct being passed to the template is:
|
||||
TestGoFiles []string // _test.go files in package
|
||||
XTestGoFiles []string // _test.go files outside package
|
||||
|
||||
// Embedded files
|
||||
EmbedPatterns []string // //go:embed patterns
|
||||
EmbedFiles []string // files matched by EmbedPatterns
|
||||
TestEmbedPatterns []string // //go:embed patterns in TestGoFiles
|
||||
TestEmbedFiles []string // files matched by TestEmbedPatterns
|
||||
XTestEmbedPatterns []string // //go:embed patterns in XTestGoFiles
|
||||
XTestEmbedFiles []string // files matched by XTestEmbedPatterns
|
||||
|
||||
// Cgo directives
|
||||
CgoCFLAGS []string // cgo: flags for C compiler
|
||||
CgoCPPFLAGS []string // cgo: flags for C preprocessor
|
||||
@ -300,7 +308,7 @@ For more about build flags, see 'go help build'.
|
||||
|
||||
For more about specifying packages, see 'go help packages'.
|
||||
|
||||
For more about modules, see 'go help modules'.
|
||||
For more about modules, see https://golang.org/ref/mod.
|
||||
`,
|
||||
}
|
||||
|
||||
@ -577,8 +585,6 @@ func runList(ctx context.Context, cmd *base.Command, args []string) {
|
||||
// Show vendor-expanded paths in listing
|
||||
p.TestImports = p.Resolve(p.TestImports)
|
||||
p.XTestImports = p.Resolve(p.XTestImports)
|
||||
p.TestEmbedFiles = p.ResolveEmbed(p.TestEmbedPatterns)
|
||||
p.XTestEmbedFiles = p.ResolveEmbed(p.XTestEmbedPatterns)
|
||||
p.DepOnly = !cmdline[p]
|
||||
|
||||
if *listCompiled {
|
||||
|
@ -96,7 +96,7 @@ type PackagePublic struct {
|
||||
|
||||
// Embedded files
|
||||
EmbedPatterns []string `json:",omitempty"` // //go:embed patterns
|
||||
EmbedFiles []string `json:",omitempty"` // files and directories matched by EmbedPatterns
|
||||
EmbedFiles []string `json:",omitempty"` // files matched by EmbedPatterns
|
||||
|
||||
// Cgo directives
|
||||
CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler
|
||||
@ -122,11 +122,11 @@ type PackagePublic struct {
|
||||
TestGoFiles []string `json:",omitempty"` // _test.go files in package
|
||||
TestImports []string `json:",omitempty"` // imports from TestGoFiles
|
||||
TestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns
|
||||
TestEmbedFiles []string `json:",omitempty"` // //files matched by EmbedPatterns
|
||||
TestEmbedFiles []string `json:",omitempty"` // files matched by TestEmbedPatterns
|
||||
XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
|
||||
XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
|
||||
XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns
|
||||
XTestEmbedFiles []string `json:",omitempty"` // //files matched by EmbedPatterns
|
||||
XTestEmbedFiles []string `json:",omitempty"` // files matched by XTestEmbedPatterns
|
||||
}
|
||||
|
||||
// AllFiles returns the names of all the files considered for the package.
|
||||
@ -304,7 +304,7 @@ func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportSta
|
||||
}
|
||||
|
||||
if path != stk.Top() {
|
||||
p = setErrorPos(p, importPos)
|
||||
p.Error.setPos(importPos)
|
||||
}
|
||||
}
|
||||
|
||||
@ -412,6 +412,9 @@ type PackageError struct {
|
||||
}
|
||||
|
||||
func (p *PackageError) Error() string {
|
||||
// TODO(#43696): decide when to print the stack or the position based on
|
||||
// the error type and whether the package is in the main module.
|
||||
// Document the rationale.
|
||||
if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) {
|
||||
// Omit import stack. The full path to the file where the error
|
||||
// is the most important thing.
|
||||
@ -447,6 +450,15 @@ func (p *PackageError) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(perr)
|
||||
}
|
||||
|
||||
func (p *PackageError) setPos(posList []token.Position) {
|
||||
if len(posList) == 0 {
|
||||
return
|
||||
}
|
||||
pos := posList[0]
|
||||
pos.Filename = base.ShortPath(pos.Filename)
|
||||
p.Pos = pos.String()
|
||||
}
|
||||
|
||||
// ImportPathError is a type of error that prevents a package from being loaded
|
||||
// for a given import path. When such a package is loaded, a *Package is
|
||||
// returned with Err wrapping an ImportPathError: the error is attached to
|
||||
@ -695,17 +707,19 @@ func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *
|
||||
Err: ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)),
|
||||
}
|
||||
p.Incomplete = true
|
||||
setErrorPos(p, importPos)
|
||||
p.Error.setPos(importPos)
|
||||
}
|
||||
}
|
||||
|
||||
// Checked on every import because the rules depend on the code doing the importing.
|
||||
if perr := disallowInternal(srcDir, parent, parentPath, p, stk); perr != p {
|
||||
return setErrorPos(perr, importPos)
|
||||
perr.Error.setPos(importPos)
|
||||
return perr
|
||||
}
|
||||
if mode&ResolveImport != 0 {
|
||||
if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != p {
|
||||
return setErrorPos(perr, importPos)
|
||||
perr.Error.setPos(importPos)
|
||||
return perr
|
||||
}
|
||||
}
|
||||
|
||||
@ -715,7 +729,8 @@ func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *
|
||||
ImportStack: stk.Copy(),
|
||||
Err: ImportErrorf(path, "import %q is a program, not an importable package", path),
|
||||
}
|
||||
return setErrorPos(&perr, importPos)
|
||||
perr.Error.setPos(importPos)
|
||||
return &perr
|
||||
}
|
||||
|
||||
if p.Internal.Local && parent != nil && !parent.Internal.Local {
|
||||
@ -730,21 +745,13 @@ func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *
|
||||
ImportStack: stk.Copy(),
|
||||
Err: err,
|
||||
}
|
||||
return setErrorPos(&perr, importPos)
|
||||
perr.Error.setPos(importPos)
|
||||
return &perr
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
func setErrorPos(p *Package, importPos []token.Position) *Package {
|
||||
if len(importPos) > 0 {
|
||||
pos := importPos[0]
|
||||
pos.Filename = base.ShortPath(pos.Filename)
|
||||
p.Error.Pos = pos.String()
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// loadPackageData loads information needed to construct a *Package. The result
|
||||
// is cached, and later calls to loadPackageData for the same package will return
|
||||
// the same data.
|
||||
@ -769,11 +776,7 @@ func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd
|
||||
}
|
||||
|
||||
if strings.Contains(path, "@") {
|
||||
if cfg.ModulesEnabled {
|
||||
return nil, false, errors.New("can only use path@version syntax with 'go get'")
|
||||
} else {
|
||||
return nil, false, errors.New("cannot use path@version syntax in GOPATH mode")
|
||||
}
|
||||
return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
|
||||
}
|
||||
|
||||
// Determine canonical package path and directory.
|
||||
@ -1653,7 +1656,7 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
|
||||
// must be either in an explicit command-line argument,
|
||||
// or on the importer side (indicated by a non-empty importPos).
|
||||
if path != stk.Top() && len(importPos) > 0 {
|
||||
p = setErrorPos(p, importPos)
|
||||
p.Error.setPos(importPos)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1663,11 +1666,6 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
|
||||
p.setLoadPackageDataError(err, path, stk, importPos)
|
||||
}
|
||||
|
||||
p.EmbedFiles, p.Internal.Embed, err = p.resolveEmbed(p.EmbedPatterns)
|
||||
if err != nil {
|
||||
setError(err)
|
||||
}
|
||||
|
||||
useBindir := p.Name == "main"
|
||||
if !p.Standard {
|
||||
switch cfg.BuildBuildmode {
|
||||
@ -1803,9 +1801,20 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
|
||||
return
|
||||
}
|
||||
|
||||
// Errors after this point are caused by this package, not the importing
|
||||
// package. Pushing the path here prevents us from reporting the error
|
||||
// with the position of the import declaration.
|
||||
stk.Push(path)
|
||||
defer stk.Pop()
|
||||
|
||||
p.EmbedFiles, p.Internal.Embed, err = resolveEmbed(p.Dir, p.EmbedPatterns)
|
||||
if err != nil {
|
||||
p.Incomplete = true
|
||||
setError(err)
|
||||
embedErr := err.(*EmbedError)
|
||||
p.Error.setPos(p.Internal.Build.EmbedPatternPos[embedErr.Pattern])
|
||||
}
|
||||
|
||||
// Check for case-insensitive collision of input files.
|
||||
// To avoid problems on case-insensitive files, we reject any package
|
||||
// where two different input files have equal names under a case-insensitive
|
||||
@ -1909,35 +1918,62 @@ func (p *Package) load(ctx context.Context, path string, stk *ImportStack, impor
|
||||
}
|
||||
}
|
||||
|
||||
// An EmbedError indicates a problem with a go:embed directive.
|
||||
type EmbedError struct {
|
||||
Pattern string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *EmbedError) Error() string {
|
||||
return fmt.Sprintf("pattern %s: %v", e.Pattern, e.Err)
|
||||
}
|
||||
|
||||
func (e *EmbedError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// ResolveEmbed resolves //go:embed patterns and returns only the file list.
|
||||
// For use by go list to compute p.TestEmbedFiles and p.XTestEmbedFiles.
|
||||
func (p *Package) ResolveEmbed(patterns []string) []string {
|
||||
files, _, _ := p.resolveEmbed(patterns)
|
||||
return files
|
||||
// For use by go mod vendor to find embedded files it should copy into the
|
||||
// vendor directory.
|
||||
// TODO(#42504): Once go mod vendor uses load.PackagesAndErrors, just
|
||||
// call (*Package).ResolveEmbed
|
||||
func ResolveEmbed(dir string, patterns []string) ([]string, error) {
|
||||
files, _, err := resolveEmbed(dir, patterns)
|
||||
return files, err
|
||||
}
|
||||
|
||||
// resolveEmbed resolves //go:embed patterns to precise file lists.
|
||||
// It sets files to the list of unique files matched (for go list),
|
||||
// and it sets pmap to the more precise mapping from
|
||||
// patterns to files.
|
||||
// TODO(rsc): All these messages need position information for better error reports.
|
||||
func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[string][]string, err error) {
|
||||
func resolveEmbed(pkgdir string, patterns []string) (files []string, pmap map[string][]string, err error) {
|
||||
var pattern string
|
||||
defer func() {
|
||||
if err != nil {
|
||||
err = &EmbedError{
|
||||
Pattern: pattern,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// TODO(rsc): All these messages need position information for better error reports.
|
||||
pmap = make(map[string][]string)
|
||||
have := make(map[string]int)
|
||||
dirOK := make(map[string]bool)
|
||||
pid := 0 // pattern ID, to allow reuse of have map
|
||||
for _, pattern := range patterns {
|
||||
for _, pattern = range patterns {
|
||||
pid++
|
||||
|
||||
// Check pattern is valid for //go:embed.
|
||||
if _, err := path.Match(pattern, ""); err != nil || !validEmbedPattern(pattern) {
|
||||
return nil, nil, fmt.Errorf("pattern %s: invalid pattern syntax", pattern)
|
||||
return nil, nil, fmt.Errorf("invalid pattern syntax")
|
||||
}
|
||||
|
||||
// Glob to find matches.
|
||||
match, err := fsys.Glob(p.Dir + string(filepath.Separator) + filepath.FromSlash(pattern))
|
||||
match, err := fsys.Glob(pkgdir + string(filepath.Separator) + filepath.FromSlash(pattern))
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("pattern %s: %v", pattern, err)
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Filter list of matches down to the ones that will still exist when
|
||||
@ -1946,7 +1982,7 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
|
||||
// then there may be other things lying around, like symbolic links or .git directories.)
|
||||
var list []string
|
||||
for _, file := range match {
|
||||
rel := filepath.ToSlash(file[len(p.Dir)+1:]) // file, relative to p.Dir
|
||||
rel := filepath.ToSlash(file[len(pkgdir)+1:]) // file, relative to p.Dir
|
||||
|
||||
what := "file"
|
||||
info, err := fsys.Lstat(file)
|
||||
@ -1959,28 +1995,28 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
|
||||
|
||||
// Check that directories along path do not begin a new module
|
||||
// (do not contain a go.mod).
|
||||
for dir := file; len(dir) > len(p.Dir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
|
||||
for dir := file; len(dir) > len(pkgdir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
|
||||
if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil {
|
||||
return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in different module", pattern, what, rel)
|
||||
return nil, nil, fmt.Errorf("cannot embed %s %s: in different module", what, rel)
|
||||
}
|
||||
if dir != file {
|
||||
if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() {
|
||||
return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in non-directory %s", pattern, what, rel, dir[len(p.Dir)+1:])
|
||||
return nil, nil, fmt.Errorf("cannot embed %s %s: in non-directory %s", what, rel, dir[len(pkgdir)+1:])
|
||||
}
|
||||
}
|
||||
dirOK[dir] = true
|
||||
if elem := filepath.Base(dir); isBadEmbedName(elem) {
|
||||
if dir == file {
|
||||
return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: invalid name %s", pattern, what, rel, elem)
|
||||
return nil, nil, fmt.Errorf("cannot embed %s %s: invalid name %s", what, rel, elem)
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("pattern %s: cannot embed %s %s: in invalid directory %s", pattern, what, rel, elem)
|
||||
return nil, nil, fmt.Errorf("cannot embed %s %s: in invalid directory %s", what, rel, elem)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("pattern %s: cannot embed irregular file %s", pattern, rel)
|
||||
return nil, nil, fmt.Errorf("cannot embed irregular file %s", rel)
|
||||
|
||||
case info.Mode().IsRegular():
|
||||
if have[rel] != pid {
|
||||
@ -1996,7 +2032,7 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rel := filepath.ToSlash(path[len(p.Dir)+1:])
|
||||
rel := filepath.ToSlash(path[len(pkgdir)+1:])
|
||||
name := info.Name()
|
||||
if path != file && (isBadEmbedName(name) || name[0] == '.' || name[0] == '_') {
|
||||
// Ignore bad names, assuming they won't go into modules.
|
||||
@ -2027,13 +2063,13 @@ func (p *Package) resolveEmbed(patterns []string) (files []string, pmap map[stri
|
||||
return nil, nil, err
|
||||
}
|
||||
if count == 0 {
|
||||
return nil, nil, fmt.Errorf("pattern %s: cannot embed directory %s: contains no embeddable files", pattern, rel)
|
||||
return nil, nil, fmt.Errorf("cannot embed directory %s: contains no embeddable files", rel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(list) == 0 {
|
||||
return nil, nil, fmt.Errorf("pattern %s: no matching files found", pattern)
|
||||
return nil, nil, fmt.Errorf("no matching files found")
|
||||
}
|
||||
sort.Strings(list)
|
||||
pmap[pattern] = list
|
||||
|
@ -124,12 +124,14 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p
|
||||
imports = append(imports, p1)
|
||||
}
|
||||
var err error
|
||||
p.TestEmbedFiles, testEmbed, err = p.resolveEmbed(p.TestEmbedPatterns)
|
||||
p.TestEmbedFiles, testEmbed, err = resolveEmbed(p.Dir, p.TestEmbedPatterns)
|
||||
if err != nil && ptestErr == nil {
|
||||
ptestErr = &PackageError{
|
||||
ImportStack: stk.Copy(),
|
||||
Err: err,
|
||||
}
|
||||
embedErr := err.(*EmbedError)
|
||||
ptestErr.setPos(p.Internal.Build.TestEmbedPatternPos[embedErr.Pattern])
|
||||
}
|
||||
stk.Pop()
|
||||
|
||||
@ -145,12 +147,14 @@ func TestPackagesAndErrors(ctx context.Context, p *Package, cover *TestCover) (p
|
||||
}
|
||||
p.XTestImports[i] = p1.ImportPath
|
||||
}
|
||||
p.XTestEmbedFiles, xtestEmbed, err = p.resolveEmbed(p.XTestEmbedPatterns)
|
||||
p.XTestEmbedFiles, xtestEmbed, err = resolveEmbed(p.Dir, p.XTestEmbedPatterns)
|
||||
if err != nil && pxtestErr == nil {
|
||||
pxtestErr = &PackageError{
|
||||
ImportStack: stk.Copy(),
|
||||
Err: err,
|
||||
}
|
||||
embedErr := err.(*EmbedError)
|
||||
pxtestErr.setPos(p.Internal.Build.XTestEmbedPatternPos[embedErr.Pattern])
|
||||
}
|
||||
stk.Pop()
|
||||
|
||||
|
@ -52,7 +52,9 @@ corresponding to this Go struct:
|
||||
|
||||
The -x flag causes download to print the commands download executes.
|
||||
|
||||
See 'go help modules' for more about module queries.
|
||||
See https://golang.org/ref/mod#go-mod-download for more about 'go mod download'.
|
||||
|
||||
See https://golang.org/ref/mod#version-queries for more about version queries.
|
||||
`,
|
||||
}
|
||||
|
||||
|
@ -122,9 +122,7 @@ Note that this only describes the go.mod file itself, not other modules
|
||||
referred to indirectly. For the full set of modules available to a build,
|
||||
use 'go list -m -json all'.
|
||||
|
||||
For example, a tool can obtain the go.mod as a data structure by
|
||||
parsing the output of 'go mod edit -json' and can then make changes
|
||||
by invoking 'go mod edit' with -require, -exclude, and so on.
|
||||
See https://golang.org/ref/mod#go-mod-edit for more about 'go mod edit'.
|
||||
`,
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,8 @@ Graph prints the module requirement graph (with replacements applied)
|
||||
in text form. Each line in the output has two space-separated fields: a module
|
||||
and one of its requirements. Each module is identified as a string of the form
|
||||
path@version, except for the main module, which has no @version suffix.
|
||||
|
||||
See https://golang.org/ref/mod#go-mod-graph for more about 'go mod graph'.
|
||||
`,
|
||||
Run: runGraph,
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ Gopkg.lock), and the current directory (if in GOPATH).
|
||||
|
||||
If a configuration file for a vendoring tool is present, init will attempt to
|
||||
import module requirements from it.
|
||||
|
||||
See https://golang.org/ref/mod#go-mod-init for more about 'go mod init'.
|
||||
`,
|
||||
Run: runInit,
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ to standard error.
|
||||
|
||||
The -e flag causes tidy to attempt to proceed despite errors
|
||||
encountered while loading packages.
|
||||
|
||||
See https://golang.org/ref/mod#go-mod-tidy for more about 'go mod tidy'.
|
||||
`,
|
||||
Run: runTidy,
|
||||
}
|
||||
|
@ -7,7 +7,9 @@ package modcmd
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
@ -19,7 +21,9 @@ import (
|
||||
"cmd/go/internal/cfg"
|
||||
"cmd/go/internal/fsys"
|
||||
"cmd/go/internal/imports"
|
||||
"cmd/go/internal/load"
|
||||
"cmd/go/internal/modload"
|
||||
"cmd/go/internal/str"
|
||||
|
||||
"golang.org/x/mod/module"
|
||||
"golang.org/x/mod/semver"
|
||||
@ -38,6 +42,8 @@ modules and packages to standard error.
|
||||
|
||||
The -e flag causes vendor to attempt to proceed despite errors
|
||||
encountered while loading packages.
|
||||
|
||||
See https://golang.org/ref/mod#go-mod-vendor for more about 'go mod vendor'.
|
||||
`,
|
||||
Run: runVendor,
|
||||
}
|
||||
@ -180,19 +186,76 @@ func moduleLine(m, r module.Version) string {
|
||||
}
|
||||
|
||||
func vendorPkg(vdir, pkg string) {
|
||||
// TODO(#42504): Instead of calling modload.ImportMap then build.ImportDir,
|
||||
// just call load.PackagesAndErrors. To do that, we need to add a good way
|
||||
// to ignore build constraints.
|
||||
realPath := modload.ImportMap(pkg)
|
||||
if realPath != pkg && modload.ImportMap(realPath) != "" {
|
||||
fmt.Fprintf(os.Stderr, "warning: %s imported as both %s and %s; making two copies.\n", realPath, realPath, pkg)
|
||||
}
|
||||
|
||||
copiedFiles := make(map[string]bool)
|
||||
dst := filepath.Join(vdir, pkg)
|
||||
src := modload.PackageDir(realPath)
|
||||
if src == "" {
|
||||
fmt.Fprintf(os.Stderr, "internal error: no pkg for %s -> %s\n", pkg, realPath)
|
||||
}
|
||||
copyDir(dst, src, matchPotentialSourceFile)
|
||||
copyDir(dst, src, matchPotentialSourceFile, copiedFiles)
|
||||
if m := modload.PackageModule(realPath); m.Path != "" {
|
||||
copyMetadata(m.Path, realPath, dst, src)
|
||||
copyMetadata(m.Path, realPath, dst, src, copiedFiles)
|
||||
}
|
||||
|
||||
ctx := build.Default
|
||||
ctx.UseAllFiles = true
|
||||
bp, err := ctx.ImportDir(src, build.IgnoreVendor)
|
||||
// Because UseAllFiles is set on the build.Context, it's possible ta get
|
||||
// a MultiplePackageError on an otherwise valid package: the package could
|
||||
// have different names for GOOS=windows and GOOS=mac for example. On the
|
||||
// other hand if there's a NoGoError, the package might have source files
|
||||
// specifying "// +build ignore" those packages should be skipped because
|
||||
// embeds from ignored files can't be used.
|
||||
// TODO(#42504): Find a better way to avoid errors from ImportDir. We'll
|
||||
// need to figure this out when we switch to PackagesAndErrors as per the
|
||||
// TODO above.
|
||||
var multiplePackageError *build.MultiplePackageError
|
||||
var noGoError *build.NoGoError
|
||||
if err != nil {
|
||||
if errors.As(err, &noGoError) {
|
||||
return // No source files in this package are built. Skip embeds in ignored files.
|
||||
} else if !errors.As(err, &multiplePackageError) { // multiplePackgeErrors are okay, but others are not.
|
||||
base.Fatalf("internal error: failed to find embedded files of %s: %v\n", pkg, err)
|
||||
}
|
||||
}
|
||||
embedPatterns := str.StringList(bp.EmbedPatterns, bp.TestEmbedPatterns, bp.XTestEmbedPatterns)
|
||||
embeds, err := load.ResolveEmbed(bp.Dir, embedPatterns)
|
||||
if err != nil {
|
||||
base.Fatalf("go mod vendor: %v", err)
|
||||
}
|
||||
for _, embed := range embeds {
|
||||
embedDst := filepath.Join(dst, embed)
|
||||
if copiedFiles[embedDst] {
|
||||
continue
|
||||
}
|
||||
|
||||
// Copy the file as is done by copyDir below.
|
||||
r, err := os.Open(filepath.Join(src, embed))
|
||||
if err != nil {
|
||||
base.Fatalf("go mod vendor: %v", err)
|
||||
}
|
||||
if err := os.MkdirAll(filepath.Dir(embedDst), 0777); err != nil {
|
||||
base.Fatalf("go mod vendor: %v", err)
|
||||
}
|
||||
w, err := os.Create(embedDst)
|
||||
if err != nil {
|
||||
base.Fatalf("go mod vendor: %v", err)
|
||||
}
|
||||
if _, err := io.Copy(w, r); err != nil {
|
||||
base.Fatalf("go mod vendor: %v", err)
|
||||
}
|
||||
r.Close()
|
||||
if err := w.Close(); err != nil {
|
||||
base.Fatalf("go mod vendor: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,14 +268,14 @@ var copiedMetadata = make(map[metakey]bool)
|
||||
|
||||
// copyMetadata copies metadata files from parents of src to parents of dst,
|
||||
// stopping after processing the src parent for modPath.
|
||||
func copyMetadata(modPath, pkg, dst, src string) {
|
||||
func copyMetadata(modPath, pkg, dst, src string, copiedFiles map[string]bool) {
|
||||
for parent := 0; ; parent++ {
|
||||
if copiedMetadata[metakey{modPath, dst}] {
|
||||
break
|
||||
}
|
||||
copiedMetadata[metakey{modPath, dst}] = true
|
||||
if parent > 0 {
|
||||
copyDir(dst, src, matchMetadata)
|
||||
copyDir(dst, src, matchMetadata, copiedFiles)
|
||||
}
|
||||
if modPath == pkg {
|
||||
break
|
||||
@ -280,7 +343,7 @@ func matchPotentialSourceFile(dir string, info fs.DirEntry) bool {
|
||||
}
|
||||
|
||||
// copyDir copies all regular files satisfying match(info) from src to dst.
|
||||
func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool) {
|
||||
func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool, copiedFiles map[string]bool) {
|
||||
files, err := os.ReadDir(src)
|
||||
if err != nil {
|
||||
base.Fatalf("go mod vendor: %v", err)
|
||||
@ -292,11 +355,14 @@ func copyDir(dst, src string, match func(dir string, info fs.DirEntry) bool) {
|
||||
if file.IsDir() || !file.Type().IsRegular() || !match(src, file) {
|
||||
continue
|
||||
}
|
||||
copiedFiles[file.Name()] = true
|
||||
r, err := os.Open(filepath.Join(src, file.Name()))
|
||||
if err != nil {
|
||||
base.Fatalf("go mod vendor: %v", err)
|
||||
}
|
||||
w, err := os.Create(filepath.Join(dst, file.Name()))
|
||||
dstPath := filepath.Join(dst, file.Name())
|
||||
copiedFiles[dstPath] = true
|
||||
w, err := os.Create(dstPath)
|
||||
if err != nil {
|
||||
base.Fatalf("go mod vendor: %v", err)
|
||||
}
|
||||
|
@ -31,6 +31,8 @@ modified since being downloaded. If all the modules are unmodified,
|
||||
verify prints "all modules verified." Otherwise it reports which
|
||||
modules have been changed and causes 'go mod' to exit with a
|
||||
non-zero status.
|
||||
|
||||
See https://golang.org/ref/mod#go-mod-verify for more about 'go mod verify'.
|
||||
`,
|
||||
Run: runVerify,
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ For example:
|
||||
# golang.org/x/text/encoding
|
||||
(main module does not need package golang.org/x/text/encoding)
|
||||
$
|
||||
|
||||
See https://golang.org/ref/mod#go-mod-why for more about 'go mod why'.
|
||||
`,
|
||||
}
|
||||
|
||||
|
@ -10,10 +10,10 @@ import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -8,11 +8,11 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
@ -768,90 +768,14 @@ var HelpModuleAuth = &base.Command{
|
||||
UsageLine: "module-auth",
|
||||
Short: "module authentication using go.sum",
|
||||
Long: `
|
||||
The go command tries to authenticate every downloaded module,
|
||||
checking that the bits downloaded for a specific module version today
|
||||
match bits downloaded yesterday. This ensures repeatable builds
|
||||
and detects introduction of unexpected changes, malicious or not.
|
||||
When the go command downloads a module zip file or go.mod file into the
|
||||
module cache, it computes a cryptographic hash and compares it with a known
|
||||
value to verify the file hasn't changed since it was first downloaded. Known
|
||||
hashes are stored in a file in the module root directory named go.sum. Hashes
|
||||
may also be downloaded from the checksum database depending on the values of
|
||||
GOSUMDB, GOPRIVATE, and GONOSUMDB.
|
||||
|
||||
In each module's root, alongside go.mod, the go command maintains
|
||||
a file named go.sum containing the cryptographic checksums of the
|
||||
module's dependencies.
|
||||
|
||||
The form of each line in go.sum is three fields:
|
||||
|
||||
<module> <version>[/go.mod] <hash>
|
||||
|
||||
Each known module version results in two lines in the go.sum file.
|
||||
The first line gives the hash of the module version's file tree.
|
||||
The second line appends "/go.mod" to the version and gives the hash
|
||||
of only the module version's (possibly synthesized) go.mod file.
|
||||
The go.mod-only hash allows downloading and authenticating a
|
||||
module version's go.mod file, which is needed to compute the
|
||||
dependency graph, without also downloading all the module's source code.
|
||||
|
||||
The hash begins with an algorithm prefix of the form "h<N>:".
|
||||
The only defined algorithm prefix is "h1:", which uses SHA-256.
|
||||
|
||||
Module authentication failures
|
||||
|
||||
The go command maintains a cache of downloaded packages and computes
|
||||
and records the cryptographic checksum of each package at download time.
|
||||
In normal operation, the go command checks the main module's go.sum file
|
||||
against these precomputed checksums instead of recomputing them on
|
||||
each command invocation. The 'go mod verify' command checks that
|
||||
the cached copies of module downloads still match both their recorded
|
||||
checksums and the entries in go.sum.
|
||||
|
||||
In day-to-day development, the checksum of a given module version
|
||||
should never change. Each time a dependency is used by a given main
|
||||
module, the go command checks its local cached copy, freshly
|
||||
downloaded or not, against the main module's go.sum. If the checksums
|
||||
don't match, the go command reports the mismatch as a security error
|
||||
and refuses to run the build. When this happens, proceed with caution:
|
||||
code changing unexpectedly means today's build will not match
|
||||
yesterday's, and the unexpected change may not be beneficial.
|
||||
|
||||
If the go command reports a mismatch in go.sum, the downloaded code
|
||||
for the reported module version does not match the one used in a
|
||||
previous build of the main module. It is important at that point
|
||||
to find out what the right checksum should be, to decide whether
|
||||
go.sum is wrong or the downloaded code is wrong. Usually go.sum is right:
|
||||
you want to use the same code you used yesterday.
|
||||
|
||||
If a downloaded module is not yet included in go.sum and it is a publicly
|
||||
available module, the go command consults the Go checksum database to fetch
|
||||
the expected go.sum lines. If the downloaded code does not match those
|
||||
lines, the go command reports the mismatch and exits. Note that the
|
||||
database is not consulted for module versions already listed in go.sum.
|
||||
|
||||
If a go.sum mismatch is reported, it is always worth investigating why
|
||||
the code downloaded today differs from what was downloaded yesterday.
|
||||
|
||||
The GOSUMDB environment variable identifies the name of checksum database
|
||||
to use and optionally its public key and URL, as in:
|
||||
|
||||
GOSUMDB="sum.golang.org"
|
||||
GOSUMDB="sum.golang.org+<publickey>"
|
||||
GOSUMDB="sum.golang.org+<publickey> https://sum.golang.org"
|
||||
|
||||
The go command knows the public key of sum.golang.org, and also that the name
|
||||
sum.golang.google.cn (available inside mainland China) connects to the
|
||||
sum.golang.org checksum database; use of any other database requires giving
|
||||
the public key explicitly.
|
||||
The URL defaults to "https://" followed by the database name.
|
||||
|
||||
GOSUMDB defaults to "sum.golang.org", the Go checksum database run by Google.
|
||||
See https://sum.golang.org/privacy for the service's privacy policy.
|
||||
|
||||
If GOSUMDB is set to "off", or if "go get" is invoked with the -insecure flag,
|
||||
the checksum database is not consulted, and all unrecognized modules are
|
||||
accepted, at the cost of giving up the security guarantee of verified repeatable
|
||||
downloads for all modules. A better way to bypass the checksum database
|
||||
for specific modules is to use the GOPRIVATE or GONOSUMDB environment
|
||||
variables. See 'go help private' for details.
|
||||
|
||||
The 'go env -w' command (see 'go help env') can be used to set these variables
|
||||
for future go command invocations.
|
||||
For details, see https://golang.org/ref/mod#authenticating.
|
||||
`,
|
||||
}
|
||||
|
||||
@ -865,8 +789,8 @@ regardless of source, against the public Go checksum database at sum.golang.org.
|
||||
These defaults work well for publicly available source code.
|
||||
|
||||
The GOPRIVATE environment variable controls which modules the go command
|
||||
considers to be private (not available publicly) and should therefore not use the
|
||||
proxy or checksum database. The variable is a comma-separated list of
|
||||
considers to be private (not available publicly) and should therefore not use
|
||||
the proxy or checksum database. The variable is a comma-separated list of
|
||||
glob patterns (in the syntax of Go's path.Match) of module path prefixes.
|
||||
For example,
|
||||
|
||||
@ -876,10 +800,6 @@ causes the go command to treat as private any module with a path prefix
|
||||
matching either pattern, including git.corp.example.com/xyzzy, rsc.io/private,
|
||||
and rsc.io/private/quux.
|
||||
|
||||
The GOPRIVATE environment variable may be used by other tools as well to
|
||||
identify non-public modules. For example, an editor could use GOPRIVATE
|
||||
to decide whether to hyperlink a package import to a godoc.org page.
|
||||
|
||||
For fine-grained control over module download and validation, the GONOPROXY
|
||||
and GONOSUMDB environment variables accept the same kind of glob list
|
||||
and override GOPRIVATE for the specific decision of whether to use the proxy
|
||||
@ -892,12 +812,6 @@ users would configure go using:
|
||||
GOPROXY=proxy.example.com
|
||||
GONOPROXY=none
|
||||
|
||||
This would tell the go command and other tools that modules beginning with
|
||||
a corp.example.com subdomain are private but that the company proxy should
|
||||
be used for downloading both public and private modules, because
|
||||
GONOPROXY has been set to a pattern that won't match any modules,
|
||||
overriding GOPRIVATE.
|
||||
|
||||
The GOPRIVATE variable is also used to define the "public" and "private"
|
||||
patterns for the GOVCS variable; see 'go help vcs'. For that usage,
|
||||
GOPRIVATE applies even in GOPATH mode. In that case, it matches import paths
|
||||
@ -905,5 +819,7 @@ instead of module paths.
|
||||
|
||||
The 'go env -w' command (see 'go help env') can be used to set these variables
|
||||
for future go command invocations.
|
||||
|
||||
For more details, see https://golang.org/ref/mod#private-modules.
|
||||
`,
|
||||
}
|
||||
|
@ -36,65 +36,8 @@ URLs of a specified form. The requests have no query parameters, so even
|
||||
a site serving from a fixed file system (including a file:/// URL)
|
||||
can be a module proxy.
|
||||
|
||||
The GET requests sent to a Go module proxy are:
|
||||
|
||||
GET $GOPROXY/<module>/@v/list returns a list of known versions of the given
|
||||
module, one per line.
|
||||
|
||||
GET $GOPROXY/<module>/@v/<version>.info returns JSON-formatted metadata
|
||||
about that version of the given module.
|
||||
|
||||
GET $GOPROXY/<module>/@v/<version>.mod returns the go.mod file
|
||||
for that version of the given module.
|
||||
|
||||
GET $GOPROXY/<module>/@v/<version>.zip returns the zip archive
|
||||
for that version of the given module.
|
||||
|
||||
GET $GOPROXY/<module>/@latest returns JSON-formatted metadata about the
|
||||
latest known version of the given module in the same format as
|
||||
<module>/@v/<version>.info. The latest version should be the version of
|
||||
the module the go command may use if <module>/@v/list is empty or no
|
||||
listed version is suitable. <module>/@latest is optional and may not
|
||||
be implemented by a module proxy.
|
||||
|
||||
When resolving the latest version of a module, the go command will request
|
||||
<module>/@v/list, then, if no suitable versions are found, <module>/@latest.
|
||||
The go command prefers, in order: the semantically highest release version,
|
||||
the semantically highest pre-release version, and the chronologically
|
||||
most recent pseudo-version. In Go 1.12 and earlier, the go command considered
|
||||
pseudo-versions in <module>/@v/list to be pre-release versions, but this is
|
||||
no longer true since Go 1.13.
|
||||
|
||||
To avoid problems when serving from case-sensitive file systems,
|
||||
the <module> and <version> elements are case-encoded, replacing every
|
||||
uppercase letter with an exclamation mark followed by the corresponding
|
||||
lower-case letter: github.com/Azure encodes as github.com/!azure.
|
||||
|
||||
The JSON-formatted metadata about a given module corresponds to
|
||||
this Go data structure, which may be expanded in the future:
|
||||
|
||||
type Info struct {
|
||||
Version string // version string
|
||||
Time time.Time // commit time
|
||||
}
|
||||
|
||||
The zip archive for a specific version of a given module is a
|
||||
standard zip file that contains the file tree corresponding
|
||||
to the module's source code and related files. The archive uses
|
||||
slash-separated paths, and every file path in the archive must
|
||||
begin with <module>@<version>/, where the module and version are
|
||||
substituted directly, not case-encoded. The root of the module
|
||||
file tree corresponds to the <module>@<version>/ prefix in the
|
||||
archive.
|
||||
|
||||
Even when downloading directly from version control systems,
|
||||
the go command synthesizes explicit info, mod, and zip files
|
||||
and stores them in its local cache, $GOPATH/pkg/mod/cache/download,
|
||||
the same as if it had downloaded them directly from a proxy.
|
||||
The cache layout is the same as the proxy URL space, so
|
||||
serving $GOPATH/pkg/mod/cache/download at (or copying it to)
|
||||
https://example.com/proxy would let other users access those
|
||||
cached module versions with GOPROXY=https://example.com/proxy.
|
||||
For details on the GOPROXY protocol, see
|
||||
https://golang.org/ref/mod#goproxy-protocol.
|
||||
`,
|
||||
}
|
||||
|
||||
|
@ -56,85 +56,49 @@ var CmdGet = &base.Command{
|
||||
UsageLine: "go get [-d] [-t] [-u] [-v] [-insecure] [build flags] [packages]",
|
||||
Short: "add dependencies to current module and install them",
|
||||
Long: `
|
||||
Get resolves and adds dependencies to the current development module
|
||||
and then builds and installs them.
|
||||
Get resolves its command-line arguments to packages at specific module versions,
|
||||
updates go.mod to require those versions, downloads source code into the
|
||||
module cache, then builds and installs the named packages.
|
||||
|
||||
The first step is to resolve which dependencies to add.
|
||||
To add a dependency for a package or upgrade it to its latest version:
|
||||
|
||||
For each named package or package pattern, get must decide which version of
|
||||
the corresponding module to use. By default, get looks up the latest tagged
|
||||
release version, such as v0.4.5 or v1.2.3. If there are no tagged release
|
||||
versions, get looks up the latest tagged pre-release version, such as
|
||||
v0.0.1-pre1. If there are no tagged versions at all, get looks up the latest
|
||||
known commit. If the module is not already required at a later version
|
||||
(for example, a pre-release newer than the latest release), get will use
|
||||
the version it looked up. Otherwise, get will use the currently
|
||||
required version.
|
||||
go get example.com/pkg
|
||||
|
||||
This default version selection can be overridden by adding an @version
|
||||
suffix to the package argument, as in 'go get golang.org/x/text@v0.3.0'.
|
||||
The version may be a prefix: @v1 denotes the latest available version starting
|
||||
with v1. See 'go help modules' under the heading 'Module queries' for the
|
||||
full query syntax.
|
||||
To upgrade or downgrade a package to a specific version:
|
||||
|
||||
For modules stored in source control repositories, the version suffix can
|
||||
also be a commit hash, branch identifier, or other syntax known to the
|
||||
source control system, as in 'go get golang.org/x/text@master'. Note that
|
||||
branches with names that overlap with other module query syntax cannot be
|
||||
selected explicitly. For example, the suffix @v2 means the latest version
|
||||
starting with v2, not the branch named v2.
|
||||
go get example.com/pkg@v1.2.3
|
||||
|
||||
If a module under consideration is already a dependency of the current
|
||||
development module, then get will update the required version.
|
||||
Specifying a version earlier than the current required version is valid and
|
||||
downgrades the dependency. The version suffix @none indicates that the
|
||||
dependency should be removed entirely, downgrading or removing modules
|
||||
depending on it as needed.
|
||||
To remove a dependency on a module and downgrade modules that require it:
|
||||
|
||||
The version suffix @latest explicitly requests the latest minor release of
|
||||
the module named by the given path. The suffix @upgrade is like @latest but
|
||||
will not downgrade a module if it is already required at a revision or
|
||||
pre-release version newer than the latest released version. The suffix
|
||||
@patch requests the latest patch release: the latest released version
|
||||
with the same major and minor version numbers as the currently required
|
||||
version. Like @upgrade, @patch will not downgrade a module already required
|
||||
at a newer version. If the path is not already required, @upgrade is
|
||||
equivalent to @latest, and @patch is disallowed.
|
||||
go get example.com/mod@none
|
||||
|
||||
Although get defaults to using the latest version of the module containing
|
||||
a named package, it does not use the latest version of that module's
|
||||
dependencies. Instead it prefers to use the specific dependency versions
|
||||
requested by that module. For example, if the latest A requires module
|
||||
B v1.2.3, while B v1.2.4 and v1.3.1 are also available, then 'go get A'
|
||||
will use the latest A but then use B v1.2.3, as requested by A. (If there
|
||||
are competing requirements for a particular module, then 'go get' resolves
|
||||
those requirements by taking the maximum requested version.)
|
||||
See https://golang.org/ref/mod#go-get for details.
|
||||
|
||||
The 'go install' command may be used to build and install packages. When a
|
||||
version is specified, 'go install' runs in module-aware mode and ignores
|
||||
the go.mod file in the current directory. For example:
|
||||
|
||||
go install example.com/pkg@v1.2.3
|
||||
go install example.com/pkg@latest
|
||||
|
||||
See 'go help install' or https://golang.org/ref/mod#go-install for details.
|
||||
|
||||
In addition to build flags (listed in 'go help build') 'go get' accepts the
|
||||
following flags.
|
||||
|
||||
The -t flag instructs get to consider modules needed to build tests of
|
||||
packages specified on the command line.
|
||||
|
||||
The -u flag instructs get to update modules providing dependencies
|
||||
of packages named on the command line to use newer minor or patch
|
||||
releases when available. Continuing the previous example, 'go get -u A'
|
||||
will use the latest A with B v1.3.1 (not B v1.2.3). If B requires module C,
|
||||
but C does not provide any packages needed to build packages in A
|
||||
(not including tests), then C will not be updated.
|
||||
releases when available.
|
||||
|
||||
The -u=patch flag (not -u patch) also instructs get to update dependencies,
|
||||
but changes the default to select patch releases.
|
||||
Continuing the previous example,
|
||||
'go get -u=patch A@latest' will use the latest A with B v1.2.4 (not B v1.2.3),
|
||||
while 'go get -u=patch A' will use a patch release of A instead.
|
||||
|
||||
When the -t and -u flags are used together, get will update
|
||||
test dependencies as well.
|
||||
|
||||
In general, adding a new dependency may require upgrading
|
||||
existing dependencies to keep a working build, and 'go get' does
|
||||
this automatically. Similarly, downgrading one dependency may
|
||||
require downgrading other dependencies, and 'go get' does
|
||||
this automatically as well.
|
||||
|
||||
The -insecure flag permits fetching from repositories and resolving
|
||||
custom domains using insecure schemes such as HTTP, and also bypassess
|
||||
module sum validation using the checksum database. Use with caution.
|
||||
@ -143,12 +107,8 @@ To permit the use of insecure schemes, use the GOINSECURE environment
|
||||
variable instead. To bypass module sum validation, use GOPRIVATE or
|
||||
GONOSUMDB. See 'go help environment' for details.
|
||||
|
||||
The second step is to download (if needed), build, and install
|
||||
the named packages.
|
||||
|
||||
The -d flag instructs get to skip this step, downloading source code
|
||||
needed to build the named packages and their dependencies, but not
|
||||
building or installing.
|
||||
The -d flag instructs get not to build or install packages. get will only
|
||||
update go.mod and download source code needed to build packages.
|
||||
|
||||
Building and installing packages with get is deprecated. In a future release,
|
||||
the -d flag will be enabled by default, and 'go get' will be only be used to
|
||||
@ -157,31 +117,14 @@ dependencies from the current module, use 'go install'. To install a package
|
||||
ignoring the current module, use 'go install' with an @version suffix like
|
||||
"@latest" after each argument.
|
||||
|
||||
If an argument names a module but not a package (because there is no
|
||||
Go source code in the module's root directory), then the install step
|
||||
is skipped for that argument, instead of causing a build failure.
|
||||
For example 'go get golang.org/x/perf' succeeds even though there
|
||||
is no code corresponding to that import path.
|
||||
|
||||
Note that package patterns are allowed and are expanded after resolving
|
||||
the module versions. For example, 'go get golang.org/x/perf/cmd/...'
|
||||
adds the latest golang.org/x/perf and then installs the commands in that
|
||||
latest version.
|
||||
|
||||
With no package arguments, 'go get' applies to Go package in the
|
||||
current directory, if any. In particular, 'go get -u' and
|
||||
'go get -u=patch' update all the dependencies of that package.
|
||||
With no package arguments and also without -u, 'go get' is not much more
|
||||
than 'go install', and 'go get -d' not much more than 'go list'.
|
||||
|
||||
For more about modules, see 'go help modules'.
|
||||
For more about modules, see https://golang.org/ref/mod.
|
||||
|
||||
For more about specifying packages, see 'go help packages'.
|
||||
|
||||
This text describes the behavior of get using modules to manage source
|
||||
code and dependencies. If instead the go command is running in GOPATH
|
||||
mode, the details of get's flags and effects change, as does 'go help get'.
|
||||
See 'go help modules' and 'go help gopath-get'.
|
||||
See 'go help gopath-get'.
|
||||
|
||||
See also: go build, go install, go clean, go mod.
|
||||
`,
|
||||
@ -1558,7 +1501,7 @@ func (r *resolver) checkPackagesAndRetractions(ctx context.Context, pkgPatterns
|
||||
}
|
||||
}
|
||||
if retractPath != "" {
|
||||
fmt.Fprintf(os.Stderr, "go: run 'go get %s@latest' to switch to the latest unretracted version\n", retractPath)
|
||||
fmt.Fprintf(os.Stderr, "go: to switch to the latest unretracted version, run:\n\tgo get %s@latest", retractPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,14 +281,14 @@ func reportError(q *query, err error) {
|
||||
// TODO(bcmills): Use errors.As to unpack these errors instead of parsing
|
||||
// strings with regular expressions.
|
||||
|
||||
patternRE := regexp.MustCompile("(?m)(?:[ \t(\"`]|^)" + regexp.QuoteMeta(q.pattern) + "(?:[ @:)\"`]|$)")
|
||||
patternRE := regexp.MustCompile("(?m)(?:[ \t(\"`]|^)" + regexp.QuoteMeta(q.pattern) + "(?:[ @:;)\"`]|$)")
|
||||
if patternRE.MatchString(errStr) {
|
||||
if q.rawVersion == "" {
|
||||
base.Errorf("go get: %s", errStr)
|
||||
return
|
||||
}
|
||||
|
||||
versionRE := regexp.MustCompile("(?m)(?:[ @(\"`]|^)" + regexp.QuoteMeta(q.version) + "(?:[ :)\"`]|$)")
|
||||
versionRE := regexp.MustCompile("(?m)(?:[ @(\"`]|^)" + regexp.QuoteMeta(q.version) + "(?:[ :;)\"`]|$)")
|
||||
if versionRE.MatchString(errStr) {
|
||||
base.Errorf("go get: %s", errStr)
|
||||
return
|
||||
|
@ -12,395 +12,16 @@ var HelpModules = &base.Command{
|
||||
UsageLine: "modules",
|
||||
Short: "modules, module versions, and more",
|
||||
Long: `
|
||||
A module is a collection of related Go packages.
|
||||
Modules are the unit of source code interchange and versioning.
|
||||
The go command has direct support for working with modules,
|
||||
including recording and resolving dependencies on other modules.
|
||||
Modules replace the old GOPATH-based approach to specifying
|
||||
which source files are used in a given build.
|
||||
Modules are how Go manages dependencies.
|
||||
|
||||
Module support
|
||||
A module is a collection of packages that are released, versioned, and
|
||||
distributed together. Modules may be downloaded directly from version control
|
||||
repositories or from module proxy servers.
|
||||
|
||||
The go command includes support for Go modules. Module-aware mode is active
|
||||
by default whenever a go.mod file is found in the current directory or in
|
||||
any parent directory.
|
||||
For a series of tutorials on modules, see
|
||||
https://golang.org/doc/tutorial/create-module.
|
||||
|
||||
The quickest way to take advantage of module support is to check out your
|
||||
repository, create a go.mod file (described in the next section) there, and run
|
||||
go commands from within that file tree.
|
||||
|
||||
For more fine-grained control, the go command continues to respect
|
||||
a temporary environment variable, GO111MODULE, which can be set to one
|
||||
of three string values: off, on, or auto (the default).
|
||||
If GO111MODULE=on, then the go command requires the use of modules,
|
||||
never consulting GOPATH. We refer to this as the command
|
||||
being module-aware or running in "module-aware mode".
|
||||
If GO111MODULE=off, then the go command never uses
|
||||
module support. Instead it looks in vendor directories and GOPATH
|
||||
to find dependencies; we now refer to this as "GOPATH mode."
|
||||
If GO111MODULE=auto or is unset, then the go command enables or disables
|
||||
module support based on the current directory.
|
||||
Module support is enabled only when the current directory contains a
|
||||
go.mod file or is below a directory containing a go.mod file.
|
||||
|
||||
In module-aware mode, GOPATH no longer defines the meaning of imports
|
||||
during a build, but it still stores downloaded dependencies (in GOPATH/pkg/mod)
|
||||
and installed commands (in GOPATH/bin, unless GOBIN is set).
|
||||
|
||||
Defining a module
|
||||
|
||||
A module is defined by a tree of Go source files with a go.mod file
|
||||
in the tree's root directory. The directory containing the go.mod file
|
||||
is called the module root. Typically the module root will also correspond
|
||||
to a source code repository root (but in general it need not).
|
||||
The module is the set of all Go packages in the module root and its
|
||||
subdirectories, but excluding subtrees with their own go.mod files.
|
||||
|
||||
The "module path" is the import path prefix corresponding to the module root.
|
||||
The go.mod file defines the module path and lists the specific versions
|
||||
of other modules that should be used when resolving imports during a build,
|
||||
by giving their module paths and versions.
|
||||
|
||||
For example, this go.mod declares that the directory containing it is the root
|
||||
of the module with path example.com/m, and it also declares that the module
|
||||
depends on specific versions of golang.org/x/text and gopkg.in/yaml.v2:
|
||||
|
||||
module example.com/m
|
||||
|
||||
require (
|
||||
golang.org/x/text v0.3.0
|
||||
gopkg.in/yaml.v2 v2.1.0
|
||||
)
|
||||
|
||||
The go.mod file can also specify replacements and excluded versions
|
||||
that only apply when building the module directly; they are ignored
|
||||
when the module is incorporated into a larger build.
|
||||
For more about the go.mod file, see 'go help go.mod'.
|
||||
|
||||
To start a new module, simply create a go.mod file in the root of the
|
||||
module's directory tree, containing only a module statement.
|
||||
The 'go mod init' command can be used to do this:
|
||||
|
||||
go mod init example.com/m
|
||||
|
||||
In a project already using an existing dependency management tool like
|
||||
godep, glide, or dep, 'go mod init' will also add require statements
|
||||
matching the existing configuration.
|
||||
|
||||
Once the go.mod file exists, no additional steps are required:
|
||||
go commands like 'go build', 'go test', or even 'go list' will automatically
|
||||
add new dependencies as needed to satisfy imports.
|
||||
|
||||
The main module and the build list
|
||||
|
||||
The "main module" is the module containing the directory where the go command
|
||||
is run. The go command finds the module root by looking for a go.mod in the
|
||||
current directory, or else the current directory's parent directory,
|
||||
or else the parent's parent directory, and so on.
|
||||
|
||||
The main module's go.mod file defines the precise set of packages available
|
||||
for use by the go command, through require, replace, and exclude statements.
|
||||
Dependency modules, found by following require statements, also contribute
|
||||
to the definition of that set of packages, but only through their go.mod
|
||||
files' require statements: any replace and exclude statements in dependency
|
||||
modules are ignored. The replace and exclude statements therefore allow the
|
||||
main module complete control over its own build, without also being subject
|
||||
to complete control by dependencies.
|
||||
|
||||
The set of modules providing packages to builds is called the "build list".
|
||||
The build list initially contains only the main module. Then the go command
|
||||
adds to the list the exact module versions required by modules already
|
||||
on the list, recursively, until there is nothing left to add to the list.
|
||||
If multiple versions of a particular module are added to the list,
|
||||
then at the end only the latest version (according to semantic version
|
||||
ordering) is kept for use in the build.
|
||||
|
||||
The 'go list' command provides information about the main module
|
||||
and the build list. For example:
|
||||
|
||||
go list -m # print path of main module
|
||||
go list -m -f={{.Dir}} # print root directory of main module
|
||||
go list -m all # print build list
|
||||
|
||||
Maintaining module requirements
|
||||
|
||||
The go.mod file is meant to be readable and editable by both programmers and
|
||||
tools. Most updates to dependencies can be performed using "go get" and
|
||||
"go mod tidy". Other module-aware build commands may be invoked using the
|
||||
-mod=mod flag to automatically add missing requirements and fix inconsistencies.
|
||||
|
||||
The "go get" command updates go.mod to change the module versions used in a
|
||||
build. An upgrade of one module may imply upgrading others, and similarly a
|
||||
downgrade of one module may imply downgrading others. The "go get" command
|
||||
makes these implied changes as well. See "go help module-get".
|
||||
|
||||
The "go mod" command provides other functionality for use in maintaining
|
||||
and understanding modules and go.mod files. See "go help mod", particularly
|
||||
"go help mod tidy" and "go help mod edit".
|
||||
|
||||
As part of maintaining the require statements in go.mod, the go command
|
||||
tracks which ones provide packages imported directly by the current module
|
||||
and which ones provide packages only used indirectly by other module
|
||||
dependencies. Requirements needed only for indirect uses are marked with a
|
||||
"// indirect" comment in the go.mod file. Indirect requirements may be
|
||||
automatically removed from the go.mod file once they are implied by other
|
||||
direct requirements. Indirect requirements only arise when using modules
|
||||
that fail to state some of their own dependencies or when explicitly
|
||||
upgrading a module's dependencies ahead of its own stated requirements.
|
||||
|
||||
The -mod build flag provides additional control over the updating and use of
|
||||
go.mod for commands that build packages like "go build" and "go test".
|
||||
|
||||
If invoked with -mod=readonly (the default in most situations), the go command
|
||||
reports an error if a package named on the command line or an imported package
|
||||
is not provided by any module in the build list computed from the main module's
|
||||
requirements. The go command also reports an error if a module's checksum is
|
||||
missing from go.sum (see Module downloading and verification). Either go.mod or
|
||||
go.sum must be updated in these situations.
|
||||
|
||||
If invoked with -mod=mod, the go command automatically updates go.mod and
|
||||
go.sum, fixing inconsistencies and adding missing requirements and checksums
|
||||
as needed. If the go command finds an unfamiliar import, it looks up the
|
||||
module containing that import and adds a requirement for the latest version
|
||||
of that module to go.mod. In most cases, therefore, one may add an import to
|
||||
source code and run "go build", "go test", or even "go list" with -mod=mod:
|
||||
as part of analyzing the package, the go command will resolve the import and
|
||||
update the go.mod file.
|
||||
|
||||
If invoked with -mod=vendor, the go command loads packages from the main
|
||||
module's vendor directory instead of downloading modules to and loading packages
|
||||
from the module cache. The go command assumes the vendor directory holds
|
||||
correct copies of dependencies, and it does not compute the set of required
|
||||
module versions from go.mod files. However, the go command does check that
|
||||
vendor/modules.txt (generated by "go mod vendor") contains metadata consistent
|
||||
with go.mod.
|
||||
|
||||
If the go command is not invoked with a -mod flag, and the vendor directory
|
||||
is present, and the "go" version in go.mod is 1.14 or higher, the go command
|
||||
will act as if it were invoked with -mod=vendor. Otherwise, the -mod flag
|
||||
defaults to -mod=readonly.
|
||||
|
||||
Note that neither "go get" nor the "go mod" subcommands accept the -mod flag.
|
||||
|
||||
Pseudo-versions
|
||||
|
||||
The go.mod file and the go command more generally use semantic versions as
|
||||
the standard form for describing module versions, so that versions can be
|
||||
compared to determine which should be considered earlier or later than another.
|
||||
A module version like v1.2.3 is introduced by tagging a revision in the
|
||||
underlying source repository. Untagged revisions can be referred to
|
||||
using a "pseudo-version" like v0.0.0-yyyymmddhhmmss-abcdefabcdef,
|
||||
where the time is the commit time in UTC and the final suffix is the prefix
|
||||
of the commit hash. The time portion ensures that two pseudo-versions can
|
||||
be compared to determine which happened later, the commit hash identifes
|
||||
the underlying commit, and the prefix (v0.0.0- in this example) is derived from
|
||||
the most recent tagged version in the commit graph before this commit.
|
||||
|
||||
There are three pseudo-version forms:
|
||||
|
||||
vX.0.0-yyyymmddhhmmss-abcdefabcdef is used when there is no earlier
|
||||
versioned commit with an appropriate major version before the target commit.
|
||||
(This was originally the only form, so some older go.mod files use this form
|
||||
even for commits that do follow tags.)
|
||||
|
||||
vX.Y.Z-pre.0.yyyymmddhhmmss-abcdefabcdef is used when the most
|
||||
recent versioned commit before the target commit is vX.Y.Z-pre.
|
||||
|
||||
vX.Y.(Z+1)-0.yyyymmddhhmmss-abcdefabcdef is used when the most
|
||||
recent versioned commit before the target commit is vX.Y.Z.
|
||||
|
||||
Pseudo-versions never need to be typed by hand: the go command will accept
|
||||
the plain commit hash and translate it into a pseudo-version (or a tagged
|
||||
version if available) automatically. This conversion is an example of a
|
||||
module query.
|
||||
|
||||
Module queries
|
||||
|
||||
The go command accepts a "module query" in place of a module version
|
||||
both on the command line and in the main module's go.mod file.
|
||||
(After evaluating a query found in the main module's go.mod file,
|
||||
the go command updates the file to replace the query with its result.)
|
||||
|
||||
A fully-specified semantic version, such as "v1.2.3",
|
||||
evaluates to that specific version.
|
||||
|
||||
A semantic version prefix, such as "v1" or "v1.2",
|
||||
evaluates to the latest available tagged version with that prefix.
|
||||
|
||||
A semantic version comparison, such as "<v1.2.3" or ">=v1.5.6",
|
||||
evaluates to the available tagged version nearest to the comparison target
|
||||
(the latest version for < and <=, the earliest version for > and >=).
|
||||
|
||||
The string "latest" matches the latest available tagged version,
|
||||
or else the underlying source repository's latest untagged revision.
|
||||
|
||||
The string "upgrade" is like "latest", but if the module is
|
||||
currently required at a later version than the version "latest"
|
||||
would select (for example, a newer pre-release version), "upgrade"
|
||||
will select the later version instead.
|
||||
|
||||
The string "patch" matches the latest available tagged version
|
||||
of a module with the same major and minor version numbers as the
|
||||
currently required version. If no version is currently required,
|
||||
"patch" is equivalent to "latest".
|
||||
|
||||
A revision identifier for the underlying source repository, such as
|
||||
a commit hash prefix, revision tag, or branch name, selects that
|
||||
specific code revision. If the revision is also tagged with a
|
||||
semantic version, the query evaluates to that semantic version.
|
||||
Otherwise the query evaluates to a pseudo-version for the commit.
|
||||
Note that branches and tags with names that are matched by other
|
||||
query syntax cannot be selected this way. For example, the query
|
||||
"v2" means the latest version starting with "v2", not the branch
|
||||
named "v2".
|
||||
|
||||
All queries prefer release versions to pre-release versions.
|
||||
For example, "<v1.2.3" will prefer to return "v1.2.2"
|
||||
instead of "v1.2.3-pre1", even though "v1.2.3-pre1" is nearer
|
||||
to the comparison target.
|
||||
|
||||
Module versions disallowed by exclude statements in the
|
||||
main module's go.mod are considered unavailable and cannot
|
||||
be returned by queries.
|
||||
|
||||
For example, these commands are all valid:
|
||||
|
||||
go get github.com/gorilla/mux@latest # same (@latest is default for 'go get')
|
||||
go get github.com/gorilla/mux@v1.6.2 # records v1.6.2
|
||||
go get github.com/gorilla/mux@e3702bed2 # records v1.6.2
|
||||
go get github.com/gorilla/mux@c856192 # records v0.0.0-20180517173623-c85619274f5d
|
||||
go get github.com/gorilla/mux@master # records current meaning of master
|
||||
|
||||
Module compatibility and semantic versioning
|
||||
|
||||
The go command requires that modules use semantic versions and expects that
|
||||
the versions accurately describe compatibility: it assumes that v1.5.4 is a
|
||||
backwards-compatible replacement for v1.5.3, v1.4.0, and even v1.0.0.
|
||||
More generally the go command expects that packages follow the
|
||||
"import compatibility rule", which says:
|
||||
|
||||
"If an old package and a new package have the same import path,
|
||||
the new package must be backwards compatible with the old package."
|
||||
|
||||
Because the go command assumes the import compatibility rule,
|
||||
a module definition can only set the minimum required version of one
|
||||
of its dependencies: it cannot set a maximum or exclude selected versions.
|
||||
Still, the import compatibility rule is not a guarantee: it may be that
|
||||
v1.5.4 is buggy and not a backwards-compatible replacement for v1.5.3.
|
||||
Because of this, the go command never updates from an older version
|
||||
to a newer version of a module unasked.
|
||||
|
||||
In semantic versioning, changing the major version number indicates a lack
|
||||
of backwards compatibility with earlier versions. To preserve import
|
||||
compatibility, the go command requires that modules with major version v2
|
||||
or later use a module path with that major version as the final element.
|
||||
For example, version v2.0.0 of example.com/m must instead use module path
|
||||
example.com/m/v2, and packages in that module would use that path as
|
||||
their import path prefix, as in example.com/m/v2/sub/pkg. Including the
|
||||
major version number in the module path and import paths in this way is
|
||||
called "semantic import versioning". Pseudo-versions for modules with major
|
||||
version v2 and later begin with that major version instead of v0, as in
|
||||
v2.0.0-20180326061214-4fc5987536ef.
|
||||
|
||||
As a special case, module paths beginning with gopkg.in/ continue to use the
|
||||
conventions established on that system: the major version is always present,
|
||||
and it is preceded by a dot instead of a slash: gopkg.in/yaml.v1
|
||||
and gopkg.in/yaml.v2, not gopkg.in/yaml and gopkg.in/yaml/v2.
|
||||
|
||||
The go command treats modules with different module paths as unrelated:
|
||||
it makes no connection between example.com/m and example.com/m/v2.
|
||||
Modules with different major versions can be used together in a build
|
||||
and are kept separate by the fact that their packages use different
|
||||
import paths.
|
||||
|
||||
In semantic versioning, major version v0 is for initial development,
|
||||
indicating no expectations of stability or backwards compatibility.
|
||||
Major version v0 does not appear in the module path, because those
|
||||
versions are preparation for v1.0.0, and v1 does not appear in the
|
||||
module path either.
|
||||
|
||||
Code written before the semantic import versioning convention
|
||||
was introduced may use major versions v2 and later to describe
|
||||
the same set of unversioned import paths as used in v0 and v1.
|
||||
To accommodate such code, if a source code repository has a
|
||||
v2.0.0 or later tag for a file tree with no go.mod, the version is
|
||||
considered to be part of the v1 module's available versions
|
||||
and is given an +incompatible suffix when converted to a module
|
||||
version, as in v2.0.0+incompatible. The +incompatible tag is also
|
||||
applied to pseudo-versions derived from such versions, as in
|
||||
v2.0.1-0.yyyymmddhhmmss-abcdefabcdef+incompatible.
|
||||
|
||||
In general, having a dependency in the build list (as reported by 'go list -m all')
|
||||
on a v0 version, pre-release version, pseudo-version, or +incompatible version
|
||||
is an indication that problems are more likely when upgrading that
|
||||
dependency, since there is no expectation of compatibility for those.
|
||||
|
||||
See https://research.swtch.com/vgo-import for more information about
|
||||
semantic import versioning, and see https://semver.org/ for more about
|
||||
semantic versioning.
|
||||
|
||||
Module code layout
|
||||
|
||||
For now, see https://research.swtch.com/vgo-module for information
|
||||
about how source code in version control systems is mapped to
|
||||
module file trees.
|
||||
|
||||
Module downloading and verification
|
||||
|
||||
The go command can fetch modules from a proxy or connect to source control
|
||||
servers directly, according to the setting of the GOPROXY environment
|
||||
variable (see 'go help env'). The default setting for GOPROXY is
|
||||
"https://proxy.golang.org,direct", which means to try the
|
||||
Go module mirror run by Google and fall back to a direct connection
|
||||
if the proxy reports that it does not have the module (HTTP error 404 or 410).
|
||||
See https://proxy.golang.org/privacy for the service's privacy policy.
|
||||
|
||||
If GOPROXY is set to the string "direct", downloads use a direct connection to
|
||||
source control servers. Setting GOPROXY to "off" disallows downloading modules
|
||||
from any source. Otherwise, GOPROXY is expected to be list of module proxy URLs
|
||||
separated by either comma (,) or pipe (|) characters, which control error
|
||||
fallback behavior. For each request, the go command tries each proxy in
|
||||
sequence. If there is an error, the go command will try the next proxy in the
|
||||
list if the error is a 404 or 410 HTTP response or if the current proxy is
|
||||
followed by a pipe character, indicating it is safe to fall back on any error.
|
||||
|
||||
The GOPRIVATE and GONOPROXY environment variables allow bypassing
|
||||
the proxy for selected modules. See 'go help private' for details.
|
||||
|
||||
No matter the source of the modules, the go command checks downloads against
|
||||
known checksums, to detect unexpected changes in the content of any specific
|
||||
module version from one day to the next. This check first consults the current
|
||||
module's go.sum file but falls back to the Go checksum database, controlled by
|
||||
the GOSUMDB and GONOSUMDB environment variables. See 'go help module-auth'
|
||||
for details.
|
||||
|
||||
See 'go help goproxy' for details about the proxy protocol and also
|
||||
the format of the cached downloaded packages.
|
||||
|
||||
Modules and vendoring
|
||||
|
||||
When using modules, the go command typically satisfies dependencies by
|
||||
downloading modules from their sources and using those downloaded copies
|
||||
(after verification, as described in the previous section). Vendoring may
|
||||
be used to allow interoperation with older versions of Go, or to ensure
|
||||
that all files used for a build are stored together in a single file tree.
|
||||
|
||||
The command 'go mod vendor' constructs a directory named vendor in the main
|
||||
module's root directory that contains copies of all packages needed to support
|
||||
builds and tests of packages in the main module. 'go mod vendor' also
|
||||
creates the file vendor/modules.txt that contains metadata about vendored
|
||||
packages and module versions. This file should be kept consistent with go.mod:
|
||||
when vendoring is used, 'go mod vendor' should be run after go.mod is updated.
|
||||
|
||||
If the vendor directory is present in the main module's root directory, it will
|
||||
be used automatically if the "go" version in the main module's go.mod file is
|
||||
1.14 or higher. Build commands like 'go build' and 'go test' will load packages
|
||||
from the vendor directory instead of accessing the network or the local module
|
||||
cache. To explicitly enable vendoring, invoke the go command with the flag
|
||||
-mod=vendor. To disable vendoring, use the flag -mod=mod.
|
||||
|
||||
Unlike vendoring in GOPATH, the go command ignores vendor directories in
|
||||
locations other than the main module's root directory.
|
||||
For a detailed reference on modules, see https://golang.org/ref/mod.
|
||||
`,
|
||||
}
|
||||
|
||||
@ -413,87 +34,22 @@ file in its root. When the go command is run, it looks in the current
|
||||
directory and then successive parent directories to find the go.mod
|
||||
marking the root of the main (current) module.
|
||||
|
||||
The go.mod file itself is line-oriented, with // comments but
|
||||
no /* */ comments. Each line holds a single directive, made up of a
|
||||
verb followed by arguments. For example:
|
||||
The go.mod file format is described in detail at
|
||||
https://golang.org/ref/mod#go-mod-file.
|
||||
|
||||
module my/thing
|
||||
go 1.12
|
||||
require other/thing v1.0.2
|
||||
require new/thing/v2 v2.3.4
|
||||
exclude old/thing v1.2.3
|
||||
replace bad/thing v1.4.5 => good/thing v1.4.5
|
||||
retract v1.5.6
|
||||
To create a new go.mod file, use 'go help init'. For details see
|
||||
'go help mod init' or https://golang.org/ref/mod#go-mod-init.
|
||||
|
||||
The verbs are
|
||||
module, to define the module path;
|
||||
go, to set the expected language version;
|
||||
require, to require a particular module at a given version or later;
|
||||
exclude, to exclude a particular module version from use;
|
||||
replace, to replace a module version with a different module version; and
|
||||
retract, to indicate a previously released version should not be used.
|
||||
Exclude and replace apply only in the main module's go.mod and are ignored
|
||||
in dependencies. See https://golang.org/ref/mod for details.
|
||||
To add missing module requirements or remove unneeded requirements,
|
||||
use 'go mod tidy'. For details, see 'go help mod tidy' or
|
||||
https://golang.org/ref/mod#go-mod-tidy.
|
||||
|
||||
The leading verb can be factored out of adjacent lines to create a block,
|
||||
like in Go imports:
|
||||
To add, upgrade, downgrade, or remove a specific module requirement, use
|
||||
'go get'. For details, see 'go help module-get' or
|
||||
https://golang.org/ref/mod#go-get.
|
||||
|
||||
require (
|
||||
new/thing/v2 v2.3.4
|
||||
old/thing v1.2.3
|
||||
)
|
||||
|
||||
The go.mod file is designed both to be edited directly and to be
|
||||
easily updated by tools. The 'go mod edit' command can be used to
|
||||
parse and edit the go.mod file from programs and tools.
|
||||
See 'go help mod edit'.
|
||||
|
||||
The go command automatically updates go.mod each time it uses the
|
||||
module graph, to make sure go.mod always accurately reflects reality
|
||||
and is properly formatted. For example, consider this go.mod file:
|
||||
|
||||
module M
|
||||
|
||||
require (
|
||||
A v1
|
||||
B v1.0.0
|
||||
C v1.0.0
|
||||
D v1.2.3
|
||||
E dev
|
||||
)
|
||||
|
||||
exclude D v1.2.3
|
||||
|
||||
The update rewrites non-canonical version identifiers to semver form,
|
||||
so A's v1 becomes v1.0.0 and E's dev becomes the pseudo-version for the
|
||||
latest commit on the dev branch, perhaps v0.0.0-20180523231146-b3f5c0f6e5f1.
|
||||
|
||||
The update modifies requirements to respect exclusions, so the
|
||||
requirement on the excluded D v1.2.3 is updated to use the next
|
||||
available version of D, perhaps D v1.2.4 or D v1.3.0.
|
||||
|
||||
The update removes redundant or misleading requirements.
|
||||
For example, if A v1.0.0 itself requires B v1.2.0 and C v1.0.0,
|
||||
then go.mod's requirement of B v1.0.0 is misleading (superseded by
|
||||
A's need for v1.2.0), and its requirement of C v1.0.0 is redundant
|
||||
(implied by A's need for the same version), so both will be removed.
|
||||
If module M contains packages that directly import packages from B or
|
||||
C, then the requirements will be kept but updated to the actual
|
||||
versions being used.
|
||||
|
||||
Finally, the update reformats the go.mod in a canonical formatting, so
|
||||
that future mechanical changes will result in minimal diffs.
|
||||
|
||||
Because the module graph defines the meaning of import statements, any
|
||||
commands that load packages also use and therefore update go.mod,
|
||||
including go build, go get, go install, go list, go test, go mod graph,
|
||||
go mod tidy, and go mod why.
|
||||
|
||||
The expected language version, set by the go directive, determines
|
||||
which language features are available when compiling the module.
|
||||
Language features available in that version will be available for use.
|
||||
Language features removed in earlier versions, or added in later versions,
|
||||
will not be available. Note that the language version does not affect
|
||||
build tags, which are determined by the Go release being used.
|
||||
To make other changes or to parse go.mod as JSON for use by other tools,
|
||||
use 'go mod edit'. See 'go help mod edit' or
|
||||
https://golang.org/ref/mod#go-mod-edit.
|
||||
`,
|
||||
}
|
||||
|
@ -31,10 +31,6 @@ type ImportMissingError struct {
|
||||
Module module.Version
|
||||
QueryErr error
|
||||
|
||||
// inAll indicates whether Path is in the "all" package pattern,
|
||||
// and thus would be added by 'go mod tidy'.
|
||||
inAll bool
|
||||
|
||||
// isStd indicates whether we would expect to find the package in the standard
|
||||
// library. This is normally true for all dotless import paths, but replace
|
||||
// directives can cause us to treat the replaced paths as also being in
|
||||
@ -58,7 +54,7 @@ func (e *ImportMissingError) Error() string {
|
||||
if e.QueryErr != nil {
|
||||
return fmt.Sprintf("cannot find module providing package %s: %v", e.Path, e.QueryErr)
|
||||
}
|
||||
if cfg.BuildMod == "mod" {
|
||||
if cfg.BuildMod == "mod" || (cfg.BuildMod == "readonly" && allowMissingModuleImports) {
|
||||
return "cannot find module providing package " + e.Path
|
||||
}
|
||||
|
||||
@ -67,16 +63,14 @@ func (e *ImportMissingError) Error() string {
|
||||
if !modfetch.IsZeroPseudoVersion(e.replaced.Version) {
|
||||
suggestArg = e.replaced.String()
|
||||
}
|
||||
return fmt.Sprintf("module %s provides package %s and is replaced but not required; try 'go get -d %s' to add it", e.replaced.Path, e.Path, suggestArg)
|
||||
return fmt.Sprintf("module %s provides package %s and is replaced but not required; to add it:\n\tgo get %s", e.replaced.Path, e.Path, suggestArg)
|
||||
}
|
||||
|
||||
suggestion := ""
|
||||
if !HasModRoot() {
|
||||
suggestion = ": working directory is not part of a module"
|
||||
} else if e.inAll {
|
||||
suggestion = "; try 'go mod tidy' to add it"
|
||||
} else {
|
||||
suggestion = fmt.Sprintf("; try 'go get -d %s' to add it", e.Path)
|
||||
suggestion = fmt.Sprintf("; to add it:\n\tgo get %s", e.Path)
|
||||
}
|
||||
return fmt.Sprintf("no required module provides package %s%s", e.Path, suggestion)
|
||||
}
|
||||
@ -136,24 +130,57 @@ func (e *AmbiguousImportError) Error() string {
|
||||
}
|
||||
|
||||
// ImportMissingSumError is reported in readonly mode when we need to check
|
||||
// if a module in the build list contains a package, but we don't have a sum
|
||||
// for its .zip file.
|
||||
// if a module contains a package, but we don't have a sum for its .zip file.
|
||||
// We might need sums for multiple modules to verify the package is unique.
|
||||
//
|
||||
// TODO(#43653): consolidate multiple errors of this type into a single error
|
||||
// that suggests a 'go get' command for root packages that transtively import
|
||||
// packages from modules with missing sums. load.CheckPackageErrors would be
|
||||
// a good place to consolidate errors, but we'll need to attach the import
|
||||
// stack here.
|
||||
type ImportMissingSumError struct {
|
||||
importPath string
|
||||
found, inAll bool
|
||||
importPath string
|
||||
found bool
|
||||
mods []module.Version
|
||||
importer, importerVersion string // optional, but used for additional context
|
||||
importerIsTest bool
|
||||
}
|
||||
|
||||
func (e *ImportMissingSumError) Error() string {
|
||||
var importParen string
|
||||
if e.importer != "" {
|
||||
importParen = fmt.Sprintf(" (imported by %s)", e.importer)
|
||||
}
|
||||
var message string
|
||||
if e.found {
|
||||
message = fmt.Sprintf("missing go.sum entry needed to verify package %s is provided by exactly one module", e.importPath)
|
||||
message = fmt.Sprintf("missing go.sum entry needed to verify package %s%s is provided by exactly one module", e.importPath, importParen)
|
||||
} else {
|
||||
message = fmt.Sprintf("missing go.sum entry for module providing package %s", e.importPath)
|
||||
message = fmt.Sprintf("missing go.sum entry for module providing package %s%s", e.importPath, importParen)
|
||||
}
|
||||
if e.inAll {
|
||||
return message + "; try 'go mod tidy' to add it"
|
||||
var hint string
|
||||
if e.importer == "" {
|
||||
// Importing package is unknown, or the missing package was named on the
|
||||
// command line. Recommend 'go mod download' for the modules that could
|
||||
// provide the package, since that shouldn't change go.mod.
|
||||
args := make([]string, len(e.mods))
|
||||
for i, mod := range e.mods {
|
||||
args[i] = mod.Path
|
||||
}
|
||||
hint = fmt.Sprintf("; to add:\n\tgo mod download %s", strings.Join(args, " "))
|
||||
} else {
|
||||
// Importing package is known (common case). Recommend 'go get' on the
|
||||
// current version of the importing package.
|
||||
tFlag := ""
|
||||
if e.importerIsTest {
|
||||
tFlag = " -t"
|
||||
}
|
||||
version := ""
|
||||
if e.importerVersion != "" {
|
||||
version = "@" + e.importerVersion
|
||||
}
|
||||
hint = fmt.Sprintf("; to add:\n\tgo get%s %s%s", tFlag, e.importer, version)
|
||||
}
|
||||
return message
|
||||
return message + hint
|
||||
}
|
||||
|
||||
func (e *ImportMissingSumError) ImportPath() string {
|
||||
@ -244,7 +271,7 @@ func importFromBuildList(ctx context.Context, path string, buildList []module.Ve
|
||||
// Check each module on the build list.
|
||||
var dirs []string
|
||||
var mods []module.Version
|
||||
haveSumErr := false
|
||||
var sumErrMods []module.Version
|
||||
for _, m := range buildList {
|
||||
if !maybeInModule(path, m.Path) {
|
||||
// Avoid possibly downloading irrelevant modules.
|
||||
@ -257,8 +284,9 @@ func importFromBuildList(ctx context.Context, path string, buildList []module.Ve
|
||||
// We are missing a sum needed to fetch a module in the build list.
|
||||
// We can't verify that the package is unique, and we may not find
|
||||
// the package at all. Keep checking other modules to decide which
|
||||
// error to report.
|
||||
haveSumErr = true
|
||||
// error to report. Multiple sums may be missing if we need to look in
|
||||
// multiple nested modules to resolve the import.
|
||||
sumErrMods = append(sumErrMods, m)
|
||||
continue
|
||||
}
|
||||
// Report fetch error.
|
||||
@ -279,8 +307,12 @@ func importFromBuildList(ctx context.Context, path string, buildList []module.Ve
|
||||
if len(mods) > 1 {
|
||||
return module.Version{}, "", &AmbiguousImportError{importPath: path, Dirs: dirs, Modules: mods}
|
||||
}
|
||||
if haveSumErr {
|
||||
return module.Version{}, "", &ImportMissingSumError{importPath: path, found: len(mods) > 0}
|
||||
if len(sumErrMods) > 0 {
|
||||
return module.Version{}, "", &ImportMissingSumError{
|
||||
importPath: path,
|
||||
mods: sumErrMods,
|
||||
found: len(mods) > 0,
|
||||
}
|
||||
}
|
||||
if len(mods) == 1 {
|
||||
return mods[0], dirs[0], nil
|
||||
@ -365,7 +397,7 @@ func queryImport(ctx context.Context, path string) (module.Version, error) {
|
||||
return module.Version{}, &ImportMissingError{Path: path, isStd: true}
|
||||
}
|
||||
|
||||
if cfg.BuildMod == "readonly" {
|
||||
if cfg.BuildMod == "readonly" && !allowMissingModuleImports {
|
||||
// In readonly mode, we can't write go.mod, so we shouldn't try to look up
|
||||
// the module. If readonly mode was enabled explicitly, include that in
|
||||
// the error message.
|
||||
@ -547,7 +579,7 @@ func fetch(ctx context.Context, mod module.Version, needSum bool) (dir string, i
|
||||
mod = r
|
||||
}
|
||||
|
||||
if cfg.BuildMod == "readonly" && needSum && !modfetch.HaveSum(mod) {
|
||||
if HasModRoot() && cfg.BuildMod == "readonly" && needSum && !modfetch.HaveSum(mod) {
|
||||
return "", false, module.VersionError(mod, &sumMissingError{})
|
||||
}
|
||||
|
||||
|
@ -58,10 +58,15 @@ var importTests = []struct {
|
||||
func TestQueryImport(t *testing.T) {
|
||||
testenv.MustHaveExternalNetwork(t)
|
||||
testenv.MustHaveExecPath(t, "git")
|
||||
defer func(old bool) {
|
||||
allowMissingModuleImports = old
|
||||
}(allowMissingModuleImports)
|
||||
AllowMissingModuleImports()
|
||||
|
||||
oldAllowMissingModuleImports := allowMissingModuleImports
|
||||
oldRootMode := RootMode
|
||||
defer func() {
|
||||
allowMissingModuleImports = oldAllowMissingModuleImports
|
||||
RootMode = oldRootMode
|
||||
}()
|
||||
allowMissingModuleImports = true
|
||||
RootMode = NoRoot
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
|
@ -202,6 +202,8 @@ func Init() {
|
||||
}
|
||||
|
||||
// We're in module mode. Set any global variables that need to be set.
|
||||
cfg.ModulesEnabled = true
|
||||
setDefaultBuildMod()
|
||||
list := filepath.SplitList(cfg.BuildContext.GOPATH)
|
||||
if len(list) == 0 || list[0] == "" {
|
||||
base.Fatalf("missing $GOPATH")
|
||||
@ -211,8 +213,6 @@ func Init() {
|
||||
base.Fatalf("$GOPATH/go.mod exists but should not")
|
||||
}
|
||||
|
||||
cfg.ModulesEnabled = true
|
||||
|
||||
if modRoot == "" {
|
||||
// We're in module mode, but not inside a module.
|
||||
//
|
||||
@ -348,8 +348,8 @@ func die() {
|
||||
// ensuring requirements are consistent. WriteGoMod should be called later to
|
||||
// write changes out to disk or report errors in readonly mode.
|
||||
//
|
||||
// As a side-effect, LoadModFile sets a default for cfg.BuildMod if it does not
|
||||
// already have an explicit value.
|
||||
// As a side-effect, LoadModFile may change cfg.BuildMod to "vendor" if
|
||||
// -mod wasn't set explicitly and automatic vendoring should be enabled.
|
||||
func LoadModFile(ctx context.Context) {
|
||||
if len(buildList) > 0 {
|
||||
return
|
||||
@ -380,14 +380,14 @@ func LoadModFile(ctx context.Context) {
|
||||
|
||||
if f.Module == nil {
|
||||
// No module declaration. Must add module path.
|
||||
base.Fatalf("go: no module declaration in go.mod.\n\tRun 'go mod edit -module=example.com/mod' to specify the module path.")
|
||||
base.Fatalf("go: no module declaration in go.mod. To specify the module path:\n\tgo mod edit -module=example.com/mod")
|
||||
}
|
||||
|
||||
if err := checkModulePathLax(f.Module.Mod.Path); err != nil {
|
||||
base.Fatalf("go: %v", err)
|
||||
}
|
||||
|
||||
setDefaultBuildMod()
|
||||
setDefaultBuildMod() // possibly enable automatic vendoring
|
||||
modFileToBuildList()
|
||||
if cfg.BuildMod == "vendor" {
|
||||
readVendorList()
|
||||
@ -458,7 +458,7 @@ func CreateModFile(ctx context.Context, modPath string) {
|
||||
}
|
||||
}
|
||||
if !empty {
|
||||
fmt.Fprintf(os.Stderr, "go: run 'go mod tidy' to add module requirements and sums\n")
|
||||
fmt.Fprintf(os.Stderr, "go: to add module requirements and sums:\n\tgo mod tidy\n")
|
||||
}
|
||||
}
|
||||
|
||||
@ -586,8 +586,8 @@ func modFileToBuildList() {
|
||||
buildList = list
|
||||
}
|
||||
|
||||
// setDefaultBuildMod sets a default value for cfg.BuildMod
|
||||
// if it is currently empty.
|
||||
// setDefaultBuildMod sets a default value for cfg.BuildMod if the -mod flag
|
||||
// wasn't provided. setDefaultBuildMod may be called multiple times.
|
||||
func setDefaultBuildMod() {
|
||||
if cfg.BuildModExplicit {
|
||||
// Don't override an explicit '-mod=' argument.
|
||||
@ -608,7 +608,7 @@ func setDefaultBuildMod() {
|
||||
|
||||
if fi, err := fsys.Stat(filepath.Join(modRoot, "vendor")); err == nil && fi.IsDir() {
|
||||
modGo := "unspecified"
|
||||
if index.goVersionV != "" {
|
||||
if index != nil && index.goVersionV != "" {
|
||||
if semver.Compare(index.goVersionV, "v1.14") >= 0 {
|
||||
// The Go version is at least 1.14, and a vendor directory exists.
|
||||
// Set -mod=vendor by default.
|
||||
@ -907,7 +907,7 @@ func WriteGoMod() {
|
||||
} else if cfg.BuildModReason != "" {
|
||||
base.Fatalf("go: updates to go.mod needed, disabled by -mod=readonly\n\t(%s)", cfg.BuildModReason)
|
||||
} else {
|
||||
base.Fatalf("go: updates to go.mod needed; try 'go mod tidy' first")
|
||||
base.Fatalf("go: updates to go.mod needed; to update it:\n\tgo mod tidy")
|
||||
}
|
||||
}
|
||||
|
||||
@ -976,9 +976,12 @@ func WriteGoMod() {
|
||||
// It also contains entries for go.mod files needed for MVS (the version
|
||||
// of these entries ends with "/go.mod").
|
||||
//
|
||||
// If addDirect is true, the set also includes sums for modules directly
|
||||
// required by go.mod, as represented by the index, with replacements applied.
|
||||
func keepSums(addDirect bool) map[module.Version]bool {
|
||||
// If keepBuildListZips is true, the set also includes sums for zip files for
|
||||
// all modules in the build list with replacements applied. 'go get' and
|
||||
// 'go mod download' may add sums to this set when adding a requirement on a
|
||||
// module without a root package or when downloading a direct or indirect
|
||||
// dependency.
|
||||
func keepSums(keepBuildListZips bool) map[module.Version]bool {
|
||||
// Re-derive the build list using the current list of direct requirements.
|
||||
// Keep the sum for the go.mod of each visited module version (or its
|
||||
// replacement).
|
||||
@ -1007,19 +1010,20 @@ func keepSums(addDirect bool) map[module.Version]bool {
|
||||
panic(fmt.Sprintf("unexpected error reloading build list: %v", err))
|
||||
}
|
||||
|
||||
actualMods := make(map[string]module.Version)
|
||||
for _, m := range buildList[1:] {
|
||||
if r := Replacement(m); r.Path != "" {
|
||||
actualMods[m.Path] = r
|
||||
} else {
|
||||
actualMods[m.Path] = m
|
||||
}
|
||||
}
|
||||
|
||||
// Add entries for modules in the build list with paths that are prefixes of
|
||||
// paths of loaded packages. We need to retain sums for modules needed to
|
||||
// report ambiguous import errors. We use our re-derived build list,
|
||||
// since the global build list may have been tidied.
|
||||
if loaded != nil {
|
||||
actualMods := make(map[string]module.Version)
|
||||
for _, m := range buildList[1:] {
|
||||
if r := Replacement(m); r.Path != "" {
|
||||
actualMods[m.Path] = r
|
||||
} else {
|
||||
actualMods[m.Path] = m
|
||||
}
|
||||
}
|
||||
for _, pkg := range loaded.pkgs {
|
||||
if pkg.testOf != nil || pkg.inStd || module.CheckImportPath(pkg.path) != nil {
|
||||
continue
|
||||
@ -1032,17 +1036,13 @@ func keepSums(addDirect bool) map[module.Version]bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Add entries for modules directly required by go.mod.
|
||||
if addDirect {
|
||||
for m := range index.require {
|
||||
var kept module.Version
|
||||
if r := Replacement(m); r.Path != "" {
|
||||
kept = r
|
||||
} else {
|
||||
kept = m
|
||||
}
|
||||
keep[kept] = true
|
||||
keep[module.Version{Path: kept.Path, Version: kept.Version + "/go.mod"}] = true
|
||||
// Add entries for the zip of each module in the build list.
|
||||
// We might not need all of these (tidy does not add them), but they may be
|
||||
// added by a specific 'go get' or 'go mod download' command to resolve
|
||||
// missing import sum errors.
|
||||
if keepBuildListZips {
|
||||
for _, m := range actualMods {
|
||||
keep[m] = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -1062,9 +1062,8 @@ func (r *keepSumReqs) Required(m module.Version) ([]module.Version, error) {
|
||||
}
|
||||
|
||||
func TrimGoSum() {
|
||||
// Don't retain sums for direct requirements in go.mod. When TrimGoSum is
|
||||
// called, go.mod has not been updated, and it may contain requirements on
|
||||
// modules deleted from the build list.
|
||||
addDirect := false
|
||||
modfetch.TrimGoSum(keepSums(addDirect))
|
||||
// Don't retain sums for the zip file of every module in the build list.
|
||||
// We may not need them all to build the main module's packages.
|
||||
keepBuildListZips := false
|
||||
modfetch.TrimGoSum(keepSums(keepBuildListZips))
|
||||
}
|
||||
|
@ -280,11 +280,11 @@ func LoadPackages(ctx context.Context, opts PackageOpts, patterns ...string) (ma
|
||||
checkMultiplePaths()
|
||||
for _, pkg := range loaded.pkgs {
|
||||
if pkg.err != nil {
|
||||
if pkg.flags.has(pkgInAll) {
|
||||
if imErr := (*ImportMissingError)(nil); errors.As(pkg.err, &imErr) {
|
||||
imErr.inAll = true
|
||||
} else if sumErr := (*ImportMissingSumError)(nil); errors.As(pkg.err, &sumErr) {
|
||||
sumErr.inAll = true
|
||||
if sumErr := (*ImportMissingSumError)(nil); errors.As(pkg.err, &sumErr) {
|
||||
if importer := pkg.stack; importer != nil {
|
||||
sumErr.importer = importer.path
|
||||
sumErr.importerVersion = importer.mod.Version
|
||||
sumErr.importerIsTest = importer.testOf != nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -870,7 +870,7 @@ func loadFromRoots(params loaderParams) *loader {
|
||||
// base.Errorf. Ideally, 'go list' should not fail because of this,
|
||||
// but today, LoadPackages calls WriteGoMod unconditionally, which
|
||||
// would fail with a less clear message.
|
||||
base.Errorf("go: %[1]s: package %[2]s imported from implicitly required module; try 'go get -d %[1]s' to add missing requirements", pkg.path, dep.path)
|
||||
base.Errorf("go: %[1]s: package %[2]s imported from implicitly required module; to add missing requirements, run:\n\tgo get %[2]s@%[3]s", pkg.path, dep.path, dep.mod.Version)
|
||||
}
|
||||
ld.direct[dep.mod.Path] = true
|
||||
}
|
||||
@ -1083,14 +1083,21 @@ func (ld *loader) load(pkg *loadPkg) {
|
||||
}
|
||||
}
|
||||
|
||||
imports, testImports, err := scanDir(pkg.dir, ld.Tags)
|
||||
if err != nil {
|
||||
pkg.err = err
|
||||
return
|
||||
}
|
||||
|
||||
pkg.inStd = (search.IsStandardImportPath(pkg.path) && search.InDir(pkg.dir, cfg.GOROOTsrc) != "")
|
||||
|
||||
var imports, testImports []string
|
||||
|
||||
if cfg.BuildContext.Compiler == "gccgo" && pkg.inStd {
|
||||
// We can't scan standard packages for gccgo.
|
||||
} else {
|
||||
var err error
|
||||
imports, testImports, err = scanDir(pkg.dir, ld.Tags)
|
||||
if err != nil {
|
||||
pkg.err = err
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
pkg.imports = make([]*loadPkg, 0, len(imports))
|
||||
var importFlags loadPkgFlags
|
||||
if pkg.flags.has(pkgInAll) {
|
||||
|
@ -446,10 +446,10 @@ func goModSummary(m module.Version) (*modFileSummary, error) {
|
||||
if actual.Path == "" {
|
||||
actual = m
|
||||
}
|
||||
if cfg.BuildMod == "readonly" && actual.Version != "" {
|
||||
if HasModRoot() && cfg.BuildMod == "readonly" && actual.Version != "" {
|
||||
key := module.Version{Path: actual.Path, Version: actual.Version + "/go.mod"}
|
||||
if !modfetch.HaveSum(key) {
|
||||
suggestion := fmt.Sprintf("; try 'go mod download %s' to add it", m.Path)
|
||||
suggestion := fmt.Sprintf("; to add it:\n\tgo mod download %s", m.Path)
|
||||
return nil, module.VersionError(actual, &sumMissingError{suggestion: suggestion})
|
||||
}
|
||||
}
|
||||
|
@ -111,19 +111,3 @@ func (*mvsReqs) Previous(m module.Version) (module.Version, error) {
|
||||
}
|
||||
return module.Version{Path: m.Path, Version: "none"}, nil
|
||||
}
|
||||
|
||||
// next returns the next version of m.Path after m.Version.
|
||||
// It is only used by the exclusion processing in the Required method,
|
||||
// not called directly by MVS.
|
||||
func (*mvsReqs) next(m module.Version) (module.Version, error) {
|
||||
// TODO(golang.org/issue/38714): thread tracing context through MVS.
|
||||
list, err := versions(context.TODO(), m.Path, CheckAllowed)
|
||||
if err != nil {
|
||||
return module.Version{}, err
|
||||
}
|
||||
i := sort.Search(len(list), func(i int) bool { return semver.Compare(list[i], m.Version) > 0 })
|
||||
if i < len(list) {
|
||||
return module.Version{Path: m.Path, Version: list[i]}, nil
|
||||
}
|
||||
return module.Version{Path: m.Path, Version: "none"}, nil
|
||||
}
|
||||
|
@ -214,6 +214,6 @@ func checkVendorConsistency() {
|
||||
}
|
||||
|
||||
if vendErrors.Len() > 0 {
|
||||
base.Fatalf("go: inconsistent vendoring in %s:%s\n\nrun 'go mod vendor' to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory", modRoot, vendErrors)
|
||||
base.Fatalf("go: inconsistent vendoring in %s:%s\n\n\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor", modRoot, vendErrors)
|
||||
}
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
exec "internal/execabs"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"text/template"
|
||||
|
@ -11,10 +11,10 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/build"
|
||||
exec "internal/execabs"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
|
@ -325,7 +325,7 @@ func testFlags(args []string) (packageNames, passToTest []string) {
|
||||
if !testC {
|
||||
buildFlag = "-i"
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "flag %s is not a 'go test' flag (unknown flags cannot be used with %s)\n", firstUnknownFlag, buildFlag)
|
||||
fmt.Fprintf(os.Stderr, "go test: unknown flag %s cannot be used with %s\n", firstUnknownFlag, buildFlag)
|
||||
exitWithUsage()
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,9 @@ package tool
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/signal"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@ -85,7 +86,19 @@ func runTool(ctx context.Context, cmd *base.Command, args []string) {
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
}
|
||||
err := toolCmd.Run()
|
||||
err := toolCmd.Start()
|
||||
if err == nil {
|
||||
c := make(chan os.Signal, 100)
|
||||
signal.Notify(c)
|
||||
go func() {
|
||||
for sig := range c {
|
||||
toolCmd.Process.Signal(sig)
|
||||
}
|
||||
}()
|
||||
err = toolCmd.Wait()
|
||||
signal.Stop(c)
|
||||
close(c)
|
||||
}
|
||||
if err != nil {
|
||||
// Only print about the exit status if the command
|
||||
// didn't even run (not an ExitError) or it didn't exit cleanly
|
||||
|
@ -8,13 +8,13 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"internal/lazyregexp"
|
||||
"internal/singleflight"
|
||||
"io/fs"
|
||||
"log"
|
||||
urlpkg "net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
@ -729,7 +729,7 @@ func checkGOVCS(vcs *Cmd, root string) error {
|
||||
if private {
|
||||
what = "private"
|
||||
}
|
||||
return fmt.Errorf("GOVCS disallows using %s for %s %s", vcs.Cmd, what, root)
|
||||
return fmt.Errorf("GOVCS disallows using %s for %s %s; see 'go help vcs'", vcs.Cmd, what, root)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -10,9 +10,9 @@ import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
|
@ -57,6 +57,9 @@ type Builder struct {
|
||||
id sync.Mutex
|
||||
toolIDCache map[string]string // tool name -> tool ID
|
||||
buildIDCache map[string]string // file name -> build ID
|
||||
|
||||
cgoEnvOnce sync.Once
|
||||
cgoEnvCache []string
|
||||
}
|
||||
|
||||
// NOTE: Much of Action would not need to be exported if not for test.
|
||||
|
@ -9,9 +9,9 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"go/build"
|
||||
exec "internal/execabs"
|
||||
"internal/goroot"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@ -113,7 +113,10 @@ and test commands:
|
||||
created with -buildmode=shared.
|
||||
-mod mode
|
||||
module download mode to use: readonly, vendor, or mod.
|
||||
See 'go help modules' for more.
|
||||
By default, if a vendor directory is present and the go version in go.mod
|
||||
is 1.14 or higher, the go command acts as if -mod=vendor were set.
|
||||
Otherwise, the go command acts as if -mod=readonly were set.
|
||||
See https://golang.org/ref/mod#build-commands for details.
|
||||
-modcacherw
|
||||
leave newly-created directories in the module cache read-write
|
||||
instead of making them read-only.
|
||||
|
@ -7,8 +7,8 @@ package work
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"cmd/go/internal/base"
|
||||
|
@ -13,13 +13,13 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"internal/lazyregexp"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
@ -1164,10 +1164,8 @@ func (b *Builder) vet(ctx context.Context, a *Action) error {
|
||||
return err
|
||||
}
|
||||
|
||||
env := b.cCompilerEnv()
|
||||
if cfg.BuildToolchainName == "gccgo" {
|
||||
env = append(env, "GCCGO="+BuildToolchain.compiler())
|
||||
}
|
||||
// TODO(rsc): Why do we pass $GCCGO to go vet?
|
||||
env := b.cgoEnv()
|
||||
|
||||
p := a.Package
|
||||
tool := VetTool
|
||||
@ -2044,6 +2042,9 @@ func (b *Builder) runOut(a *Action, dir string, env []string, cmdargs ...interfa
|
||||
|
||||
var buf bytes.Buffer
|
||||
cmd := exec.Command(cmdline[0], cmdline[1:]...)
|
||||
if cmd.Path != "" {
|
||||
cmd.Args[0] = cmd.Path
|
||||
}
|
||||
cmd.Stdout = &buf
|
||||
cmd.Stderr = &buf
|
||||
cleanup := passLongArgsInResponseFiles(cmd)
|
||||
@ -2110,6 +2111,24 @@ func (b *Builder) cCompilerEnv() []string {
|
||||
return []string{"TERM=dumb"}
|
||||
}
|
||||
|
||||
// cgoEnv returns environment variables to set when running cgo.
|
||||
// Some of these pass through to cgo running the C compiler,
|
||||
// so it includes cCompilerEnv.
|
||||
func (b *Builder) cgoEnv() []string {
|
||||
b.cgoEnvOnce.Do(func() {
|
||||
cc, err := exec.LookPath(b.ccExe()[0])
|
||||
if err != nil || filepath.Base(cc) == cc { // reject relative path
|
||||
cc = "/missing-cc"
|
||||
}
|
||||
gccgo := GccgoBin
|
||||
if filepath.Base(gccgo) == gccgo { // reject relative path
|
||||
gccgo = "/missing-gccgo"
|
||||
}
|
||||
b.cgoEnvCache = append(b.cCompilerEnv(), "CC="+cc, "GCCGO="+gccgo)
|
||||
})
|
||||
return b.cgoEnvCache
|
||||
}
|
||||
|
||||
// mkdir makes the named directory.
|
||||
func (b *Builder) Mkdir(dir string) error {
|
||||
// Make Mkdir(a.Objdir) a no-op instead of an error when a.Objdir == "".
|
||||
@ -2435,7 +2454,7 @@ func (b *Builder) fcExe() []string {
|
||||
func (b *Builder) compilerExe(envValue string, def string) []string {
|
||||
compiler := strings.Fields(envValue)
|
||||
if len(compiler) == 0 {
|
||||
compiler = []string{def}
|
||||
compiler = strings.Fields(def)
|
||||
}
|
||||
return compiler
|
||||
}
|
||||
@ -2581,7 +2600,14 @@ func (b *Builder) gccArchArgs() []string {
|
||||
case "386":
|
||||
return []string{"-m32"}
|
||||
case "amd64":
|
||||
if cfg.Goos == "darwin" {
|
||||
return []string{"-arch", "x86_64", "-m64"}
|
||||
}
|
||||
return []string{"-m64"}
|
||||
case "arm64":
|
||||
if cfg.Goos == "darwin" {
|
||||
return []string{"-arch", "arm64"}
|
||||
}
|
||||
case "arm":
|
||||
return []string{"-marm"} // not thumb
|
||||
case "s390x":
|
||||
@ -2703,13 +2729,13 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo
|
||||
// along to the host linker. At this point in the code, cgoLDFLAGS
|
||||
// consists of the original $CGO_LDFLAGS (unchecked) and all the
|
||||
// flags put together from source code (checked).
|
||||
cgoenv := b.cCompilerEnv()
|
||||
cgoenv := b.cgoEnv()
|
||||
if len(cgoLDFLAGS) > 0 {
|
||||
flags := make([]string, len(cgoLDFLAGS))
|
||||
for i, f := range cgoLDFLAGS {
|
||||
flags[i] = strconv.Quote(f)
|
||||
}
|
||||
cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
|
||||
cgoenv = append(cgoenv, "CGO_LDFLAGS="+strings.Join(flags, " "))
|
||||
}
|
||||
|
||||
if cfg.BuildToolchainName == "gccgo" {
|
||||
@ -2940,7 +2966,7 @@ func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe
|
||||
if p.Standard && p.ImportPath == "runtime/cgo" {
|
||||
cgoflags = []string{"-dynlinker"} // record path to dynamic linker
|
||||
}
|
||||
return b.run(a, base.Cwd, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
|
||||
return b.run(a, base.Cwd, p.ImportPath, b.cgoEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
|
||||
}
|
||||
|
||||
// Run SWIG on all SWIG input files.
|
||||
|
@ -6,8 +6,8 @@ package work
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
exec "internal/execabs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -93,6 +93,12 @@ func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg,
|
||||
args = append(args, "-I", root)
|
||||
}
|
||||
}
|
||||
if embedcfg != nil && b.gccSupportsFlag(args[:1], "-fgo-embedcfg=/dev/null") {
|
||||
if err := b.writeFile(objdir+"embedcfg", embedcfg); err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
args = append(args, "-fgo-embedcfg="+objdir+"embedcfg")
|
||||
}
|
||||
|
||||
if b.gccSupportsFlag(args[:1], "-ffile-prefix-map=a=b") {
|
||||
if cfg.BuildTrimpath {
|
||||
|
2
src/cmd/go/testdata/addmod.go
vendored
2
src/cmd/go/testdata/addmod.go
vendored
@ -25,7 +25,7 @@ import (
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
exec "internal/execabs"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
|
24
src/cmd/go/testdata/script/build_darwin_cc_arch.txt
vendored
Normal file
24
src/cmd/go/testdata/script/build_darwin_cc_arch.txt
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
# Test that we pass -arch flag to C compiler on Darwin (issue 43692).
|
||||
|
||||
[!darwin] skip
|
||||
[!cgo] skip
|
||||
|
||||
# clear CC, in case user sets it
|
||||
env CC=
|
||||
|
||||
env CGO_ENABLED=1
|
||||
|
||||
env GOARCH=amd64
|
||||
go build -n -x c.go
|
||||
stderr 'clang.*-arch x86_64'
|
||||
|
||||
env GOARCH=arm64
|
||||
go build -n -x c.go
|
||||
stderr 'clang.*-arch arm64'
|
||||
|
||||
-- c.go --
|
||||
package main
|
||||
|
||||
import "C"
|
||||
|
||||
func main() {}
|
35
src/cmd/go/testdata/script/cgo_path.txt
vendored
Normal file
35
src/cmd/go/testdata/script/cgo_path.txt
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
[!cgo] skip
|
||||
|
||||
env GOCACHE=$WORK/gocache # Looking for compile flags, so need a clean cache.
|
||||
[!windows] env PATH=.:$PATH
|
||||
[!windows] chmod 0777 p/gcc p/clang
|
||||
[!windows] exists -exec p/gcc p/clang
|
||||
[windows] exists -exec p/gcc.bat p/clang.bat
|
||||
! exists p/bug.txt
|
||||
go build -x
|
||||
! exists p/bug.txt
|
||||
|
||||
-- go.mod --
|
||||
module m
|
||||
|
||||
-- m.go --
|
||||
package m
|
||||
|
||||
import _ "m/p"
|
||||
|
||||
-- p/p.go --
|
||||
package p
|
||||
|
||||
// #define X 1
|
||||
import "C"
|
||||
|
||||
-- p/gcc --
|
||||
#!/bin/sh
|
||||
echo ran gcc >bug.txt
|
||||
-- p/clang --
|
||||
#!/bin/sh
|
||||
echo ran clang >bug.txt
|
||||
-- p/gcc.bat --
|
||||
echo ran gcc >bug.txt
|
||||
-- p/clang.bat --
|
||||
echo ran clang >bug.txt
|
45
src/cmd/go/testdata/script/embed.txt
vendored
45
src/cmd/go/testdata/script/embed.txt
vendored
@ -3,6 +3,14 @@ go list -f '{{.EmbedPatterns}}'
|
||||
stdout '\[x\*t\*t\]'
|
||||
go list -f '{{.EmbedFiles}}'
|
||||
stdout '\[x.txt\]'
|
||||
go list -test -f '{{.TestEmbedPatterns}}'
|
||||
stdout '\[y\*t\*t\]'
|
||||
go list -test -f '{{.TestEmbedFiles}}'
|
||||
stdout '\[y.txt\]'
|
||||
go list -test -f '{{.XTestEmbedPatterns}}'
|
||||
stdout '\[z\*t\*t\]'
|
||||
go list -test -f '{{.XTestEmbedFiles}}'
|
||||
stdout '\[z.txt\]'
|
||||
|
||||
# build embeds x.txt
|
||||
go build -x
|
||||
@ -20,7 +28,7 @@ cp x.go2 x.go
|
||||
go build -x
|
||||
cp x.txt .git
|
||||
! go build -x
|
||||
stderr 'pattern [*]t: cannot embed file [.]git'
|
||||
stderr '^x.go:5:12: pattern [*]t: cannot embed file [.]git: invalid name [.]git$'
|
||||
rm .git
|
||||
|
||||
# build rejects symlinks
|
||||
@ -32,19 +40,26 @@ rm .git
|
||||
# build rejects empty directories
|
||||
mkdir t
|
||||
! go build -x
|
||||
stderr 'pattern [*]t: cannot embed directory t: contains no embeddable files'
|
||||
stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$'
|
||||
|
||||
# build ignores symlinks and invalid names in directories
|
||||
cp x.txt t/.git
|
||||
! go build -x
|
||||
stderr 'pattern [*]t: cannot embed directory t: contains no embeddable files'
|
||||
stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$'
|
||||
go list -e -f '{{.Incomplete}}'
|
||||
stdout 'true'
|
||||
[symlink] symlink t/x.link -> ../x.txt
|
||||
[symlink] ! go build -x
|
||||
[symlink] stderr 'pattern [*]t: cannot embed directory t: contains no embeddable files'
|
||||
[symlink] stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$'
|
||||
|
||||
cp x.txt t/x.txt
|
||||
go build -x
|
||||
|
||||
# build reports errors with positions in imported packages
|
||||
rm t/x.txt
|
||||
! go build m/use
|
||||
stderr '^x.go:5:12: pattern [*]t: cannot embed directory t: contains no embeddable files$'
|
||||
|
||||
-- x.go --
|
||||
package p
|
||||
|
||||
@ -53,6 +68,22 @@ import "embed"
|
||||
//go:embed x*t*t
|
||||
var X embed.FS
|
||||
|
||||
-- x_test.go --
|
||||
package p
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed y*t*t
|
||||
var Y string
|
||||
|
||||
-- x_x_test.go --
|
||||
package p_test
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed z*t*t
|
||||
var Z string
|
||||
|
||||
-- x.go2 --
|
||||
package p
|
||||
|
||||
@ -64,9 +95,15 @@ var X embed.FS
|
||||
-- x.txt --
|
||||
hello
|
||||
|
||||
-- y.txt --
|
||||
-- z.txt --
|
||||
-- x.txt2 --
|
||||
not hello
|
||||
|
||||
-- use/use.go --
|
||||
package use
|
||||
|
||||
import _ "m"
|
||||
-- go.mod --
|
||||
module m
|
||||
|
||||
|
22
src/cmd/go/testdata/script/embed_fmt.txt
vendored
Normal file
22
src/cmd/go/testdata/script/embed_fmt.txt
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
# go fmt ignores file not found
|
||||
go fmt xnofmt.go
|
||||
cmp xnofmt.go xfmt.ref
|
||||
! go build xnofmt.go
|
||||
stderr 'xnofmt.go:5:12: pattern missing.txt: no matching files found'
|
||||
|
||||
-- xnofmt.go --
|
||||
package p
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed missing.txt
|
||||
var X embed.FS
|
||||
-- xfmt.ref --
|
||||
package p
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed missing.txt
|
||||
var X embed.FS
|
||||
-- go.mod --
|
||||
module m
|
52
src/cmd/go/testdata/script/govcs.txt
vendored
52
src/cmd/go/testdata/script/govcs.txt
vendored
@ -5,40 +5,40 @@ env GOPROXY=direct
|
||||
# GOVCS stops go get
|
||||
env GOVCS='*:none'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'go get: GOVCS disallows using git for public github.com/google/go-cmp'
|
||||
stderr '^go get: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$'
|
||||
env GOPRIVATE='github.com/google'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'go get: GOVCS disallows using git for private github.com/google/go-cmp'
|
||||
stderr '^go get: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$'
|
||||
|
||||
# public pattern works
|
||||
env GOPRIVATE='github.com/google'
|
||||
env GOVCS='public:all,private:none'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'go get: GOVCS disallows using git for private github.com/google/go-cmp'
|
||||
stderr '^go get: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$'
|
||||
|
||||
# private pattern works
|
||||
env GOPRIVATE='hubgit.com/google'
|
||||
env GOVCS='private:all,public:none'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'go get: GOVCS disallows using git for public github.com/google/go-cmp'
|
||||
stderr '^go get: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$'
|
||||
|
||||
# other patterns work (for more patterns, see TestGOVCS)
|
||||
env GOPRIVATE=
|
||||
env GOVCS='github.com:svn|hg'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'go get: GOVCS disallows using git for public github.com/google/go-cmp'
|
||||
stderr '^go get: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$'
|
||||
env GOVCS='github.com/google/go-cmp/inner:git,github.com:svn|hg'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'go get: GOVCS disallows using git for public github.com/google/go-cmp'
|
||||
stderr '^go get: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$'
|
||||
|
||||
# bad patterns are reported (for more bad patterns, see TestGOVCSErrors)
|
||||
env GOVCS='git'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'go get github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"'
|
||||
stderr '^go get github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"$'
|
||||
|
||||
env GOVCS=github.com:hg,github.com:git
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'go get github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"'
|
||||
stderr '^go get github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"$'
|
||||
|
||||
# bad GOVCS patterns do not stop commands that do not need to check VCS
|
||||
go list
|
||||
@ -50,19 +50,19 @@ env GOPROXY=direct
|
||||
env GOPRIVATE=
|
||||
env GOVCS=
|
||||
! go get rsc.io/nonexist.svn/hello
|
||||
stderr 'go get rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn'
|
||||
stderr '^go get rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn; see ''go help vcs''$'
|
||||
|
||||
# fossil is disallowed by default
|
||||
env GOPRIVATE=
|
||||
env GOVCS=
|
||||
! go get rsc.io/nonexist.fossil/hello
|
||||
stderr 'go get rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil'
|
||||
stderr '^go get rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil; see ''go help vcs''$'
|
||||
|
||||
# bzr is disallowed by default
|
||||
env GOPRIVATE=
|
||||
env GOVCS=
|
||||
! go get rsc.io/nonexist.bzr/hello
|
||||
stderr 'go get rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr'
|
||||
stderr '^go get rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr; see ''go help vcs''$'
|
||||
|
||||
# git is OK by default
|
||||
env GOVCS=
|
||||
@ -77,12 +77,12 @@ env GONOSUMDB='*'
|
||||
# git can be disallowed
|
||||
env GOVCS=public:hg
|
||||
! go get rsc.io/nonexist.git/hello
|
||||
stderr 'go get rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git'
|
||||
stderr '^go get rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git; see ''go help vcs''$'
|
||||
|
||||
# hg can be disallowed
|
||||
env GOVCS=public:git
|
||||
! go get rsc.io/nonexist.hg/hello
|
||||
stderr 'go get rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg'
|
||||
stderr '^go get rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg; see ''go help vcs''$'
|
||||
|
||||
# Repeat in GOPATH mode. Error texts slightly different.
|
||||
|
||||
@ -91,40 +91,40 @@ env GO111MODULE=off
|
||||
# GOVCS stops go get
|
||||
env GOVCS='*:none'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp'
|
||||
stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$'
|
||||
env GOPRIVATE='github.com/google'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp'
|
||||
stderr '^package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$'
|
||||
|
||||
# public pattern works
|
||||
env GOPRIVATE='github.com/google'
|
||||
env GOVCS='public:all,private:none'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp'
|
||||
stderr '^package github.com/google/go-cmp: GOVCS disallows using git for private github.com/google/go-cmp; see ''go help vcs''$'
|
||||
|
||||
# private pattern works
|
||||
env GOPRIVATE='hubgit.com/google'
|
||||
env GOVCS='private:all,public:none'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp'
|
||||
stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$'
|
||||
|
||||
# other patterns work (for more patterns, see TestGOVCS)
|
||||
env GOPRIVATE=
|
||||
env GOVCS='github.com:svn|hg'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp'
|
||||
stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$'
|
||||
env GOVCS='github.com/google/go-cmp/inner:git,github.com:svn|hg'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp'
|
||||
stderr '^package github.com/google/go-cmp: GOVCS disallows using git for public github.com/google/go-cmp; see ''go help vcs''$'
|
||||
|
||||
# bad patterns are reported (for more bad patterns, see TestGOVCSErrors)
|
||||
env GOVCS='git'
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'package github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"'
|
||||
stderr '^package github.com/google/go-cmp: malformed entry in GOVCS \(missing colon\): "git"$'
|
||||
|
||||
env GOVCS=github.com:hg,github.com:git
|
||||
! go get github.com/google/go-cmp
|
||||
stderr 'package github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"'
|
||||
stderr '^package github.com/google/go-cmp: unreachable pattern in GOVCS: "github.com:git" after "github.com:hg"$'
|
||||
|
||||
# bad GOVCS patterns do not stop commands that do not need to check VCS
|
||||
go list
|
||||
@ -133,19 +133,19 @@ go list
|
||||
env GOPRIVATE=
|
||||
env GOVCS=
|
||||
! go get rsc.io/nonexist.svn/hello
|
||||
stderr 'package rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn'
|
||||
stderr '^package rsc.io/nonexist.svn/hello: GOVCS disallows using svn for public rsc.io/nonexist.svn; see ''go help vcs''$'
|
||||
|
||||
# fossil is disallowed by default
|
||||
env GOPRIVATE=
|
||||
env GOVCS=
|
||||
! go get rsc.io/nonexist.fossil/hello
|
||||
stderr 'package rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil'
|
||||
stderr '^package rsc.io/nonexist.fossil/hello: GOVCS disallows using fossil for public rsc.io/nonexist.fossil; see ''go help vcs''$'
|
||||
|
||||
# bzr is disallowed by default
|
||||
env GOPRIVATE=
|
||||
env GOVCS=
|
||||
! go get rsc.io/nonexist.bzr/hello
|
||||
stderr 'package rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr'
|
||||
stderr '^package rsc.io/nonexist.bzr/hello: GOVCS disallows using bzr for public rsc.io/nonexist.bzr; see ''go help vcs''$'
|
||||
|
||||
# git is OK by default
|
||||
env GOVCS=
|
||||
@ -160,12 +160,12 @@ env GONOSUMDB='*'
|
||||
# git can be disallowed
|
||||
env GOVCS=public:hg
|
||||
! go get rsc.io/nonexist.git/hello
|
||||
stderr 'package rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git'
|
||||
stderr '^package rsc.io/nonexist.git/hello: GOVCS disallows using git for public rsc.io/nonexist.git; see ''go help vcs''$'
|
||||
|
||||
# hg can be disallowed
|
||||
env GOVCS=public:git
|
||||
! go get rsc.io/nonexist.hg/hello
|
||||
stderr 'package rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg'
|
||||
stderr '^package rsc.io/nonexist.hg/hello: GOVCS disallows using hg for public rsc.io/nonexist.hg; see ''go help vcs''$'
|
||||
|
||||
-- go.mod --
|
||||
module m
|
||||
|
@ -19,7 +19,7 @@ stderr 'malformed module path "x/y.z": missing dot in first path element'
|
||||
! go build ./useappengine
|
||||
stderr '^useappengine[/\\]x.go:2:8: cannot find package$'
|
||||
! go build ./usenonexistent
|
||||
stderr '^usenonexistent[/\\]x.go:2:8: no required module provides package nonexistent.rsc.io; try ''go mod tidy'' to add it$'
|
||||
stderr '^usenonexistent[/\\]x.go:2:8: no required module provides package nonexistent.rsc.io; to add it:\n\tgo get nonexistent.rsc.io$'
|
||||
|
||||
|
||||
# 'get -d' should be similarly definitive
|
||||
|
6
src/cmd/go/testdata/script/mod_edit.txt
vendored
6
src/cmd/go/testdata/script/mod_edit.txt
vendored
@ -21,6 +21,12 @@ cmpenv go.mod $WORK/go.mod.edit1
|
||||
go mod edit -droprequire=x.1 -dropexclude=x.1@v1.2.1 -dropreplace=x.1@v1.3.0 -require=x.3@v1.99.0 -dropretract=v1.0.0 -dropretract=[v1.1.0,v1.2.0]
|
||||
cmpenv go.mod $WORK/go.mod.edit2
|
||||
|
||||
# -exclude and -retract reject invalid versions.
|
||||
! go mod edit -exclude=example.com/m@bad
|
||||
stderr '^go mod: -exclude=example.com/m@bad: version "bad" invalid: must be of the form v1.2.3$'
|
||||
! go mod edit -retract=bad
|
||||
stderr '^go mod: -retract=bad: version "bad" invalid: must be of the form v1.2.3$'
|
||||
|
||||
# go mod edit -json
|
||||
go mod edit -json
|
||||
cmpenv stdout $WORK/go.mod.json
|
||||
|
@ -6,5 +6,5 @@ env GOPROXY=https://proxy.golang.org,direct
|
||||
env GOSUMDB=off
|
||||
|
||||
go get -x -v -d golang.org/x/tools/cmd/goimports
|
||||
stderr '# get https://proxy.golang.org/golang.org/x/tools/@latest'
|
||||
stderr '# get https://proxy.golang.org/golang.org/x/tools/@v/list'
|
||||
! stderr '# get https://golang.org'
|
||||
|
@ -6,10 +6,12 @@ cp go.mod.orig go.mod
|
||||
go list -m indirect-with-pkg
|
||||
stdout '^indirect-with-pkg v1.0.0 => ./indirect-with-pkg$'
|
||||
! go list ./use-indirect
|
||||
stderr '^go: m/use-indirect: package indirect-with-pkg imported from implicitly required module; try ''go get -d m/use-indirect'' to add missing requirements$'
|
||||
stderr '^go: m/use-indirect: package indirect-with-pkg imported from implicitly required module; to add missing requirements, run:\n\tgo get indirect-with-pkg@v1.0.0$'
|
||||
|
||||
# We can promote the implicit requirement by getting the importing package,
|
||||
# as hinted.
|
||||
# We can promote the implicit requirement by getting the importing package.
|
||||
# NOTE: the hint recommends getting the imported package (tested below) since
|
||||
# it's more obvious and doesn't require -d. However, that adds an '// indirect'
|
||||
# comment on the requirement.
|
||||
go get -d m/use-indirect
|
||||
cmp go.mod go.mod.use
|
||||
cp go.mod.orig go.mod
|
||||
@ -17,6 +19,8 @@ cp go.mod.orig go.mod
|
||||
# We can also promote implicit requirements using 'go get' on them, or their
|
||||
# packages. This gives us "// indirect" requirements, since 'go get' doesn't
|
||||
# know they're needed by the main module. See #43131 for the rationale.
|
||||
# The hint above recommends this because it's more obvious usage and doesn't
|
||||
# require the -d flag.
|
||||
go get -d indirect-with-pkg indirect-without-pkg
|
||||
cmp go.mod go.mod.indirect
|
||||
|
||||
|
@ -87,7 +87,7 @@ stderr '^go get: malformed module path "example": missing dot in first path elem
|
||||
go mod edit -replace example@v0.1.0=./example
|
||||
|
||||
! go list example
|
||||
stderr '^module example provides package example and is replaced but not required; try ''go get -d example@v0.1.0'' to add it$'
|
||||
stderr '^module example provides package example and is replaced but not required; to add it:\n\tgo get example@v0.1.0$'
|
||||
|
||||
go get -d example
|
||||
go list -m example
|
||||
|
@ -11,7 +11,7 @@ cp go.mod.orig go.mod
|
||||
go mod edit -require example.com/retract/self/prev@v1.9.0
|
||||
go get -d example.com/retract/self/prev
|
||||
stderr '^go: warning: example.com/retract/self/prev@v1.9.0: retracted by module author: self$'
|
||||
stderr '^go: run ''go get example.com/retract/self/prev@latest'' to switch to the latest unretracted version$'
|
||||
stderr '^go: to switch to the latest unretracted version, run:\n\tgo get example.com/retract/self/prev@latest$'
|
||||
go list -m example.com/retract/self/prev
|
||||
stdout '^example.com/retract/self/prev v1.9.0$'
|
||||
|
||||
|
@ -19,7 +19,7 @@ exec $WORK/testimport$GOEXE other/x/y/z/w .
|
||||
stdout w2.go
|
||||
|
||||
! exec $WORK/testimport$GOEXE gobuild.example.com/x/y/z/w .
|
||||
stderr 'no required module provides package gobuild.example.com/x/y/z/w; try ''go get -d gobuild.example.com/x/y/z/w'' to add it'
|
||||
stderr 'no required module provides package gobuild.example.com/x/y/z/w; to add it:\n\tgo get gobuild.example.com/x/y/z/w'
|
||||
|
||||
cd z
|
||||
exec $WORK/testimport$GOEXE other/x/y/z/w .
|
||||
|
4
src/cmd/go/testdata/script/mod_init_tidy.txt
vendored
4
src/cmd/go/testdata/script/mod_init_tidy.txt
vendored
@ -8,14 +8,14 @@ cd ..
|
||||
# 'go mod init' should recommend 'go mod tidy' if the directory has a .go file.
|
||||
cd pkginroot
|
||||
go mod init m
|
||||
stderr '^go: run ''go mod tidy'' to add module requirements and sums$'
|
||||
stderr '^go: to add module requirements and sums:\n\tgo mod tidy$'
|
||||
cd ..
|
||||
|
||||
# 'go mod init' should recommend 'go mod tidy' if the directory has a
|
||||
# subdirectory. We don't walk the tree to see if it has .go files.
|
||||
cd subdir
|
||||
go mod init m
|
||||
stderr '^go: run ''go mod tidy'' to add module requirements and sums$'
|
||||
stderr '^go: to add module requirements and sums:\n\tgo mod tidy$'
|
||||
cd ..
|
||||
|
||||
-- empty/empty.txt --
|
||||
|
@ -16,7 +16,7 @@ env GO111MODULE=auto
|
||||
cd m
|
||||
cp go.mod go.mod.orig
|
||||
! go list -m all
|
||||
stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; try ''go mod download example.com/cmd'' to add it$'
|
||||
stderr '^go: example.com/cmd@v1.1.0-doesnotexist: missing go.sum entry; to add it:\n\tgo mod download example.com/cmd$'
|
||||
go install example.com/cmd/a@latest
|
||||
cmp go.mod go.mod.orig
|
||||
exists $GOPATH/bin/a$GOEXE
|
||||
@ -67,9 +67,9 @@ cd tmp
|
||||
go mod init tmp
|
||||
go mod edit -require=rsc.io/fortune@v1.0.0
|
||||
! go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0
|
||||
stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; try ''go mod download rsc.io/fortune'' to add it$'
|
||||
stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; to add it:\n\tgo mod download rsc.io/fortune$'
|
||||
! go install -mod=readonly ../../pkg/mod/rsc.io/fortune@v1.0.0
|
||||
stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; try ''go mod download rsc.io/fortune'' to add it$'
|
||||
stderr '^go: rsc.io/fortune@v1.0.0: missing go.sum entry; to add it:\n\tgo mod download rsc.io/fortune$'
|
||||
go get -d rsc.io/fortune@v1.0.0
|
||||
go install -mod=readonly $GOPATH/pkg/mod/rsc.io/fortune@v1.0.0
|
||||
exists $GOPATH/bin/fortune$GOEXE
|
||||
@ -175,6 +175,11 @@ stdout '^\tmod\texample.com/cmd\tv1.0.0\t'
|
||||
go install example.com/cmd/a@v1.9.0
|
||||
go version -m $GOPATH/bin/a$GOEXE
|
||||
stdout '^\tmod\texample.com/cmd\tv1.9.0\t'
|
||||
env GO111MODULE=
|
||||
|
||||
# 'go install pkg@version' succeeds when -mod=readonly is set explicitly.
|
||||
# Verifies #43278.
|
||||
go install -mod=readonly example.com/cmd/a@v1.0.0
|
||||
|
||||
-- m/go.mod --
|
||||
module m
|
||||
|
@ -3,7 +3,7 @@
|
||||
# Test that go list fails on a go.mod with no module declaration.
|
||||
cd $WORK/gopath/src/mod
|
||||
! go list .
|
||||
stderr '^go: no module declaration in go.mod.\n\tRun ''go mod edit -module=example.com/mod'' to specify the module path.$'
|
||||
stderr '^go: no module declaration in go.mod. To specify the module path:\n\tgo mod edit -module=example.com/mod$'
|
||||
|
||||
# Test that go mod init in GOPATH doesn't add a module declaration
|
||||
# with a path that can't possibly be a module path, because
|
||||
|
@ -39,7 +39,7 @@ stdout example.com/notfound
|
||||
|
||||
# Listing the missing dependency directly should fail outright...
|
||||
! go list -f '{{if .Error}}error{{end}} {{if .Incomplete}}incomplete{{end}}' example.com/notfound
|
||||
stderr 'no required module provides package example.com/notfound; try ''go get -d example.com/notfound'' to add it'
|
||||
stderr 'no required module provides package example.com/notfound; to add it:\n\tgo get example.com/notfound'
|
||||
! stdout error
|
||||
! stdout incomplete
|
||||
|
||||
|
10
src/cmd/go/testdata/script/mod_readonly.txt
vendored
10
src/cmd/go/testdata/script/mod_readonly.txt
vendored
@ -13,7 +13,7 @@ cmp go.mod go.mod.empty
|
||||
# -mod=readonly should be set by default.
|
||||
env GOFLAGS=
|
||||
! go list all
|
||||
stderr '^x.go:2:8: no required module provides package rsc\.io/quote; try ''go mod tidy'' to add it$'
|
||||
stderr '^x.go:2:8: no required module provides package rsc\.io/quote; to add it:\n\tgo get rsc\.io/quote$'
|
||||
cmp go.mod go.mod.empty
|
||||
|
||||
env GOFLAGS=-mod=readonly
|
||||
@ -51,7 +51,7 @@ cmp go.mod go.mod.inconsistent
|
||||
# We get a different message when -mod=readonly is used by default.
|
||||
env GOFLAGS=
|
||||
! go list
|
||||
stderr '^go: updates to go.mod needed; try ''go mod tidy'' first$'
|
||||
stderr '^go: updates to go.mod needed; to update it:\n\tgo mod tidy'
|
||||
|
||||
# However, it should not reject files missing a 'go' directive,
|
||||
# since that was not always required.
|
||||
@ -75,15 +75,15 @@ cmp go.mod go.mod.indirect
|
||||
|
||||
cp go.mod.untidy go.mod
|
||||
! go list all
|
||||
stderr '^x.go:2:8: no required module provides package rsc.io/quote; try ''go mod tidy'' to add it$'
|
||||
stderr '^x.go:2:8: no required module provides package rsc.io/quote; to add it:\n\tgo get rsc.io/quote$'
|
||||
|
||||
! go list -deps .
|
||||
stderr '^x.go:2:8: no required module provides package rsc.io/quote; try ''go mod tidy'' to add it$'
|
||||
stderr '^x.go:2:8: no required module provides package rsc.io/quote; to add it:\n\tgo get rsc.io/quote$'
|
||||
|
||||
# However, if we didn't see an import from the main module, we should suggest
|
||||
# 'go get -d' instead, because we don't know whether 'go mod tidy' would add it.
|
||||
! go list rsc.io/quote
|
||||
stderr '^no required module provides package rsc.io/quote; try ''go get -d rsc.io/quote'' to add it$'
|
||||
stderr '^no required module provides package rsc.io/quote; to add it:\n\tgo get rsc.io/quote$'
|
||||
|
||||
|
||||
-- go.mod --
|
||||
|
@ -9,7 +9,7 @@ cp go.mod go.mod.orig
|
||||
# can't in readonly mode, since its go.mod may alter the build list.
|
||||
go mod edit -replace rsc.io/quote=./quote
|
||||
! go list rsc.io/quote
|
||||
stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; try ''go get -d rsc.io/quote'' to add it$'
|
||||
stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; to add it:\n\tgo get rsc.io/quote$'
|
||||
go get -d rsc.io/quote
|
||||
cmp go.mod go.mod.latest
|
||||
go list rsc.io/quote
|
||||
@ -18,7 +18,7 @@ cp go.mod.orig go.mod
|
||||
# Same test with a specific version.
|
||||
go mod edit -replace rsc.io/quote@v1.0.0-doesnotexist=./quote
|
||||
! go list rsc.io/quote
|
||||
stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; try ''go get -d rsc.io/quote@v1.0.0-doesnotexist'' to add it$'
|
||||
stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; to add it:\n\tgo get rsc.io/quote@v1.0.0-doesnotexist$'
|
||||
go get -d rsc.io/quote@v1.0.0-doesnotexist
|
||||
cmp go.mod go.mod.specific
|
||||
go list rsc.io/quote
|
||||
@ -28,7 +28,7 @@ cp go.mod.orig go.mod
|
||||
go mod edit -replace rsc.io/quote@v1.0.0-doesnotexist=./quote
|
||||
go mod edit -replace rsc.io/quote@v1.1.0-doesnotexist=./quote
|
||||
! go list rsc.io/quote
|
||||
stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; try ''go get -d rsc.io/quote@v1.1.0-doesnotexist'' to add it$'
|
||||
stderr '^module rsc.io/quote provides package rsc.io/quote and is replaced but not required; to add it:\n\tgo get rsc.io/quote@v1.1.0-doesnotexist$'
|
||||
|
||||
-- go.mod --
|
||||
module m
|
||||
|
22
src/cmd/go/testdata/script/mod_sum_ambiguous.txt
vendored
22
src/cmd/go/testdata/script/mod_sum_ambiguous.txt
vendored
@ -10,20 +10,34 @@ go mod tidy
|
||||
grep '^example.com/ambiguous/a v1.0.0 h1:' go.sum
|
||||
grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum
|
||||
|
||||
# 'go mod download' should also add sums.
|
||||
cp go.sum.buildlist-only go.sum
|
||||
go mod download example.com/ambiguous/a
|
||||
grep '^example.com/ambiguous/a v1.0.0 h1:' go.sum
|
||||
! grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum
|
||||
go mod download example.com/ambiguous/a/b
|
||||
grep '^example.com/ambiguous/a/b v0.0.0-empty h1:' go.sum
|
||||
|
||||
# If two modules could provide a package, and we're missing a sum for one,
|
||||
# we should see a missing sum error, even if we have a sum for a module that
|
||||
# provides the package.
|
||||
cp go.sum.a-only go.sum
|
||||
! go list example.com/ambiguous/a/b
|
||||
stderr '^missing go.sum entry needed to verify package example.com/ambiguous/a/b is provided by exactly one module$'
|
||||
stderr '^missing go.sum entry needed to verify package example.com/ambiguous/a/b is provided by exactly one module; to add:\n\tgo mod download example.com/ambiguous/a/b$'
|
||||
! go list -deps .
|
||||
stderr '^use.go:3:8: missing go.sum entry needed to verify package example.com/ambiguous/a/b is provided by exactly one module; try ''go mod tidy'' to add it$'
|
||||
stderr '^use.go:3:8: missing go.sum entry needed to verify package example.com/ambiguous/a/b \(imported by m\) is provided by exactly one module; to add:\n\tgo get m$'
|
||||
|
||||
cp go.sum.b-only go.sum
|
||||
! go list example.com/ambiguous/a/b
|
||||
stderr '^missing go.sum entry for module providing package example.com/ambiguous/a/b$'
|
||||
stderr '^missing go.sum entry for module providing package example.com/ambiguous/a/b; to add:\n\tgo mod download example.com/ambiguous/a$'
|
||||
! go list -deps .
|
||||
stderr '^use.go:3:8: missing go.sum entry for module providing package example.com/ambiguous/a/b; try ''go mod tidy'' to add it$'
|
||||
stderr '^use.go:3:8: missing go.sum entry for module providing package example.com/ambiguous/a/b \(imported by m\); to add:\n\tgo get m$'
|
||||
|
||||
cp go.sum.buildlist-only go.sum
|
||||
! go list example.com/ambiguous/a/b
|
||||
stderr '^missing go.sum entry for module providing package example.com/ambiguous/a/b; to add:\n\tgo mod download example.com/ambiguous/a example.com/ambiguous/a/b$'
|
||||
! go list -deps .
|
||||
stderr '^use.go:3:8: missing go.sum entry for module providing package example.com/ambiguous/a/b \(imported by m\); to add:\n\tgo get m$'
|
||||
|
||||
-- go.mod --
|
||||
module m
|
||||
|
12
src/cmd/go/testdata/script/mod_sum_readonly.txt
vendored
12
src/cmd/go/testdata/script/mod_sum_readonly.txt
vendored
@ -4,7 +4,7 @@ env GO111MODULE=on
|
||||
# When a sum is needed to load the build list, we get an error for the
|
||||
# specific module. The .mod file is not downloaded, and go.sum is not written.
|
||||
! go list -m all
|
||||
stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; try ''go mod download rsc.io/quote'' to add it$'
|
||||
stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
|
||||
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
|
||||
! exists go.sum
|
||||
|
||||
@ -12,7 +12,7 @@ stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; try ''go mod download rs
|
||||
# we should see the same error.
|
||||
cp go.sum.h2only go.sum
|
||||
! go list -m all
|
||||
stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; try ''go mod download rsc.io/quote'' to add it$'
|
||||
stderr '^go: rsc.io/quote@v1.5.2: missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
|
||||
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
|
||||
cmp go.sum go.sum.h2only
|
||||
rm go.sum
|
||||
@ -21,7 +21,7 @@ rm go.sum
|
||||
cp go.mod go.mod.orig
|
||||
go mod edit -replace rsc.io/quote@v1.5.2=rsc.io/quote@v1.5.1
|
||||
! go list -m all
|
||||
stderr '^go: rsc.io/quote@v1.5.2 \(replaced by rsc.io/quote@v1.5.1\): missing go.sum entry; try ''go mod download rsc.io/quote'' to add it$'
|
||||
stderr '^go: rsc.io/quote@v1.5.2 \(replaced by rsc.io/quote@v1.5.1\): missing go.sum entry; to add it:\n\tgo mod download rsc.io/quote$'
|
||||
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.1.mod
|
||||
! exists go.sum
|
||||
cp go.mod.orig go.mod
|
||||
@ -35,19 +35,19 @@ exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
|
||||
# When a sum is needed to load a .mod file for a package outside the build list,
|
||||
# we get a generic missing import error.
|
||||
! go list example.com/doesnotexist
|
||||
stderr '^no required module provides package example.com/doesnotexist; try ''go get -d example.com/doesnotexist'' to add it$'
|
||||
stderr '^no required module provides package example.com/doesnotexist; to add it:\n\tgo get example.com/doesnotexist$'
|
||||
|
||||
# When a sum is needed to load a .zip file, we get a more specific error.
|
||||
# The .zip file is not downloaded.
|
||||
! go list rsc.io/quote
|
||||
stderr '^missing go.sum entry for module providing package rsc.io/quote$'
|
||||
stderr '^missing go.sum entry for module providing package rsc.io/quote; to add:\n\tgo mod download rsc.io/quote$'
|
||||
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
|
||||
|
||||
# The error is attached to the package from the missing module. We can load
|
||||
# a package that imports it without that error.
|
||||
go list -e -deps -f '{{.ImportPath}}{{with .Error}} {{.Err}}{{end}}' .
|
||||
stdout '^m$'
|
||||
stdout '^rsc.io/quote missing go.sum entry for module providing package rsc.io/quote; try ''go mod tidy'' to add it$'
|
||||
stdout '^rsc.io/quote missing go.sum entry for module providing package rsc.io/quote \(imported by m\); to add:\n\tgo get m$'
|
||||
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
|
||||
|
||||
# go.sum should not have been written.
|
||||
|
@ -66,7 +66,7 @@ stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$'
|
||||
stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt'
|
||||
stderr '^\texample.com/unused: is replaced in go.mod, but not marked as replaced in vendor/modules.txt'
|
||||
stderr '^\texample.com/version@v1.2.0: is replaced in go.mod, but not marked as replaced in vendor/modules.txt'
|
||||
stderr '\n\nrun .go mod vendor. to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory$'
|
||||
stderr '^\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor$'
|
||||
|
||||
# Module-specific subcommands should continue to load the full module graph.
|
||||
go mod graph
|
||||
@ -135,7 +135,7 @@ stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$'
|
||||
stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but not marked as explicit in vendor/modules.txt'
|
||||
stderr '^\texample.com/unused: is replaced in go.mod, but not marked as replaced in vendor/modules.txt'
|
||||
stderr '^\texample.com/version@v1.2.0: is replaced in go.mod, but not marked as replaced in vendor/modules.txt'
|
||||
stderr '\n\nrun .go mod vendor. to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory$'
|
||||
stderr '^\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor$'
|
||||
|
||||
# If -mod=vendor is set, limited consistency checks should apply even when
|
||||
# the go version is 1.13 or earlier.
|
||||
@ -151,7 +151,7 @@ cp $WORK/modules-bad-1.13.txt vendor/modules.txt
|
||||
! go list -mod=vendor -f {{.Dir}} -tags tools all
|
||||
stderr '^go: inconsistent vendoring in '$WORK[/\\]auto':$'
|
||||
stderr '^\texample.com/printversion@v1.0.0: is explicitly required in go.mod, but vendor/modules.txt indicates example.com/printversion@v1.1.0$'
|
||||
stderr '\n\nrun .go mod vendor. to sync, or use -mod=mod or -mod=readonly to ignore the vendor directory$'
|
||||
stderr '^\tTo ignore the vendor directory, use -mod=readonly or -mod=mod.\n\tTo sync the vendor directory, run:\n\t\tgo mod vendor$'
|
||||
|
||||
# If the go version is still 1.13, 'go mod vendor' should write a
|
||||
# matching vendor/modules.txt containing the corrected 1.13 data.
|
||||
|
179
src/cmd/go/testdata/script/mod_vendor_embed.txt
vendored
Normal file
179
src/cmd/go/testdata/script/mod_vendor_embed.txt
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
go mod vendor
|
||||
cmp vendor/example.com/a/samedir_embed.txt a/samedir_embed.txt
|
||||
cmp vendor/example.com/a/subdir/embed.txt a/subdir/embed.txt
|
||||
cmp vendor/example.com/a/subdir/test/embed.txt a/subdir/test/embed.txt
|
||||
cmp vendor/example.com/a/subdir/test/xtest/embed.txt a/subdir/test/xtest/embed.txt
|
||||
|
||||
cd broken_no_matching_files
|
||||
! go mod vendor
|
||||
stderr 'go mod vendor: pattern foo.txt: no matching files found'
|
||||
|
||||
cd ../broken_bad_pattern
|
||||
! go mod vendor
|
||||
stderr 'go mod vendor: pattern ../foo.txt: invalid pattern syntax'
|
||||
|
||||
# matchPotentialSourceFile prunes out tests and unbuilt code.
|
||||
# Make sure that they are vendored if they are embedded files.
|
||||
cd ../embed_unbuilt
|
||||
go mod vendor
|
||||
cmp vendor/example.com/dep/unbuilt.go dep/unbuilt.go
|
||||
cmp vendor/example.com/dep/dep_test.go dep/dep_test.go
|
||||
! exists vendor/example.com/dep/not_embedded_unbuilt.go
|
||||
! exists vendor/example.com/dep/not_embedded_dep_test.go
|
||||
-- go.mod --
|
||||
module example.com/foo
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
example.com/a v0.1.0
|
||||
)
|
||||
|
||||
replace (
|
||||
example.com/a v0.1.0 => ./a
|
||||
)
|
||||
-- foo.go --
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"example.com/a"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(a.Str())
|
||||
}
|
||||
-- a/go.mod --
|
||||
module example.com/a
|
||||
-- a/a.go --
|
||||
package a
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed samedir_embed.txt
|
||||
var sameDir string
|
||||
|
||||
//go:embed subdir/embed.txt
|
||||
var subDir string
|
||||
|
||||
func Str() string {
|
||||
return sameDir + subDir
|
||||
}
|
||||
-- a/a_test.go --
|
||||
package a
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed subdir/test/embed.txt
|
||||
var subderTest string
|
||||
-- a/a_x_test.go --
|
||||
package a_test
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed subdir/test/xtest/embed.txt
|
||||
var subdirXtest string
|
||||
-- a/samedir_embed.txt --
|
||||
embedded file in same directory as package
|
||||
-- a/subdir/embed.txt --
|
||||
embedded file in subdirectory of package
|
||||
-- a/subdir/test/embed.txt --
|
||||
embedded file of test in subdirectory of package
|
||||
-- a/subdir/test/xtest/embed.txt --
|
||||
embedded file of xtest in subdirectory of package
|
||||
-- broken_no_matching_files/go.mod --
|
||||
module example.com/broken
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
example.com/brokendep v0.1.0
|
||||
)
|
||||
|
||||
replace (
|
||||
example.com/brokendep v0.1.0 => ./brokendep
|
||||
)
|
||||
-- broken_no_matching_files/f.go --
|
||||
package broken
|
||||
|
||||
import _ "example.com/brokendep"
|
||||
|
||||
func F() {}
|
||||
-- broken_no_matching_files/brokendep/go.mod --
|
||||
module example.com/brokendep
|
||||
go 1.16
|
||||
-- broken_no_matching_files/brokendep/f.go --
|
||||
package brokendep
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed foo.txt
|
||||
var foo string
|
||||
-- broken_bad_pattern/go.mod --
|
||||
module example.com/broken
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
example.com/brokendep v0.1.0
|
||||
)
|
||||
|
||||
replace (
|
||||
example.com/brokendep v0.1.0 => ./brokendep
|
||||
)
|
||||
-- broken_bad_pattern/f.go --
|
||||
package broken
|
||||
|
||||
import _ "example.com/brokendep"
|
||||
|
||||
func F() {}
|
||||
-- broken_bad_pattern/brokendep/go.mod --
|
||||
module example.com/brokendep
|
||||
go 1.16
|
||||
-- broken_bad_pattern/brokendep/f.go --
|
||||
package brokendep
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed ../foo.txt
|
||||
var foo string
|
||||
-- embed_unbuilt/go.mod --
|
||||
module example.com/foo
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
example.com/dep v0.1.0
|
||||
)
|
||||
|
||||
replace (
|
||||
example.com/dep v0.1.0 => ./dep
|
||||
)
|
||||
-- embed_unbuilt/foo.go --
|
||||
package a
|
||||
|
||||
import _ "example.com/dep"
|
||||
|
||||
func F() {}
|
||||
-- embed_unbuilt/dep/go.mod --
|
||||
module example.com/dep
|
||||
go 1.16
|
||||
-- embed_unbuilt/dep/dep.go --
|
||||
package dep
|
||||
|
||||
import _ "embed"
|
||||
|
||||
//go:embed unbuilt.go
|
||||
var unbuilt string
|
||||
|
||||
//go:embed dep_test.go
|
||||
var depTest string
|
||||
-- embed_unbuilt/dep/unbuilt.go --
|
||||
// +build ignore
|
||||
|
||||
package dep
|
||||
-- embed_unbuilt/dep/not_embedded_unbuilt.go --
|
||||
// +build ignore
|
||||
|
||||
package dep
|
||||
-- embed_unbuilt/dep/dep_test.go --
|
||||
package dep
|
||||
-- embed_unbuilt/dep/not_embedded_dep_test.go --
|
||||
package dep
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user