fetch the full graph of packages needed to build A. Essentially “just” graph traversal. Getting “new” stuff is more complex... Managing the chaos of code changes |-F-| D E | | B C | | A----
- therefore, can’t have two versions of the same package in one binary. Managing the chaos of code changes |-F.1-| F.2 D E.1 | | | E.3 G.3 B C.1 | | | | C.2- A------
need to re-build the graph. A *cannot* be built if we’re upgrading C.1 to C.2 Managing the chaos of code changes |-F.1-| F.2 D E.1 | | | E.3 G.3 B C.1 | | | | C.2- A------
How do I safely use code from external sources? - How do I publish code that others can use? - What happens when a dep “dies” like uuid? Managing the chaos of code changes |-F-| D E | | B - C | A
submodule-ing, import path rewriting was used to keep the source we built programs from consistent from build-to-build. Handling updates for deps-of-deps is an error-prone process. dep management before go mod
go get Redirects to github.com/foo/bar with branch / tag vN, vN.M, vN.M.O Helps us avoid getting a major version update we aren’t ready for, but still get minor updates. If $foo/$bar’s dependencies don’t use Gopkg.in, still vulnerable to breakage from changes in dependencies. dep management before go mod
is run from a directory d/, it resolves import paths - in a vendor/ directory rooted at d/ - in vendor/ directories rooted at parents of d/ - in the $GOPATH Put all your dependencies in vendor/ and what’s in $GOPATH won’t affect your build. (But you still need to be in $GOPATH!) dep management before go mod
vendor/ directory for reproducible builds - Include a manifest specifying constraints for *direct dependencies* (Gopkg.toml) - output a version lockfile of some kind. (Gopkg.lock) - Updates the lockfile by finding a set of versions that satisfy the constraints in the constraint file. But how do you find that set of versions? dep management before go mod
import paths - Accumulate constraints from modules along the way. (pom.xml, Gopkg.toml, Cargo.toml) - Find a set of N in the graph that can satisfy the constraints - This problem is NP complete! - But we have some good heuristic approaches using SAT solvers Most dependency management systems
Semantic Import Versioning github.com/foo (v0 and v1) github.com/foo/v2 2. exclusions only used from the *main module* 3. Requirements *must specify one and only one version*. require github.com/foo/v2 v2.1.1 (roughly means >=v2.1.1) Minimal Version Selection
(MVS). A.1 -> A.1 -> A.1 -> A.1 B.2 B.2 B.2 C.1 C.1 C.1.2 C.1.2 Traverse the graph, building a list of all imports and their required versions. Keep the maximum version listed in any requirements. Never select a version that is newer than *any* of the requirements. Minimal Version Selection
to set up your module’s go.mod file Add a dependency with an import statement while programming. go build, go test will fetch missing imports and update go.mod Get more specific: go get github.com/foo/[email protected] Great stuff
your dependencies. (flashbacks to ~/.m2/*) You can still put dependencies in a vendor/ folder and check them in. Great for CI Helps solve the “left-pad problem” where a module goes away. go mod vendor Great stuff
the dependencies specify! This can help with the “malicious bitcoin miner” problem but may also slow the speed of fixes through the ecosystem. Updating a dep to the newest version is simple: go get -u module/name MVS is fast (linear time!) MVS gives the base binary control over exclusion and replacement, not your dependencies. Great stuff
import my/foo/v3/mypkg I suspect this will lead to slower adoption of major versions by most users, and fewer changes Requires some serious finagling of your builds to support both Go modules and older Go code if you have releases >= v2.0.0 For Libraries
tools need to move off of go/build and onto golang.org/x/tools/go/packages Particularly hard on us vim users … the big corporate IDEs are in great shape! Tooling
you were relying on .c, .protos, etc in subdirectories, you’ll need to use some tools to help you pull those back in. Repos with multiple modules under edit need to do a tricky replace dance in their modules files. Distributing versioned go tools “for free” by abusing your dependency manager doesn’t really work well with go mod Local code management
infra. (How do I know what’s in my build?) Plans for a Google-hosted proxy & separate notary service to provide verifiable source code hashes. (How do I safely use code from external sources?) (How do I know what’s in my build?) Module proxies & notary