This patch updates the controller-gen package loader to support
loading packages across Go module boundaries for filesystem paths.
What does this actually mean? Imagine a project with the following
structure:
my-project/
|
|-- go.mod
|-- go.sum
|
|-- apis/
|
|-- v1alpha1/
|
|-- go.mod
|-- go.sum
Prior to this patch, the following command, executed from the root of
"my-project," would *not* include the package my-project/apis/v1alpha1:
controller-gen crd \
paths=./apis/... \
crd:trivialVersions=true \
output:crd:dir=./config/crd/bases
The reason the above command would not parse the types from the package
my-project/apis/v1alpha1 is because it is a distinct Go module from the
root module, where the command was executed. In fact, while the above
command would silently fail to include those types, the following
command will fail with an error:
controller-gen crd \
paths=./apis/v1alpha1 \
crd:trivialVersions=true \
output:crd:dir=./config/crd/bases
The above command fails because the underlying logic to load packages
cannot load a path from one package when executed from the working
directory of another package.
With this patch, it is now possible for the first command to
successfully traverse Go module boundaries for roots that are file-
system paths ending with "..." with the following, high-level logic:
1. If no roots are provided then load the working directory and
return early.
2. Otherwise sort the provided roots into two, distinct buckets:
a. package/module names
b. filesystem paths
A filesystem path is distinguished from a Go package/module name
by the same rules as followed by the "go" command. At a high
level, a root is a filesystem path IFF it meets ANY of the
following criteria:
* is absolute
* begins with .
* begins with ..
For more information please refer to the output of the command
"go help packages".
3. Load the package/module roots as a single call to packages.Load.
If there are no filesystem path roots then return early.
4. For filesystem path roots ending with "...", check to see if its
descendants include any nested, Go modules. If so, add the
directory that contains the nested Go module to the filesystem
path roots.
5. Load the filesystem path roots and return the load packages for
the package/module roots AND the filesystem path roots.