Skip to content

Latest commit

 

History

History
105 lines (63 loc) · 8.14 KB

Gopkg.lock.md

File metadata and controls

105 lines (63 loc) · 8.14 KB
title
Gopkg.lock

The Gopkg.lock file is generated by dep ensure and dep init. It is the output of the solving function: a transitively complete snapshot of a project's dependency graph, expressed as a series of [[project]] stanzas. That means:

  • Every package a project needs to compile
  • Plus any required packages
  • Less any ignored packages

Gopkg.lock also contains some metadata about the algorithm and inputs 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 autogenerated; editing it manually is generally 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.

[[projects]]

The dependency graph is expressed as a series of [[projects]] 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 [[projects]] 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
pruneopts Y
digest Y

name

The project to which the stanza applies, as identified by its 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.

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 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

pruneopts

A compactly-encoded form of the prune options designated in Gopkg.toml . Each character represents one of the three possible rules:

Character Pruning Rule in Gopkg.toml
N non-go
U unused-packages
T go-tests

If the character is present in pruneopts, the pruning rule is enabled for that project. Thus, NUT indicates that all three pruning rules are active.

digest

The hash digest of the contents of vendor/ for this project, after pruning rules have been applied. The digest is versioned, by way of a colon-delimited prefix; the string is of the form <version>:<hex-encoded digest> . The hashing algorithm corresponding to version 1 is SHA256, as implemented in the stdlib package crypto/sha256.

There are some tweaks that differentiate the hasher apart from a naive filesystem tree hashing implementation:

  • Symlinks are ignored.
  • Line endings are normalized to LF (using an algorithm similar to git's) in order to ensure digests do not vary across platforms.

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.

input-imports

A sorted list of all the import inputs that were present at the time the Gopkg.lock was computed. This list includes both actual import statements from the project, as well as any required import paths listed in Gopkg.toml, excluding any that were ignored.

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. 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, though the algorithm is actually a specialized, domain-specific SMT solver.

The same general principles of version-bumping apply to the solver version: if the solver starts enforcing Go 1.4 import path comments, 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.