go list -json=<fields> zeroes out the fields in the package struct
that aren't specified. The problem with this is that some of the fields
have references into other fields: specifically, the NoGoError's
Error() function accesses the package struct's Dir field, so if we
clear it out the error will just print out "no Go files in" without a
directory. Instead, make a copy of the package struct before we zero
out the fields so the original values are still there.
For #64946
Change-Id: I95103e91fa0782bb23a86a965d5eb87cb12654c6
Cq-Include-Trybots: luci.golang.try:gotip-linux-amd64-longtest,gotip-windows-amd64-longtest
Reviewed-on: https://go-review.googlesource.com/c/go/+/553795
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
if listJson {
do = func(x any) {
if !listJsonFields.needAll() {
- v := reflect.ValueOf(x).Elem() // do is always called with a non-nil pointer.
- // Clear all non-requested fields.
+ // Set x to a copy of itself with all non-requested fields cleared.
+ v := reflect.New(reflect.TypeOf(x).Elem()).Elem() // do is always called with a non-nil pointer.
+ v.Set(reflect.ValueOf(x).Elem())
for i := 0; i < v.NumField(); i++ {
if !listJsonFields.needAny(v.Type().Field(i).Name) {
v.Field(i).SetZero()
}
}
+ x = v.Interface()
}
b, err := json.MarshalIndent(x, "", "\t")
if err != nil {
--- /dev/null
+cd mod
+go list -e -json=ImportPath,Error ./foo
+stdout '"Err": "no Go files in .*(/|\\\\)src(/|\\\\)mod(/|\\\\)foo"'
+
+-- mod/go.mod --
+module example.com/foo
+
+go 1.21
+-- mod/foo/README.md --
+empty
\ No newline at end of file