Skip to content

Commit 98a7303

Browse files
author
Jay Conrod
committed
cmd/go: in 'go get', promote named implicit dependencies to explicit
'go get pkg@vers' will now add an explicit requirement for the module providing pkg if that version was already indirectly required. 'go get mod@vers' will do the same if mod is a module path but not a package. Requirements promoted this way will be marked "// indirect" because 'go get' doesn't know whether they're needed to build packages in the main module. So users should prefer to run 'go get ./pkg' (where ./pkg is a package in the main module) to promote requirements. Fixes #43131 Change-Id: Ifbb65b71274b3cc752a7a593d6ddd875f7de23b8 Reviewed-on: https://go-review.googlesource.com/c/go/+/278812 Run-TryBot: Jay Conrod <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Jay Conrod <[email protected]> Reviewed-by: Bryan C. Mills <[email protected]>
1 parent fd6ba1c commit 98a7303

File tree

5 files changed

+39
-8
lines changed

5 files changed

+39
-8
lines changed

src/cmd/go/internal/modload/buildlist.go

+11
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ import (
2828
//
2929
var buildList []module.Version
3030

31+
// additionalExplicitRequirements is a list of modules paths for which
32+
// WriteGoMod should record explicit requirements, even if they would be
33+
// selected without those requirements. Each path must also appear in buildList.
34+
var additionalExplicitRequirements []string
35+
3136
// capVersionSlice returns s with its cap reduced to its length.
3237
func capVersionSlice(s []module.Version) []module.Version {
3338
return s[:len(s):len(s)]
@@ -121,6 +126,12 @@ func EditBuildList(ctx context.Context, add, mustSelect []module.Version) error
121126

122127
if !inconsistent {
123128
buildList = final
129+
additionalExplicitRequirements = make([]string, 0, len(mustSelect))
130+
for _, m := range mustSelect {
131+
if m.Version != "none" {
132+
additionalExplicitRequirements = append(additionalExplicitRequirements, m.Path)
133+
}
134+
}
124135
return nil
125136
}
126137

src/cmd/go/internal/modload/init.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"os"
1616
"path"
1717
"path/filepath"
18+
"sort"
1819
"strconv"
1920
"strings"
2021
"sync"
@@ -27,6 +28,7 @@ import (
2728
"cmd/go/internal/modfetch"
2829
"cmd/go/internal/mvs"
2930
"cmd/go/internal/search"
31+
"cmd/go/internal/str"
3032

3133
"golang.org/x/mod/modfile"
3234
"golang.org/x/mod/module"
@@ -845,13 +847,15 @@ func AllowWriteGoMod() {
845847
// MinReqs returns a Reqs with minimal additional dependencies of Target,
846848
// as will be written to go.mod.
847849
func MinReqs() mvs.Reqs {
848-
var retain []string
850+
retain := append([]string{}, additionalExplicitRequirements...)
849851
for _, m := range buildList[1:] {
850852
_, explicit := index.require[m]
851853
if explicit || loaded.direct[m.Path] {
852854
retain = append(retain, m.Path)
853855
}
854856
}
857+
sort.Strings(retain)
858+
str.Uniq(&retain)
855859
min, err := mvs.Req(Target, retain, &mvsReqs{buildList: buildList})
856860
if err != nil {
857861
base.Fatalf("go: %v", err)

src/cmd/go/internal/modload/query.go

+3-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"cmd/go/internal/imports"
2222
"cmd/go/internal/modfetch"
2323
"cmd/go/internal/search"
24+
"cmd/go/internal/str"
2425
"cmd/go/internal/trace"
2526

2627
"golang.org/x/mod/module"
@@ -1005,13 +1006,8 @@ func (rr *replacementRepo) Versions(prefix string) ([]string, error) {
10051006
sort.Slice(versions, func(i, j int) bool {
10061007
return semver.Compare(versions[i], versions[j]) < 0
10071008
})
1008-
uniq := versions[:1]
1009-
for _, v := range versions {
1010-
if v != uniq[len(uniq)-1] {
1011-
uniq = append(uniq, v)
1012-
}
1013-
}
1014-
return uniq, nil
1009+
str.Uniq(&versions)
1010+
return versions, nil
10151011
}
10161012

10171013
func (rr *replacementRepo) Stat(rev string) (*modfetch.RevInfo, error) {

src/cmd/go/internal/str/str.go

+14
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,20 @@ func Contains(x []string, s string) bool {
9696
return false
9797
}
9898

99+
// Uniq removes consecutive duplicate strings from ss.
100+
func Uniq(ss *[]string) {
101+
if len(*ss) <= 1 {
102+
return
103+
}
104+
uniq := (*ss)[:1]
105+
for _, s := range *ss {
106+
if s != uniq[len(uniq)-1] {
107+
uniq = append(uniq, s)
108+
}
109+
}
110+
*ss = uniq
111+
}
112+
99113
func isSpaceByte(c byte) bool {
100114
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
101115
}

src/cmd/go/testdata/script/mod_get_promote_implicit.txt

+6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ go get -d m/use-indirect
1414
cmp go.mod go.mod.use
1515
cp go.mod.orig go.mod
1616

17+
# We can also promote implicit requirements using 'go get' on them, or their
18+
# packages. This gives us "// indirect" requirements, since 'go get' doesn't
19+
# know they're needed by the main module. See #43131 for the rationale.
20+
go get -d indirect-with-pkg indirect-without-pkg
21+
cmp go.mod go.mod.indirect
22+
1723
-- go.mod.orig --
1824
module m
1925

0 commit comments

Comments
 (0)