Skip to content

cmd/go: go list -e -m -json all to start displaying hashes of modules #52792

@HakanSunay

Description

@HakanSunay

Proposal source: Gophers Slack

I came to notice that the go tool does not list module hash sums when the list -e -m -json all command is invoked.

$ go mod init hash

$ go get github.com/vmware/govmomi@latest                                                                                                                         ─╯
go: downloading github.com/vmware/govmomi v0.28.0
go: added github.com/vmware/govmomi v0.28.0

$ go list -e -m -json all
{
	"Path": "hash",
	"Main": true,
	"Dir": "/Users/hhalil/test",
	"GoMod": "/Users/hhalil/test/go.mod",
	"GoVersion": "1.18"
}
{
	"Path": "github.com/a8m/tree",
	"Version": "v0.0.0-20210115125333-10a5fd5b637d",
	"Time": "2021-01-15T12:53:33Z",
	"Indirect": true
}
{
	"Path": "github.com/dougm/pretty",
	"Version": "v0.0.0-20171025230240-2ee9d7453c02",
	"Time": "2017-10-25T23:02:40Z",
	"Indirect": true
}
{
	"Path": "github.com/google/uuid",
	"Version": "v1.3.0",
	"Time": "2021-07-12T22:33:52Z",
	"Indirect": true
}
{
	"Path": "github.com/kr/pretty",
	"Version": "v0.3.0",
	"Time": "2020-11-24T22:22:38Z",
	"Indirect": true
}
{
	"Path": "github.com/kr/text",
	"Version": "v0.2.0",
	"Time": "2020-02-14T20:31:06Z",
	"Indirect": true
}
{
	"Path": "github.com/rasky/go-xdr",
	"Version": "v0.0.0-20170217172119-4930550ba2e2",
	"Time": "2017-02-17T17:21:19Z",
	"Indirect": true
}
{
	"Path": "github.com/vmware/govmomi",
	"Version": "v0.28.0",
	"Time": "2022-04-27T15:48:05Z",
	"Indirect": true,
	"Dir": "/Users/hhalil/go/pkg/mod/github.com/vmware/govmomi@v0.28.0",
	"GoMod": "/Users/hhalil/go/pkg/mod/cache/download/github.com/vmware/govmomi/@v/v0.28.0.mod",
	"GoVersion": "1.17"
}
{
	"Path": "github.com/vmware/vmw-guestinfo",
	"Version": "v0.0.0-20170707015358-25eff159a728",
	"Time": "2017-07-07T01:53:58Z",
	"Indirect": true
}

That is not the case with go mod download -json

$ go mod download -json                                                                                                                                         ─╯
{
	"Path": "github.com/vmware/govmomi",
	"Version": "v0.28.0",
	"Info": "/Users/hhalil/go/pkg/mod/cache/download/github.com/vmware/govmomi/@v/v0.28.0.info",
	"GoMod": "/Users/hhalil/go/pkg/mod/cache/download/github.com/vmware/govmomi/@v/v0.28.0.mod",
	"Zip": "/Users/hhalil/go/pkg/mod/cache/download/github.com/vmware/govmomi/@v/v0.28.0.zip",
	"Dir": "/Users/hhalil/go/pkg/mod/github.com/vmware/govmomi@v0.28.0",
	"Sum": "h1:VgeQ/Rvz79U9G8QIKLdgpsN9AndHJL+5iMJLgYIrBGI=",
	"GoModSum": "h1:F7adsVewLNHsW/IIm7ziFURaXDaHEwcc+ym4r3INMdY="
}

The proposal here is to extend the underlying data structures of go list -m to present information such as Sum and GoModSum, just like go mod download -json. By definition, "The -m flag causes list to list modules instead of packages.", therefore I believe it makes sense for the module data to include hash information.

Also, it would be useful if go list -m can also function in workspace mode, meaning that it would present the hashes of the modules after MVS has been applied to all of them, but that is conditional logic on GOWORK.

The target struct to modify might be this:

type ModulePublic struct {
Path string `json:",omitempty"` // module path
Version string `json:",omitempty"` // module version
Versions []string `json:",omitempty"` // available module versions
Replace *ModulePublic `json:",omitempty"` // replaced by this module
Time *time.Time `json:",omitempty"` // time version was created
Update *ModulePublic `json:",omitempty"` // available update (with -u)
Main bool `json:",omitempty"` // is this the main module?
Indirect bool `json:",omitempty"` // module is only indirectly needed by main module
Dir string `json:",omitempty"` // directory holding local copy of files, if any
GoMod string `json:",omitempty"` // path to go.mod file describing module, if any
GoVersion string `json:",omitempty"` // go version used in module
Retracted []string `json:",omitempty"` // retraction information, if any (with -retracted or -u)
Deprecated string `json:",omitempty"` // deprecation message, if any (with -u)
Error *ModuleError `json:",omitempty"` // error loading module
}

... and its implementation of the Stringer interface:

func (m *ModulePublic) String() string {
s := m.Path
versionString := func(mm *ModulePublic) string {
v := mm.Version
if len(mm.Retracted) == 0 {
return v
}
return v + " (retracted)"
}
if m.Version != "" {
s += " " + versionString(m)
if m.Update != nil {
s += " [" + versionString(m.Update) + "]"
}
}
if m.Deprecated != "" {
s += " (deprecated)"
}
if m.Replace != nil {
s += " => " + m.Replace.Path
if m.Replace.Version != "" {
s += " " + versionString(m.Replace)
if m.Replace.Update != nil {
s += " [" + versionString(m.Replace.Update) + "]"
}
}
if m.Replace.Deprecated != "" {
s += " (deprecated)"
}
}
return s
}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions