Description
The modload
package has a lot of global state. In general, variables that are set once during initialization and global caches are fine. But buildList
and loader
in particular cause problems, since most exported functions either read values out of them or replace and overwrite them. It's frequently not obvious when this is happening.
This leads to some unfortunate situations. For example, see get.go in CL 228383. If modload.ListModules
is called before modload.WriteGoMod
, the go.mod
file will contain spurious // indirect
comments. This happens because WriteGoMod
uses loaded.direct
to decide whether to mark a requirement as indirect, but ListModules
calls LoadBuildList
, which replaces loaded
, so it appears that nothing is directly required.
I think these side effects should be more obvious to callers, and the loaded
and buildList
variables should be removed. Instead, the loader
struct type should be exported, and exported functions that create, read, or write it should be converted to methods.