You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To this point, dep has completely sidestepped the question of build tags. This is a big thing we need to deal with, and may affect the structure of lock and manifest files.
The basic issue: whereas the toolchain today operates within a concrete build environment (for any given run, there is one GOOS, one GOARCH, and a finite set of applied build tags), dep produces more broadly useful results when it computes not just the current environment, but across potential build environments - ideally, across all of them. In essence, the goal is that even if you're running dep on darwin/amd64, the lock file it produces should have sufficient information to be able to construct a vendor tree for linux/386, or freebsd/sparc64, or whatever (assuming they're any different).
Compare these examples - first, a lock.json now indicating three subpackages of a project are used:
With this additional information, it's immediately evident that the source code in golang.org/x/sys/unix - a rather large repository - isn't needed unless we need to build for solaris. Without this information, the tool would have to redo static analysis of the code in order to figure it out, which is just wasteful. Also, note that this example is not only real, but common; it results from relying on the very popular github.com/sirupsen/logrus - project.
Taking this approach means cross-compiling is possible by default. That's already something the go toolchain aims for, which strongly suggests that we're on the right track, and dep's strong default behavior should be to create portable lock files.
Now, if you/your project isn't cross-compiling or testing different os/arch combinations itself, then lock parameterization might seem a bit misleading - how do we know a lock's solution works on a different concrete build environment? Well, we don't, of course, but that's the wrong way to think about it; we don't know that a different os/arch would work today, either, and if a user on a different os/arch has a build that doesn't work, it's still strictly better if that build is reproducible than not.
Achieving lock parameterization first requires that gps start supporting a notion of it in the first place. There's a solid chunk of work to do on this:
The parser in gps.ListPackages() currently lumps all imports together in the returned PackageTree's PackageOrErrs, regardless of build tag context. It needs to be refactored to return a parameterized view of a given directory's go code (no issue created yet)
Following on the preceding, PackageTree.ToReachMap() also needs to parameterize its returned information (no issue created yet)
"A parameterized view" sounds nice, but it could actually be tricky to create a concise representation of a directory when accounting for negated build tags (e.g. // +build !debug, because negative-matching against a non-finite set (build tags) is nasty. We may just have to preserve such negations directly in the lock.
Once the basic support for this is in place, we can also think about the ways that project authors can indicate that they want to ignore a particular os/arch/build tag set, or (an even stronger statement) that they do not work with a certain tag set.
To this point,
dephas completely sidestepped the question of build tags. This is a big thing we need to deal with, and may affect the structure of lock and manifest files.The basic issue: whereas the toolchain today operates within a concrete build environment (for any given run, there is one
GOOS, oneGOARCH, and a finite set of applied build tags),depproduces more broadly useful results when it computes not just the current environment, but across potential build environments - ideally, across all of them. In essence, the goal is that even if you're runningdepondarwin/amd64, the lock file it produces should have sufficient information to be able to construct a vendor tree forlinux/386, orfreebsd/sparc64, or whatever (assuming they're any different).Compare these examples - first, a
lock.jsonnow indicating three subpackages of a project are used:{ "name": "golang.org/x/sys", "branch": "master", "revision": "e48874b42435b4347fc52bdee0424a52abc974d7", "packages": ["unix"] }And one where the requirement for those subpackages is parameterized:
{ "name": "golang.org/x/sys", "branch": "master", "revision": "e48874b42435b4347fc52bdee0424a52abc974d7", "parameterized-packages": [ { "os": "solaris", "packages": ["unix"] } ] }With this additional information, it's immediately evident that the source code in
golang.org/x/sys/unix- a rather large repository - isn't needed unless we need to build for solaris. Without this information, the tool would have to redo static analysis of the code in order to figure it out, which is just wasteful. Also, note that this example is not only real, but common; it results from relying on the very popular github.com/sirupsen/logrus - project.Taking this approach means cross-compiling is possible by default. That's already something the go toolchain aims for, which strongly suggests that we're on the right track, and
dep's strong default behavior should be to create portable lock files.Now, if you/your project isn't cross-compiling or testing different os/arch combinations itself, then lock parameterization might seem a bit misleading - how do we know a lock's solution works on a different concrete build environment? Well, we don't, of course, but that's the wrong way to think about it; we don't know that a different os/arch would work today, either, and if a user on a different os/arch has a build that doesn't work, it's still strictly better if that build is reproducible than not.
Achieving lock parameterization first requires that gps start supporting a notion of it in the first place. There's a solid chunk of work to do on this:
gps.ListPackages()currently lumps all imports together in the returnedPackageTree'sPackageOrErrs, regardless of build tag context. It needs to be refactored to return a parameterized view of a given directory's go code (no issue created yet)PackageTree.ToReachMap()also needs to parameterize its returned information (no issue created yet)// +build !debug, because negative-matching against a non-finite set (build tags) is nasty. We may just have to preserve such negations directly in the lock.Once the basic support for this is in place, we can also think about the ways that project authors can indicate that they want to ignore a particular os/arch/build tag set, or (an even stronger statement) that they do not work with a certain tag set.