Skip to content

Commit 0067586

Browse files
author
Bryan C. Mills
committed
cmd/go: add a Latest field to the output of 'go mod download -json'
Fixes #32239 Change-Id: I5723abaa9b6bed7e8fb2d95f749a4e03ecc8741b Reviewed-on: https://go-review.googlesource.com/c/go/+/183841 Run-TryBot: Bryan C. Mills <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Jay Conrod <[email protected]>
1 parent 726b1bf commit 0067586

File tree

5 files changed

+69
-1
lines changed

5 files changed

+69
-1
lines changed

src/cmd/go/alldocs.go

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cmd/go/internal/modcmd/download.go

+25
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ corresponding to this Go struct:
4343
Dir string // absolute path to cached source root directory
4444
Sum string // checksum for path, version (as in go.sum)
4545
GoModSum string // checksum for go.mod (as in go.sum)
46+
Latest bool // would @latest resolve to this version?
4647
}
4748
4849
See 'go help modules' for more about module queries.
@@ -65,6 +66,7 @@ type moduleJSON struct {
6566
Dir string `json:",omitempty"`
6667
Sum string `json:",omitempty"`
6768
GoModSum string `json:",omitempty"`
69+
Latest bool `json:",omitempty"`
6870
}
6971

7072
func runDownload(cmd *base.Command, args []string) {
@@ -98,6 +100,26 @@ func runDownload(cmd *base.Command, args []string) {
98100
work.Add(m)
99101
}
100102

103+
latest := map[string]string{} // path → version
104+
if *downloadJSON {
105+
// We need to populate the Latest field, but if the main module depends on a
106+
// version newer than latest — or if the version requested on the command
107+
// line is itself newer than latest — that's not trivial to determine from
108+
// the info returned by ListModules. Instead, we issue a separate
109+
// ListModules request for "latest", which should be inexpensive relative to
110+
// downloading the modules.
111+
var latestArgs []string
112+
for _, m := range mods {
113+
latestArgs = append(latestArgs, m.Path+"@latest")
114+
}
115+
116+
for _, info := range modload.ListModules(latestArgs, listU, listVersions) {
117+
if info.Version != "" {
118+
latest[info.Path] = info.Version
119+
}
120+
}
121+
}
122+
101123
work.Do(10, func(item interface{}) {
102124
m := item.(*moduleJSON)
103125
var err error
@@ -128,6 +150,9 @@ func runDownload(cmd *base.Command, args []string) {
128150
m.Error = err.Error()
129151
return
130152
}
153+
if latest[m.Path] == m.Version {
154+
m.Latest = true
155+
}
131156
})
132157

133158
if *downloadJSON {

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ stderr 'this.domain.is.invalid'
1717
stdout '"Error": ".*this.domain.is.invalid.*"'
1818

1919
# download -json with version should print JSON
20+
# and download the .info file for the 'latest' version.
2021
go mod download -json 'rsc.io/quote@<=v1.5.0'
2122
stdout '^\t"Path": "rsc.io/quote"'
2223
stdout '^\t"Version": "v1.5.0"'
@@ -27,13 +28,14 @@ stdout '^\t"Sum": "h1:6fJa6E\+wGadANKkUMlZ0DhXFpoKlslOQDCo259XtdIE="' # hash of
2728
stdout '^\t"GoModSum": "h1:LzX7hefJvL54yjefDEDHNONDjII0t9xZLPXsUe\+TKr0="'
2829
! stdout '"Error"'
2930

31+
exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
32+
3033
# download queries above should not have added to go.mod.
3134
go list -m all
3235
! stdout rsc.io
3336

3437
# add to go.mod so we can test non-query downloads
3538
go mod edit -require rsc.io/[email protected]
36-
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.info
3739
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.mod
3840
! exists $GOPATH/pkg/mod/cache/download/rsc.io/quote/@v/v1.5.2.zip
3941

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
env GO111MODULE=on
2+
3+
# If the module is the latest version of itself,
4+
# the Latest field should be set.
5+
go mod download -json rsc.io/[email protected]
6+
stdout '"Latest":\s*true'
7+
8+
# If the module is older than latest, the field should be unset.
9+
go mod download -json rsc.io/[email protected]
10+
! stdout '"Latest":'
11+
12+
# If the module is newer than "latest", the field should be unset...
13+
go mod download -json rsc.io/[email protected]
14+
! stdout '"Latest":'
15+
16+
# ...even if that version is also what is required by the main module.
17+
go mod init example.com
18+
go mod edit -require rsc.io/[email protected]
19+
go mod download -json rsc.io/[email protected]
20+
! stdout '"Latest":'
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,28 @@
11
env GO111MODULE=on
22

3+
# If the current version is not latest, 'go list -u' should include its upgrade.
34
go list -m -u all
45
stdout 'rsc.io/quote v1.2.0 \[v1\.5\.2\]'
56

7+
# If the current version is latest, 'go list -u' should omit the upgrade.
8+
go get -d rsc.io/[email protected]
9+
go list -m -u all
10+
stdout 'rsc.io/quote v1.5.2$'
11+
12+
# If the current version is newer than latest, 'go list -u' should
13+
# omit the upgrade.
14+
go get -d rsc.io/[email protected]
15+
go list -m -u all
16+
stdout 'rsc.io/quote v1.5.3-pre1$'
17+
18+
# If the current build list has a higher version and the user asks about
19+
# a lower one, -u should report the upgrade for the lower one
20+
# but leave the build list unchanged.
21+
go list -m -u rsc.io/[email protected]
22+
stdout 'rsc.io/quote v1.5.1 \[v1.5.2\]$'
23+
go list -m -u rsc.io/quote
24+
stdout 'rsc.io/quote v1.5.3-pre1$'
25+
626
-- go.mod --
727
module x
828
require rsc.io/quote v1.2.0

0 commit comments

Comments
 (0)