From adb9a566d929600bfeb51f07e5ec1575641eda25 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Mon, 15 Jan 2018 12:58:23 -0800 Subject: [PATCH] docs: Add Gopkg.lock.md --- docs/Gopkg.lock.md | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/docs/Gopkg.lock.md b/docs/Gopkg.lock.md index e69de29b..ac38519f 100644 --- a/docs/Gopkg.lock.md +++ b/docs/Gopkg.lock.md @@ -0,0 +1,80 @@ +--- +title: Gopkg.lock +--- + +The `Gopkg.lock` file is generated by `dep ensure` and `dep init`. It is the output of [the solving function](ensure-mechanics.md#functional-flow): a transitively complete snapshot of a project's dependency graph, expressed as a series of `[[project]]` stanzas; every package a project needs to compile, plus anything [`required`](Gopkg.toml.md#required) and less anything [`ignored`](Gopkg.toml.md#ignored). The file also contains some metadata about the algorithm used to arrive at the final graph, under `[solve-meta]`. + +`Gopkg.lock` always includes a `revision` for all listed dependencies, as the semantics of `revision` guarantee them to be immutable. Thus, the `Gopkg.lock` acts as a reproducible build list - as long as the upstream remains available, all dependencies can be precisely reproduced. + +`Gopkg.lock` is strictly autogenerated; editing it manually is an antipattern. If there is a goal you can only achieve by hand-editing `Gopkg.lock`, it is at least a feature request, and likely a bug. + +## `[[project]]` + +The dependency graph is expressed as a series of `[[project]]` stanzas, each representing a single dependency project. A given project can only appear once in the list, and the version information expressed about them encompasses all contained packages - it is not possible to have multiple packages from a single project at different versions. + +These are all the properties that can appear in a `[[project]]` stanza, and whether or not they are guaranteed to be present/must be present for a stanza to be valid. + +| **Property** | **Always present?** | +| ------------ | ------------------- | +| `name` | Y | +| `packages` | Y | +| `source` | N | +| `revision` | Y | +| `version` | N | +| `branch` | N | + +### `name` + +The project to which the stanza applies, as identified by its [project root](glossary.md#project-root). + +### `source` + +If present, it indicates the upstream source from which the project should be retrieved. It has the same properties as [`source` in `Gopkg.toml`](Gopkg.toml.md#source). + +### `packages` + +A complete list of directories from within the source that dep determined to be necessary for the build. + +In general, this is the set of packages that were found to be participants in the package import graph, through at least one but as many as all of the following mechanisms: + +* Being in the current project's [`required`](Gopkg.toml.md#required) list +* Being imported by a package from either the current project or a different dependency +* Being imported by a package from within this project that, directly or transitively, is imported by a package from a different project + +### Version information: `revision`, `version`, and `branch` + +In order to provide reproducible builds, it is an absolute requirement that every project stanza contain a `revision`, no matter what kinds of constraints were encountered in `Gopkg.toml` files. It is further possible that exactly one of either `version` or `branch` will _additionally_ be present. + +When one of the other two are present, the `revision` is understood to be the underlying, immutable identifier that corresponded to that `version` or `branch` _at the time when the `Gopkg.lock` was written_. + +## `[solve-meta]` + +Metadata contained in this section tells us about the algorithm that was used to generate the `Gopkg.lock` file. These are very coarse indicators, primarily used to trigger a re-evaluation of the lock when it might have become invalid, as well as warn a team when its members are using algorithms with potentially subtly different effects. + +More details on "analyzer" and "solver" follow, but the versioning principle is the same: algorithmic changes that result in a decrease to the set of acceptable solutions for at least one input set generally require a version bump, while changes that increase the size of that set do not. However, this is not a formal definition; we leave room for judgment calls on small changes and bug fixes, and we bump at most once per release. + +By bumping versions only on solution set contractions, but not expansions, it allows us to avoid having to bump constantly (which could make using dep across teams awkward), while still making it likely that when the solver and version numbers match between `Gopkg.lock` and a running version of dep, what's recorded in the file is acceptable by the running version's rules. + +### `analyzer-name` and `analyzer-version` + +The analyzer is an internal dep component responsible for interpreting the contents of `Gopkg.toml` files, as well as metadata files from any tools dep knows about: `glide.yaml`, `vendor.json`, etc. + +The analyzer is named because the dep needs to identify itself to its engine, gps (`github.com/golang/dep/gps`); gps knows nothing about dep. The analyzer version is bumped when something in the analyzer's logic begins treating data that it already accepted in a significantly different way, or stops accepting a particular class of data. It is _not_ changed when support for entirely new types of data are added. + +For example, if dep's analyzer stopped supporting automated conversions from glide, then that would not require bumping the analyzer version, as doing so makes _more_ solutions possible. Adding support for converting from a new tool, or changing the interpretation of `version` fields in `Gopkg.toml` so that it was only allowed to specify minimum versions, would entail a version bump. + +### `solver-name` and `solver-version` + +The solver is the algorithm behind [the solving function](ensure-mechanics.md#functional-flow). It selects all the versions that ultimately appear in `Gopkg.lock` by finding a combination that satisfies all the rules, including those from `Gopkg.toml` (fed to the solver by the analyzer). + +The solver is named because, like the analyzer, it is pluggable; an alternative algorithm could be written that applies different rules to achieve the same goal. The one dep uses, "gps-cdcl", is named after [the general class of SAT solving algorithm it most resembles](https://en.wikipedia.org/wiki/Conflict-Driven_Clause_Learning), though the algorithm is actually a specialized, domain-specific [SMT solver](https://en.wikipedia.org/wiki/Satisfiability_modulo_theories). + +The same general principles of version-bumping apply to the solver version: if the solver starts enforcing [Go 1.4 import path comments](https://golang.org/cmd/go/#hdr-Import_path_checking), that entails a bump, because it can only narrow the solution set. If it were to later relax that requirement, it would not require a bump, as that can only expand the solution set. + +### `inputs-digest` + +A SHA256 hash digest of all the [inputs to the solving function](ensure-mechanics.md#functional-flow). Those inputs can be shown directly with the hidden command `dep hash-inputs`, allowing this hash digest to be externally generated: + +``` +dep hash-inputs | tr -d ā€œ\nā€ | shasum -a256 +``` \ No newline at end of file