Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
cmd/go: outer module can provide packages that appear to be in an inner module #29736
Consider two modules, one of which is nested in the other:
I think most people would find this surprising. I certainly did. I had thought that the presence of a nested module "punched a hole" in the containing module, but I guess that's only true if the
Is this a bug, or expected behavior?
This is working as designed. Consider what happens if you have a stable
One way to do that would be to create three modules:
As you move packages back and forth, you end up creating a module for every directory — not a great experience for the maintainer.
In contrast, with this sort of interleaving, you can have:
and just move
I expect that would be particularly useful when
I think this behavior is too confusing. I'd be much happier in a world where each module in the build list is a namespace of packages. You would be able to find out what module a package belongs to just by finding the longest matching prefix.
This also has an I/O cost. In order to determine whether a module contains a package, we need to list the directory, and then parse and apply build tags to confirm the package is buildable. I'm hoping that cost will be reduced with additional caching in 1.13, but still.
“longest matching prefix” seems like a non-starter. That would make it impossible to recombine modules that have been split. (Recombination is important: without it, any time you make a change to the internal interactions between two packages, you have to remember to tag and update the requirements of all of the involved modules.)
The I/O cost should not be terribly high. I don't think we should need to parse or apply build tags: it should be fine to issue an ambiguous import error if there are Go source files at the same import path in two different modules, even if one of the variants happens to be unbuildable in the current configuration.
Hmm, recombination is really important.
Let's suppose we had simpler "longest prefix" module resolution, and we didn't issue an error for ambiguous imports. If I import
The incremental migration approach described above is pretty difficult, too, though. In order to promote a package from module
Is there any better way?
In any case, +1 to Hana's suggestion document things like "how to recombine modules" in a "best practices" document.
Yep! (But, importantly, they only need to do that once, not every time they change the package thereafter.)
Also true. See also #27899.