I just can't figure out how to do this.  Maybe it can't be done in `go
list` ?  Or maybe we're just missing some detail of go modules..

I have a repo (kubernetes, but minimized at
https://github.com/thockin/go-list-modules) which has a "main" go
module, and several other modules in the same repo.  It's probable not
worth explaining the history right now, but here we are.

As part of the build, I need to run some code generators.  They are
slow, so I only want to run them if their inputs have actually
changed.  To do this, I need to build a list of all the individual
files that are transitively depended on by the package in question.

First I do a `find` for any file that has a specific comment tag,
indicating that the package needs codegen.  The results span several
of the in-repo submodules.

For each target package, I want to get the list of all deps and
extract the GoFiles.  Then I can use that to determine if the codegen
needs to run.

Where it breaks down is that I can't seem to `go list` all at once:

```
# This works within the "root" module
$ go list -f '{{.GoFiles}}' ./subdir
[file.go]

# This does not work across modules
$ go list -f '{{.GoFiles}}' ./submod/used ./submod/unused
main module (example.com/m) does not contain package example.com/m/submod/used
main module (example.com/m) does not contain package example.com/m/submod/unused

# Nor does this work, even with module replacements
$ go list -f '{{.GoFiles}}' ./staging/src/example.com/other1/used
./staging/src/example.com/other1/unused
main module (example.com/m) does not contain package
example.com/m/staging/src/example.com/other1/used
main module (example.com/m) does not contain package
example.com/m/staging/src/example.com/other1/unused
```

I can run `go list` multiple times, but that's INCREDIBLY slow - most
of these submodules have common deps that are large.  This re-parses
everything over and over.  It takes almost 60 seconds just to do `cd
$dir; go list` (on the real kubernetes repo).

I wrote a program against go/packages which does SLIGHTLY better, in
that it finds packages in other modules but ONLY if they a) are a dep
of something in the root module; and b) exist in vendor/.  Note here
that ./subir DOES depend on ./submod, but that is not listed.

```
$go2make2 -p ./subdir
Package "example.com/other1/used" {
  Name: "used"
  PkgPath: "example.com/other1/used"
  GoFiles: [
    "/tmp/m/go-list-modules/vendor/example.com/other1/used/file.go"
  ]
  Imports: [
  ]
}
Package "example.com/other2/used" {
  Name: "used"
  PkgPath: "example.com/other2/used"
  GoFiles: [
    "/tmp/m/go-list-modules/vendor/example.com/other2/used/file.go"
  ]
  Imports: [
  ]
}
Package "example.com/m/subdir" {
  Name: "subdir"
  PkgPath: "example.com/m/subdir"
  Module: "example.com/m"
  ModuleDir: "/tmp/m/go-list-modules"
  GoFiles: [
    "/tmp/m/go-list-modules/subdir/file.go"
  ]
  Imports: [
    "example.com/m/submod/used"
    "example.com/other1/used"
    "example.com/other2/used"
  ]
}
```

Also note that `Module` info is missing for the ones it does find.

So I guess I am looking for some magical incantation that lets me
process and load all of the files across multiple modules exactly
once.  I wrote a similar program against go/build which runs in < 3
seconds, but doesn't work properly outside of a GOPATH (not sure why).

Any clues on how to approach this better would be well appreciated.

Tim

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAO_RewakNiSEKk6uBFjcGbQP0AgxqT0tDcyWsY5JTz_NaZDn4A%40mail.gmail.com.

Reply via email to