From af7528018abd0a32606a4890c6685def3cd7a4a2 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Mon, 1 Jan 2018 15:59:46 -0500 Subject: [PATCH 01/13] docs: incremental checkin of numerous new docs --- docs/FAQ.md | 5 + docs/Gopkg.lock.md | 0 docs/Gopkg.toml.md | 150 +++++++++++++------------ docs/assets | 1 + docs/day-to-day-dep.md | 105 +++++++++++++++++ docs/deduction.md | 12 ++ docs/dep-basics.md | 1 + docs/ensure-mechanics.md | 174 +++++++++++++++++++++++++++++ docs/glossary.md | 97 ++++++++++++++++ docs/img/annotated-func-arrows.png | Bin 0 -> 42366 bytes docs/img/base-arrows.png | Bin 0 -> 33999 bytes docs/img/four-states.png | Bin 0 -> 32855 bytes docs/img/func-toggles.png | Bin 0 -> 50383 bytes docs/img/lock-back.png | Bin 0 -> 35714 bytes docs/img/required-arrows.png | Bin 0 -> 47424 bytes docs/introduction.md | 9 ++ docs/migrating.md | 126 +++++++++++++++++++++ docs/new-project.md | 39 +++++++ 18 files changed, 648 insertions(+), 71 deletions(-) create mode 100644 docs/Gopkg.lock.md create mode 120000 docs/assets create mode 100644 docs/day-to-day-dep.md create mode 100644 docs/deduction.md create mode 100644 docs/dep-basics.md create mode 100644 docs/ensure-mechanics.md create mode 100644 docs/glossary.md create mode 100644 docs/img/annotated-func-arrows.png create mode 100644 docs/img/base-arrows.png create mode 100644 docs/img/four-states.png create mode 100644 docs/img/func-toggles.png create mode 100644 docs/img/lock-back.png create mode 100644 docs/img/required-arrows.png create mode 100644 docs/introduction.md create mode 100644 docs/migrating.md create mode 100644 docs/new-project.md diff --git a/docs/FAQ.md b/docs/FAQ.md index e9acbb61c2..22c5a27f92 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -1,3 +1,8 @@ +-- +id: faq.md +title: FAQ +-- + # FAQ _The first rule of FAQ is don't bikeshed the FAQ, leave that for diff --git a/docs/Gopkg.lock.md b/docs/Gopkg.lock.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/docs/Gopkg.toml.md b/docs/Gopkg.toml.md index cb0253e810..a2e27acf29 100644 --- a/docs/Gopkg.toml.md +++ b/docs/Gopkg.toml.md @@ -1,9 +1,70 @@ -# Gopkg.toml +--- +title: Gopkg.toml +--- + +The `Gopkg.toml` file is initially generated by `dep init`, and is primarily hand-edited. It contains several types of rule declarations that govern dep's behavior: + +* [`constraints`](#constraint) and [`overrides`](#override) allow the user to specify which versions of dependencies are acceptable, and where they should be retrieved from. +* [`required`](#required) and [`ignored`](#ignored) allow the user to manipulate the import graph by including or excluding import paths, respectively. +* [`metadata`](#metadata) is a user-defined map of key-value pairs that dep will preserve and ignore. + +Note that because of TOML does not adhere to a tree structure, the `required` and `ignored` fields must be declared before any `[[constraint]]` or `[[override]]`. + +--- + +## `constraint` + +A `constraint` provides rules for how a [direct dependency](FAQ.md#what-is-a-direct-or-transitive-dependency) may be incorporated into the dependency graph. dep respects these declarations from the current project's `Gopkg.toml`, as well as that of all dependencies. + +```toml +[[constraint]] + # Required: the root import path of the project being constrained. + name = "github.com/user/project" + # Recommended: the version constraint to enforce for the project. + # Only one of "branch", "version" or "revision" can be specified. + version = "1.0.0" + branch = "master" + revision = "abc123" + + # Optional: an alternate location (URL or import path) for the project's source. + source = "https://github.com/myfork/package.git" + + # Optional: metadata about the constraint or override that could be used by other independent systems + [metadata] + key1 = "value that convey data to other systems" + system1-data = "value that is used by a system" + system2-data = "value that is used by another system" +``` + +**Use this for:** having a [direct dependency](FAQ.md#what-is-a-direct-or-transitive-dependency) use a specific branch, version range, revision, or alternate source (such as a fork). + +## `override` + +An `override` has the same structure as a `constraint` declaration, but supersede all `constraint` declarations from all projects. Only `override` declarations from the current project's `Gopkg.toml` are applied. + +```toml +[[override]] + # Required: the root import path of the project being constrained. + name = "github.com/user/project" + # Optional: specifying a version constraint override will cause all other constraints on this project to be ignored; only the overridden constraint needs to be satisfied. Again, only one of "branch", "version" or "revision" can be specified. + version = "1.0.0" + branch = "master" + revision = "abc123" + # Optional: specifying an alternate source location as an override will enforce that the alternate location is used for that project, regardless of what source location any dependent projects specify. + source = "https://github.com/myfork/package.git" + + # Optional: metadata about the constraint or override that could be used by other independent systems + [metadata] + key1 = "value that convey data to other systems" + system1-data = "value that is used by a system" + system2-data = "value that is used by another system" +``` + +**Use this for:** all the same things as a [`constraint`](#constraint), but for [transitive dependencies](FAQ.md#what-is-a-direct-or-transitive-dependency). See [How do I constrain a transitive dependency's version?](FAQ.md#how-do-i-constrain-a-transitive-dependencys-version) for more details on how overrides differ from `constraint`s. _Overrides should be used cautiously, sparingly, and temporarily._ ## `required` -`required` lists a set of packages (not projects) that must be included in -Gopkg.lock. This list is merged with the set of packages imported by the current -project. + +`required` lists a set of packages (not projects) that must be included in Gopkg.lock. This list is merged with the set of packages imported by the current project. ```toml required = ["github.com/user/thing/cmd/thing"] ``` @@ -36,21 +97,19 @@ You might also try [virtualgo](https://github.com/GetStream/vg), which installs ignored = ["github.com/user/project/badpkg"] ``` -Use wildcard character (*) to define a package prefix to be ignored. Use this -to ignore any package and their subpackages. +Use wildcard character (*) to define a package prefix to be ignored. Use this to ignore any package and their subpackages. ```toml ignored = ["github.com/user/project/badpkg*"] ``` -**Use this for:** preventing a package and any of that package's unique -dependencies from being installed. +**Use this for:** preventing a package and any of that package's unique dependencies from being installed. ## `metadata` `metadata` can exist at the root as well as under `constraint` and `override` declarations. `metadata` declarations are ignored by dep and are meant for usage by other independent systems. -A `metadata` declaration at the root defines metadata about the project itself. While a `metadata` declaration under a `constraint` or an `override` defines metadata about that `constraint` or `override`. +The root `metadata` declaration defines informatino about the project itself, while a `metadata` declaration under a `[[constraint]]` or an `[[override]]` defines metadata about that rule, for the `name`d project. ```toml [metadata] key1 = "value that convey data to other systems" @@ -58,80 +117,26 @@ system1-data = "value that is used by a system" system2-data = "value that is used by another system" ``` -## `constraint` -A `constraint` provides rules for how a [direct dependency](FAQ.md#what-is-a-direct-or-transitive-dependency) may be incorporated into the -dependency graph. -They are respected by dep whether coming from the Gopkg.toml of the current project or a dependency. -```toml -[[constraint]] - # Required: the root import path of the project being constrained. - name = "github.com/user/project" - # Recommended: the version constraint to enforce for the project. - # Only one of "branch", "version" or "revision" can be specified. - version = "1.0.0" - branch = "master" - revision = "abc123" - # Optional: an alternate location (URL or import path) for the project's source. - source = "https://github.com/myfork/package.git" - # Optional: metadata about the constraint that could be used by other independent systems - [constraint.metadata] - key1 = "value that convey data to other systems" - system1-data = "value that is used by a system" - system2-data = "value that is used by another system" -``` - -**Use this for:** having a [direct dependency](FAQ.md#what-is-a-direct-or-transitive-dependency) -use a specific branch, version range, revision, or alternate source (such as a -fork). - -## `override` -An `override` has the same structure as a `constraint` declaration, but supersede all `constraint` declarations from all projects. Only `override` declarations from the current project's `Gopkg.toml` are applied. - -```toml -[[override]] - # Required: the root import path of the project being constrained. - name = "github.com/user/project" - # Optional: specifying a version constraint override will cause all other constraints on this project to be ignored; only the overridden constraint needs to be satisfied. Again, only one of "branch", "version" or "revision" can be specified. - version = "1.0.0" - branch = "master" - revision = "abc123" - # Optional: specifying an alternate source location as an override will enforce that the alternate location is used for that project, regardless of what source location any dependent projects specify. - source = "https://github.com/myfork/package.git" +---- - # Optional: metadata about the override that could be used by other independent systems - [override.metadata] - key1 = "value that convey data to other systems" - system1-data = "value that is used by a system" - system2-data = "value that is used by another system" -``` -**Use this for:** all the same things as a [`constraint`](#constraint), but for -[transitive dependencies](FAQ.md#what-is-a-direct-or-transitive-dependency). -See [How do I constrain a transitive dependency's version?](FAQ.md#how-do-i-constrain-a-transitive-dependencys-version) -for more details on how overrides differ from `constraint`s. _Overrides should -be used cautiously, sparingly, and temporarily._ ## `version` -`version` is a property of `constraint`s and `override`s. It is used to specify -version constraint of a specific dependency. +`version` is a property of `constraint`s and `override`s. It is used to specify version constraint of a specific dependency. -Internally, dep uses [Masterminds/semver](https://github.com/Masterminds/semver) -to work with semver versioning. +Internally, dep uses [Masterminds/semver](https://github.com/Masterminds/semver) to work with semver versioning. -`~` and `=` operators can be used with the versions. When a version is specified -without any operator, `dep` automatically adds a caret operator, `^`. The caret -operator pins the left-most non-zero digit in the version. For example: +`~` and `=` operators can be used with the versions. When a version is specified without any operator, `dep` automatically adds a caret operator, `^`. The caret operator pins the left-most non-zero digit in the version. For example: ``` ^1.2.3 means 1.2.3 <= X < 2.0.0 ^0.2.3 means 0.2.3 <= X < 0.3.0 ^0.0.3 means 0.0.3 <= X < 0.1.0 ``` -To pin a version of direct dependency in manifest, prefix the version with `=`. -For example: +To pin a version of direct dependency in manifest, prefix the version with `=`. For example: ```toml [[constraint]] name = "github.com/pkg/errors" @@ -147,7 +152,10 @@ Here's an example of a sample Gopkg.toml with most of the elements ```toml required = ["github.com/user/thing/cmd/thing"] -ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +ignored = [ + "github.com/user/project/pkgX", + "bitbucket.org/user/project/pkgA/pkgY" +] [metadata] codename = "foo" @@ -156,7 +164,7 @@ codename = "foo" name = "github.com/user/project" version = "1.0.0" - [constraint.metadata] + [metadata] property1 = "value1" property2 = 10 @@ -169,6 +177,6 @@ codename = "foo" name = "github.com/x/y" version = "2.4.0" - [override.metadata] + [metadata] propertyX = "valueX" ``` diff --git a/docs/assets b/docs/assets new file mode 120000 index 0000000000..cf2d7699c6 --- /dev/null +++ b/docs/assets @@ -0,0 +1 @@ +img \ No newline at end of file diff --git a/docs/day-to-day-dep.md b/docs/day-to-day-dep.md new file mode 100644 index 0000000000..1bcbc46ad1 --- /dev/null +++ b/docs/day-to-day-dep.md @@ -0,0 +1,105 @@ +--- +title: Day-to-day dep +--- + +In keeping with Go's general design philosophy of minimizing knobs, dep has a sparse interface - there are only two commands you're likely to run regularly. For existing projects, `dep ensure` is the primary workhorse command, and the only thing you'll run that actually changes disk state. `dep status` is a read-only command that can help you understand the current state of your project. + +Sparse interface notwithstanding, acclimating to `dep ensure` can take some practice. The verb here is "ensure", as we're asking dep to "make sure that my `Gopkg.lock` satisfies all the imports from my project and the rules in `Gopkg.toml`, and that `vendor/` contains exactly what `Gopkg.lock` says it should." In other words, dep is designed around the idea that it's fine to run `dep ensure` at most any time, and it will bring your project and its dependencies into a good state, while doing as little work as possible to achieve that guarantee (though [we're still optimizing "as little as possible"]()). + +That's pretty vague, though. Let's make it clearer by exploring some concrete examples. We'll start by moving to the root of a hypothetical project, then running `dep ensure`: + +``` +$ cd $GOPATH/src/github.com/me/example +$ dep ensure +``` + +If `dep ensure` exits 0, then we're guaranteed (with [one fixable caveat]()), that our project is "in sync" - `vendor/` is populated with a depgraph that satisfies all imports and rules. So, let's assume `dep ensure` exited 0, and our project is now in sync. That means we're ready to develop normally: edit `.go` files, run `go test` and `go build`, etc. We don't need to think about dep again until one of the following happens: + +- We want to add a new dependency +- We want to upgdate an existing dependency +- We've imported a package for the first time, or removed the last import of a package +- We've made a change to a rule in `Gopkg.toml` + +There's a bit of [TIMTOWTDI](https://en.wiktionary.org/wiki/TMTOWTDI) here, as it's possible, and sometimes preferable, to handle each of these cases with a plain `dep ensure`, but dep also allows some additional parameters to make some of these cases a bit more ergonomic. We'll explore each in turn. + +### Adding a new dependency + +Let's say that we want to introduce a new dependency on `github.com/pkg/errors`. We can accomplish this with one command: + +``` +$ dep ensure -add github.com/pkg/errors +``` + +_Much like git, `dep status` and `dep ensure` can also be run from any subdirectory of your project root, which is determined by the presence of a `Gopkg.toml` file._ + +This should succeed, resulting in an updated `Gopkg.lock` and `vendor/` directory, as well as injecting a best-guess version constraint for `github.com/pkg/errors` into our `Gopkg.toml`. But, it will also report a warning: + +``` +"github.com/pkg/errors" is not imported by your project, and has been temporarily added to Gopkg.lock and vendor/. +If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/. +``` + +This reflects the nature of `dep ensure` - `github.com/pkg/errors` isn't in our project's imports, and as such, a subsequent `dep ensure` will classify it as unnecessary, and remove it. If we're ready to use the package, though, then this shouldn't be a problem - add an `import "github.com/pkg/errors"` to a `.go` file, and the project's now back in sync. + +It's also possible to introduce the new dependency without relying on `-add`. If, as a first step, you add `import "github.com/pkg/errors"` to a `.go` file, then run a plain `dep ensure`, your project will be in almost the same state as with `-add`: `Gopkg.lock` and `vendor/` will include `github.com/pkg/errors`. The only difference is that `Gopkg.toml` will not have been updated with a guess at a version constraint. + +In a sense, the plain `dep ensure` approach is more natural here, as using `-add` effectively dupes dep into violating its guarantee - `dep ensure` exits 0, but the extra dependency means our project is out of sync. However, the plain approach has a chicken-or-egg problem. Many Go developers use something like [`goimports`]() to read the contents of a `.go` file and infer what import statements to add. `goimports`, in turn, works by searching vendor and GOPATH for packages that match the identifiers in a file - which requires that those packages already be present locally. + +**Both approaches can be useful in different situations. If you're genuinely experimenting with permanently adding a new dependency to your project, then `dep ensure -add` is probably best: you'll probably want that constraint ** + +### Updating dependencies + +First, a quick definition: in dep's world, updating a dependency is the act of changing the value of the `revision` field in `Gopkg.lock` for that project (and, by extension, the version in the `vendor` directory). There are two basic ways of achieving this: + +* Run `dep ensure -update `; this will update the project to the latest version allowed by the version constraints in `Gopkg.toml`. +* Edit `Gopkg.toml`, changing the version constraint to one that does not allow the version currently in `Gopkg.lock`, then run `dep ensure`. + +The CLI-driven approach is strongly preferred to hand-editing `Gopkg.toml`. Let's look at that first. + +#### CLI-driven updates + +`dep ensure -update` can be used to update multiple dependencies at once: + +``` +$ dep ensure -update github.com/foo/bar github.com/baz/quux +``` + +Or all dependencies (not recommended): + +``` +dep ensure -update +``` + +The CLI-driven approach is preferred because it is much more convenient, less expressive (read: safer), and better for the Go packaging ecosystem. However, it doesn't always work, as the semantics of `-update` are dependent on the constraint declared in `Gopkg.toml`: + +* If `version` is specified with a semantic version range, then `dep ensure -update` will try to get the latest version in that range. +* If `branch` is specified, `dep ensure -update` will try to move to the latest tip of the named branch. +* If `version` is specified with a non-semantic version, or with a non-range (e.g., `version = "=v1.0.0"`), `dep ensure -update` will only make changes if the release moved (e.g., someone did a `git push --force`). +* If a `revision` is specified, `dep ensure -update` cannot make any changes. +* If no constraint is specified (typically not recommended), `dep ensure -update` will try versions in [the upgrade sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade). + +There's a fair bit of nuance to the options here, which is explored in greater detail in [Zen of Constraints and Locks](). But only the first and second kinds of constraints are especially useful with `dep ensure -update`. And that's only partially under your control - if the dependency you're working with hasn't made any semver releases, then you can't use semver ranges. + +#### Manual updates + +If using semver ranges or branches isn't an option for a particular dependency, you'll have to rely instead on hand-editing `Gopkg.toml` with the exact version you want, then running `dep ensure`. + +Given that the version constraints given in `Gopkg.toml` determine the behavior of `dep ensure -update`, hand-editing the constraints necessarily allows a superset of the changes to `Gopkg.lock` allowed by `dep ensure -update`. Really, these sorts of manual edits can be considered "updates" only in the loosest sense; they could just as easily be downgrades, or a change of the constraint type (e.g. from `version` to `branch`) that is not neatly classifiable as "up" or "down." + +Note that these approaches are not mutually exclusive. If, for example, you initially constrain a project to `version = "^1.1.0"`, then later run `dep ensure -update` bringing it to `v1.2.0` in `Gopkg.lock` and start using new features introduced in `v1.2.0` in your code, then it's important to update the bottom of the constraint range: `version = "^1.2.0"`. + + + + hand-edit `Gopkg.toml` update the range are also times when you'll need to + + + + + +but it may not be possible to use. Whether it's possible is a combination of what releases the dependency has published, and what kind of constraint you've chosen to + + + +The first approach is simultaneously more convenient and less expressive than the second, + + diff --git a/docs/deduction.md b/docs/deduction.md new file mode 100644 index 0000000000..fd7d560f3c --- /dev/null +++ b/docs/deduction.md @@ -0,0 +1,12 @@ +--- +title: Import path deduction +--- + +Deduction is dep's algorithm for looking at an import path and determining the portion of the path that corresponds to the source root. The algorithm has a static component, by which a small set of known, popular hosts like GitHub and Bitbucket have their roots deduced: + +- `github.com/golang/dep/gps` -> `github.com/golang/dep` +- `bitbucket.org/foo/bar/baz` -> `bitbucket.org/foo/bar` + +The set of hosts supported by static deduction are the same as [those supported by `go get`](). + +If the static logic cannot identify the root for a given import path, the algorithm continues to a dynamic component, where it makes an HTTP(S) request to the import path, and a server is expected to return a response that indicates the root import path. This, again, is equivalent to the behavior of `go get`. \ No newline at end of file diff --git a/docs/dep-basics.md b/docs/dep-basics.md new file mode 100644 index 0000000000..af84291d02 --- /dev/null +++ b/docs/dep-basics.md @@ -0,0 +1 @@ +Normal work with dep will have \ No newline at end of file diff --git a/docs/ensure-mechanics.md b/docs/ensure-mechanics.md new file mode 100644 index 0000000000..e45041e129 --- /dev/null +++ b/docs/ensure-mechanics.md @@ -0,0 +1,174 @@ +--- +title: dep ensure mechanics +--- + +As `dep ensure` is dep's sole state-mutating command, its mechanics are essentially the mechanics of dep as a whole. + + + +## Functional flow + +Dep's operation centers around the idea of the "four state system" - a model for organizing the on-disk state a package manager deals with, originally articulated in [this (very long) article](https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527). Those states are: + +1. The [current project's](glossary.md#current-project) source code. +2. A [manifest](glossary.md#manifest) - a file describing the current project's dependency requirements. In dep, this is the `Gopkg.toml` file. +3. A [lock](glossary.md#lock) - a file containing a transitively-complete, reproducible description of the dependency graph. In dep, this is the `Gopkg.lock` file. +4. The source code of the dependences themselves. In dep's current design, this is the `vendor/` directory. + +Let's visually represent these four states as follows: + +![dep's four states](img/four-states.png) + +It's best to think of `dep ensure` as a unidirectional series of functions, analyzing and transforming inputs into outputs. Specifically, there are two functions: + +* A _solving function_, that takes as its input the set of imports in the current project and the rules in `Gopkg.toml`, and returns as its output a transitively-complete, immutable dependency graph - the information in a `Gopkg.lock`. +* A _vendoring function_, that takes the information in a `Gopkg.lock` as its input and ensures an on-disk arrangement of source files such that the compiler will use the versions designated in the lock. + +We can represent these two functions visually: + +![dep's two main functions](img/annotated-func-arrows.png) + +This diagram directly corresponds directly to code, as well. The solving function is actually split into a constructor and a method - we first create a [`Solver`](https://godoc.org/github.com/golang/dep/gps#Solver) type, then call its `Solve()` method. The inputs to the constructor are wrapped up in a [`SolveParameters`](https://godoc.org/github.com/golang/dep/gps#SolveParameters), which should look familiar: + +```go +type SolveParameters struct { + RootPackageTree pkgtree.PackageTree // Parsed project src; contains lists of imports + Manifest gps.RootManifest // Gopkg.toml + ... +} +``` + +The vendoring function is [`gps.WriteDepTree()`](https://godoc.org/github.com/golang/dep/gps#WriteDepTree). It takes a handful of arguments, but the key one is a [`Lock`](https://godoc.org/github.com/golang/dep/gps#Lock) - that is, the data held in `Gopkg.lock`. + +Almost all of dep's behaviors are best understood with respect to this functional model. If you want to understand dep's mechanics, keep this model centered in your mind. + +## Functional optimizations + +It is one of dep's foundational design goals that both of its functions do as little work as possible, and result in as little change for their outputs as possible. Consequently, both "functions" peek ahead at the their current result to understand what work, if any, actually needs to be done: + +* The solving function checks the existing `Gopkg.lock` to determine if all of its inputs (project import statements + `Gopkg.toml` rules) are satisfied. If they are, the solving function can be bypassed entirely. If not, the solving function proceeds, but attempts to change as few of the selections in `Gopkg.lock` as possible. + * WIP: The current implementation's check relies on a coarse heuristic check that can be wrong in some cases. There is a [plan to fix this](https://github.com/golang/dep/issues/1496). +* The vendoring function hashes each discrete project already in `vendor/` to see if the code present on disk is what `Gopkg.lock` indicates it should be. Only projects that deviate from expectations are written out. + * WIP: the hashing check is generally referred to as "vendor verification," and [is not yet complete](https://github.com/golang/dep/issues/121). Without this verification, dep is blind to whether code in `vendor/` is correct or not; as such, dep must defensively re-write all projects to ensure the state of `vendor/` is correct. + +## Flags and behavior variations + +Each of `dep ensure`'s various flags affects the behavior of these functions - or even whether they run at all. + + + +## `-no-vendor` and `-vendor-only` + +These two flags are mutually exclusive, and determine which of `dep ensure`'s two functions are actually performed. Passing `-no-vendor` will cause only the solving function to be run, resulting in the creation of a new `Gopkg.lock`; `-vendor-only` will skip solving and run only the vendoring function, causing `vendor/` to be repopulated from the pre-existing `Gopkg.lock`. + +![Flags to run only one or the other of dep's functions](img/func-toggles.png) + +Passing `-no-vendor` has the additional effect of causing the solving function to run unconditionally, bypassing the pre-check ordinarily made against `Gopkg.lock` to see if it already satisfies all inputs. + +## `-add` + +The general purpose of `dep ensure -add` is to facilitate the introduction of new dependencies into the depgraph. There are two parts to this: + +1. Running the solving function in order to generate a new `Gopkg.lock` with the new dependency +2. If no version constraint is already set in `Gopkg.toml` for a named dependency, then inferring appropriate version constraint(s) and appending them into `Gopkg.toml` + +In keeping with these output goals, if `Gopkg.lock` and `Gopkg.toml` both contain entries for the provided arguments, then there is no work to be done, and `dep ensure -add` will abort early with an error. + +However, this is complicated a bit by the fact that `dep ensure -add` takes _package_ import paths, rather than only _project root_ import paths. This design is intended to allow the user to add additional subpackages from a dependency that they already include. Thus, the check made against the existing `Gopkg.lock` is actually a two-step check: 1) is there a `[[project]]` entry for the project root of the argument, and 2) does the argument appear in the `packages` list within that dependency's stanza. + +As long as there is at least one package/project not present in `Gopkg.lock`, thus necessitating a solve, then the mechanism by which `dep ensure -add` achieves its goal is to perform an in-memory-only modification of the `required` list it reads out of `Gopkg.toml` and passes to the solving function: + +![Model modifications made by -add](img/required-arrows.png) + +Because this modification of `required` is ephemeral, a successful `dep ensure -add` run of this type will result in an on-disk state which is immediately out of sync with the current project. If this is the case, it will warn the user accordingly: + +``` +$ dep ensure -add github.com/foo/bar +"github.com/foo/bar" is not imported by your project, and has been temporarily added to Gopkg.lock and vendor/. +If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/. +``` + + + +## `-update` + +The behavior of `dep ensure -update` is intimately linked to the behavior of the solver itself. Full detail on that is a topic for the [solver reference material](the-solver.md), but for the purposes of understanding `-update`, we can simplify a bit. + +First, to solidify an implication in the discussion of [functional optimizations](#functional-optimizations), the solving function actually takes into account the pre-existing `Gopkg.lock` when it runs: + +![Pre-existing lock feeds back into solving function](img/lock-back.png) + +Injecting `Gopkg.lock` into the solver is a necessity. We want the solver to preserve previously-selected versions by default, but unless `Gopkg.lock` is injected somewhere, then the solver can't know what versions it's trying to preserve. + +As such, the lock is another one of the properties encoded onto the `SolveParameters` struct, discussed [previously](#functional-flow). That, plus two other properties, are the salient ones for `-update`: + +```go +type SolveParameters struct { + ... + Lock gps.Lock // Gopkg.lock + ToChange []gps.ProjectRoot // args to -update + ChangeAll bool // true if no -update args passed + ... +} +``` + +Ordinarily, when the solver encounters a project name for which there's an entry in `Gopkg.lock`, it pulls that version out and puts it at the head of the queue of possible versions for that project. When a specific dependency is passed to `dep ensure -update`, however, it is added to the `ToChange` list; when the solver encounters a project listed in `ToChange`, it simply skips pulling the version from the lock. + +"Skips pulling the version from the lock" would imply that `dep ensure -update github.com/foo/bar` is equivalent to removing the `[[project]]` stanza for `github.com/foo/bar` from your `Gopkg.lock`, then running `dep ensure`. And indeed it is - however, that approach is not recommended, and subtle changes may be introduced in the future that complicate the equivalency. + +If `-update` is passed with no arguments, then `ChangeAll` is set to `true`, resulting in the solver ignoring `Gopkg.lock` for all newly-encountered project names. This is equivalent to explicitly passing all of your dependences as arguments to `dep ensure -update`, as well as `rm Gopkg.lock && dep ensure`. Again, however, neither of these approaches are recommended, and future changes may introduce subtle differences. + +When a version hint from `Gopkg.lock` is not placed at the head of the version queue, it means that dep will explore the set of possible versions for a particular dependency. This exploration is performed according to a [fixed sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade), where newer versions are tried first, resulting in an update. + +For example, say there is a project, `github.com/foo/bar`, with the following versions: + +``` +v1.2.0, v1.1.1, v1.1.0, v1.0.0, master +``` + +If we depend on that project with `^1.1.0`, and have `v1.1.0` in our `Gopkg.lock` , then it means there are three versions that match our constraint, and two of them are newer than the one currently selected. (There's also an older version, `v1.0.0`, and a `master` branch, but these aren't allowed by a `^1.1.0` constraint.) An ordinary `dep ensure` run will duplicate and push `v1.1.0` ahead of all the others in the queue: + +``` +[v1.1.0, v1.2.0, v1.1.1, v1.1.0, v1.0.0, master] +``` + +And `v1.1.0` will be selected again, unless some other condition is presented that forces the solver to discard it. When running `dep ensure -update github.com/foo/bar`, however, the locked version is not prepended: + +``` +[v1.2.0, v1.1.1, v1.1.0, v1.0.0, master] +``` + +So, barring some other conflict, `v1.2.0` is selected, resulting in the desired update. + +### `-update` and constraint types + +Continuing with our example, it's important to note that updates with `-update` are achieved incidentally - the solver never explicitly targets a newer version by the solver. It just removes the hint from the lock, then selects the first version in the queue that satisfies constraints. Consequently, `-update` is only effective with certain types of constraints. + +It does work with branch constraints, which we can observe by including the underlying revision. If the user has constrained on `branch = "master"`, and `Gopkg.lock` points at an older revision (say, `aabbccd`) than the canonical source's `master` branch points to (`bbccdde`), then `dep ensure` will end up contructing a queue that looks like this: + +``` +[master@aabbccd, v1.1.0, v1.2.0, v1.1.1, v1.1.0, v1.0.0, master@bbccdde] +``` + +With `-update`, the hint at the head will be omitted, and `branch = "master"` will reject all of the semantic versions, finally settling on `master@bbccdde`. + +All versions in the version queue keep track of an underlying revision, which means the same is true if, for example, some upstream project force-pushes a git tag: + +``` +[v1.1.0@aabbccd, v1.1.0, v1.2.0, v1.1.1, v1.1.0@bbccdde, v1.0.0, master] +``` + +Thus, even if an upstream tag is force-pushed in one of your project's dependences, dep will retain the original revision until you explicitly allow it to change via a `dep ensure -update`. + +The bottom line here is that `-update`'s behavior is governed by the type of constraints specified: + +| `Gopkg.toml` constraint type | Constraint example | `dep ensure -update` behavior | +| ---------------------------- | ------------------ | ---------------------------------------- | +| `version` (semver range) | `"^1.0.0"` | Tries to get the latest version allowed by the range | +| `branch` | `"master"` | Tries to move to the current tip of the named branch | +| `version` (non-range semver) | `"=1.0.0"` | Change can only occur if the upstream release was moved | +| `version` (non-semver) | `"foo"` | Change can only occur if the upstream release was moved | +| `revision` | `aabbccd...` | No change is possible | +| (none) | | The first version that works, according to [the sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade) (not recommended) | + + diff --git a/docs/glossary.md b/docs/glossary.md new file mode 100644 index 0000000000..44d60f6de4 --- /dev/null +++ b/docs/glossary.md @@ -0,0 +1,97 @@ +--- +id: glossary +title: Glossary +--- + +dep uses some specialized terminology. Learn about it here! + +* [Constraint](#constraint) +* [Current Project](#current-project) +* [Deduction](#deduction) +* [Direct Dependency](#direct-dependency) +* [GPS](#gps) +* [Lock](#lock) +* [Manifest](#manifest) +* [Override](#override) +* [Project](#project) +* [Project Root](#project-root) +* [Solver](#solver) +* [Source](#source) +* [Source Root](#source-root) +* [Sync](#sync) +* [Transitive Dependency](#transitive-dependency) + +--- + +## Constraint + +Constraints have both a narrow and a looser meaning. The narrow sense refers to a [`[[constraint]]`](Gopkg.toml.md#constraint) stanza in `Gopkg.toml`. However, in some contexts, the word may be used more loosely to refer to the idea of applying rules and requirements to dependency management in general. + +## Current Project + +The project on which dep is operating - writing its `Gopkg.lock` and populating its `vendor` directory. + +Also called the "root project." + +## Deduction + +Deduction is the process of determining a source root from an import path. See the reference on [import path deduction]() for specifics. + +## Direct Dependency + +A project's direct dependencies are those that it imports from one or more of its packages, or includes in its [`required`](Gopkg.toml.md#required) list in `Gopkg.toml`. If each letter in `A -> B -> C -> D` represents a project, then only `B` is `A`'s direct dependency. + +## GPS + +Stands for "Go packaging solver", it is [a subtree of library-style packages within dep](https://godoc.org/github.com/golang/dep/gps), and is the engine around which dep is built. Most commonly referred to as "gps." + +## Lock + +A generic term, used across many language package managers, for the kind of information dep keeps in a `Gopkg.lock` file. + +## Manifest + +A generic term, used across many language package managers, for the kind of information dep keeps in a `Gopkg.toml` file. + +## Override + +An override is a [`[[override]]`](Gopkg.toml.md#override) stanza in `Gopkg.toml`. + +## Project + +A project is a tree of Go packages. Projects cannot be nested. See [Project Root](#project-root) for more information about how the root of the tree is determined. + +## Project Root + +The root import path for a project. A project root is defined as: + +* For the current project, the location of the `Gopkg.toml` file defines the project root +* For dependencies, the root of the network [source](#source) (VCS repository) is treated as the project root + +These are generally one and the same, though not always. When using dep inside a monorepo, multiple `Gopkg.toml` files may exist at subpaths for discrete projects, defining each of those import paths as Project Roots. This works fine when working directly on those projects. If, however, any project not in the repository seeks to import the monorepo, dep will treat the monorepo's as one big Project, with the root directory being the Project Root; it will disregard any and all `Gopkg.toml` files in subdirectories. + +This may also be referred to as the "import root" or "root import path." + +## Solver + +"The solver" is a reference to the domain-specific SAT solver contained in [gps](#gps). More detail can be found on its [reference page](solver.md). + +## Source + +The remote entities that hold versioned code. Sources are specifically the entity containing the code, not any particular version of thecode itself. + +Used in lieu of "VCS" because Go package management tools will soon learn to use more than just VCS systems. + +## Source Root + +The portion of an import path that corresponds to the network location of a source. This is similar to [Project Root](#project-root), but refers strictly to the second definition, network-oriented. + +## Sync + +dep's interaction model is based around the idea of maintaining a well-defined relationship between your project's import statements and `Gopkg.toml`, and your project's `Gopkg.lock` - keeping them "in sync". When the `Gopkg.lock` has more or fewer entries than are necessary, or entries that are incompatible with constraint rules established in `Gopkg.toml`, your project is "out of sync". + +When your project is out of sync, running `dep ensure` will always either fail with an informative message, or bring your project back in sync. + +## Transitive Dependency + +A project's transitive dependencies are those dependencies that it does not import itself, but are imported by one of its dependencies. If each letter in `A -> B -> C -> D` represents a project, then `C` and `D` are `A`'s transitive dependencies. \ No newline at end of file diff --git a/docs/img/annotated-func-arrows.png b/docs/img/annotated-func-arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..cc9190f2a0431c36d7d53bce3ceb2198ca3e67fa GIT binary patch literal 42366 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 R{SFzh=xdwYtI=|P_CFilNeKV| literal 0 HcmV?d00001 diff --git a/docs/img/base-arrows.png b/docs/img/base-arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..d60e598c86421c9ccd0630cb1edd5fcfe0b15dc4 GIT binary patch literal 33999 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

I5SS1n1J9++n`<`JM&vJfhQNtbD5P4^} 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 literal 0 HcmV?d00001 diff --git a/docs/img/four-states.png b/docs/img/four-states.png new file mode 100644 index 0000000000000000000000000000000000000000..a1aa5a566e59e21451e044e241e5fe0d586911f9 GIT binary patch literal 32855 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 Q`~vtB6OtAz70~hiU*ZW{V*mgE literal 0 HcmV?d00001 diff --git a/docs/img/lock-back.png b/docs/img/lock-back.png new file mode 100644 index 0000000000000000000000000000000000000000..ad769756d36b3179018e919d5d4ad6a72eba4d29 GIT binary patch literal 35714 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 Nw1k3qshFYv{{aD-p_c#v literal 0 HcmV?d00001 diff --git a/docs/img/required-arrows.png b/docs/img/required-arrows.png new file mode 100644 index 0000000000000000000000000000000000000000..e9765468096525034ce01a00da5d8da7b22ff51d GIT binary patch literal 47424 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 Date: Wed, 3 Jan 2018 02:21:02 -0500 Subject: [PATCH 02/13] docs: Incremental checkin, mostly ensure mechanics --- docs/day-to-day-dep.md | 90 ++++++++++++++++------------------- docs/ensure-mechanics.md | 73 ++++++++++++++++++++-------- docs/glossary.md | 2 +- docs/img/required-arrows.png | Bin 47424 -> 46651 bytes docs/migrating.md | 7 ++- 5 files changed, 97 insertions(+), 75 deletions(-) diff --git a/docs/day-to-day-dep.md b/docs/day-to-day-dep.md index 1bcbc46ad1..6d21955e02 100644 --- a/docs/day-to-day-dep.md +++ b/docs/day-to-day-dep.md @@ -2,25 +2,36 @@ title: Day-to-day dep --- -In keeping with Go's general design philosophy of minimizing knobs, dep has a sparse interface - there are only two commands you're likely to run regularly. For existing projects, `dep ensure` is the primary workhorse command, and the only thing you'll run that actually changes disk state. `dep status` is a read-only command that can help you understand the current state of your project. +In keeping with Go's philosophy of minimizing knobs, dep has a sparse interface: there are only two commands you're likely to run regularly. `dep ensure` is the primary workhorse command, and after the initial `dep init`, is the only thing you'll run that actually changes disk state. `dep status` is a read-only command that can help you understand the current state of your project. -Sparse interface notwithstanding, acclimating to `dep ensure` can take some practice. The verb here is "ensure", as we're asking dep to "make sure that my `Gopkg.lock` satisfies all the imports from my project and the rules in `Gopkg.toml`, and that `vendor/` contains exactly what `Gopkg.lock` says it should." In other words, dep is designed around the idea that it's fine to run `dep ensure` at most any time, and it will bring your project and its dependencies into a good state, while doing as little work as possible to achieve that guarantee (though [we're still optimizing "as little as possible"]()). +This guide primarily centers on `dep ensure`, as that's the command you run to effect changes on your project. The [ensure mechanics](ensure-mechanics.md) document details how the command actually works, and is worth reading if you're encountering a confusing `dep ensure` behavior (or just curious!). This guide is more of a high-level tour for folks trying to get a handle on the basics of dep. -That's pretty vague, though. Let's make it clearer by exploring some concrete examples. We'll start by moving to the root of a hypothetical project, then running `dep ensure`: +## Basics -``` -$ cd $GOPATH/src/github.com/me/example -$ dep ensure -``` +Let's start with some semantics: the verb is "ensure" to emphasize that the action being taken is not only performing a single, discrete action (like adding a dependency), but rather enforcing a kind of broader guarantee. Expressing that guarantee In narrative terms, running `dep ensure` is like saying: + +> Hey dep, please make sure that my project is [in sync](glossary.md#sync): that `Gopkg.lock` satisfies all the imports in my project, and all the rules in `Gopkg.toml`, and that `vendor/` contains exactly what `Gopkg.lock` says it should." + +As the narrative indicates, `dep ensure` is a holistic operation; rather than offering a series of commands that you run in succession to incrementally achieve a some final state, each run of `dep ensure` delivers a complete, consistent final state with respect to the inputs of your project. You might think of this like a frog, hopping from lilypad to lilypad: `dep ensure` moves your project from one safe (transitively complete import graph, with all constraints satisfied, and a fully populated `vendor`) island to the the next, or it doesn't move at all. Barring critical, unknown bugs, there are no intermediate failure states. This makes `dep ensure` fine to run at most any time, as it will always drive towards a safe, known good state. + +General guidelines for using dep: + +* Never directly edit anything in `vendor/`; dep will unconditionally overwrite such changes. +* `dep ensure` is almost never the wrong thing to run; if you're not sure what's going on, running it will bring you back to safety, or fail informatively. -If `dep ensure` exits 0, then we're guaranteed (with [one fixable caveat]()), that our project is "in sync" - `vendor/` is populated with a depgraph that satisfies all imports and rules. So, let's assume `dep ensure` exited 0, and our project is now in sync. That means we're ready to develop normally: edit `.go` files, run `go test` and `go build`, etc. We don't need to think about dep again until one of the following happens: + + +## Using `dep ensure` + +There are five basic times when you'll run `dep ensure` (with and without flags): - We want to add a new dependency - We want to upgdate an existing dependency - We've imported a package for the first time, or removed the last import of a package - We've made a change to a rule in `Gopkg.toml` +- We're not quite sure if one of the above has happened -There's a bit of [TIMTOWTDI](https://en.wiktionary.org/wiki/TMTOWTDI) here, as it's possible, and sometimes preferable, to handle each of these cases with a plain `dep ensure`, but dep also allows some additional parameters to make some of these cases a bit more ergonomic. We'll explore each in turn. +Let's explore each of these. To play along at home, you'll need to `cd` into a project that's already managed by dep (by `dep init` - there are separate guides for [new projects](new-project.md) and [migrations](migrating.md)). ### Adding a new dependency @@ -39,67 +50,46 @@ This should succeed, resulting in an updated `Gopkg.lock` and `vendor/` director If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/. ``` -This reflects the nature of `dep ensure` - `github.com/pkg/errors` isn't in our project's imports, and as such, a subsequent `dep ensure` will classify it as unnecessary, and remove it. If we're ready to use the package, though, then this shouldn't be a problem - add an `import "github.com/pkg/errors"` to a `.go` file, and the project's now back in sync. +As the warning suggests, you should introduce an `import "github.com/pkg/errors"` in your code, ideally right away. If you don't, a later `dep ensure` run will interpret your newly-added dependency as unused, and automatically get rid of it. -It's also possible to introduce the new dependency without relying on `-add`. If, as a first step, you add `import "github.com/pkg/errors"` to a `.go` file, then run a plain `dep ensure`, your project will be in almost the same state as with `-add`: `Gopkg.lock` and `vendor/` will include `github.com/pkg/errors`. The only difference is that `Gopkg.toml` will not have been updated with a guess at a version constraint. +Note that it is not _required_ to use `dep ensure -add` to add new dependencies - you can also just add an appropriate `import` statement in your code, then run `dep ensure`. This approach doesn't always play nicely with [`goimports`](https://godoc.org/golang.org/x/tools/cmd/goimports), and also won't append a `[[constraint]]` into `Gopkg.toml`. Still, it can be useful at times, often for rapid iteration and off-the-cuff experimenting. -In a sense, the plain `dep ensure` approach is more natural here, as using `-add` effectively dupes dep into violating its guarantee - `dep ensure` exits 0, but the extra dependency means our project is out of sync. However, the plain approach has a chicken-or-egg problem. Many Go developers use something like [`goimports`]() to read the contents of a `.go` file and infer what import statements to add. `goimports`, in turn, works by searching vendor and GOPATH for packages that match the identifiers in a file - which requires that those packages already be present locally. - -**Both approaches can be useful in different situations. If you're genuinely experimenting with permanently adding a new dependency to your project, then `dep ensure -add` is probably best: you'll probably want that constraint ** +The [ensure mechanics section on `-add`](ensure-mechanics.md#add) has more detail on internals, as well as some subtle variations in `dep ensure -add`'s behavior. ### Updating dependencies -First, a quick definition: in dep's world, updating a dependency is the act of changing the value of the `revision` field in `Gopkg.lock` for that project (and, by extension, the version in the `vendor` directory). There are two basic ways of achieving this: - -* Run `dep ensure -update `; this will update the project to the latest version allowed by the version constraints in `Gopkg.toml`. -* Edit `Gopkg.toml`, changing the version constraint to one that does not allow the version currently in `Gopkg.lock`, then run `dep ensure`. - -The CLI-driven approach is strongly preferred to hand-editing `Gopkg.toml`. Let's look at that first. - -#### CLI-driven updates - -`dep ensure -update` can be used to update multiple dependencies at once: +Ideally, updating a dependency to a newer version is a single command: ``` -$ dep ensure -update github.com/foo/bar github.com/baz/quux +$ dep ensure -update github.com/foo/bar ``` -Or all dependencies (not recommended): +This also works without arguments to try to update all dependencies, though it's generally not recommended: ``` -dep ensure -update +$ dep ensure -update ``` -The CLI-driven approach is preferred because it is much more convenient, less expressive (read: safer), and better for the Go packaging ecosystem. However, it doesn't always work, as the semantics of `-update` are dependent on the constraint declared in `Gopkg.toml`: - -* If `version` is specified with a semantic version range, then `dep ensure -update` will try to get the latest version in that range. -* If `branch` is specified, `dep ensure -update` will try to move to the latest tip of the named branch. -* If `version` is specified with a non-semantic version, or with a non-range (e.g., `version = "=v1.0.0"`), `dep ensure -update` will only make changes if the release moved (e.g., someone did a `git push --force`). -* If a `revision` is specified, `dep ensure -update` cannot make any changes. -* If no constraint is specified (typically not recommended), `dep ensure -update` will try versions in [the upgrade sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade). - -There's a fair bit of nuance to the options here, which is explored in greater detail in [Zen of Constraints and Locks](). But only the first and second kinds of constraints are especially useful with `dep ensure -update`. And that's only partially under your control - if the dependency you're working with hasn't made any semver releases, then you can't use semver ranges. - -#### Manual updates - -If using semver ranges or branches isn't an option for a particular dependency, you'll have to rely instead on hand-editing `Gopkg.toml` with the exact version you want, then running `dep ensure`. - -Given that the version constraints given in `Gopkg.toml` determine the behavior of `dep ensure -update`, hand-editing the constraints necessarily allows a superset of the changes to `Gopkg.lock` allowed by `dep ensure -update`. Really, these sorts of manual edits can be considered "updates" only in the loosest sense; they could just as easily be downgrades, or a change of the constraint type (e.g. from `version` to `branch`) that is not neatly classifiable as "up" or "down." - -Note that these approaches are not mutually exclusive. If, for example, you initially constrain a project to `version = "^1.1.0"`, then later run `dep ensure -update` bringing it to `v1.2.0` in `Gopkg.lock` and start using new features introduced in `v1.2.0` in your code, then it's important to update the bottom of the constraint range: `version = "^1.2.0"`. - - - - hand-edit `Gopkg.toml` update the range are also times when you'll need to +The behavior of `dep ensure -update` is heavily dependent on [the type of constraints in use](ensure-mechanics.md#update-and-constraint-types). For semver range and branch cases, the above CLI-driven approach works. For other types - non-semver releases and revisions (e.g. git hashes) - the only option to achieve an analogous "update" is to manually update `Gopkg.toml` with a new constraints, then run `dep ensure`. +### Adding and removing package imports +As described in the +### Rule changes in `Gopkg.toml` +`Gopkg.toml` files contain five basic types of rules. The [`Gopkg.toml` docs](#gopkg.toml.md) explain them in detail, but here's an overview: -but it may not be possible to use. Whether it's possible is a combination of what releases the dependency has published, and what kind of constraint you've chosen to +* `required`, which are mostly equivalent to import statements in code, except it's OK to include a `main` package +* `ignored`, which causes dep to black hole an import path (and any imports it uniquely introduces) +* `[[constraint]]`, stanzas that express version constraints and some other rules on a per-project dependency basis +* `[[override]]`, stanzas identical to `[[constraint]]` except that only the current project can express them and they supersede `[[constraint]]` in both the current project and dependencies +* `[prune]`, global and per-project rules that govern what kinds of files should be removed from `vendor/` +Changes to any one of these rules will likely necessitate changes in `Gopkg.lock` and `vendor/`; a single successful `dep ensure` run will effect all such changes at once, bringing your project back in sync. +### Or, just, any time -The first approach is simultaneously more convenient and less expressive than the second, +So, you're humming along, working on a project, and diff --git a/docs/ensure-mechanics.md b/docs/ensure-mechanics.md index e45041e129..75750c84f8 100644 --- a/docs/ensure-mechanics.md +++ b/docs/ensure-mechanics.md @@ -4,8 +4,6 @@ title: dep ensure mechanics As `dep ensure` is dep's sole state-mutating command, its mechanics are essentially the mechanics of dep as a whole. - - ## Functional flow Dep's operation centers around the idea of the "four state system" - a model for organizing the on-disk state a package manager deals with, originally articulated in [this (very long) article](https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527). Those states are: @@ -51,6 +49,16 @@ It is one of dep's foundational design goals that both of its functions do as li * The vendoring function hashes each discrete project already in `vendor/` to see if the code present on disk is what `Gopkg.lock` indicates it should be. Only projects that deviate from expectations are written out. * WIP: the hashing check is generally referred to as "vendor verification," and [is not yet complete](https://github.com/golang/dep/issues/121). Without this verification, dep is blind to whether code in `vendor/` is correct or not; as such, dep must defensively re-write all projects to ensure the state of `vendor/` is correct. +## Sync + +It's easy to think about + + + +## Imports, and the package tree + + + ## Flags and behavior variations Each of `dep ensure`'s various flags affects the behavior of these functions - or even whether they run at all. @@ -67,20 +75,47 @@ Passing `-no-vendor` has the additional effect of causing the solving function t ## `-add` -The general purpose of `dep ensure -add` is to facilitate the introduction of new dependencies into the depgraph. There are two parts to this: +The general purpose of `dep ensure -add` is to facilitate the introduction of new dependencies into the depgraph. Whereas `-update` is restricted to [source roots](glossary.md#source-root), (e.g. `github.com/foo/bar`), `-add` can take any package import path as an argument (e.g. `github.com/foo/bar` OR `github.com/foo/bar/baz`). + +Conceptually, there are two possible things that `-add` might be introducing. Any `dep ensure -add` run will do at least one of these: + +1. Running the solving function in order to generate a new `Gopkg.lock` with the new dependenc(ies) +2. Appending a version constraint into `Gopkg.toml` -1. Running the solving function in order to generate a new `Gopkg.lock` with the new dependency -2. If no version constraint is already set in `Gopkg.toml` for a named dependency, then inferring appropriate version constraint(s) and appending them into `Gopkg.toml` +This implies two preconditions for `dep ensure -add`, at least one of which must be met: -In keeping with these output goals, if `Gopkg.lock` and `Gopkg.toml` both contain entries for the provided arguments, then there is no work to be done, and `dep ensure -add` will abort early with an error. +1. The named import path is not currently in the project's import statements, or in `Gopkg.toml`'s `required` list +2. There is no `[[constraint]]` stanza in `Gopkg.toml` for the project root corresponding to the named import path -However, this is complicated a bit by the fact that `dep ensure -add` takes _package_ import paths, rather than only _project root_ import paths. This design is intended to allow the user to add additional subpackages from a dependency that they already include. Thus, the check made against the existing `Gopkg.lock` is actually a two-step check: 1) is there a `[[project]]` entry for the project root of the argument, and 2) does the argument appear in the `packages` list within that dependency's stanza. -As long as there is at least one package/project not present in `Gopkg.lock`, thus necessitating a solve, then the mechanism by which `dep ensure -add` achieves its goal is to perform an in-memory-only modification of the `required` list it reads out of `Gopkg.toml` and passes to the solving function: +It is also possible to explicitly specify a version constraint: + +``` +$ dep ensure -add github.com/foo/bar@v1.0.0 +``` + +When no version constraint is included in the argument, the solving function will select the latest version that works (generally, the newest semver release, or the default branch if there are no semver releases). Either this inferred version, or the specified version, will be appended into `Gopkg.toml`. + +The behavioral variations that arise from the assorted differences in input and current project state are best expressed as a matrix: + +| Argument to `dep ensure -add` | Has `[[constraint]]` stanza in `Gopkg.toml` | In imports or `required` | Result | +| ----------------------------- | ---------------------------------------- | ------------------------ | ---------------------------------------- | +| `github.com/foo/bar` | N | N | Added temporarily to `Gopkg.lock` & `vendor/`; inferred version constraint appended to `Gopkg.toml` | +| `github.com/foo/bar@v1.0.0` | N | N | Added temporarily to `Gopkg.lock` & `vendor/`; specified version constraint appended to `Gopkg.toml` | +| `github.com/foo/bar` | Y | N | Added temporarily to `Gopkg.lock` & `vendor/` | +| `github.com/foo/bar@v1.0.0` | Y | - | **Immediate error**: constraint already present in `Gopkg.toml` | +| `github.com/foo/bar` | N | Y | Infer version constraint from `Gopkg.lock` and add to `Gopkg.toml` | +| `github.com/foo/bar` | Y | Y | **Immediate error:** nothing to do | + +For any of the paths where `dep ensure -add` needs to run the solving function in order to generate an updated `Gopkg.lock`, the relevant information from CLI arguments is applied to the in-memory representation of `Gopkg.toml`: ![Model modifications made by -add](img/required-arrows.png) -Because this modification of `required` is ephemeral, a successful `dep ensure -add` run of this type will result in an on-disk state which is immediately out of sync with the current project. If this is the case, it will warn the user accordingly: +Import path arguments that need to be added are injected via the `required` list, and if an explicit version requirement was specified, the equivalent of a `[[constraint]]` is created. + +Though these rules may ultimately be persisted if solving succeeds, they are ephemeral at least until solving succeeds. And, from the solver's perspective, the ephemeral rules are indistinguishable from rules sourced directly from disk. Thus, to the solver, `dep ensure -add foo@v1.0.0` is identical to modifying `Gopkg.toml` by adding `"foo"` to the `required` list, plus a `[[constraint]]` stanza with `version = "v1.0.0"`, then running `dep ensure`. + +However, because these modifications are ephemeral, a successful `dep ensure -add` may actually push the project out of sync. Constraint modifications generally do not, but if the `required` list is modified, then the project will desync. The user is warned accordingly: ``` $ dep ensure -add github.com/foo/bar @@ -88,8 +123,6 @@ $ dep ensure -add github.com/foo/bar If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/. ``` - - ## `-update` The behavior of `dep ensure -update` is intimately linked to the behavior of the solver itself. Full detail on that is a topic for the [solver reference material](the-solver.md), but for the purposes of understanding `-update`, we can simplify a bit. @@ -160,15 +193,15 @@ All versions in the version queue keep track of an underlying revision, which me Thus, even if an upstream tag is force-pushed in one of your project's dependences, dep will retain the original revision until you explicitly allow it to change via a `dep ensure -update`. -The bottom line here is that `-update`'s behavior is governed by the type of constraints specified: +The key takeaway here is that `-update`'s behavior is governed by the type of constraints specified: -| `Gopkg.toml` constraint type | Constraint example | `dep ensure -update` behavior | -| ---------------------------- | ------------------ | ---------------------------------------- | -| `version` (semver range) | `"^1.0.0"` | Tries to get the latest version allowed by the range | -| `branch` | `"master"` | Tries to move to the current tip of the named branch | -| `version` (non-range semver) | `"=1.0.0"` | Change can only occur if the upstream release was moved | -| `version` (non-semver) | `"foo"` | Change can only occur if the upstream release was moved | -| `revision` | `aabbccd...` | No change is possible | -| (none) | | The first version that works, according to [the sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade) (not recommended) | +| `Gopkg.toml` version constraint type | Constraint example | `dep ensure -update` behavior | +| ------------------------------------ | ------------------ | ---------------------------------------- | +| `version` (semver range) | `"^1.0.0"` | Tries to get the latest version allowed by the range | +| `branch` | `"master"` | Tries to move to the current tip of the named branch | +| `version` (non-range semver) | `"=1.0.0"` | Change can only occur if the upstream release was moved | +| `version` (non-semver) | `"foo"` | Change can only occur if the upstream release was moved | +| `revision` | `aabbccd...` | No change is possible | +| (none) | (none) | The first version that works, according to [the sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade) (not recommended) | diff --git a/docs/glossary.md b/docs/glossary.md index 44d60f6de4..b7a53a2a7c 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -35,7 +35,7 @@ Also called the "root project." ## Deduction -Deduction is the process of determining a source root from an import path. See the reference on [import path deduction]() for specifics. +Deduction is the process of determining a source root from an import path. See the reference on [import path deduction](deduction.md) for specifics. ## Direct Dependency diff --git a/docs/img/required-arrows.png b/docs/img/required-arrows.png index e9765468096525034ce01a00da5d8da7b22ff51d..791076f991fb7a82b408ce99932718ce32fc1616 100644 GIT binary patch literal 46651 zcmeGEbyQT{+Xsvzj0y^Zpme7S3=Pr<2qKL%4BbOBbW5p}(jC&>LzhT*=g{5V@gDB` z`#iVb`&qyLfA3l^>#){vX77Ejef7Ss&*7__j5x*bNEi|yL=}*bP~b>N4?d$l z0`822Xy1SFz)nG27^$$2cmwzY&H96y9TE~Q&He8K2?gqXV8E!UqAE;PT8c;C$^xuw zV5MgWcCxSrMk68dIq?7=Eev70g%1@~(Ek`b5 zWot;z0cHm?QwlsGCnx8#H8A2)5Ec8+bl@+3N)s5&num$W(a{m?$Og8uHD+Sr=H_N% zW@Tb!Wduer+BsXobe$M2?Wq1<uVM$=aG40=xceHp_oz|9S5}9oB+9q$7wf9hF? z;=>Z3dOVoD#d;xB?XIQ@{_<+7yAYwI^86(cywyKDTUAKz`z%I%rI7IDb^qQEUS}&- zv~U9>))hyAAG|>S-}V1K4v@2=R{dg+KXsctlXh@VWE-!d z@m8gnKb4oe;=XDK&E|WLOfB@!HTaHP6J2z<^0CUzTR)=bIl=h4Qg#hw9G9VVwuCy~ieh@XuwU zgN$J@v3Oyl-yX7)924_a3}fQcNtHed+rp9rc^v9;ZZmIndiru?JDI0j5^laG3V-$B zvA-JbKTD85=$4$q!e2a2Erb@;!}VQUE+J+ES}CNo3E@G@q8p>EB0QYZWv6Tk*cmno zpQ&k7qlqYs+-T8!`MnoQZ6`k|zH#=W2~$y|tmb`Ua1g}@C5u&&Eu5-c!8tlQ+H={= z$+A6p5u|}%{o>DuVt;W$PCcDaC!P8v%g<5mxHo%d7QK`=nj-x*)UF!SbbN$^oKAAe zC{v725!Va!%de>hab>XUpU7&r^UP7LT4P5;Mc34HgDnt`sX_m6x$}LTtc!KaiXjWx zpPaX+#roKS3m&fuWNN5Vl9B1-ooW(L^l=q($lRK+EJ&9yQ%HQ;OeEn2GNUbqYL`es z8q`)TXA0)RX22MNmJ`JbGiW%p=3~6NGefQ#Y{FVJe{dgFA32rT`~cneJg=z1Maal# z)wO1>@T&vM?NZaTA%D^-=38fG=%AQRy^Hl+OqsfaX|!QvMXlqWz}2L2a$??rHR z7uo;i1Sms1R7z^TU5y6tWPx0FtR?CQ}9*o zSIz9CsbyasftnhI13t9xLJDpP=pCk%yidLv9?kwr9~l|JQHPsf6o%CLWpopSU*J&u zvHdS^k(Ss5Lpdbvq7ZP(ZI z&G%7U;YeuT|L5`z6JoAoZPSRKNEHdNQIDZ!*l3vy6}eEqV8Gr_MuOq+9j6-EL6k7~=c-4sADv>D;dkzU{N^3wHm}!wn{0fDQ zQ)}atTr677-C3ajOcg?wLH1@h53a-w@2Ad4PbUr)*HwG|1d#PP4*vIWL&H*G#{-Th zHBvW_aWe<0V9bZOEE)Ug*Ci&c^ZO=~f-6{iB+6h(cIR`!y|99<)A?zzGf zqwqiHjG=;t^q;2TLhx|H!^3MI7_>9EK%2dVk$(uM=nvoUXr#6MF!u&_105za6p%lWr z)30gRi%Uxyl;P~=C>OagxM-kcuffSDB>t6AI3FI8@h1PTB!CZcviH&~*zG_=L+kxf z)Fxqq^9c|mrQcsuI1%6FW#^Y(`u(vlK*nK0g z!vAYuf6+83;^l8~Tqhaj`^SvGvL?O1nChSs)S3M3DTzKPdyVDvmzw53QRWLZvNy9i zRZd+G{eMaQ-l&Blo~P&%88St*{^`>0W2?6+l~4=k*zDVG$$z%-H(l~#04)*qa<~Ei zhn8R@jA>QZB?hK{KS`9}0U=!eR9KDpAHx0);a@nA+0FHLg3Iduy=yE(kjaGDDU6Wz=CRG6n*vvOkU6*htSs*RIJ9a$&3=T86D3RH{-F6Q)aWu1?43C3#k0$k)Ja?F)5ccRPiI+pg_-mEv6M?>%UwLDx` zD6VoIA?|KtYYC4p+}{41KkP36#e2Ct{3(oviof@ORDC^WYL>@lB!}uz=Ky_M=V@Ji z($grOlAh>3e;;GKek`Wu`~sc02}8)e*;!stG3M#Iy#S2&$X*KuXkcHw`qT2{R<3ISbM~ zqfdEAFPxxrNn<}}>~S#@L`b(4w05J2lHFVEo~)d5F|B4Y@;Y{FXx~tixeIEHSt2On z9k=0NL#WEmX+c~kw>T-KCq8#wR{*-GdV@n+9rFb=Jffn0uYV2As6(sNrJnC_tew?; zR$;QrJ*&>PJJPmKKH%-*ZMjaYR3g82liu#(=vX^eot-b+Ga|~hP(DR$>_w8Z{ePYK zQak`#zw9g$zuJDoGCom5C!28Tb6r(z>!4j(W$2V_X}ehv+9eA=Vy@X%kW-~z(sB_` ziaD;1s70Jgj=8VSiqBrFYSnG@*DT9vixb=J577-1mr*7Q=oQPhIK&h7s0f^v)}0~x zSC#u6+LPS8%e=n?uiL+&Arxm9BjEP?D)vmcI%GKIU+nGy2(76e^_eW3TVR9v#UfcFZ$!h zTwx9GC#{xqQv)X}_S~Gq_#AruY*(L)^cKwg%g>F3BhiH(;>_!vj5$lTk1^KCI)~_{ zC2{ZC1juhytCpZpRo=zK7pQsH2dnQ@HEt1Bq_xd5Io7jwUWLuI?>{-KKc-CoJ?|<_O1zBnrH_ zvxJuO{9WgZ%XbSw)1){ITrl#B!{`fJ363__T|~KiH2O{V+lxxp15UI0;Wk&kvqCx$ zsU47P{b5nxg>+B{^tT?j8}1+Ws>{(BNkdy@E{!r*D)Mc^cYaS~X&33?JD4LhLkLF1 zr{E@;Vh5~wd0^U7R@=QivX0j+k2}97CHB5Y}dy;N@#iJbPcI}+G4^HhEK*6aJEMgaI$A=Z*_YZ z{ZJuWONwfLR_ksAbTXqwyYDdvDN){8tC0F!pfBQji9;_5yjRzK2yY*3Pz03@6UJu$7 zx`JkFvS#BcdCykkCC41H38M<)jClGcF$Z4ah5c-!YRiANF(@&=fKX91PfX^4Hmr1( zKYMeVkQuI6?|ODJ<|Jcx8*m}Hk{(YAN0&|TS#W4gW9rJko1r^6xaFN88!l{o3cJqx zv7ITsTqbTgc2G;w^Sb)3-}AfO==|je3>GR(*#ynjVv?(4sDgsB(NEN%Da<`0dO8fU zb?$(Y%A2+s1N$8gI+op&oGq|Y3#a(*z;69_i0e~ge~W}deQ06q)%D~rqU)ou$dGK6 z1eYLUj^axDLQ^rSynJ`q%;CcL?9$h>md_cbkak+GZu4#KwR-*86^io#bD9 ztpU;=jpiNLPSj>mQ{MUV9mKY2y`YqJdFip$;ReM0ytgytDn4i7qz^LA9i%RbKUfsN z=QesVR;6m!LYx?Ziu0nGYCW_`3r@t8A`MsHM^ZEB#2O=4BGC;X3IorV|?>W zS-}zFbC*ntaTor^yFHT4;FB?Oi!n}&PFc0go~Qgyv~=W@s98tN}Lsl9Z|_Qv;_wZ_|*DWP|NV zO@n2w>gP65{E33J$%4|>%NkX%Q7RbE0MxyCP9L)|p)nQQFm|O_(QZ^tEZT%E?$FHB zK$06P`m}AvyRB$yICt-MCpzJ^%H7sWaaQK_xmeEOCsp5LlX4{qPlnaL26Q-!W1gAj z^I#94FmQvc;FZfOcpZ-t-*$lmP77{*#FLJjL>72yljS=OLx7k^;RtYzxWtdFbE@t1jVdnM0BAVurN;ggrJA~!L<;Ru- ztm$S-GB%!RFqySuAo#h#@2hH6B2LZaT(*#kHukwx$<6%X6R3NqCFJL0NfL^glP=f8 z%PQ#d_gRSh`;&wgtCna6NLfkO#2L~ zI4^ZsQ{#SLxk!hTIA{4B)Xomo`rIY80oFm;e-DU|Yf7 z7s@clTb4RlR4^_1teBW#?`^q{`fL|9O>Z*}C*jjEV$Rc?Hau>>sV#Txi3@UzjExA_D5*<_O#Q^^9cR~- zUMA0oX|TX>xcFWoh)I7|v)xwKsb96By<@XCQs1PPy9`od84mV~fIf?imF(l*#Oh~p z{MXTB^Zsmvs2be@GraWSP-a;w{&ChAue5_+&4yQy%^HQ%J$6ptu-FIWX(2>YbH>=N zPfk1g_#?ZCIEKKZs^G`SEhAvp)0dlJAD+5po(z9Bv~9BpoletW!yaevQ&eHg9h7sR zHsU?EpWI`$S|RKwaB7w1hJCl6sgv+eaP48Hzjoi~wC#wjbTx7p^Ht*+wu6A!$Q-TW z8BYsmokBhDT3!o;*NU~@d8C%95ph=;;}OCiJ*xb#q+JdZxdCB*^5J{srFfI8LI&9g z>hDsX+0Pj+yQFtXOYC*^;>07}Hiel!oQ!cFJ(+x7bl+9!zIOpsO$FCqJHYO)9|y>u z*1!6#1Srst8FSF>#qX!O7)th}8ee4>CPJgjm#MjH^dM?i&Q}6s8x=&^r%;Zaq7lnh zebVbtI!){TVFh*d>aoIVN9)kOA-JEN(W=ZOW6z4ZRVc|+zfHgF)95R=(4*0HI8j9v zS{cWE>EX|7Qx*`z4Z+xJKVC4mCI!U%_}sF& zU-W!-8;`N$YoEBVoWqx|%==N}CZCX3>bp;Uw^9pj z3x7bouqLJJe6nOMiQ3BJBrS!v>^c72?4zn`e+xWF;rhlFQ$=#=>Ep9?#TDYQQ!HII8Kyx+HH4f87mdhlEieTT<=>N*Gz|QUd|=Xcrcv-b?HBan*drbu|GuJ z7&HyQh~k1(6KI!FUv+gzv^?rq3!SA@C4+;JMF_=m5M^o*o|qS=i#y{kZ8=j*H0$O~ z$pUWS37mR&_{vut+E@D~9!_%@VWUoWZy~P445=e|A|W@5iDz^(4iyRNEQMp#rAp)I zw?h2wMKZBkt=SflkrdiDTb#)ktY=qctsps^TbsxU;fgP3fSq%m_zap%$X z1P5N%an{}oDb0vw{c1w|^0iQ6Fk4b>dz^Vr&2e$Up!nGxWZb)cswg%%f z8(ytO5^(rZR>Y+`iVgHqofo`}~pGZRT!E9W{&g6K< zr3EklkG_EwOMxn@{I!YkXSA8>HAZOyRs}9LOX(t8t3%SkCTu9BMXtHL(M9^|Yg-Kc zlH-;U$~8e)LmLCR)lIcqMLLt@J#9hr3O)jC{7S`IOs89v_)9e|!<;LnBID7FxcTCN zUMr!SnF1O?EGu@_qc(D78;||Y}@^1D9_i(lKU&eoaenCGgr9;`14^r zBrN`5HA+x@O#R<=OTsWA#AP|BK}g#5q{S#z;C$$dtr$(Gk8?LhnJw9^^^9@s0y@~t zyYmtSeeo_$AoJ%#_7W+&?lo%74mHZPs!#F!8HCBx>j}qDQ*rSZ6H7JJDMtENkN#BZ z59GK&xC@@I^k`u#>b4`3w$JZ0`!-x+kBBa2F|`JYa9Av$Z3N-=RVGqHUo3PcOeh~K zyQVGi%T0p2pmNM_GwvPxpYC(}`}TdBOHm*_Kd&O5L65!$GF&N>3IA4TwkvH{SKe(V zvjZ+0=-yxcj6x!WC|4b{5nZ*mwGY^VwQXdYQGKzav-Jlp=&bKd?I# z41X>0^>9BD??a`-Bs79T8D?c)k?cKP&harP1F|FpH78r zY-~8@ymR%w4KFdOU>cw7d#Yg|VWX`7didssLVo7pR(1yWG{g9j1bGu^v8#)^Fk5sn z@LR$6a=XxUb41SCH{M(iNPJkBZ7*Zx3@eME;9X%>lFJ(vGR!4hF)$4)s-lK5?H2JD zMtgzZnY->hN2amqCLe60KOi@1i?+oZf{A>+#$ptfKYkbfIvy*!WEeoN1YfUft|3#l zr)@A8Re4Kq>yCElfsIOqobZx6NUQC3x6KB4gqiK$Z2jISxLqahUHoE*UG>p)x$VnU z_UJ|Q)3?v^xY~L|*}c>2>cdKP@~Wt9dPhG9e67yFfClnH5_mze z?AYPJp;fIs#AzWrhWU}}cw^YuNm+TU8i!VDB0tpIMsm*r$?5UiuW#&W+YFbh&OUIR z$(%4nK03FN3ITmUBKyWV8ah2#KV2~sNkf!j<1-ektisvwclXx2m_o;yn4RlDMce(P ziPK{08k7cSppk%+&a_wLS*fJT6LIc+BlxO-JixL}2zyrZn8X(>OqUu@m|s{ZuYUc3 zKB}LG?LEe%?#dSA2BG06W|3a6u*x-rD%73=9pGNq5*dwUH>cW(Zn*}EFrsV^hJ_@n z4!h_d8yOkN4F7`DkJ;x`k`Bp!oY;9AH^<+N>kmq?8{l70`N+FY4f}L9xD?#Rn9ZJl zp3hbWTb@f@*%}S^on5+bV9GuB>U(#V;`4^0h|P4ue^dI1`#ukoV|&0pfVJ4qvz2eY zbNW`|Z1`*=-Fo`bS(t4ib%-$F30#nY2av<$X-I0&NJibAEQ4nk32Dkf=&s_4u?0&e z0cI`gSwl}PEYI12SQLl^!{kAQD59ArO0+}?3g3q(R7_-(bQ*MgX7U1!N=vJahLs$| zWLDXwpQ=(oJG~xQFUo6^95(1=nVL4BwDO>z5f+W@f~>SD<@EJ3(h9D*k=p+(`2#Yw z4ruEj2BzR!$kXYS7E*Y>9lpD2y7&Uk4<%e8M+P6cmOc z2h^lPmMpfK%b!&$=dhjlx~8}UOx#pGV|RXv2Ks>n!v=VW@g86e=NG1MiEyC^Y$xe% zj%o3Af{YamhY~r=mZk8&+MPAhZ%hz9tzUnB4o=(%7eb&4aiylYINJL4=^^pe!|hwt zqH6*ACwKY5GB1?yBI*J_pJkEmB}DhI{@z7hpLNoG7b<_gp7D@yn<`ygz9($gi6fZvlSy#6wByuViUc3dz2BrNCmcbmhHeB`>&9njUXFr+`g% z_5(5n#s73lFXdb;M1*HAo#wOIrmK%MHM2O`_b*;xXVX7ee+A>1xaWCI1I6rLovafo z9X?F_%>G6e4M_VwyR%ncH<^t#(Kzp&eJwEybAwBfiHs8WJ=PIAgZpPK;N-nS24xA_iarsdRGr z`WC5W1CaINRWGgS`3CLQY|GF&3=6&66A6qR)imNB8Jhu+~lkRH|`S@uRGAZ zvruu(h@r7@@)r%jqw9*?_dl_a#f<4;6ZmkkMym7|&wog_jK~|qBR+rW;A4|OrY^p3 zbL!k%`Gq9ay>|Iics(Ml0n^gb(K(9Xev4yo^S`$`3edN*(=BtqXD!8kG9s0)z3JpK z`g&~lo?d^7p}gk;Dtp1e{X#&y4WaG=x^FKZW2YoNK1KZ8eP3LMImMX85ym9j%*=oP zRXWzI;lhsZPe?dPfiCb5g`f`|S-P9qY@fQzloZgNCU*h_^%0Uhn+?|!Fofla+&tZr5q5KPlf+^PHrT$8?!W%--NKL6>@X1i zA)k=Nn~d*yW$hJ z&x1mQg+FuDo2ju93*0-c4-`5uxNv|pmjNN%+tXWMtB2ZAVm|rz3m{AXEY`GcUcA{O zL3BkC(uhtgh5U~EubGoKZ&8CdB-jU}s4(oAgQnRr7DL*>_d8ZV zoq*x;pg;7NA!@;Ok;xJCHrwg}h4|(PLNbMrDS#I7WXeb^(8uRrGOv&~cQ!xz2BbFo zmA}M)2-TzECvxy;{zwt8+`2)c)j^#gGAlR2cxfp?UW$g_GPdq$5KUWWYZVh0>b(%j zyXp`6kOBrFYZ*W4D(1k@Htz;tIx1*QJqmAs%D>2E`7m2JjS*R3;#yem z?a%X8?!>y>M$h>J`4B3;d)wH$b9y8N@ex#Y>cU@NAeIi`(A4wdt@6R6sf_uTL}-sb z4j{pQ4P{7rivA3&Tz>e*B2xs=CFH+VGHsZ`3C1AsOL6g^K6KUIcQ>Ez=$vq&Y&4K& z77EbQZeyzBRgPiNZ+o)SRrL@-IKHz=sGoWpx$jIZhlf0%w9Wv-UaWCxByR1mKG%?%_DU61)Zhqdr+LHJV;`jEN>+EHx%Hdme3L6a#Qi40&XS@L=SE zvU-ew#EROxm==o}@yu5jN?6}ki_!vz-Ckd4uP@fFu#N9p?@g%?kFm#cV}G%~_f~IU zxHWlv#mdnqKR#9tSfs7hNTQKHP+WbGH-HkuL<@BP24}9_(+Xa2txk3 z=FMvUpp#G|PeXqKchh6AcCUfg2FUul9bZP7ptxYv@KWB}ONuv|5MFBdJrF2eB7DAp zaR>?FX9L{}$qxVw^$)lMDuC5sHShh+%4|7^&l$Yr{^r7LMnGOuvyRHqxIrqeF{I7H z=@vI851$e#4YvmMuh5*D_YG;wPK_)B2IT`Br~VhLz>j|*0k9+hP{zd19;3rowe7gU z%b%s=IW1yY4ZFetF8s&L?(2hyazr!Y2h$ZtX1NMp2GEo&mSK!K&WX910E&v0A8W}3 zD-FAG^IQGE9j^3nX6w}2Od?iT91tD;K#u52130CEgQ=hL=vLNskN8j?T-i*0kBZiE z**GZc7r5#<-I*riHf|~Ob&hwa{Tt+$^|icLYS`r7!3triR@MrwT29d18;*XWdg4tL z0~goXG^XOWZ{H4&37AdJOaS~$+k{>aA1r28-S58&%&4CCz#MtK+HqVA1N?H-B-4b7 zcZ@i6GH&7+(;HOcA$%G3TVp<+n)MJY)-aq5m2UKn3HIKp{tprnZ4zi<5m+5s!*N7U z&_thmFAmvGrs*3W!Tgu%eqwhbF>80ug5>({S3M6IKhR=LUGHH~Cc{&36yM~|&}kh+sm zZ;ZP6^KCK4`idvMf65+<8}!+5;xiIonTZ@xGYc|d?^`RvX%p)#6R(B1bc};YLRv~V5-e73YMr$yfUW^z3oIpw4{WYzs~Uw!nk*Ay&$O{VsC{5|+&!J`m(=_TT35lW zr`t1yp|0uk?kR$OWBuNH{83Y*^buml(7+O+BEYa1R&B!#HrAi{RqTg{7Hr{UQL>7O z90WL`DY~RmqViMsU>OSU7)m4v>!M_1ivH@-k3qKeIR2&-4lQ-U3V+)Fsw6)bC!g?V z^okLyoD4_})TyCNOSJ%?a0Q6s_p?%t23AFk!Rme@U!9TLsyKLzVBKzSONro_jvzQ{ zmA_ZjssJM6PsjaTX!$v+pDr{z<-pv^E55DL)Vf6yT0;SJz^04etFxQE12A$|XcNI2 z`YFPdK^_YzVJvzjttDu*4H6z{gPf24W!6?M)y zkzj%8`y`#W3FSRjc4oj!EF*;Rjq7&27*~+0mCsl$5i3BfD8&ON`La}!qvzNBfys)Kr&{s)A!<6aj;KuAEQ9v}w^TTH|W$1%lB{ETNI zL`+;hVKxeW2Zg(Q15`)u9g^6a-}sdSd2ye=S|NT5k|GCeXpMhMORc$y_P;a5FIup} z$j;JJ_;$A1UB@*W$uaC1#!tklq&u&W26yhaWSt*6qA}k0dNWS7@p~kGH=;fs?o^rp zoGS?&ZX%PGtP!y{*Yu^Q?H_sHWJqKtoG<$<#6iRxC?l)Wuu7b*3vp|I`2TphpoVBj z)2;L0^AF_IAVPJN zfhIBi=fT$cP0E!OD5>7itmYe4nt6*9!WMX@MSkgF)=ad^`(H74c5jgLtH(Kl#*5`d zdOD&W2Cmdzk%nLQYUDAN)#gjV!J3qxtm;0gW3JOZ*1j_C+#E@rI$v;m;9rYy3J~YP zPS?4T>C~uf4j&Ce?&-uQz|QHR^0Ab&bIwuO+@IIddak?)NNt=we@y5gylEBju+)-{ z_=@A{B7lgtwnq}$E`x09g1RSSKcvodT~FCFw&R3hW%gyNuxt0wHumhY_Hf#_5_EOjm05kX z64*EgrV~8+!fuA>nw!QC1+w5$RM_bD&uB^eq4!KPc?+Z%+E6E@7FWUvB{d3=2z+;v zu2L!v+4f~4`06R>(*eNv!sJz7%s?-C)3ThQmYG_p8l*jW(*h-K{WBx1c*GvWM z3i78x4i?K30eewm1?q3*(hZC{npiv|G9f&jT#kbIpJJ38O4W{9qzFzc^Bz88zCX+4 zqVnZtG=p5*p;d}4ri5V}=kySE%9_`61-fzfc0Sxx*!84Y!{5F$%EKbjzUb@G&QQhS zfN>dhBWhrfVprf?Z!}d+Wu#HC0==wlDClPb(C2>T*~~x+h_wLKt*GSrtt?6nop$bm z35E^f^-EV3!z%uEXj6WdjHJA*Z<=`wzslGRd-sous^6mA3)*KAW}g_;HZ*vMZL-S+ zx3Lnro&D*MYpAU>>ZH_?SoOM5wOQ!cmc%t{4i=^JG@Sj#LUHpid)aPX%r<~yyeGQJ-g!DoJZ zZm;}!6WOATFae@Ee!1Wr~4DLz}fXS^K7?UM!M| z+n}oX6y_^uro(y51xMLbPkXWDSoUK!Hn{b)>d`?sfQ`KFV%QwQ_`=XnU1Jr z@j1xNnd|uWTD$vuqox@_*J-?Kf``HY`m~TWmowwA*c1~}!)DpmWnX0DQ)B^$9uh%$ ze@**X*ju-%>I&uQDdr-jU#X!%xKP7N{{cb4@3QEy#IH=;(MllIXGLZ)DY}V|K4O4u zM_%!`3*p6Pi$y}B%qJ`bVcVW*k9PDw8A&D)hB!>-BNCn)-84uD+*(A=IF9K?l|Vy% zZgK*Zd5sL)ig;KAWZK;K>t94gIR9jttrEeay(!gvWN-5NEP+LsFppx5(KYbfN}FTD zC!Z>_BwcFCCZs!)zK;ZB+#0*wcD~dq`Y_il3&FxYJI)-IyVHKj9f__Cs>==)9{9zA ztg%FF!MH-hSg3mwdHvOM(jf#meI9wgnDcC$w@-S-IbI;&9-{yoWf0*$ZA7y<1MZB+^KAU zJb>id$>cs-9)?;*)N?TC8Z5e40Y20AWg5Jm5Xu~}G+Jg6y^<^wS!C5Xr#muLq)*mO zeRJI-Ih*CT6%%3(Vqw5X;zOMVN2l#g*;;Gm?cX^@w!msHA}dWA%GK@wef(|w|=y;OBybwf5RAFV&%RxoP8pL($1!AF=Fgamr)T@ zLU#6Wi@VWelI(oh7{GL`O&Shu8y=2xH5BTNOfBg&YR-*EUk=X0&l;n#As<5(c!4Ma zZ4WE~ieI8}*uwRw=wr2HK(5llM)-`rXhqPtp3bDy^+a8K3cSNPRt}|Wuf8PR?t)M? zHXO%M5jd$WNbGnHRx6*)h)wood%(8rkxlpK5LVH4Y+e14kd5OXcTgZ@%j% z&UfWCoSC)EI6mPcS^(+fkfc4(_QW-Hl50W2c)^5>FBzY>k-w(X(R^iwhcBJn*K+px zah$N=ZTGlqXUX45$s%T%k^+0aEo)T-j zPpE~EpNk@qRxQ@|F>RPK#-RmiXnzJ5Ts+=)X``Y2&`u@pWEpTa-`<||ymChp=4Klf zRA-f7fXUN=Q>0lW+qh@bJfTR1e^q-~n+yxew_+;(8XYz&8sd4KJd`fNYxl8z!7{4< zj#K8Sw$;vZGf|7cm8XBqzHx z<6t0K#;=)0E`tPG>4$W2lV=o`=k?uHLmq(YtqWTi9 z$A6%VOlzq1w{+B7F0zL{#x|AFhHHh4u#|F0e1hRN45)Z2594qy@R6@>Ulw9^-M!)S_(3v;%jHoax)@LwdrWu%7Yq*S}szrPK+V+_L zZXds5RWI~Y==ebk*;@fG^B9gb0FnfWi8r<-QUd8aZjB$nX*4GsNV)k7dj&7>jvAt$t)vnJF8%V^R6+fbxOW>N0$d@wZHU9!&97}F3 z!$WrLqn0_6j$*!6(|YR$qor&Q{gjm@@Mz%}T}>^|?$GU6m<6|!e6qMMR2O3?c_DT0 z&fLtSL&Sr>ryu7Ao55JfPUaIs4hCoSf9!1NG=h8Thv#iRpn}T!eBYns`lAt!nKIiO z?JyA3vqYtLKw~*05SH8ExuCtFNY?UC(AQ(TU9Aer&ZT;LScxf}mJ`34KL40uP0LMM ziegBVCV-f^OU%K0Gd>+jK_BVZxvxY)j8t5<@;j4z9X)1zyw4i?>Vh&to|#Q67%N%Q zlEC0bzBM0WjF zwe#1`+;xzo26CKyt^8Nt;W(~H#T_2aM5oX_Mn;D68k`oCEy+08w%k%FYp<(=9X{NZ zQ|H&_=ELqWr>9ZOQw`>R?0bW~S7G*b#`Q;Ad@@Gm2Z;Hy!is|J5F;5**v$X@F8~@W zUqSEXkb{;hI4@BL^JyLsQYsyv7J-wvweeP0XHh41NBMU5lJOtJ7QDyZ0>JY(&vn=& zTAVQEOuZ^`vElZsx7&XG+ETbHjHem;$`**7s_TV>m!Id0wg*-mbJ@&!HxxKdcY9_{ zPe&|k8n+Gw#W;6=ZOt-?o8qlWltph+EA?GdHKO7edNL)08RI%A5;Zhtm*FoFZqkIe z<~}D0IG6V2QCA0%0UW%C#94!o85oA6=70}~#MrgiLoQ_`Q3yf^wf7|4yMI5`d!N=i z#%PZQW52i|Q#ajzYAn2Qlm9O3!C2QMAuTk!{KW~m=0j42eBjk=R>)Ky0@wGiyq3f)%v?`|gK65mtyplYI?jXItEY#z3W{|0g@&G@9 z&eTa9rD0WvwJw#=j4CtlfW`&Kh=?d{K?9>Ldld3b5X2n6`>5!k!iEPeB3AB6l3M;J z4YEl!In|vVY5T;N(i%(6i8s5*NQ<2kGU?aH;ys?@UYV@HPHBf1E<2F{Cr|e0Z?&J=h58rTGrXAb zC;}8w*W3R~WY4o5!?oPekZY!^b320LtU!`AYp>3vx<*Da6Uy{uDPu0yEA=uZ(iA#3 zh-_c>EEWTzvR{QY$Ftd)Xwk8pgm=73Lv+cvxZSE`bDrEFPmDaCQU|a>Ozk^^%b~uaexgfWn&g znbxCM@95-8`x|EJY;tGvpu>gJ)#4ti4eyNBEW<8%G!6wcJf!287Z*&$CVSpO>~@5v zb@;N>FvRN5u%%{+pG9bE6_Eg*vSO)q0?0T9C6JN=rU)z6&CsnF2#rq*+g$Lg!}zls zmu2F2Uo{PNeoDXdTLUVDy%^*{OMC+iozgsTyL60DQ)zu8_X0?~Y5dN_j~G%NwUjvO zx$ZB&gE~fo$2m5RYv+kK_%C4>`(b&lv(gUD@p}@FAs@5V&cL*}6&!%Ib(?^;wj2ak zob1*oEH4?)=Y)|v`ODmSxAeX0-8k&k`iBcAr=xW{mOX4teZ~Y*W4Nv6#-gfkv~~l0 zks9Pi$Fluuu~1gqp+YnwMft+0zB+2jbd93M6j{WDY{yd%mo)J#v#-DVtA(_aa{VUF z=({?V$aSMBRpKvq=(G&mE!*`wJF4?>RZW%Jk_&3Rkq@$s>#)DyFyW_JswgBQynMQ6J z?4a~%p5VS?^u-N%5Bfa8$2FH}n8{^B9b?_hEyVxJhFQKde+rCWH{HN~WBp42T6#mx zPO^f+ye8%#DH_7r)9GB|>UHu}OkF3K=HV4cOxwQHXJx-SC9@O03;=@~Q{7 zd#@(3Ie9HPYv3_fbgjP4c^qRubwvUvQ9fessbM|y;0*Qohy*_0gE}D>&gGH}wwKyYIN zXm((*UpmSz`D)_HeYv*5Jt*@3VehTNs`|P&P(egMk&PL14@wfhD4dU>RJuX+9U z&_Fy56`TG2)Jv%d{gBA>W-olz1OfAVqSoRbcRn4+%fmP#dJQqBx}wbN0)`=v;xucm z2pU=DgKD1K5?ijDqYr?^CclNHjge9BE8txVQC}Y5VsyWO} zuhr6cPO#(fFgup+;22x46OQnXk z++~pC`W}2}%RPyNU!xPeXigDqom8;%Og+Z`asNZS>+hw`MMQ@O+{ny(?T$jj_*>3U z4%y8Rk8uXt8m;*^*C#OzFV>u8XkBnNn|G@h`)TV;*jE&O)gjfMx%S>~x^y?B+IK%^ zT+i<>+=z+5&FP;K>|fu?(X@RFzZQ>F`KIjNZ;rlZsrx<*8LLE!ec*!h%$cDAr=p+? zQQXaeaQsJvF$tEM3qVFwF#j~YMvSkP$Dp>u(74t?xKZA5(+9U-9i(r9kq>o0-iLUS zQp{w6S=i(Z(BtJMiD)KMs0|Sh$U$oQy$SnHCmX9QCx0q6JE))YtgSsRVa}vp6Cdn8D zxt6M!fi?yh0&U-f^<@*<*aY&B@}*Z9uhPhOfFgwTFBS!W*t@$R!Tpt--bP!o6(i;Lbt~Zq_o(wiIUH0L8=FeXb|r%Lo_Q3|scAIo|#n z2j0D23a;yId#+RX;k*x=0wv80s$#W$-*F_b`WyX79VtJ;jP!3T;kZu$gK)t~Qh#>_ z1Hczc@rHOM3CN8&^jc%TdhBUopPp>V$})_;<;s(CW9dd{UR}eR3gfOfY}lpc9FkHi zS41|B2&@XUeaCa8&~xm@*|)x=2;YSuaABNM?7AVK46b-Ld=P zz%zIWHGj*|aQiDh(_J*q6_u&U<ekJfRo@P3>uvOl?M1p8 zKSqxgx+t-4TzA_gnYZ*sR&!@st)g9u_2W!=Rtc6|n*XZPh0g6Tuha0L+Hv0~+QOy~ zDXEY=rYd$I^@w*_n)d9bKYBCedDBVo#-f$$#m(r^Nc$Xi-Uq- z$q2i!{EoNjuv|lS@Wv95^&@r(U5rm2Tq=aFW@LmGT0wG4lD8V51Q_-B5{?@pb~7y{ zVdkI=x1*$v0^3n0U)hA^zK+{x~d{{k)T-Z4$lD(|Cts zJfSP>Er*32#v8#G@zSqT030!_CPyFyxJcurKB@6z^p$!juaN3Fn5N>9NrQD@j+bWw zSI|{9qLTAWYu}GUXlzosU#+2yQ#4w)kj>=`R3my&!`riynTk_xy<6Km|a- z+^73!uMM;j<-;K+nohXsty)B1XtgA^H0Y2C?^7LVkK1*=qV9_8;KNZFfl13VrP}pU zJ)x<4J>hkFAma&he$1k(jYn>ZZi->`AWl}_y&<7_a4^AR2fvBLN}m_&t!@?>S{3^(S>EJs*m>QGUszmo-iu~H zz1ZZOyrTg?OaVu9|y?vJI6b36l>1W8Z5kaOFql_Dp##T{IA{|i*ljwadj5V9ani0KDt>T>1bV6-_T49o2j5*!?~_D$TNt!Yf|k zr8~C50;uQHzDLy0Y|v3)mg5HrY^9}762g*9i(Z18$W7e{{p^fU_-SmqTgU>*-PWC` zU(ZLTI%W1H)C837tx={p&H%6HHV<4wdd|7vNFDAH&EGGccec)p5M{$Ni-?7P!k2~a zBWe&K`IH+-T0lH6L6OQ2m+iaD-rVQ85l3(J7Mjcw24}AHI|J_JRs5-scBepRy|;*nDDOi z{1*!5NeF|}SNc5_bUw>Vh`&fib3a*}7tB$&V2)K+F4cllG;Y*VQ)y2AVmDzaHYJ}} zMbyp-9sp~2T0q0knNcWo_hfD!MlvU}Hg9C_k16Jy4pYAu9}w@y8kyg4c9~rpzHcrk zdW=BpzQ3oCc+o`@^c8~iK!*DzW($V8*Bf8BPMJ8JDxS{rF0Sc%qr3CYcD{f?xD^lrvko|?;yS-FP@)|X@>ubw!12ucmZgg-~gJkCj4Ox>-&P3(m zChyHzp;XKu=Rpjn#!SJFQ6F&Rd#MP%d$?a}2e~f~!;Bnw-h&M}{8Mzj$qq$gMiiVz zHZVm~PlpPZd>~-&KS;{X_g>OC)kkApO*XgOO+w5j=Wdd+`H~5%)+J-V{kIVJcls>e z*0wD(+|a6+qUQ1g91i4|v%|ezUXvfTQ0~IYWU&$h~3|SH8l(+H7u;8 zBGJuZp{*F7Q0i@ zhuRXayq8|B0k|cI{P|vDsJcdFmB`)=jb9O}55v68I7x}g1Z5d<)x;i&-u%H>z5CHR zNTCyNfB^4{>816^R#i`65{|}Gx79Yp=E|3bb=qJKHrc$_ZrAH=1A_Xjqo}4>>YD6awK2&AG@bt2tw* zF4!oDt3zM=*1~ZvO)2`DF$9tuNTYcke0rG{I3lu5ZYzK4RRtZq=*OYv3Lpxez+)%k z0i4;qF9StNoRiM2u5553kV#_X*`VqlC;l@0jC8zfn9}yJ%SRLjc6$obN{|+z^r{ zpMek+LCE{cDm+iIps+;9L0tugU-zll?sPw=o&|kcwXU;Ee{aug?uj`d9Kk06GeUz6 z@GJH~A9d+%71wMU%_K$~gP&mAi1y%MI!aj<=Q>x|%`~N_LroNFSd;EQ?rCr{eFm^% zTKtsT@28^thIVH^Bc9EjynH$mfN%$GHiKhfwwhS8;I4RC*@fS?wg#$~H0yk(EhGXE z_WsMxVDz*KyzyEy(>;FK#`ssDfX^2Nu2LI(Jau6_cLy6gzppyg;PcAl+yCm_?NlKy zP5(}MO0#rCfy)FClT`rUVuCm;d?R~se{KpK&IJ@K;e?@;A709)HHg&rmsMk+JUo>b zfOCN8+;K0?9kVT1J4gC<`nnlWmN)4~S{kn38Pj$o0|ev$ew*#coq zt}sb)yYzSl=RPD%mOk<6m1RN@2)5g5uCLHBeBQGPf452=Nkf076guZ~c9rUuj zR4_$6W17+Qd9p}0K)eBPfI+~dH+*75d4)tnLjwx2?n0050gm9^8#aR%V&CS z%>MLTY2;|z-fahvEoAAUuJ#hGXx3l5hjfwTnR+$Y{$6$sWDlK<+Fi}X z%j>~HOTNFL8`=SgI>kXzF;(8cw)pRkq# zEzHnFUhhfxKyQX#2?`7%h{e+0qlA8$t!MfurIQad_~}39&CP)y<5UWBIng#h6&-Ak#f>`mj*Nga60{}bYyM6yGYL2dH z@D_e7o`hmm5jJKK+{AFU!9qk7=~Xs)mXzp?|16oNofz6VR^o zQ89!CBmi-)sQ*x;V8T6{()?K5|HI1|7Mm@l2?*661G?)4m{AqKgSM?oeIY;|@^XGV zo~O6FV!Atk7$M06`~Zcob=#O8LJ31T641f`7D4(?Pop!O!{<01S*KgWkNmOE=%h4T zX7O7}-sd9>v_p7l|0Pb)XyyR`eg2x@6k)Yd+;lF#tYHqDA}Rq)=&f>I#ABT+anz$f za-BGP98Ac5G!0ZYw~E-IFz;eL)rT=n7~GFhPDpATiHF&7jJr-fVXb=iW-FA;LG|Y^ zmFngv9XIB}3DSev{|wWE$y_mlHzhoXB4n=;Dwo(wI)FRlIq(nvqsW{T%)?A{0PsMB~8u$r0&iHgRXGj12LyB%ZMJ zTwGnHG!ysf4ohwhtBXx8vE7&$hZcOX8Qj8vIexQ*&JUzFPD>ma6^SHoQwxMT9#IES z!1~+Fwuz{Y&@5B&-#Pp&B)^)N1PLz_4nkO2#$wNkF#q9D&NY*DQ9vT48#KNe4jAT% zk^iBD7)=xOs@94MuZ`6z2)#x9_7OVYXGHK%cM;SlU+<4=xkZf?LAZZYUs+dZ3CWY}CpGlQr|oyPj8PBj$D)8*Q*(kGZ-lvNJr}qWG z7nx(U+nu23@9z(kWiyN1Y@s%&(R(2PL~TT#2ia^OtH~w-;{Qi&Z zr4b6Vv)hDvbuUjb}UTXe^*^XuVRBu=u6~vXApw!q0Fcf5Xd= zlq{Sfr~X=N`CT&ju@&H}mh^=M4bix3Y|{c{(kg&3O)0kV`d6D9i#T@-yjHR*^$sAj z#2_QDp|SX3-~DbOhDME*3e)z}qFUK^uU8-zP*~b{)H2FZ!%$RE&=Aw=Tx|u&#BQFjD#WZVX@s+;revlFmJBcE-p@Tf-bJDO{mlEba5RpotVtwSr+ge+vpXCb+ z3q}wQiXg5rC$ke)r4#x*cm4Np;EC?}71Hw)xlhMq$H(tq)<>*O)iW;4agRl3zBzw8 zw2$ts)G6GF0Ok12!+~Y=xRM6sRJ;yb!n9Ks9IZ*v570LO%G4eKoa^V-m%=c*>!LC; z;omxLk^zp56d}9yIwinwCRq5kPyXq>lw?FZhKg*`q;j9FhsT$<4z5JaYJOCVn}IO9 z!mSF5w_|HtvCw5qrG+&wze`k2{ZpWuqsczu!*-DZ z5pfvDWPE{oymwfkpP87OodoE%&<(3zV7<^!YGoG1u}05bKvW-^oX>BZms`C$ zCR+CkKza$;Mf22fkX`o%WhC?qXQfrO)=&~V69%0|qpF;bWP9#+!zrvv0~6;;OVgru z__R0mIFf8gS9a9C1E2};>% z1_UOJXx}>1#2oWkYn8q!XWSlM0zTXfAfesr8yHlJiiq@nk(3nrhKGsipGFLH2#OGf zUM{DP0MY6D_wP=Cy7yw^x6$-#u^4KVoY6EBOAt;5Mv4kkHijBZgG@hd4+3c?py1Hi zdR;q1j!X%06EhFVY;`6fny#S)K%uNmu(gcA_&5#T`3Lj+G>T^jg-im&$x=ZQ z&?qv7W2M1^gcM>DfZ4dih_7J}_=l~p@&xx=O`3D`Pg7g*d6U*xC*A(g0+C%L9 zU~0<5Teq>WuNpJwvMFyx-9u-4BEG|M!CYYd* zwASq6S73-|AGl*xk%oA7B2N#zs~qhIFRehKLG+22etekdZW>z2Yzc2FC4EJp25$>ROhdYh=iQEKb0)MJVt9toLxY5Q|qp zA(QS@Da}HI(iEKrc>|kSjGL27reMyS2v9~Mv-uQrzDE`{9^j5<&`Q~2Br*^Y*~ZZU zmQMk0x%s{y&92Qj{_MPoScc+?v`&hrQ7$&Vj|OoZlCXWp)LBR?2Gle%^7KMZLlixc z)*?kY@W5Vcz*Qi#z`QFS3S#fLs2R@gn=sUjdZFn~lJ)yab0ey2FtJxAR+BVm!LcdR zki|+P=vRg&g$FsB1>RQA@eI;ZR8k5Ef6H;C6sEdJg9M4dBbx+mYk^79FB#0W70~LV zOzhcJVN^PcyOdkI%10r>*&0{iCsQSq8vgs!F4~Jgecq;pDXDDOfo({aN^p#(g znU#GmA7-jJaej6&!uUOV2>;b)_K>Ev#9Xi4>5N;s2nr)9IT_=Z`9jnK^GoXDSra2+ zXepAwlkgkFX!4p_#LQW3*#VwCeAukkGHQ~Z-DM=bo49sOV#s9tz z1<_A=d`|@73jvk}rfQ92fi0TdrTjxVf?}>E$}WR#%BPIGnv%FfLxE8?6zVk5At&+m z%zNI^JQU>IVILck)^t0ftG`50n4_Vv9BejMT*NXpr8K=RMc~A*YQOuQl2I0P1qtu@J49Q4z zCIhG9hRN-FyOS;Jy-AOgq_sbS%Ya?o@?ze)W9f&hK(cL!=tv30{;hW8Cj&r``_~0b z`dq2o{!L;5GW$w>K|WU1#TSvhJnQSz#~8JjL8YmR9T(#`h-%`J=l8xfqz(rb95D{z zg_^aWaaj5z?C)>BZPUC=c1*IxWt|AmzJG?s?RLNFcuUECnOYMlhIl}idRsz$YvqSC zUy;>VDc>|8kOd|d&|9XYm~e?%o3z>LMM7J$<6@&^5yZZih!`Kk+Y0Z-K6E9bG8l@8 zW-?T(5ONrGJ-d6n73r~0FfdZJ;9+ynL63WryTGL4_onsU$g2p0 z3__-6=X1n(-cuJt$@5*Z{>(L6&c3OJ!=FWocpSeR_!}02@H(_FdG-i6Tv&**W6BMi z&r@7aZ`2sKI-~??uq_&fQ_4Z^w>`x7&ixqbHK9qTsX3{!4niT(-{Yq7J+ zvSeE(OWiIHYl`^~&3F1zaAJA%Dj=6X1bp5=$LI+=&JYx~Ujrc#dXVc5HPE-!o4M9| zyk=J#Y6N2#&6VrBM!DWz+*%Jal!-OIeq1x8SSrzQA|Y;qU1u|T_j}E+AIdN#0r{~v z(}*$s@mJgtr-AGH`Mo+9Qq#7}ij50`?*2LbeiH2uGnyA;Z)f)d4#Mfrw@*Hi+#rhP zPZb?=;#IbsH5}h2yj86!qXAWgvu);(9S<}|Bu#!mbB-$-6s!22(afM}T!6okp zx#DI@1zYjjkVg0OzC`PBVGDVq=7W2RBw`Ne_`aPJ?#JmZyle1uo%L8%Y?f#Y^H*Wb zLynVmthDM+ZXjKrwAS6u_^|%!h)G0@!n9Wby{s#^O_&4k z1C>edf|K>7%wv?CdA+J+!}VNW1g8m9fpltL9$yh5i#^Ak*0tX1cwWSh{0d%|@%?g} zOMy%(9_W#O4e5_5VZ5s5C6(SSx7hpkmEYSKcAJskIH?bOcYR$xp7v53#)j9h(_!kC zus339Qz(Kuv4tVY?VuU9$a z^-6}+Mh&*6(tF=-y@b`}fK{8%Mar?!F+FDugg-^Hz%%vG4&Xu7;2(*$*LLvyX18Y5 zT}e9~nPxdO8#%)d;9O*vB8`@S4c`ln2dtg)Lk$L}--NaNW;q~xtBH6I|DUJchX%h% z$4zz-s#I%=UlJ14V-yXIE4EGB^&MTS9Y&Zex{e~QraURfLW*#RFy)G+>K|Psp#e0% zojBaM=ecsh1z2fG6lV)@0fRq`GgbEcTm0XzwT2475qZbPcSr8eH*5v~EMq=~$MIeN zNsSzp(&Q9-n;_ESM#}D9s*mMad#TGiZ4R8P6A)5gD?_MYyR1_T-B(fv0;>pW|NLrj zf?4^GulHT2<)9_h7mw3~H?f6kWn&V%d!a2S5x!M!3bpP#A-B3?3YV=4EehHkpGx=L zbMH?5sL;yg(GR57HsKE4R?Do9D|3>Npbp@9-A@SX4zHNr3OpmQ-)2ZRdDmdx=1`$dcL~|io_vhn zg?-d!mcVASW%al_GvP;{vt3{$7JnW?r@RiA`oUANa?o`xx#v3Hxgc>m*}lID-iGbo z$;rB{vpdV|>uiaZ+d^N`kbf|y@j0GC8fc#oq$~O8c=uLjO&GmS!GkuufnK(Nq`FwH zLvp(5R8}@kaoqK4U5_oVLaD78a}&P1fyoaGW`25cf_eD_7cLRQ@uASGvC{4gC zSp)|wwG>w+_T9UU%reMuFg9A+r{7eug(K_-dfd(8l46PzPyjqM67m7=nObch>RY#F zm+d{I{Ur*ao>L)$g!KDG=ADb~f)|7nTd#ZRi@TMHz@HD|O7 zk9JYZ#(C3Q+T%~*x=Iq9sM6gjETx-!$rOdZor-w6F_#Jz3Sd^`VmI=7%&OfApMkRn z{i97wOeWKkFX>n50@N5OQ9u3r5SK8%IXJz2JT>(O=EW?WQPXj&SL_b*g~p{rpWL8e z{bcLDTPen>S;VO3PI9dx5*W>-v-2u^%c?uyOf)LbG)F7kz&UIb%3ocR#eY29m`-BP z=NQ92oN9X}+c?f*E?0-KKbQS8Kl13e4JwT$#o8Xt*R`hhy>wD1$MJ#>PK-GuXBt~b z!v*JldAzeH(#J-Q0K(&mbwh*%dza=+Vhx3oKny<+a&as_I4?^YEgD3|aj^OyXA*27 z2EgAQ^@=cbAHSrT??$l70;f+|tc~wlm0$J2w2f7nMCxz&<|SA*_S1>e*w!1dd6hQW zUn3l=!nyCRQYG6duYGU7P;;=B3fxnoeIQv4y>vvB{oOtJ+bR$^+a|O3qf7r(xOGXv z9**Pq7;uWr)82)}!|3=YGggGK7{5(_bxaQ|PwK;=7*jCg!Cl9Z5Fq z;h~kl=6*NLqKaXvU(IVB^^24{^J% z-u3GMMrD>00*~R-;&SQZYir(`gv4vrbY4DfvZqR9|7s%3;e&Pmrf|_G6Atw*e?a!` zABzLN{IY_q8%0Fc^QOlO-+~NqfctU#nXjcqYf!9)UCi3C-|t(_0~}6&hmHi6llz9p z5Gf4y5V{J1EwfCK)6MWJy%ajC+^rx?O^J{C75g<3aHp_IyjDTE^p2~O0%%i>_b0!V z)+_Rcogz8;i;C00c1#-1G;PnKy9%;4E(r+_B@z@ph@?}(QZ?3S>=%g1xl$_FPPT?y zqOMT3^tzH8w?_VVKCdCmMB(f<*}i;lY^^k|Kw44tL+Aw_QOUxsrT1}mFd5m&yD1%f z4QBeyB)yl$G&S^+^lrx?x1Uc#9c*}RxWS!sh|(lJ-Z0xss1OrwzXE)fqQI zGHW{RlaA4}baLS)WA8}6U@{xMdk$o4zL`?$w%-eHOhm-5$^_^F*cH(?IYU3nG`Ecj zXMv~1;N@NH)ECv>aLD$xmb}a9O8GhO5Hd?U%Ub0{ZJ}}6{4nK$b$sZ4hJw=KYzt3b zq}E79M-{o{55h+)%xL1ox0e>jLi*Q(@r1!4^eV(KJ-0sdSWkhmQ^kGVH(_ECF4nL| zi)lY6a=^a%wyu62N_N2>*XbgA9^b2|TrBTYX1I3WFHSH2r^_QecXE}C9n58Ds(ZMD zP*Ai>C^wCeL><|t-$movW}HnVe(o`2_cqP=~g+!ug<0$z(J^jtXtMz@4U@OPktt9I;g^<2Vm%>|r z$sH049u8TI`=iJxt(5Y7DU&z{d>x6)VQ@*|h+}Ma8bmwo$*0E^+9_W1_uQnkf)SmQ zy>}4%A-_oVLU4X|S3yoanK=-;pUel9fI58dWia1FNRe~nM{eF;KG4)Ftp6lv6jQA< zlaq<~vTzekh3`d+8rGR%^P?eko=!yk_b1~oCY#{H0ECs|+tuq>LE)cBaIcy^Xla}b zI11B$ZKk)^C@D?`*Bcb6^<&p8z313fQ;UsFrBmB)P8_(`jA}x-{;&+LW?6m1Sx_P; z9*IGt*Q$HTes0r0DYF4DP-2A?dBAzln2}_8o+Yw|1?U_;^%WzvaC-LvMH(S)k{pr; zH=A-h_Iew;Ee9K%rPD^%lO|<0lAw*mr-b-UkH~U?vmMVWY}vhh7rc= z!tV*{8^%z67uD~7U~@k*t`af<-OZcUeNW=qbH1c6S6Z<>kH`wwML)8*UG;&fGH3I` ziLXCiDiN9Xxv=puZsOG$0W{kMN)E5ly1ppT;2m1+gh)4}$#O%f1*+I|-)^*8MRRSYCEn+BjxKdHvds>SVd>NjP<$E!iMA&9k#e z$>y#&-!lod>Zs>KTnY!t=bAx<7g7OI=%r*r=oZ&|_|(70xj!YV3cCV3uA2G7)gX+* ziu^U%E8Y`tuQ8_*Zk=@bjqBc5y22U?=Qs5Z8Zo0(?hY4j2Tg-3wvS2JC)59+EnmzT95&U;lrS2mG0K`hsq(8v2;u!sHt(f-eJ!4XRb!t#)cn+rg}s>X%5gh*89!o6c{p&m3u=gbyb0Q+7^Mu^DdE7@tTuS&-G=Zbv08o6RO7gleT$M=oN%gSU#er8MlX) z^bhB_vdsWu+8*%0e zgN6QgD(_*eh0xh=>GVOBM;19xE7_Q3MhfPe;v zgT{chP=fR{@`1CZvydsti}63TrKe^r0%zID3jY>X5I%P_i%Qc?Xd=S0as0YQ%smm8 zWFkM`x}?FvF39M2&KASJuq;51Kk))8WM=BcB+mM5rGnU>G{(?anfxQmL}ot@5K!Yg z8Llf|Ukp0@ZtyFbk||<#;JkrjH{brQP_35)Z>Ed?zy6*V3ZWX?8nI@{LlgVr`W9O@ zvD5gGVgu>NWVEibWV-G3qa^!~&(1{ePWj2dPO>6Z5sPiqVoL0um`t z-4!2nov5d`S+Rywb>hFn3Qw4FU!W({bz!Ek|2uE%AAoVzId9CG|Ep(!gYQ9wersB> z&R>rGKh2Pa6~Mfo+1!mbZ1@Yh_)i!^BnBs4I{5$bfV^zssxgjiAuFjz1KM?{;u5IN z{2jx{HhiW)sf1_gsH*VDAQhEVfG*@k-X^MLs>&ty&_Y7F!QUSP6O2qIP2s&i$M+@O ztiG9971a&+FSb;xn*qr1;~Lcf!c&Ay*fY3HwNkqY^y#Qrc2u)*J6yPUAgn_{u}qyk zViG@J6SCb`R`@&9J^Ii)Z%y&fb-&kTo33$y*wmELIXQrbEX4nx2EOk1RDixDv>88b zWgW}Q7QXr*u;jp}pVd@37mw{;S0!Xc&qf3YAc2<1(hNTaOgX0RcY!`mJ}Wk*QXP4Qm`P6|V2%udtY&bE8j zPlDj_5Pd`6D;q493DTspeoK=m0UaFZ$y0DMuv<|uOm9r+l)d7RdfGMlek$gPB@$7< z0k=_*J`gKuhI?81VyjStRf>e;aqk;hK`gL%huR8DI@k_DsNNVibmuE?>e*2pm7|pIX-)R;2#c+OA zR{&4LdjZTedmdTslHuyxqz*L}!)^&MQC5~*=iHlj1~fzM24!s)6D8Wtg^3n4qMoDd zSHT3g0xoi;ig#b;MW+%{xY-no^s?VQjd@t0$t4gKq3V#;Y)p$vtA0-%fEx(hbwa1i z*lw##D6R{;7va(&2KX8JW%DEN&dD0|wZY^G?`7k~ScQym)m=5j=NoT)jXjdpu2CHd ziJuYa^FCb7ES}_GFw&8u<*}*3{%Wf`_6_!5PoCP#Hvb(sH>CM$H=BeC_s|VIDa^30 z+i+JoQmtN&@CgzX#0&AIO1KI22Upz;q`MED1~%PtHIP(K7T04dSMr^lzCqJ%F1YB0 zr%+CfYotK)#(wHW!cJkv$Yz`;!}|FqofuN?9_E+a>h+FGqy?G%o6a>U7k>Hh{Aq-r zFIB{i^&I>DZ1{J}HdA1Iop%vWzlPm9j>7!wz0(|KlSTaeZlmnTm$(i;}P{cNvc{37}RkF(P&EA`@jHP0w@v88`ODqv^irf?*uq%_#-1lh$kx>e%N?k3ZYZrWPel zm34`K@fYy~-iYr4X;UswLGB~0>5wqx9tcJ4^14{zRNQJhdvT{W86O{1y>Vn6X1?&b2yp1;P2 zXNG}N;GHs*P8D<`KcAg2d~2r?I*4uxwCI*So^7CgbE!!o!GVud&{M+RP9sjF^uz0z z+rXHyPc3U8KHy2azsk_Q#46~;`VgkLno5*awPs^Pu)$jt(Q)lW30Ux+bb1xtJ3ZLZ zB=q?U?^E=1RthoW1D?%<;w+lxet>+?M4cf&yThm0$QZPT{qQ|UjNM;_`0gqcn)IN_)3Uf^?}=8{0yOYR?N z4pErgtjE+kyL%?$(Jr@FETHd2GbtPRmmtMDdWFfnWF0#P33pH zQGCCEQvqwF>UWwFI=bkesUFFoJgo>8`FF=01;ty&Wz>{v&0t%a!}7HXGHU8AMvD~+ zScl&<*>9&M+AYBTkQh0v;XNo1j&E?IP^r%AYk@3-9iowgl4xmm4I*{J!HQ-8jTON| zNTcx)$uFHiwc7a{Au6ps4WZ)0!mc|atAdFA_c>ME5Pl6xeC9MaM(g%3WsJz`P%z(y zdx}2gK8QrBYxVCw`}SG$N02?DzJa2a#JtB3L>>dbvqvg@sGxskUGUI$#4`Z@Nz@wc zN_|D~#aDE5J2{q(YzhL)BgvX1N7a_5Is0$^mu5M%xCt!bFOu0JTUae9z=>?(h=Ykb zR8c2f(a}4Akw&2OP|?L^gGI~C!VJKoT5pZxA-e)|h)+S=vu8|OBA-9WtCz@u6uvTF z6l{pafEe%V;Kv_Nd+}g)zN(@dEBu<2c%cfE2_wIvuXA7*2|l0z^WW3+14&!{BEmOZ zjiiLnl3NDNe@uddpnY%hBUfi{>-JaoQ{Sr-!ev>$Hz*H(V_vT$KinupJsV1s28;#2RJGc3Q$clU;t*PZT{weR17?iIXHP=L2=G0*_LZMY* zWs+(cSj}{42f0OEJ8&i0666c-W~}VgEo$%%M2I5c9k*KQ+rKpe3qBvA=-^usLRqmT z7@-m;2f7HM-MN`f6K|@;$I=CZ$Blcf&_ykHbw92*QAA}KA&C)Ya3s|5#%Pb_jK4$N z>Tx((_lem78#M>?IWdtjc75KjUHqm=nYk+oVN*M~l__*nyTi?uqLS%QQd`n6Ihe-w z9IA=kMf|+UCWNYd@5028sV<8}8C8kH&F2vZ)9bi*;TEefG0{&iRmPFXAp-y zaVWPH_xN{9077yNUus>hCB3{lHw6{B4u9!u{ zYeQ^X_IMI#!a|=@&U~Pw8Ag{^u(V?X?$Ct088TD91FElgAvp=_-rca}=wyctA$am<2Y8B?^4 z-b14^eMe?e(g}A!HiY-J@G$U9E{)eZlD%YU7(KcF^_8mhCQRFGKs|}#M&wsBeCMm&VlB1N=4No*=*Fy-Ty?}) zxf;>L8_%ERgwO{#SBH_C7j3($dPCcO<<@_LjIa$DMg_jJseZ5nop3olTZjv44?6U* zcTx2`?&kRxLL^Srct}cP0ZiW^Y!ezkcAOxxWl1ElTX$kuy>;-(hREMr0YEzePiUQc zO9KcpBG}UtpM8hE%(oG2$L_K-YYBK8 zJ($8OAtA{{%hjAyHfFd-)=NIc{AIPft!PXj&L`z&ZaD<$K+b^R-ns z|ES;s=CF`hOE`pA$s6|6!it;z z3sFUxnWlKgmqvNEt-N*xPhsrWnH0Q?&HmloLT)1NctGZQ`WIrYUT zzgtq-6Askf%bnZ_$9uUMWH;b#K8fAx#DR(jt)^RbGLRr>z|F{vCyH49KGoUy_O@0w z=m)!XxdGaj$S-vl4zB zCmZ{{ZITWikB@qi4zvn*l2j95ok0>xJ~tGg0hVT}DeZp;2lO}i+15-pA{i4TkM`O{E1kO0TlXc4GnrRBIc4phtM*Xj#eA9^)=2=} zt#iAdbq0P9ORg0JpN^1G1~alX#$h4&T*?181j_pVfBs+30AC0yJ^P$F>(gQ((F?%q z-#zHK-3CPC|DLPX(Swh8_~3q8XDWNdJ6>T(^gHi0q#)@9OB^;$l*Q`Jzn@EYDskMb zAN(sHvH|h=A(u|!d`u*s6v-9Jo~BD{SHaQpmr^FtQTydYHF$kLuV=)BYgVxr0H69P zjI-6q(`c;s^-f*sC~Gz>dJRdoEe55FGPHI17y1OB`HJX{ihNg_&v!dQ-m^wp7lkfK zwuh&Wy37C*eqh(sKU6b#`>-=Eezo6YqjKwbH0?Xx!LVjDR8$3qXS}E#GO_CUaa>UYalr;(S~BwO-k?GDqXfXs z!MBSnzrbcsOT_0nX0>r2?Wh`J4#xgvF^4iMA$ZU6OA{ACdpDlhV7L%i=jFbh8844xM` zxkLN3Y?>~Yz>wAX%{G}AESZ*YP-^h49Yqf619@WHYDxi4CBL0Y?XWBHr;4^6iqAZ` z{prS0HRo>7Uby!^CV3v4a5lodC}zXahCBPujt7+3--j8%bs}{8-iSw+bIG~Fvm|F=DbpVM<&OQ&Jzb#V*e)XRZ^sN!l^c?=CoaMDbY;$Dai_P< zy4@1Hlbnfpz}#AUd$yfXC}|HS#IAmyOVVl;0{k(vF*G~Pj2|Lt($?2c zBrRVW+8?sFdQH|!aw!jPc{X#^5!38nbKJXPDb!*bg#<};>jF=9feiV9D8`Dv$VCtm z(YBW00@a&m@T91vtob^7OuS^k=}3@2=&^bwVVM4oN<})?fy=j?T6l$?2$RNYeeL%) zI1&ZTg0I~S+5Y`zJhPy4F2NWj-~m)kj-xF|Ha0wf80S%x0$rHjB7VolNHS|oGc`$V2D#LMA+%5=X$eZR!-?Q~kMT7`{CMsh8cG$YEo zZWp!BcH4Wljl!w$ZZcT@Q!PG|yBa(zy!@qm2~mIL=UL{e@#YKFw7X_kPRhNj0`>-B zp;{;9`%vQ%YG3Ja*?^9eTNiyDtPLFn+VD$o%5XR901$7H{8U>4!T^Co6B( zf(ZT`+bI=zI=(5H4@Llstp;;fEBE-Zzq4uIqb$6&kWu8PqP7U3`(_xA6rK>({b<82 zalR?SU9?iTRuu$LJM=R0U5{4|A`5u9dM)I9?r(xbl1;Uw(jTRiK3a!=!PUhse>G0W zTPdq@1ny7|#vHuAJ4?8P#wA?<&jqunZNN*D1x~9s99lWi*D5tN#R3nF3 zDs5!jO2;(Q@Z#hPp>yX;b&c(`cqdKmBT%u1ZuCd=ld?TAmS5)yG;)_j;-Up8Rd_x1 z3#OD|b7gwi@K#sO>W+ldLdS}#jl-!_@X2=_6++ma!g=TUrsJIRee)Q4iCH7H(6{v! zdZR)iE4HB(uqaBu^7y1;vBECXMR_<{+rRM}W!aA=9TZ&}P?O6+ zo3>`+IzDxq(}cv)9*0-&5nGeQi0%^L8bl1gr}-!nAR`dpmIS{`kL#HWCCYW zQ#;y}4%8U4%xDR`r?D63c<2$|E?*NJQAQ?x*NpDRo72nDAg~L@dJb#A>3E6V)ply5 z>1(g^Y3h8R0^cK>4Q!vRHB_p$rRg1%8q?JrB^L`dcXE0;7}#f4D3_v_V{>C9k;vt7 zd?^O}^%VWfiL{dyG_oKqT#VH9ZO`Y2%{TLXy$MQF1)+F~^+eYb44Z`b19J`C=jB|M z(yY!_eJRvuza(s%ueq)FCQaPeIglI;8f6TugTX58ZKjYqgA*!ZU zB!Uqlvdh3)QE@zPX0FZz)ves+Cc7{CbvIS@;#6WZj4>`Fpqsn1U zp;yo@L?rlcwJ7Un*}w*#s9)W}_-sTEA4W9@if*W9BXY>zE&NqY5}@+?H1U1bPa z0N=sch8`y6o!KU7Jmt*TmaSAqPPIVDflhD= zR3}t|jLY1SEnsZoAj;PV{=NPD_JSovl-TN?|7?_*ZRWTZ#n5F0#Mx<&)-Tw5t(R|w zHme?Sf`Jxu(eXNwsXS`J1T|-bGy-iw2p1}`^9W;&w;o>TNELK zTZ038mybJ`8UKKpeA8l+U{T|?3Q=7QFJgCLQdyenb}8^-8#O|5=1D%X4wl#Q(xayH zS~zU6hEqjdu!zmifp&1e5R_k6=ozQJ?GYr*d6KP9n$x=*KcIDnF0F86vS{kHw!90m z!C1ro`^vl%W@PM(I@#{G&eIp>S?s_fFaLsRxVsU_Srff8Ij~_`NTupR-COH0 zSmoGit#;63uf-xRN%?9_aMv$47`4!U*nt0;6uOKe(F!?R8&3~A1xoB4HX8BbK}CLK zl3Y#8WdTOozP5?6TDFu$9MwoEiKpEQl98{(S?;i+r@*1oCU!ur=V_UO`_C%zr)=I| zUF!i{%=ivaW+lAvvFuP}=UB00jC%j%n5F~)@RiM9OM(_m(T|=a0pBVIA3{AMg@T@g zj_lAFP9!|j_6d!Tu;(;Ys;0SVXh>@i0*Gc{2M?)nGDOb;d12-hUIKCeb-5KX<%f&s z_w7-QEz{kdd*3vM0v%|vrFWoi%nk~{E&~8@@~+}` zxf}kY;H1MJRvSI>P-%U)&1+fjIsT4x!=R+iB5tII$FRJeT-u_wA7_6y(xZ)RFbuf@ zOB)wIkA(#3?CAXMrb+kP8Kefad<=cSy4VbS0kzW5B;$l>Z8=;|b)Wq$%!Hdn zGsL~2ns*I}kF8tu^`O79Bi$}~Z8)f|ZV~cQCahP; zoU;{0f}rv^Q|)=TxzJ-P8~bnq>kRtQVOMbj2eeTN)^e#P0Pc>OFahy1sxh9m(Y45qvdjP`CMrDzgNs^I#Nt-|q)M_mh5Bw$ zN6HHQil0I{eAdUIfc$KGe;d%O5v`(=O9|AWm9QItL4Ocf1I<@OD57o+B@o>`-Zf5g z;m;R+OzEWtLii++Rj4xyv~p%>4@gC9G(BmL4K1yU0^LJK*CJeU>Nt;hl&ZLKX8gXS zD^vU=pKzh2S_w}_dQx7K&n3f6@+ildoKr%#Z9xPX%Rcd_zo;%+ycID45P;ikmc9>h zJF0~*#YkC_8>yXrfhbc9BCG)&+4=<#S=8c3sma3>_6MuHc&z}FxRxW0azTHU`(Cp- zbkyll3s#NU%elJES}-LhVADpa2tM7eH;K_qF*WorKam6UXNo`X8+ifkN0yZNU*J3Y zO?-b!Vq4)PvTvYF;5Sy9Y{R~s<1joSTZwzq%_B{>!Q-tqg)f=^?wrwRqJUH>IzFUZzVMBB@Ko#Nl}I0%x(_BSrgnp+_WNS~ z*6wcc^@)lfepZY}cOI1-9nXNIjC|nNP{ObYlEvRg`0(m5`QogMs1hJLXv z7}+rGq;CQmmE5GagDuGYScL(y_x=p+=AU@nWiUI8*u4kp;t~qv42}Un+cmElg^=-9 zqPHAk%>jR$mPo`q?g@a#Pm>j zgn+Ui9;GV5VO%LHdRXi|JK^E56=tH!5A5=fJzW$kQZ4`w=FClypAU#RqH))4*Zs6M z85J>SP#gA@_@IY(*Q9YA3{ZTZ|#@}DR0((`QIPj1Ea5FYhnIt5>U-q@O4#= zGP{KGz}0fV;lSI6PgS-s$GQGnBi?R`&u|}9%pQNhxKpD&xfw(f-@RL+h;XqG)lu}b z1Ra2m*;XZsVF(7Fd*^o9pL;r3zSnvpDK?^cq>GApXYiqVrnB0*XC8<4P%0|ci|*!j zrpebna+V4^k}mXT)s^X~^k1UPNbtb>iC0Kcw3yqIM!qFjB|e5Ay-)FgIx>8>dri`5yJ$W~XUI8yk z(61(>b_}5W07m5-;9@4$>zPb^VzcD-o8;Y(nezvuNoC;xr`^wyx2h> zB(C(hEYPv*(mYww{7~|+NY;9B>@mvA=88%V$j5|tR9<)R{gLahDdYgUC#M~*N#5^10 zxXHOD@?fhi1lhR=RzaJSUnp?!R#!_2r|}J!2fXC;Q25A~JF&H&qK-z&Am!EN!sb~QG z;-R%$aM^6{Y~f>zLSpbam(~H7ZU)}FP6GRMm6eUw0 zV@cCWjAhNTSLph(^-tj$P%oEU>5)-U9`&mY&33+e-meBezoBu>xuKj6rXsufEVJVz z3iYl!YGat>n)-i+v}g3YKGaVlKc7w!+?a(lJQtQl#}IrPv-se@Gq4Tug9H%vnJV?UI5ho2z$3QVO&`pwZUp%$#NRsdvAc z%9yocB^zt$I8;X`2Wsg4ZnHAYsnacUS_7YXT%f<%IIk4jzhzayNmQltlme?a*nrU{ za|aTmiZohtC$-r?E4*iG5l1X)+E}P;Q?^t>o3_QKi#;x$pm%o?YNUY{WW zHcBa6z2;GsxYh`GPCu-fbebQ5J9Qh+KB(X)q^Cy__svbDkyVkbHU9h%TeHa8%Sc5T zZD=6e6cR$)tYYC}&mJ9DEi9=Og^JFcX7noaKKgr@J z_w!eUe3q#dPsx3YOu4$M&sY2WHr@ts&&n!QDTf@b#nD;?ANP$XXH>)aL$)D8EuyWXLF*^vK9uO0*%X3N*Uo!wx)KWS>dcp$EN_`7b+2!c zjA}Hk#;aKbzoScoR#+l5O*TF#BM7Zb zss+LCn^_~?3y0o4z&dc3tcoY3x}Ms0g};`1K&HioR?wy~Sz>K$Ut|FrAOEds$M9Jq zFe{oRfE?1?I0jT#OlNlQn$f7gNl>Fjz+4PsYssk9!k?Kk>}=G0+yyBzGg~M}_z4W` zN9QIP&;q~Ek`NwveGo2qPXe!;Ep7B9d)o_@;r?F@~YLA-UQU* zs$^9mnB@(y`ZkuCS7H~lQPt0R_}*b}l0TwCp8|_MKU}o(x5OgnIV*;+;c!|%tB z?L)N1nIh|g2a^;%em-77ItSa|fGhJZOWdHpY^T5n=SwNv$`iLk=<2dzZVRUp=S+Pf zHbdM|gO%LQ=sez};LyYbBtQT1fF;tmp!HY;CaX_lyPNkjnDp*_EEltcYUKB|XB$MS zrEaT06O0!M0Z3*l!RZc;)C#GN%-q~?)ur^%LFiim$xmdzDj=hXaa?2t$&GGA3)LI- zzWSH~hR?fGklP^vA35-y>A2&{fr=kSmfe-ZQC>}EQ~^Z&90P)y6^R&OTww|9g$&Y#^3}`W|hvR zsFkhR#(vG@+-dDsb85%xnhAWEQoHiZwz;MCQ|gRKG8udd&tr-{bspczyTDyZraQrTf;_}{fyqt~lK?`Eh-1?sQgwokQ=Q93bfOH{#;qIA-1C zJn^}};O61#39_OCVC>EdI%t{Es4>e{&xgv>j$GAsjGm~?WMb+Z!A8axl@UgpHi?*r zy?@Sbu>Slx;sxkEumA2>OBz(yooxNOsEpa0;TZ+oitwv2n@v~Vai-tXsXyGtk-b8b zucggh#tYKltNJEckA&AuMZ0hB#|?=AL+1p6${)69eVn&%Q^LHC?9o$Uy@XH_)q0Ng zH~6}_dD3Zl&srgG9TA>iD0H6$EPDD4!kS1=n@AroyT?8Z4(qa;n;)&M;JwpLqm{}@ zB6b*Y-@mMdYJYzia7SHe@8q8Qcf9S7oMH z9C+QUiImZKM+*OzyuTe`n>TCUpw?lp{x>uoPx>sW}Zhslx zoXxSDk{n#R7eY#L80>3Snf#&eG1%A1Q$g!dyqPg>Ty!z)@rsXQ^ZaoQVs4M{Uml&t zQ)$eq!AqV$7K1v0<62&HynvBr6b{>2ehmZl4pj?i^A90hCn6Z&@~$#YtdXk^ z_02pEN62Kxg&jYTwP4@?E66b5v^%5W+if97y7E)c;>0S!YU$MiC5YE|Q-uRFrOU2R zl?2Moy-kb;xvDVFmKHh1=O&+K?h7H=&yGUTe`ijSkt*;~R@O`SJ@oV(5P`Cef3>Uf zCPDFI=$1o{@I4(ek-C<&hD|FTP?*!g8$;sjQ!B08_8)iI+qN4*JR|@$!Qn`z?Cb;E z$4F3>8_UQ1U0*VuV&uh>F2!j|yZvB`V$Gha_=S=&Uq zLs{Ym4?vDGe>RzHNDwP#7XDXD=x{?KQn!D?N!g3{$G{cZm0trcOq;?2$FyP}GN+^0 ze)l|1%qdyTZhnlAJxD)QRSDgEf+X|dR(6>s^$blZqGi5(9&?cJOps$17j@5oo562B zh^%AuFt@@Cki|`H^(6Cz$`oJXj{A5MMVd8^>fLt;pA0_e9!cN>GWCm{AmU0G`6^nOR2 zJuZ2esj6b6mId^kUiWam%fk~i+d#BWx{s=u;hUAACuv1qTe@|Y&aoUKkMo6Syc^~H zd|at%{3w_>f}16NUy9_a+C|vB*K=}SX@{!k1o^KsYr`YHYV>)x3?tbW*N^MOJ-yR+ zIg<`MJ4a;uBxb&P{=>?Jvtuhq4k$Mcmms@*ySiOJI&l8rq~-nLhdREe`P)lV@Bo>I zbs$B@f8an68fm}}hE>w&Zzk4EZ`l?QS>ogi+?Lb#Tg-a56Q5*8)0-w<3xTFRT)g)T z>FqGS`fKJQOo%aeT^M;J20RMm?PX`ZqIJSK_`T$E`0{Zg*s{T5o?QI!#4p|TncGHbmvJXmK1!3tt zeF2n~j#5ImDE@@jcWA^~5QkUZIXsT3)yZ!|f3tJEbjaC3=@&2Ve`o)Nhg@37D%R}B zh_zT>D>_216bRi*lS?lY*f>^Hy*r(Mm$z%yt+QmNa;0#uw3Kq1|e*x0kG=kAQ}7n>3g(K zqt^857Cds<(#Vc5oE~9OLGSZOHxZI{>AKDTu*_&#gbNQ?&t+Ay5`0u%KBp<|*k7Bgi;2;>W_TGBVBupN8Iy9EbZk;%Q%7Vj`&_w0GXJsbZo_DH7Cp>5uY zBGJAl=u=STXojMhqz+dQEsb7*vGqj4nfz<0o6`a5yWmphR+GsS5s^q z+AueXFr6=0BR4$T6lX_|4HPh8bU3gj1MjWA=azipn?K2GN^JD(RWK7$6N$6{f8W?G z+T7Vj+HlkK=Wa_ii^A)^8zaSE#2?xcYyS02RPFwu%y>ZhQi_1;P(%is`wG7TaK0EgS#nv6t2WOInq}4QaIXg35&a zrfD|MR~LD)szR;|$^MrtlcfQoiyc@~Mx?lbMC(QGD>alDBE8W|H$si=*&>m@ZmOFW z$kK5CgFzz>I&|{G#AF*XTo4WRD?@QhZ3-9#ft4LbL%s9%?-_otVGVwL?8ae z^%JZ)FxSh)xe&y)Yf5 zEJe|%?_!qWj&LvQF6y_{dY8p8lB)O~NvZtCyf{`p&iEe#8XYUqk3sE z)^P4abA*vOls`@UWhMjfe=yPiPqO~slmDy0|Aq=+%dWm4o*Csdv|i56Bfu{?DJ97Y IkWs+@10a)xk^lez literal 47424 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 Date: Sun, 7 Jan 2018 17:58:29 -0500 Subject: [PATCH 03/13] docs: Done with next stage of ensure docs --- docs/FAQ.md | 8 ++++-- docs/day-to-day-dep.md | 55 +++++++++++++++++++++++++--------------- docs/ensure-mechanics.md | 6 ++--- docs/introduction.md | 2 +- docs/migrating.md | 7 +++-- 5 files changed, 47 insertions(+), 31 deletions(-) diff --git a/docs/FAQ.md b/docs/FAQ.md index 22c5a27f92..a8c9f309f3 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -1,5 +1,9 @@ --- +--- id: faq.md +--- + + + title: FAQ -- @@ -289,7 +293,7 @@ There's another major performance issue that's much harder - the process of pick ## How does `dep` handle symbolic links? > because we're not crazy people who delight in inviting chaos into our lives, we need to work within one `GOPATH` at a time. --[@sdboyer in #247](https://github.com/golang/dep/pull/247#issuecomment-284181879) +> -[@sdboyer in #247](https://github.com/golang/dep/pull/247#issuecomment-284181879) Out of convenience, one might create a symlink to a directory within their `GOPATH/src`, e.g. `ln -s ~/go/src/github.com/user/awesome-project ~/Code/awesome-project`. diff --git a/docs/day-to-day-dep.md b/docs/day-to-day-dep.md index 6d21955e02..c5d6893093 100644 --- a/docs/day-to-day-dep.md +++ b/docs/day-to-day-dep.md @@ -2,17 +2,20 @@ title: Day-to-day dep --- -In keeping with Go's philosophy of minimizing knobs, dep has a sparse interface: there are only two commands you're likely to run regularly. `dep ensure` is the primary workhorse command, and after the initial `dep init`, is the only thing you'll run that actually changes disk state. `dep status` is a read-only command that can help you understand the current state of your project. +In keeping with Go's philosophy of minimizing knobs, dep has a sparse interface; there are only two commands you're likely to run regularly: -This guide primarily centers on `dep ensure`, as that's the command you run to effect changes on your project. The [ensure mechanics](ensure-mechanics.md) document details how the command actually works, and is worth reading if you're encountering a confusing `dep ensure` behavior (or just curious!). This guide is more of a high-level tour for folks trying to get a handle on the basics of dep. +* `dep ensure` is the primary workhorse command, and is the only command that changes disk state. +* `dep status` reports on the state of your project, and the universe of Go dependencies. + +This guide primarily centers on `dep ensure`, as that's the command you run to effect changes on your project. The [ensure mechanics](ensure-mechanics.md) reference details how the command actually works, and is worth reading if you're encountering a confusing `dep ensure` behavior (or just curious!). This guide is more of a high-level tour for folks trying to get a basic handle on using dep effectively. ## Basics -Let's start with some semantics: the verb is "ensure" to emphasize that the action being taken is not only performing a single, discrete action (like adding a dependency), but rather enforcing a kind of broader guarantee. Expressing that guarantee In narrative terms, running `dep ensure` is like saying: +Let's start with some semantics: the verb is "ensure" to emphasize that the action being taken is not only performing a single, discrete action (like adding a dependency), but rather enforcing a kind of broader guarantee. To put that guarantee in narrative terms, running `dep ensure` is like saying: > Hey dep, please make sure that my project is [in sync](glossary.md#sync): that `Gopkg.lock` satisfies all the imports in my project, and all the rules in `Gopkg.toml`, and that `vendor/` contains exactly what `Gopkg.lock` says it should." -As the narrative indicates, `dep ensure` is a holistic operation; rather than offering a series of commands that you run in succession to incrementally achieve a some final state, each run of `dep ensure` delivers a complete, consistent final state with respect to the inputs of your project. You might think of this like a frog, hopping from lilypad to lilypad: `dep ensure` moves your project from one safe (transitively complete import graph, with all constraints satisfied, and a fully populated `vendor`) island to the the next, or it doesn't move at all. Barring critical, unknown bugs, there are no intermediate failure states. This makes `dep ensure` fine to run at most any time, as it will always drive towards a safe, known good state. +As the narrative indicates, `dep ensure` is a holistic operation; rather than offering a series of commands that you run in succession to incrementally achieve a some final state, each run of `dep ensure` delivers a complete, consistent final state with respect to the inputs of your project. It's a bit like a frog, hopping from lilypad to lilypad: `dep ensure` moves your project from one safe (transitively complete import graph, with all constraints satisfied, and a fully populated `vendor`) island to the the next, or it doesn't move at all. There are no known intermediate failure states. This makes `dep ensure` fine to run at most any time, as it will always drive towards a safe, known good state. General guidelines for using dep: @@ -23,25 +26,26 @@ General guidelines for using dep: ## Using `dep ensure` -There are five basic times when you'll run `dep ensure` (with and without flags): +There are four times when you'll run `dep ensure`: - We want to add a new dependency -- We want to upgdate an existing dependency +- We want to update an existing dependency - We've imported a package for the first time, or removed the last import of a package - We've made a change to a rule in `Gopkg.toml` -- We're not quite sure if one of the above has happened -Let's explore each of these. To play along at home, you'll need to `cd` into a project that's already managed by dep (by `dep init` - there are separate guides for [new projects](new-project.md) and [migrations](migrating.md)). +There's also an implicit fifth time: when you're not sure if one of the above has happened. Running `dep ensure` without any additional flags will get your project back in sync - a known good state. As such, it's generally safe to defensively run `dep ensure` as a way of simply making sure that your project is in that state. + +Let's explore each of moments. To play along, you'll need to `cd` into a project that's already been set up by `dep init`. If you haven't done that yet, check out the guides for [new projects](new-project.md) and [migrations](migrating.md). ### Adding a new dependency -Let's say that we want to introduce a new dependency on `github.com/pkg/errors`. We can accomplish this with one command: +Let's say that we want to introduce a new dependency on `github.com/pkg/errors`. This can be accomplished with one command: ``` $ dep ensure -add github.com/pkg/errors ``` -_Much like git, `dep status` and `dep ensure` can also be run from any subdirectory of your project root, which is determined by the presence of a `Gopkg.toml` file._ +> Much like git, `dep status` and `dep ensure` can also be run from any subdirectory of your project root, which is determined by the presence of a `Gopkg.toml` file. This should succeed, resulting in an updated `Gopkg.lock` and `vendor/` directory, as well as injecting a best-guess version constraint for `github.com/pkg/errors` into our `Gopkg.toml`. But, it will also report a warning: @@ -50,15 +54,15 @@ This should succeed, resulting in an updated `Gopkg.lock` and `vendor/` director If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/. ``` -As the warning suggests, you should introduce an `import "github.com/pkg/errors"` in your code, ideally right away. If you don't, a later `dep ensure` run will interpret your newly-added dependency as unused, and automatically get rid of it. +As the warning suggests, you should introduce an `import "github.com/pkg/errors"` in your code, the sooner the better. If you don't, a later `dep ensure` run will interpret your newly-added dependency as unused, and automatically remove it from `Gopkg.lock` and `vendor/`. This is because, in contrast to other dependency management tools that rely on a metadata file to indicate which dependencies are required, dep considers the import statements it discovers through static analysis of your project's code to be the canonical indicator of what dependencies must be present. -Note that it is not _required_ to use `dep ensure -add` to add new dependencies - you can also just add an appropriate `import` statement in your code, then run `dep ensure`. This approach doesn't always play nicely with [`goimports`](https://godoc.org/golang.org/x/tools/cmd/goimports), and also won't append a `[[constraint]]` into `Gopkg.toml`. Still, it can be useful at times, often for rapid iteration and off-the-cuff experimenting. +Note that you do not _have to_ use `dep ensure -add` to add new dependencies - you can also just add an appropriate `import` statement in your code, then run `dep ensure`. This approach doesn't always play nicely with [`goimports`](https://godoc.org/golang.org/x/tools/cmd/goimports), and also won't append a `[[constraint]]` into `Gopkg.toml`. Still, it can be useful at times, often for rapid iteration and off-the-cuff experimenting. The [ensure mechanics section on `-add`](ensure-mechanics.md#add) has more detail on internals, as well as some subtle variations in `dep ensure -add`'s behavior. ### Updating dependencies -Ideally, updating a dependency to a newer version is a single command: +Ideally, updating a dependency project to a newer version is a single command: ``` $ dep ensure -update github.com/foo/bar @@ -70,11 +74,24 @@ This also works without arguments to try to update all dependencies, though it's $ dep ensure -update ``` -The behavior of `dep ensure -update` is heavily dependent on [the type of constraints in use](ensure-mechanics.md#update-and-constraint-types). For semver range and branch cases, the above CLI-driven approach works. For other types - non-semver releases and revisions (e.g. git hashes) - the only option to achieve an analogous "update" is to manually update `Gopkg.toml` with a new constraints, then run `dep ensure`. +`dep ensure -update` searches for versions that work with the `branch`, `version`, or `revision` constraint defined in `Gopkg.toml`. These constraint types have different semantics, some of which allow `dep ensure -update` to effectively find a "newer" version, while others will necessitate hand-updating the `Gopkg.toml`. The [ensure mechanics](ensure-mechanics.md#update-and-constraint-types) guide explains this in greater detail, but if you want to know what effect a `dep ensure -update` is likely to have for a particular project, the `LATEST` field in `dep status` output will tell you. + +### Adding and removing `import` statements + +As noted in [the section on adding dependencies](#adding-a-new-dependency), dep relies on the import statements in your code to figure out which dependencies your project actually needs. Thus, when you add or remove import statements, dep might need to care about it. + +It's only "might," though, because most of the time, adding or removing imports doesn't matter to dep. Only if one of the following has occurred will a `dep ensure` be necessary to bring the project back in sync: -### Adding and removing package imports +1. You've added the first `import` of a package, but already `import` other packages from that project. +2. You've removed the last `import` of a package, but still `import` other packages from that project. +3. You've added the first `import` of any package within a particular project. (Note: this is the [alternate adding approach](#adding-a-new-dependency)) +4. You've removed the last `import` of a package from within a particular project. -As described in the +In short, dep is concerned with the set of unique import paths across your entire project, and only cares when you make a change that adds or removes an import path from that set. + +Of course, especially on large projects, it can be tough to keep track of whether adding or removing (especially removing) a particular import statement actually does change the overall set. Fortunately, you needn't keep close track, as you can run `dep ensure` and it will automatically pick up any additions or removals, and bring your project back in sync. + +Only if it is the first/last import of a project being added/removed - cases 3 and 4 - are additional steps needed: `Gopkg.toml` should be updated to add/remove the corresponding project's `[[constraint]]`. ### Rule changes in `Gopkg.toml` @@ -86,10 +103,6 @@ As described in the * `[[override]]`, stanzas identical to `[[constraint]]` except that only the current project can express them and they supersede `[[constraint]]` in both the current project and dependencies * `[prune]`, global and per-project rules that govern what kinds of files should be removed from `vendor/` -Changes to any one of these rules will likely necessitate changes in `Gopkg.lock` and `vendor/`; a single successful `dep ensure` run will effect all such changes at once, bringing your project back in sync. - -### Or, just, any time - -So, you're humming along, working on a project, and +Changes to any one of these rules will likely necessitate changes in `Gopkg.lock` and `vendor/`; a single successful `dep ensure` run will incorporate all such changes at once, bringing your project back in sync. diff --git a/docs/ensure-mechanics.md b/docs/ensure-mechanics.md index 75750c84f8..d5c9e0abc3 100644 --- a/docs/ensure-mechanics.md +++ b/docs/ensure-mechanics.md @@ -151,7 +151,7 @@ Ordinarily, when the solver encounters a project name for which there's an entry If `-update` is passed with no arguments, then `ChangeAll` is set to `true`, resulting in the solver ignoring `Gopkg.lock` for all newly-encountered project names. This is equivalent to explicitly passing all of your dependences as arguments to `dep ensure -update`, as well as `rm Gopkg.lock && dep ensure`. Again, however, neither of these approaches are recommended, and future changes may introduce subtle differences. -When a version hint from `Gopkg.lock` is not placed at the head of the version queue, it means that dep will explore the set of possible versions for a particular dependency. This exploration is performed according to a [fixed sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade), where newer versions are tried first, resulting in an update. +When a version hint from `Gopkg.lock` is not placed at the head of the version queue, it means that dep will explore the set of possible versions for a particular dependency. This exploration is performed according to a [fixed sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade), where newer versions are tried first, resulting in an update. For example, say there is a project, `github.com/foo/bar`, with the following versions: @@ -175,7 +175,7 @@ So, barring some other conflict, `v1.2.0` is selected, resulting in the desired ### `-update` and constraint types -Continuing with our example, it's important to note that updates with `-update` are achieved incidentally - the solver never explicitly targets a newer version by the solver. It just removes the hint from the lock, then selects the first version in the queue that satisfies constraints. Consequently, `-update` is only effective with certain types of constraints. +Continuing with our example, it's important to note that updates with `-update` are achieved incidentally - the solver never explicitly targets a newer version. It just skips adding a hint from the lock, then selects the first version in the queue that satisfies constraints. Consequently, `-update` is only effective with certain types of constraints. It does work with branch constraints, which we can observe by including the underlying revision. If the user has constrained on `branch = "master"`, and `Gopkg.lock` points at an older revision (say, `aabbccd`) than the canonical source's `master` branch points to (`bbccdde`), then `dep ensure` will end up contructing a queue that looks like this: @@ -199,7 +199,7 @@ The key takeaway here is that `-update`'s behavior is governed by the type of co | ------------------------------------ | ------------------ | ---------------------------------------- | | `version` (semver range) | `"^1.0.0"` | Tries to get the latest version allowed by the range | | `branch` | `"master"` | Tries to move to the current tip of the named branch | -| `version` (non-range semver) | `"=1.0.0"` | Change can only occur if the upstream release was moved | +| `version` (non-range semver) | `"=1.0.0"` | Change can only occur if the upstream release was moved (e.g. `git push --force `) | | `version` (non-semver) | `"foo"` | Change can only occur if the upstream release was moved | | `revision` | `aabbccd...` | No change is possible | | (none) | (none) | The first version that works, according to [the sort order](https://godoc.org/github.com/golang/dep/gps#SortForUpgrade) (not recommended) | diff --git a/docs/introduction.md b/docs/introduction.md index 3583bf8e17..6e2fb8e4a7 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -6,4 +6,4 @@ title: Getting Started Welcome! This is documentation for dep, the "official experiment" dependency management tool for the Go language. dep is a tool intended primarily for use by developers, to support the work of actually writing and shipping code. It is not intended for end users who are installing Go software - that's what go get does. -This documentation contains both guides and reference material. The guides are practical explanations of how to actually do things with dep, whereas the reference material provides deeper dives on specific topics. Of particular note is the glossary - if you're unfamiliar with terminology used in this documentation, make sure to check there! +This documentation contains both guides and reference material. The guides are practical explanations of how to actually do things with dep, whereas the reference material provides deeper dives on specific topics. Of particular note is the [glossary](#glossary.md) - if you're unfamiliar with terminology used in this documentation, make sure to check there! diff --git a/docs/migrating.md b/docs/migrating.md index 81f8da1896..93aee90acc 100644 --- a/docs/migrating.md +++ b/docs/migrating.md @@ -1,6 +1,5 @@ --- title: Migrating to dep -sidebar_label: Migrating existing projects --- Ideally, migrating an existing Go project to dep is straightforward: @@ -60,7 +59,7 @@ The solver returns a solution, which itself is just [a representation](https://g First and foremost, make sure that you're running `dep init` with the `-v` flag. That will provide a lot more information. -`dep init` has both hard and soft failure modes. Hard failures result in the process hanging or aborting entirely, without anything being written to disk. Soft failures may or may not include warnings, but do ultimately write out a `Gopkg.toml`, `Gopkg.lock`, and `vendor/` - just, not the ones you wanted. Before we dig into those, though, let's set some context. +`dep init`, like dep in general, has both hard and soft failure modes. Hard failures result in the process hanging or aborting entirely, without anything being written to disk. Soft failures may or may not include warnings, but do ultimately write out a `Gopkg.toml`, `Gopkg.lock`, and `vendor/` - just, not the ones you wanted. Before we dig into those, though, let's set some context. While dep contributors have invested enormous effort into creating automated migration paths into dep, these paths will always best-effort and imprecise. It's simply not always possible to convert from other tools or GOPATH with full fidelity. dep is an opinionated tool, with a correspondingly opinionated model, and that model does sometimes fundamentally differ from that of other tools. Sometimes these model mismatches result in hard failures, sometimes soft, and sometimes there's no harm at all. @@ -72,11 +71,11 @@ Because these are deep assumptions, their symptoms can be varied and surprising. - dep generally does not care about what's on your GOPATH; it deals exclusively with projects sourced from remote network locations. (Hint inference is the only exception to this; once solving begins, GOPATH - and any custom changes you've made to code therein - is ignored.) - dep generally prefers semantic versioning-tagged releases to branches (when not given any additional rules). This is a significant shift from the "default branch" model of `go get` and some other tools. It can result in dep making surprising choices for dependencies for which it could not infer a rule. -Some projects that have been unable, thus far, to find a reasonable way of adapting to these requirements. If you can't figure out how to make your project fit, please file an issue - dep's goal is to define rules that everyone is reasonably able to adapt to. +A small number of projects that have reported being unable, thus far, to find a reasonable way of adapting to these requirements. If you can't figure out how to make your project fit, please file an issue - while dep necessarily cannot accommodate every single existing approach, it is dep's goal is define rules to which all Go projects can reasonably adapt. ### Hard failures -Hard failures are mostly going to come in four flavors: +Hard failures come in four flavors: * Deduction failures * Local cache errors From b2c090f40ab91efa1c6fed10b52f6e24caaf329f Mon Sep 17 00:00:00 2001 From: sam boyer Date: Mon, 8 Jan 2018 01:15:39 -0800 Subject: [PATCH 04/13] docs: Add solver and failures doc; misc others --- docs/Gopkg.toml.md | 11 ++++- docs/ensure-mechanics.md | 10 ++--- docs/failure-modes.md | 28 ++++++++++++ docs/glossary.md | 13 ++++-- docs/migrating.md | 4 +- docs/the-solver.md | 93 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 146 insertions(+), 13 deletions(-) create mode 100644 docs/failure-modes.md create mode 100644 docs/the-solver.md diff --git a/docs/Gopkg.toml.md b/docs/Gopkg.toml.md index a2e27acf29..a40f813a83 100644 --- a/docs/Gopkg.toml.md +++ b/docs/Gopkg.toml.md @@ -7,8 +7,9 @@ The `Gopkg.toml` file is initially generated by `dep init`, and is primarily han * [`constraints`](#constraint) and [`overrides`](#override) allow the user to specify which versions of dependencies are acceptable, and where they should be retrieved from. * [`required`](#required) and [`ignored`](#ignored) allow the user to manipulate the import graph by including or excluding import paths, respectively. * [`metadata`](#metadata) is a user-defined map of key-value pairs that dep will preserve and ignore. +* [`prune`](#prune) settings govern what files and directories can be deemed unnecessary, and thus automatically removed from `vendor/`. -Note that because of TOML does not adhere to a tree structure, the `required` and `ignored` fields must be declared before any `[[constraint]]` or `[[override]]`. +Note that because TOML does not adhere to a tree structure, the `required` and `ignored` fields must be declared before any `[[constraint]]` or `[[override]]`. --- @@ -123,7 +124,13 @@ system2-data = "value that is used by another system" -## `version` +## Version rules + +Version rules can be used in either `[[constraint]]` or `[[override]]` stanzas. There are three types of version rules - `version`, `branch`, and `revision`. At most one of the three types can be specified. + +TODOOOOOOOOOOOOO + +### `version` `version` is a property of `constraint`s and `override`s. It is used to specify version constraint of a specific dependency. diff --git a/docs/ensure-mechanics.md b/docs/ensure-mechanics.md index d5c9e0abc3..fdf8934b4e 100644 --- a/docs/ensure-mechanics.md +++ b/docs/ensure-mechanics.md @@ -111,7 +111,7 @@ For any of the paths where `dep ensure -add` needs to run the solving function i ![Model modifications made by -add](img/required-arrows.png) -Import path arguments that need to be added are injected via the `required` list, and if an explicit version requirement was specified, the equivalent of a `[[constraint]]` is created. +Import path arguments that need to be added are injected via the `required` list, and if an explicit version requirement was specified, the equivalent of a `[[constraint]]` is created. Though these rules may ultimately be persisted if solving succeeds, they are ephemeral at least until solving succeeds. And, from the solver's perspective, the ephemeral rules are indistinguishable from rules sourced directly from disk. Thus, to the solver, `dep ensure -add foo@v1.0.0` is identical to modifying `Gopkg.toml` by adding `"foo"` to the `required` list, plus a `[[constraint]]` stanza with `version = "v1.0.0"`, then running `dep ensure`. @@ -131,9 +131,9 @@ First, to solidify an implication in the discussion of [functional optimizations ![Pre-existing lock feeds back into solving function](img/lock-back.png) -Injecting `Gopkg.lock` into the solver is a necessity. We want the solver to preserve previously-selected versions by default, but unless `Gopkg.lock` is injected somewhere, then the solver can't know what versions it's trying to preserve. +Injecting `Gopkg.lock` into the solver is a necessity. If we want the solver to preserve previously-selected versions by default, then the solver has to learn about the existing `Gopkg.lock` from somewhere. Otherwise, it wouldn't know what to preserve! -As such, the lock is another one of the properties encoded onto the `SolveParameters` struct, discussed [previously](#functional-flow). That, plus two other properties, are the salient ones for `-update`: +As such, the lock is another one of the properties encoded onto the [previously-discussed](#functional-flow) `SolveParameters` struct. That, plus two other properties, are the salient ones for `-update`: ```go type SolveParameters struct { @@ -177,13 +177,13 @@ So, barring some other conflict, `v1.2.0` is selected, resulting in the desired Continuing with our example, it's important to note that updates with `-update` are achieved incidentally - the solver never explicitly targets a newer version. It just skips adding a hint from the lock, then selects the first version in the queue that satisfies constraints. Consequently, `-update` is only effective with certain types of constraints. -It does work with branch constraints, which we can observe by including the underlying revision. If the user has constrained on `branch = "master"`, and `Gopkg.lock` points at an older revision (say, `aabbccd`) than the canonical source's `master` branch points to (`bbccdde`), then `dep ensure` will end up contructing a queue that looks like this: +It does work with branch constraints, which we can observe by including the underlying revision. If the user has constrained on `branch = "master"`, and `Gopkg.lock` points at a topologically older revision (say, `aabbccd`) than the tip of the canonical source's `master` branch (say, `bbccdde`), then `dep ensure` will end up contructing a queue that looks like this: ``` [master@aabbccd, v1.1.0, v1.2.0, v1.1.1, v1.1.0, v1.0.0, master@bbccdde] ``` -With `-update`, the hint at the head will be omitted, and `branch = "master"` will reject all of the semantic versions, finally settling on `master@bbccdde`. +With `-update`, the hint at the head will be omitted; `branch = "master"` will cause the solver to reject all of the semantic versions, and finally settle on `master@bbccdde`. All versions in the version queue keep track of an underlying revision, which means the same is true if, for example, some upstream project force-pushes a git tag: diff --git a/docs/failure-modes.md b/docs/failure-modes.md new file mode 100644 index 0000000000..bd2612be6d --- /dev/null +++ b/docs/failure-modes.md @@ -0,0 +1,28 @@ +--- +title: Failure Modes +--- + +Like all complex, network-oriented software, dep has known failure modes. These can generally be divided into two groups: hard failures, where the dep process exits non-zero, and soft failures, where it exits zero, but maybe shouldn't have. + + + +## Solving failures + +When `dep ensure` or `dep init` exit with an error message looking something like this: + +``` +$ dep init +init failed: unable to solve the dependency graph: Solving failure: No versions of github.com/foo/bar met constraints: + v1.0.1: Could not introduce github.com/foo/bar@v1.13.1, as its subpackage github.com/foo/bar/foo is missing. (Package is required by (root).) + v1.0.0: Could not introduce github.com/foo/bar@v1.13.0, as... + v0.1.0: (another error) + master: (another error) +``` + +It means that the solver was unable to find a combination of versions for all dependencies that satisfy all the rules enforced by the solver. These rules are described in detail in the section on [solver invariants](the-solver.md#solving-invariants), but here's a summary: + +* **`[[constraint]]` conflicts:** when projects in the dependency graph disagree on what [versions](gopkg.toml.md#version-rules) are acceptable for a project, or where to [source](gopkg.toml.md#source) it from. +* **Package validity failure:** when an imported package is quite obviously not capable of being built. +* **Import comment failure:** when the import path used to address a package differs from the [import comment](https://golang.org/cmd/go/#hdr-Import_path_checking) the package uses to specify how it should be imported. +* **Case-only import variation failure:** when two equal-except-for-case imports exist in the same build. + diff --git a/docs/glossary.md b/docs/glossary.md index b7a53a2a7c..e0bab7ac77 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -5,6 +5,7 @@ title: Glossary dep uses some specialized terminology. Learn about it here! +* [Atom](#atom) * [Constraint](#constraint) * [Current Project](#current-project) * [Deduction](#deduction) @@ -23,6 +24,10 @@ dep uses some specialized terminology. Learn about it here! --- +## Atom + +Atoms are a source at a particular version. In practice, this means a two-tuple of [project root](#project-root) and version, e.g. `github.com/foo/bar@master`. Atoms are primarily internal to the [solver](#solver), and the term is rarely used elsewhere. + ## Constraint Constraints have both a narrow and a looser meaning. The narrow sense refers to a [`[[constraint]]`](Gopkg.toml.md#constraint) stanza in `Gopkg.toml`. However, in some contexts, the word may be used more loosely to refer to the idea of applying rules and requirements to dependency management in general. @@ -68,19 +73,19 @@ The root import path for a project. A project root is defined as: * For the current project, the location of the `Gopkg.toml` file defines the project root * For dependencies, the root of the network [source](#source) (VCS repository) is treated as the project root -These are generally one and the same, though not always. When using dep inside a monorepo, multiple `Gopkg.toml` files may exist at subpaths for discrete projects, defining each of those import paths as Project Roots. This works fine when working directly on those projects. If, however, any project not in the repository seeks to import the monorepo, dep will treat the monorepo's as one big Project, with the root directory being the Project Root; it will disregard any and all `Gopkg.toml` files in subdirectories. +These are generally one and the same, though not always. When using dep inside a monorepo, multiple `Gopkg.toml` files may exist at subpaths for discrete projects, designating each of those import paths as Project Roots. This works fine when working directly on those projects. If, however, any project not in the repository seeks to import the monorepo, dep will treat the monorepo's as one big Project, with the root directory being the Project Root; it will disregard any and all `Gopkg.toml` files in subdirectories. This may also be referred to as the "import root" or "root import path." ## Solver -"The solver" is a reference to the domain-specific SAT solver contained in [gps](#gps). More detail can be found on its [reference page](solver.md). +"The solver" is a reference to the domain-specific SAT solver contained in [gps](#gps). More detail can be found on its [reference page](the-solver.md). ## Source -The remote entities that hold versioned code. Sources are specifically the entity containing the code, not any particular version of thecode itself. +The remote entities that hold versioned code. Sources are specifically the entity containing the code, not any particular version of thecode itself. -Used in lieu of "VCS" because Go package management tools will soon learn to use more than just VCS systems. +"Source" is used in lieu of "VCS" because Go package management tools will soon learn to use more than just VCS systems. ## Source Root diff --git a/docs/migrating.md b/docs/migrating.md index 93aee90acc..cf196a32ae 100644 --- a/docs/migrating.md +++ b/docs/migrating.md @@ -109,13 +109,13 @@ Unfortunately, `dep init` does not write out a partial `Gopkg.toml` when it fail Soft failures are usually obvious: `dep init` exits cleanly, but subsequent builds or tests fail. dep's soft failures are usually more drastically than subtly wrong - an explosion of type errors when you try to build, because a wildly incorrect version for some dependency got selected. -If you do encounter problems like this, `dep status` is your first diagnostic step. This will tell you what versions were selected for all your dependencies. You may know which dependencies are a problem simply from your building or testing error messages; if not, compare the `dep status` list against the versions recorded by your previous tool to find the differences. +If you do encounter problems like this, `dep status` is your first diagnostic step; it will report what versions were selected for all your dependencies. It may be clear which dependencies are a problem simply from your building or testing error messages. If not, compare the `dep status` list against the versions recorded by your previous tool to find the differences. Once you've identified the problematic dependenc(ies), the next step is exerting appropriate controls over them via `Gopkg.toml`. (Note - this advice is intentionally terse; look at [Zen of Constraints and Locks]() if you want a deeper understanding of how to optimally utilize dep's controls) For each of the following items, assume that you should run `dep ensure` after making the suggested change. If that fails, consult [dealing with solving failures](). -* If the wrong `[[constraint]]` was inferred for one of your direct dependencies, change it. Then, file an issue against dep, please - while `dep init` may choose to omit a constraint, converting one incorrectly is considered a bug. +* If the wrong `[[constraint]]` was inferred for one of your direct dependencies, change it. Then, file an issue against dep (please!) - while `dep init` may choose to omit a constraint, converting one incorrectly is considered a bug. * If one of your transitive dependencies is at the wrong version, define an `[[override]]` on it to force it to the version you need. * If the version you need is a specific git commit, it's preferable to instead manually change the `revision` to the desired hash in `Gopkg.lock` for that project, then drop the `version` or `branch` fields (if any). * If one of your direct dependencies is at the wrong version and there's no `[[constraint]]` on it in `Gopkg.toml` already, then define an appropriate one. diff --git a/docs/the-solver.md b/docs/the-solver.md new file mode 100644 index 0000000000..ff9748e354 --- /dev/null +++ b/docs/the-solver.md @@ -0,0 +1,93 @@ +--- +title: The Solver +--- + +At the heart of dep is a constraint solving engine - a [CDCL]()-style [SMT]() solver, tailored specifically to the domain of Go package management. It lives in the `github.com/golang/dep/gps` package, and is where the work of determining a valid, transitively complete dependency graph (aka, the contents of `Gopkg.lock`) is performed. + +This page will eventually detail the solver's mechanics, but in the meantime, there are [docs for an older version of the solver]() that are still accurate enough to provide a rough picture of its behavior. + +## Solving invariants + +The solver guarantees certain invariants in every complete solution it returns. Each invariant is explored in detail later, but they can be summarized as follows: + +* All rules specified in activated `[[constraint]]` stanzas in both the current project and dependency projects will be satisfied, unless superseded by a `[[override]]` stanza in the current project. +* For all import paths pointing into a given project, the version of the project selected will contain "valid" Go packages in the corresponding directory. +* If an [import comment](https://golang.org/cmd/go/#hdr-Import_path_checking) is specified by a package, any import paths addressing that package will be of the form specified in the comment. +* For any given import path, all instances of that import path will use the exact same casing. + +The solver is an iterative algorithm, working its way project-by-project through possible dependency graphs. In order to select a project, it must first prove that, to the best of its current knowledge, all of the above conditions are met. When the solver cannot find a solution, failure is defined in terms of a project's version's inability to meet one of the above criteria. + +### `[[constraint]]` rules + +As described in the `Gopkg.toml` docs, each [`[[constraint]]`](gopkg.toml.md#constraint) stanza is associated with a single project, and each stanza can contain both [a version rule](gopkg.toml.md#version-rules) and a [source rule](gopkg.toml.md#source). For any given project `P`, all dependers on `P` whose constraint rules are "activated" must express mutually compatible rules. That means: + +* For version rules, all activated constraints on `P` must [intersect](https://en.wikipedia.org/wiki/Intersection_(set_theory)), and and there must be at least one published version must exist in the intersecting space. Intersection varies depending on version rule type: + * For `revision` and `branch`, it must be a string-literal match. + * For `version`, if the string is not a valid semantic version, then it must be a string-literal match. + * For `version` that are valid semantic version ranges, intersection is standard set-theoretic intersection of the possible values in each range range. Semantic versions without ranges are treated as a single element set (e.g., `version = "=v1.0.0"`) for intersection purposes. +* For `source` rules, all projects with a particular dependency must either express a string-equal `source` value, or have no `source` value at all. This allows one dependency to specify an alternate `source`, and other dependencies to play along if they have no opinion. (NB: this play-along behavior may be removed in a future version.) + +If the current project's `Gopkg.toml` has an [`[[override]]`](gopkg.toml.md#override) on `P`, then all `[[constraint]]` declarations (including any in the current project) are ignored, obviating the possibility of conflict. + +#### Activated constraints + +Just because a `[[constraint]]` on `P` appears in `D`'s `Gopkg.toml` doesn't necessarily mean the constraint on `P` is considered active. A package in `P` must be imported by a package in `D` - and, if `D` is not the current project, then one of its packages importing `P` must also be imported. + +Given the following dependency graph, where `C` is the current project: + +``` +C -> D +C -> P +D/subpkg -> P +``` + +Even though `C` imports `D`, because `D/subpkg` is not reachable through `C`'s imports, any `[[constraint]]` declared in `D`'s `Gopkg.toml`' on `P` will not be active. + +The reasoning behind this behavior is explained further [in this gist](https://gist.github.com/sdboyer/b0813bf2b9dba58a335a85092085472f). + +### Package validity + +dep does only superficial validaton of code in packages, but it does do some. For a package to be considered valid, three things must be true: + +* There must be at least one `.go` file. +* No errors are reported from [`parser.ParseFile()`](https://golang.org/pkg/go/parser/#ParseFile) when called with [`parser.ImportsOnly|parser.ParseComments`](https://golang.org/pkg/go/parser/#Mode) on any file in the package directory. + +- The package must not contain any [local imports](https://golang.org/pkg/go/build/#IsLocalImport). Note: this disallows something the standard toolchain compiler does allow, which is normally means dep must support it. However, local imports are already strongly discouraged in the toolchain, and skipping them allows dep to avoid [dot-dot hell](https://9p.io/sys/doc/lexnames.html). + +If any of the above are untrue, the code in a package is considered malformed, and cannot be used in a solution. + +It is not immediately disqualifying for a project to merely contain some invalid packages; they must be imported for the invariant to be broken. So, if `P/invalid` is a subpackage with invalid code in it, then it is still acceptable if `C -> P`. However, internal imports within `P` are also considered, so this import chain: + +``` +C -> P +P -> invalid +``` + +will result in an error, as `C` imports a package that will necessarily result in the import of an invalid package. + +### Import comments + +Go 1.4 introduced [import comments](https://golang.org/cmd/go/#hdr-Import_path_checking), which allow a package to specify the import path that must be used when addressing it. For example, `import "github.com/golang/net/dict"` would point to a valid package, but because [it uses an import comment](https://github.com/golang/net/blob/42fe2e1c20de1054d3d30f82cc9fb5b41e2e3767/dict/dict.go#L7) to enforce that it must be imported as `golang.org/x/net/dict`, dep would reject any project attempting to import it directly through its github address. + +**Remediation:** Because most projects are consistent about their import comment use over time, this issue typically only occurs when adding a new dependency or attempting to revive an older project. However, if you do encounter it, your only recourse is to change the code by fixing the offending import paths. If the offending import paths are in a dependency, not your/the current project, that may entail forking the dependency. + +### Import path casing + +The standard Go toolchain compiler [does not](https://github.com/golang/go/issues/4773) [allow](https://github.com/golang/go/issues/20264) import paths that vary only in case to exist in the same build. For example, either of `github.com/sirupsen/logrus` or `github.com/Sirupsen/logrus` are fine (GitHub treats usernames as case-insensitive) individually, but they cannot exist in the same project. + +The solver keeps track of the accepted case variant for each import path it's processed. Any subsequent projects it sees that introduces a case-only variation for a known import path will be rejected. + +**Remediation:** + +--- + + + +The solving algorithm works by iteratively constructing a depgraph, working one project at a time. For each project, it walks through a [sorted queue]() of the project's published versions, searching for a version that satisfies all of the these invariants. The first version encountered that satisfies all invariants will be selected. + +At any given point in the algorithm, it is impossible to know _a priori_ if all the rules that will ultimately be discovered for a given project have been discovered. As such, it is possible that, if new dependencies are discovered on an already-selected + +whether all rules that will eventually be needed for a given project are known at the time that project is visited, it is possible that a project for which a version is selected may need to be revisited later, through a backtracking process. + +This process is complicated by the fact that, for any given project being evaluated by the algorithm, it cannot be known _a priori_ whether we know all of the invariants for a project. + From 7f60cb3aeea998cbf836dfb5cec2241313f1dfc0 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Sun, 14 Jan 2018 02:53:29 -0800 Subject: [PATCH 05/13] docs: Failure modes doc nearly done. Now only basic explanations of solving failures are missing. Also includes relevant glossary updates. --- docs/failure-modes.md | 156 +++++++++++++++++++++++++++++++++++++++++- docs/glossary.md | 27 +++++++- 2 files changed, 180 insertions(+), 3 deletions(-) diff --git a/docs/failure-modes.md b/docs/failure-modes.md index bd2612be6d..ceeb6ba57c 100644 --- a/docs/failure-modes.md +++ b/docs/failure-modes.md @@ -2,11 +2,160 @@ title: Failure Modes --- -Like all complex, network-oriented software, dep has known failure modes. These can generally be divided into two groups: hard failures, where the dep process exits non-zero, and soft failures, where it exits zero, but maybe shouldn't have. +Like all complex, network-oriented software, dep has known failure modes. These generally fall into two categories: I/O and logical. I/O errors arise from unexpected responses to system calls when dep is interacting with the network or local disk. Logical failures occur when dep encounters issues within the package management problem domain. +## I/O errors +dep reads from the network, and reads and writes to disk, and is thus subject to all the typical errors that are possible with such activities: full disks, failed disks, lack of permissions, network partitions, firewalls, etc. However, there are three specific classes of I/O errors that are worth addressing specifically: -## Solving failures +* Network failures +* Bad local cache state +* `vendor` write errors + +In general, these problems aren't things we can reasonably program around in dep. Therefore, they can't be considered bugs for us to fix. Fortunately, most of these problems have straightforward remediations. + +### Network failures + +dep talks to the network at several different points. These vary somewhat depending on source (VCS) type and local disk state, but this list of operations is generally instructive: + +* When dep cannot [statically deduce](deduction.md#static-deduction) the source root of an import path, it issues a `go-get` HTTP metadata request to a URL constructed from the import path. +* Retrieving the list of available versions for a source (think `git ls-remote`) necessarily requires network activity. +* Initially downloading (in git terms, `git clone`) an upstream source into the local cache also necessarily requires network activity. +* Updating a local cache (in git terms, `git fetch`) with the latest changes from an upstream source. +* Writing out code trees under `vendor` is typically done from the local cache, but under some circumstances a tarball may be fetched on-the-fly from a remote source. + + +Network failures that you actually may observe are biased towards the earlier items in the list, simply because those operations tend to happen first: you generally don't see update failures as much as version-listing failures, because they usually have the same underlying cause (source host is down, network partition, etc.), but the version-list request happens first on most paths. + +#### Persistent network failures + +Most of the time, errors from the above list will be ephemeral, and **simply re-running the command will result in success**. However, there are three well-defined cases where that's not true: + +* **The network on which the source resides is permanently unreachable from the user's location:** in practice, this generally means one of two things: you've forgotten to log into your company VPN, or you're behind [the GFW](https://en.wikipedia.org/wiki/Great_Firewall). In the latter case, setting the *de facto* standard HTTP proxy environment variables that [`http.ProxyFromEnvironment()`](https://golang.org/pkg/net/http/#ProxyFromEnvironment) respects will cause dep's `go-get` HTTP metadata requests, as well as git, bzr, and hg subcommands, to utilize the proxy. + + +* * Remediation is also exactly the same when the custom `go-get` HTTP metadata service for a source is similarly unreachable. The failure messages, however, will look like [deduction failures](#deduction-failures). + +* **The source has been permanently deleted or moved:** these are [left-pad](https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/) events, though note that [GitHub automatically redirects traffic after renames](https://help.github.com/articles/renaming-a-repository/), mitigating the rename problem. But, if an upstream source is removed, dep will be unable to proceed until a new upstream source is established for the import path. To that end: + + * If you still have a copy of the source repository in your local cache or GOPATH, consider uploading it to a new location (e.g. forking it) and using a [`source`](Gopkg.toml.md#source) rule to point to the fork. + * If you don't have a whole repository locally, then extracting the code currently in your `vendor` directory into a new repository and pushing it to a . (Note: this may have licensing implications.) + * If you have no instances of the code locally, then there's little that can be done - that code is simply gone, and you'll need to refactor your project. + + Future versions of dep will be able to better handle an interim period before a new upstream/forked source is created, or simply living in a world where a given code tree exists solely in your project's `vendor` directory. + +* **The user lacks the necessary credentials to interact with a source:** see the [FAQ on configuring credentials](FAQ.md#how-do-i-get-dep-to-authenticate-to-a-git-repo). + +The exact error text will vary depending on which of the operations is running, what type of source dep is trying to communicate with, and what actual network problem has occurred. The error text may not always make it immediately clear which combination of these you're dealing with, but for persistent problems, it should at least reduce the search space. + +#### Hangs + +Almost any case where a dep command, run with `-v`, hangs for more than ten minutes will ultimately be a bug. However, the most common explanation for an apparent dep hangs is actually normal behavior: because dep's operation requires that it keep its own copies of upstream sources hidden away in the [local cache](glossary.md#local-cache), the first run of dep against a project, especially large projects, can take a long time while it populates the cache. + +The only known case where dep may hang indefinitely is if one of the underlying VCS binaries it calls is prompting for some kind of input. Typically this means credentials (though not always - make sure to accept remote hosts' SSH keys into your known hosts!), and dep's normal assumption is that necessary credentials have been provided via environmental mechanisms - [configuration files or daemons](FAQ.md#how-do-i-get-dep-to-authenticate-to-a-git-repo), SSH agents, etc. This assumption is necessary for dep's concurrent network activity to work. If your use case absolutely cannot support the use of any such environmental caching mechanism, [please weigh in on this issue](). + +Unfortunately, until dep [improves the observability of its ongoing I/O operations](), it cannot accurately report to the user which operations are actually underway at any given moment. This can make it difficult to differentiate from other hangs - credentials prompts, long network timeouts induced by firewalls, sluggish TCP when faced with packet loss, etc. + +### Bad local cache state + +It is possible for parts of the [local cache](glossary.md#local-cache) maintained by dep to get into a bad state. This primarily happens when dep processes are forcibly terminated (e.g. Ctrl-C). This can, for example, terminate a `git` command partway through, leaving bad state on disk. By dep's definition, a [dirty git working copy]() is bad state. + +The error messages arising from bad local cache state often do not include full paths, so it may not be immediately obvious that problems are originating in the local cache. If full paths aren't included, then the best hint tends to be that the errors look like local VCS errors, but they're not on files from your own project. + +However, for the most part, **dep automatically discovers and recovers from bad local cache state problems**, rebounding back into a good state as it bootstraps each command execution. If you do encounter what appears to be a local cache problem from which dep does not automatically recover, then the fix is typically to just throw out the cache, `rm -rf $GOPATH/pkg/dep/sources`; dep will repopulate it automatically on the next run. However, if you have time, please preserve the local cache dir and report it as a bug! + +There are no known cases where, in the course of normal operations, dep can irreparably corrupt its own local cache. Any such case would be considered a critical bug in dep, and you should report it! If you think you've encountered such a case, it should have the following characteristics: + +* The error message you're seeing is consistent with some sort of disk state error in a downloaded source within `$GOPATH/pkg/dep/sources` +* You can identify a bad state (generally: a vcs "status"-type command will either fail outright, or report a modified working tree) in a subdirectory of `$GOPATH/pkg/dep/sources` suggested by the above error +* The exact same error recurs after removing the local cache dir and running the same command, **without** prematurely terminating the project (e.g. via Ctrl-C) + +### `vendor` write errors + +dep may encounter errors while attempting to write out the `vendor` directory itself (any such errors will result in a full rollback; causing no changes to be made to disk). To help pinpoint where the problem may be, know that this is the flow for populating `vendor`: + +1. Allocate a new temporary directory within the system temporary directory. +2. Rename the existing `vendor` directory to `vendor.orig`. Do this within the current project's root directory if possible; if not, rename and move it to the tempdir. +3. Create a new `vendor` directory within the tempdir and concurrently populate it with all the projects named in `Gopkg.lock`. +4. Move the new `vendor` directory into place in the current project's root directory. +5. Delete the old `vendor` directory. + +Note: this flow will become more targeted after [vendor verification]() allows dep to identify and target the subset of projects currently in `vendor` that need to be changed. + +Known problems in this category include: + +* Insufficient space in the temporary directory will cause an error, triggering a rollback. However, because the rollback process cleans up files written so-far, the temporary partition won't actually be full after dep exits, which can be misleading. +* Attempting to [re]move the original `vendor` directory can fail with permissions errors if any of the files therein are "open", in some editors/on some OSes (particularly Windows). [There's an issue for this](). + +## Logical failures + +Logical failures encompass everything that can happen within dep's logical problem-solving domain - after + +Some of these failures can be as straightforward as typos, and are just as easily resolved. Others, unfortunately, may necessitate forking and modifying an upstream project - although such cases are very rare. + +### Deduction failures + +Import path deduction, as detailed in the [deduction reference](deduction.md), has both static and dynamic phases. When neither of these phases is able to determine the source root for a given import path, it is considered to be a deduction failure. Deduction failures all have this key error text: + +``` +unable to deduce repository and source type for ""... +``` + +_Note: there are [more varied error messages for the small subset of cases](#malformed-import-paths) where an import path appears to be deducible, but is somehow malformed._ + +When a deduction failure occurs on a given import path, the proximal cause will have been one of following five scenarios (arranged from most to least likely): + +* The import path was never deducible. +* **Dynamic deduction failures:** + * The import path was, at one time, dynamically deducible, and the metadata service for it is up, but it is unreachable by dep. + * The import path was, at one time, dynamically deducible, but the metadata service for it is down. +* **Static rule changes:** + * The import path cannot be statically deduced by the running version of dep, but a newer version of dep has added rules that can statically deduce it. + * The import path was once statically deducible, but the running version of dep has discontinued support for it. + +In all of these cases, your last recourse will be to add a [`source`](Gopkg.toml.md#source) directive to fix the problem. However, these directives are brittle, and should only be used when other options have been exhausted; also, until [this problem is solved](https://github.com/golang/dep/issues/860), even `source` may not be able to help. + +#### Undeducible paths + +The most likely cause of deduction failure is minor user error. Specifically, the user is the _current_ user (you), and the error is there is a mistyped import path somewhere in the current (your) project. The problem may be in your `Gopkg.toml`, or one of your imports, but the error message should point you directly at the problem, and the solution is usually obvious - e.g., "gihtub". + +Validation of the inputs from the current project are made fast and up front in dep, so these errors will tend to present themselves immediately. Between this fast validation, and the fact that projects are typically uncompilable, or at least not `go get`-able, with these kinds of errors, they tend to be caught early. This is why truly undeducible paths pop up primarily as temporary accidents while hacking on your own projects - you have to fix them to move on. + +That undeducibility is an immediate and hard blocker, however, has led to this being a sticking point for migration to dep. In particular, there are two issues: + +* Several other Go dependency management tools do allow specifying arbitrary VCS/source URLs, and [but support for that via `source` in dep is still pending](https://github.com/golang/dep/issues/860). +* GitHub Enterprise only implements `go-get` HTTP metadata correctly for the root package of a repository. In practice, this makes all import paths pointing to GHE undeducible, and `source` can't help either without the aforementioned improvement. + +If the problem import path is in your current project, but the problem isn't an obvious typo, then you're likely experiencing a dynamic failure, or may need to check the [deduction reference](deduction.md) to understand what what a deducible import path looks like. + +#### Dynamic deduction failures + +Most dynamic deduction failures are either ephemeral network or service availability issues, and will go away by re-running the previous command. Always try that first. + +If the issue persists, and you're certain the import path should be deducible, network issues are the first culprit to check. The typical causes (VPN, firewalls) and remediation for when a metadata service is unreachable are the same as [when a source itself is unreachable](#persistent-network-failures). + +The next possibility is a metadata service that's permanently gone away. Whereas network errors are still reasonably common, it is rare to encounter an import path pointing to a defunct public metadata service. Consider: that one import path can render the entire project unfetchable and/or uncompilable, and neither of those are states that popular projects can afford to be in for long. So, being that most (public Go ecosystem) dependencies are on the more popular projects, as long as you're also depending on the more popular projects, you're unlikely to encounter this. + +Of course, defunct _private_ metadata services may be much more common, as they are subject to entirely different incentives. + +If you think you've encountered a defunct metadata service, try probing the domain portion of the import path directly to see if there is an HTTP(S) server there at all. If not, you can only force with `source` - assuming you know what source URL you should use. If not, you may need to refactor your code (if the problem is in your project), pick a different version of the problem dependency, or drop the problem dependency entirely; sometimes, you just have to get rid of dead code. + +#### Static rule changes + +Static rule changes are very unlikely to be the cause of your deduction failures. + +It is plausible that dep will add new static deduction rules in the future. And it is possible that, if you have an older version of dep, and you collaborate with or pull in code from someone using a newer version of dep, then their code may take advantage of new import path patterns that your dep doesn't know about yet. But very, very few static rules additions are likely to ever be made to dep over its lifetime - and getting access to them is just a question of updating once. + +The final scenario - dep discontinuing support for a static deduction pattern - is included for clarity and completeness, but simply should never happen. Even if a hosting service covered by static rules today were to shut down, dep would retain the existing static rules; if hosted code had been migrated elsewhere, then dep would attempt to perform a remapping automatically. If no such remapping were possible, then dep would still recognize the basic host pattern, but may fall back on using malformed import path errors - the next topic - to informatively reject new imports from the host. + +#### Malformed import paths + +For the most part, static ("is it one of the handful of hosts we know?") and dynamic ("just do whatever the metadata service tells us to do") deduction are single-pass checks. However, both cases can perform some minor additional validation: + +* In static deduction, the rules are necessarily specific to each host, but most enforce allowable characters and schemes in URLs that are known to be required by the underlying host. +* In dynamic deduction, responses from the metadata service are minimally validated to ensure that the source type and scheme are all supported, and that the URL contains valid characters. + +### Solving failures When `dep ensure` or `dep init` exit with an error message looking something like this: @@ -26,3 +175,6 @@ It means that the solver was unable to find a combination of versions for all de * **Import comment failure:** when the import path used to address a package differs from the [import comment](https://golang.org/cmd/go/#hdr-Import_path_checking) the package uses to specify how it should be imported. * **Case-only import variation failure:** when two equal-except-for-case imports exist in the same build. + + + diff --git a/docs/glossary.md b/docs/glossary.md index e0bab7ac77..a8e5f72ad8 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -6,13 +6,16 @@ title: Glossary dep uses some specialized terminology. Learn about it here! * [Atom](#atom) +* [Cache lock](#cache-lock) * [Constraint](#constraint) * [Current Project](#current-project) * [Deduction](#deduction) * [Direct Dependency](#direct-dependency) * [GPS](#gps) +* [Local cache](#local-cache) * [Lock](#lock) * [Manifest](#manifest) +* [Metadata Service](#metadata-service) * [Override](#override) * [Project](#project) * [Project Root](#project-root) @@ -28,6 +31,10 @@ dep uses some specialized terminology. Learn about it here! Atoms are a source at a particular version. In practice, this means a two-tuple of [project root](#project-root) and version, e.g. `github.com/foo/bar@master`. Atoms are primarily internal to the [solver](#solver), and the term is rarely used elsewhere. +## Cache lock + +Also "cache lock file." A file, named `sm.lock`, used to ensure only a single dep process operates on the [local cache](#local-cache) at a time, as it is unsafe in dep's current design for multiple processes to access the local cache. + ## Constraint Constraints have both a narrow and a looser meaning. The narrow sense refers to a [`[[constraint]]`](Gopkg.toml.md#constraint) stanza in `Gopkg.toml`. However, in some contexts, the word may be used more loosely to refer to the idea of applying rules and requirements to dependency management in general. @@ -38,9 +45,13 @@ The project on which dep is operating - writing its `Gopkg.lock` and populating Also called the "root project." +## Deducible + +A shorthand way of referring to whether or not import path [deduction](#deduction) will return successfully for a given import path. "Undeducible" is also often used, to refer to an import path for which deduction fails. + ## Deduction -Deduction is the process of determining a source root from an import path. See the reference on [import path deduction](deduction.md) for specifics. +Deduction is the process of determining the subset of an import path that corresponds to a source root. Some patterns are known a priori (static); others must be discovered via network requests (dynamic). See the reference on [import path deduction](deduction.md) for specifics. ## Direct Dependency @@ -50,6 +61,12 @@ A project's direct dependencies are those that it imports from one or more of it Stands for "Go packaging solver", it is [a subtree of library-style packages within dep](https://godoc.org/github.com/golang/dep/gps), and is the engine around which dep is built. Most commonly referred to as "gps." +## Local cache + +dep maintains its own, pristine set of upstream sources (so, generally, git repository clones). This is kept separate from `$GOPATH/src` so that there is no obligation to maintain disk state within `$GOPATH`, as dep frequently needs to change disk state in order to do its work. + +By default, the local cache lives at `$GOPATH/pkg/dep`. If you have multiple `$GOPATH` entries, dep will use whichever is the logical parent of the process' working directory. Alternatively, the location can be forced via the `DEPCACHEDIR` environment variable. + ## Lock A generic term, used across many language package managers, for the kind of information dep keeps in a `Gopkg.lock` file. @@ -58,6 +75,14 @@ A generic term, used across many language package managers, for the kind of info A generic term, used across many language package managers, for the kind of information dep keeps in a `Gopkg.toml` file. +## Metadata Service + +An HTTP service that, when it receives an HTTP request containing a `go-get=1` in the query string, treats interprets the path portion of the request as an import path, and responds by embedding data in HTML `` tags that indicate the type and URL of of the underlying source root. This is the server-side component of dynamic [deduction](#deduction). + +The behavior of metadata services is defined in the [Go documentation on remote import paths](https://golang.org/cmd/go/#hdr-Remote_import_paths). + +Variously referenced as "HTTP metadata service", "`go-get` HTTP metadata service", "`go-get` service", etc. + ## Override An override is a [`[[override]]`](Gopkg.toml.md#override) stanza in `Gopkg.toml`. From adb9a566d929600bfeb51f07e5ec1575641eda25 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Mon, 15 Jan 2018 12:58:23 -0800 Subject: [PATCH 06/13] 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 e69de29bb2..ac38519ff5 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 From afb1cd6650d7a3e7d32859ef3c84d5d5480d9543 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Mon, 15 Jan 2018 19:07:49 -0800 Subject: [PATCH 07/13] docs: Penultimate docs changeset Just tidying and deduction left now before the first mountain of docs can be called complete. --- docs/Gopkg.toml.md | 2 +- docs/day-to-day-dep.md | 57 ++++++++++++++++++++++++++------------- docs/deduction.md | 33 ++++++++++++++++++++++- docs/dep-basics.md | 1 - docs/ensure-mechanics.md | 58 +++++++++++++++++++--------------------- docs/failure-modes.md | 36 ++++++++++++++++++++----- docs/glossary.md | 9 +++++-- docs/introduction.md | 9 +++++-- docs/migrating.md | 40 +++++++-------------------- docs/new-project.md | 14 +++++----- docs/the-solver.md | 23 +++++----------- 11 files changed, 165 insertions(+), 117 deletions(-) delete mode 100644 docs/dep-basics.md diff --git a/docs/Gopkg.toml.md b/docs/Gopkg.toml.md index a40f813a83..7eca5ab72f 100644 --- a/docs/Gopkg.toml.md +++ b/docs/Gopkg.toml.md @@ -110,7 +110,7 @@ ignored = ["github.com/user/project/badpkg*"] `metadata` declarations are ignored by dep and are meant for usage by other independent systems. -The root `metadata` declaration defines informatino about the project itself, while a `metadata` declaration under a `[[constraint]]` or an `[[override]]` defines metadata about that rule, for the `name`d project. +The root `metadata` declaration defines information about the project itself, while a `metadata` declaration under a `[[constraint]]` or an `[[override]]` defines metadata about that rule, for the `name`d project. ```toml [metadata] key1 = "value that convey data to other systems" diff --git a/docs/day-to-day-dep.md b/docs/day-to-day-dep.md index c5d6893093..b115d6252d 100644 --- a/docs/day-to-day-dep.md +++ b/docs/day-to-day-dep.md @@ -1,37 +1,37 @@ --- -title: Day-to-day dep +title: Daily Dep --- -In keeping with Go's philosophy of minimizing knobs, dep has a sparse interface; there are only two commands you're likely to run regularly: +This guide is an introduction to the day-to-day use of dep. If you haven't set up a Go project at all yet, though, run through [Creating a New Project](new-project.md) first. + +Dep is a tool you'll use regularly in the course of normal Go development. Regularly, but briefly - dependency management is never the place we want to be spending our time or energy! In keeping with Go's philosophy of minimizing knobs, dep has a sparse interface; there are only two commands you're likely to run regularly: * `dep ensure` is the primary workhorse command, and is the only command that changes disk state. -* `dep status` reports on the state of your project, and the universe of Go dependencies. +* `dep status` reports on the state of your project, and the visible universe of Go software projects. -This guide primarily centers on `dep ensure`, as that's the command you run to effect changes on your project. The [ensure mechanics](ensure-mechanics.md) reference details how the command actually works, and is worth reading if you're encountering a confusing `dep ensure` behavior (or just curious!). This guide is more of a high-level tour for folks trying to get a basic handle on using dep effectively. +This guide primarily centers on `dep ensure`, as that's the command you run to effect changes on your project. The [ensure mechanics](ensure-mechanics.md) reference document details how the things work under the hood, and is worth reading if you're encountering a confusing `dep ensure` behavior (or just curious!). ## Basics -Let's start with some semantics: the verb is "ensure" to emphasize that the action being taken is not only performing a single, discrete action (like adding a dependency), but rather enforcing a kind of broader guarantee. To put that guarantee in narrative terms, running `dep ensure` is like saying: - -> Hey dep, please make sure that my project is [in sync](glossary.md#sync): that `Gopkg.lock` satisfies all the imports in my project, and all the rules in `Gopkg.toml`, and that `vendor/` contains exactly what `Gopkg.lock` says it should." +Let's start with words! -As the narrative indicates, `dep ensure` is a holistic operation; rather than offering a series of commands that you run in succession to incrementally achieve a some final state, each run of `dep ensure` delivers a complete, consistent final state with respect to the inputs of your project. It's a bit like a frog, hopping from lilypad to lilypad: `dep ensure` moves your project from one safe (transitively complete import graph, with all constraints satisfied, and a fully populated `vendor`) island to the the next, or it doesn't move at all. There are no known intermediate failure states. This makes `dep ensure` fine to run at most any time, as it will always drive towards a safe, known good state. +Dep's main command is `dep ensure`. The verb is "ensure" to imply that the action is not just some single, discrete action (like adding a dependency), but enforcing some kind of broader guarantee. If we wanted to express the `dep ensure` guarantee as a sentence, it would go something like this: -General guidelines for using dep: +> Hey dep, please make sure that [my project](glossary.md#current-project) is [in sync](glossary.md#sync): that [`Gopkg.lock`](Gopkg.lock.md) satisfies all the imports in my project, and all the rules in[ `Gopkg.toml`](Gopkg.toml.md), and that `vendor/` contains exactly what `Gopkg.lock` says it should." -* Never directly edit anything in `vendor/`; dep will unconditionally overwrite such changes. -* `dep ensure` is almost never the wrong thing to run; if you're not sure what's going on, running it will bring you back to safety, or fail informatively. +As the narrative indicates, `dep ensure` is a holistic operation; rather than offering a series of commands that you run in succession to incrementally achieve a some final state, each run of `dep ensure` delivers a safe, complete, and reproducible set of dependencies with respect to the current state of your project. You might imagine repeated runs of `dep ensure` as being a bit like a frog, hopping from one lilypad to the next. + `dep ensure` also guarantees that, barring `kill -9`, power failure, or a critical bug, its disk writes are all-or-nothing: on any given run, either nothing changes (and you get an error), or you're on the nearest safe lilypad. This makes `dep ensure` fine to run at most any time. ## Using `dep ensure` There are four times when you'll run `dep ensure`: -- We want to add a new dependency -- We want to update an existing dependency -- We've imported a package for the first time, or removed the last import of a package -- We've made a change to a rule in `Gopkg.toml` +- To add a new dependency +- To update an existing dependency +- To catch up after importing a package for the first time in your project, or removing the last import of a package in your project +- To catch up to a change to a rule in `Gopkg.toml` There's also an implicit fifth time: when you're not sure if one of the above has happened. Running `dep ensure` without any additional flags will get your project back in sync - a known good state. As such, it's generally safe to defensively run `dep ensure` as a way of simply making sure that your project is in that state. @@ -54,11 +54,17 @@ This should succeed, resulting in an updated `Gopkg.lock` and `vendor/` director If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/. ``` -As the warning suggests, you should introduce an `import "github.com/pkg/errors"` in your code, the sooner the better. If you don't, a later `dep ensure` run will interpret your newly-added dependency as unused, and automatically remove it from `Gopkg.lock` and `vendor/`. This is because, in contrast to other dependency management tools that rely on a metadata file to indicate which dependencies are required, dep considers the import statements it discovers through static analysis of your project's code to be the canonical indicator of what dependencies must be present. +As the warning suggests, you should introduce an `import "github.com/pkg/errors"` in your code, the sooner the better. If you don't, a later `dep ensure` run will interpret your newly-added dependency as unused, and automatically remove it from `Gopkg.lock` and `vendor/`. This also means that if you want to add multiple dependencies at once, you'll need to do it in a single command, rather than one after the other: + +``` +$ dep ensure -add github.com/pkg/errors github.com/foo/bar +``` + +Dep works this way because it considers the import statements it discovers through static analysis of your project's code to be the canonical indicator of what dependencies must be present. That choice does add some pain at this moment, but it reduces friction and automates cleanup elsewhere. Tradeoffs! -Note that you do not _have to_ use `dep ensure -add` to add new dependencies - you can also just add an appropriate `import` statement in your code, then run `dep ensure`. This approach doesn't always play nicely with [`goimports`](https://godoc.org/golang.org/x/tools/cmd/goimports), and also won't append a `[[constraint]]` into `Gopkg.toml`. Still, it can be useful at times, often for rapid iteration and off-the-cuff experimenting. +Of course, given this model, you don't _have to_ use `dep ensure -add` to add new dependencies - you can also just add an appropriate `import` statement in your code, then run `dep ensure`. However, this approach doesn't always play nicely with [`goimports`](https://godoc.org/golang.org/x/tools/cmd/goimports), and also won't append a `[[constraint]]` into `Gopkg.toml`. Still, it can be useful at times, often for rapid iteration and off-the-cuff experimenting. -The [ensure mechanics section on `-add`](ensure-mechanics.md#add) has more detail on internals, as well as some subtle variations in `dep ensure -add`'s behavior. +The [ensure mechanics section on `-add`](ensure-mechanics.md#add) has a more thorough exploration, including some ways that `dep ensure -add`'s behavior subtly varies depending on the state of your project. ### Updating dependencies @@ -97,7 +103,7 @@ Only if it is the first/last import of a project being added/removed - cases 3 a `Gopkg.toml` files contain five basic types of rules. The [`Gopkg.toml` docs](#gopkg.toml.md) explain them in detail, but here's an overview: -* `required`, which are mostly equivalent to import statements in code, except it's OK to include a `main` package +* `required`, which are mostly equivalent to `import` statements in `.go` files, except that it's OK to list a `main` package here * `ignored`, which causes dep to black hole an import path (and any imports it uniquely introduces) * `[[constraint]]`, stanzas that express version constraints and some other rules on a per-project dependency basis * `[[override]]`, stanzas identical to `[[constraint]]` except that only the current project can express them and they supersede `[[constraint]]` in both the current project and dependencies @@ -105,4 +111,17 @@ Only if it is the first/last import of a project being added/removed - cases 3 a Changes to any one of these rules will likely necessitate changes in `Gopkg.lock` and `vendor/`; a single successful `dep ensure` run will incorporate all such changes at once, bringing your project back in sync. +## Key Takeaways + +Here are the key takeaways from this guide: + +- `dep ensure -update` is the preferred way to update dependencies, though it's less effective for projects that don't publish semver releases. +- `dep ensure -add` is usually the easiest way to introduce new dependencies, though it's not the only one. To add more than one at a time, you'll need to use multiple arguments, not multiple invocations - and make sure to add real `import` statements for the projects after the command completes! +- If you ever make a manual change in `Gopkg.toml`, it's best to run `dep ensure` to make sure everything's in sync. +- `dep ensure` is almost never the wrong thing to run; if you're not sure what's going on, running it will bring you back to safety ("the nearest lilypad"), or fail informatively. + +Also, a couple other miscellaneous tidbits: + +- As in the Go toolchain generally, avoid symlinks within your own project. dep tolerates a bit of this, but like the Go toolchain itself, is generally not terribly supportive of symlinks. +- Never directly edit anything in `vendor/`; dep will unconditionally overwrite such changes. If you need to modify a dependency, fork it and do it properly. diff --git a/docs/deduction.md b/docs/deduction.md index fd7d560f3c..acfc16b939 100644 --- a/docs/deduction.md +++ b/docs/deduction.md @@ -9,4 +9,35 @@ Deduction is dep's algorithm for looking at an import path and determining the p The set of hosts supported by static deduction are the same as [those supported by `go get`](). -If the static logic cannot identify the root for a given import path, the algorithm continues to a dynamic component, where it makes an HTTP(S) request to the import path, and a server is expected to return a response that indicates the root import path. This, again, is equivalent to the behavior of `go get`. \ No newline at end of file +If the static logic cannot identify the root for a given import path, the algorithm continues to a dynamic component, where it makes an HTTP(S) request to the import path, and a server is expected to return a response that indicates the root import path. This, again, is equivalent to the behavior of `go get`. + + + +Import path deduction is applied to all of the following: + +* `import` statements found in all `.go` files +* Import paths named in the [`required`](gopkg.toml.md#required) property in `Gopkg.toml` +* `name` properties in both [`[[constraint]]`](Gopkg.toml.md#constraint) and [`[[override]]`](Gopkg.toml.md#override) stanzas in `Gopkg.toml`. This is solely for validation purposes, enforcing that these names correspond strictly to source roots. + + + + +The results of import path deduction are, in practice, almost entirely fixed; it's easy to imagine why. In the public ecosystem, even dynamic deductions rarely change in practice, as it would either require: + +- a `go-get` metadata service to intentionally change its mappings, or +- a `go-get` metadata service to disappear. + +`go get` itself is only partially resilient to these cases, but each is potentially catastrophic for a package's retrievability across the ecosystem, sooner rather than later. This steep and abrupt downside makes it nearly impossible for projects only accessible via an unreliable metadata service to ever become popular or widely used in the ecosystem. Thus, in the public ecosystem, we almost only ever see reliable, well-behaved services. + + + + + + + + + + +Because deduction has a dynamic component, the deducibility of any given path necessarily cannot be fixed. However, because the + +## Static deduction \ No newline at end of file diff --git a/docs/dep-basics.md b/docs/dep-basics.md deleted file mode 100644 index af84291d02..0000000000 --- a/docs/dep-basics.md +++ /dev/null @@ -1 +0,0 @@ -Normal work with dep will have \ No newline at end of file diff --git a/docs/ensure-mechanics.md b/docs/ensure-mechanics.md index fdf8934b4e..a85e9f1620 100644 --- a/docs/ensure-mechanics.md +++ b/docs/ensure-mechanics.md @@ -1,23 +1,27 @@ --- -title: dep ensure mechanics +title: Models and Mechanics --- -As `dep ensure` is dep's sole state-mutating command, its mechanics are essentially the mechanics of dep as a whole. +While dep has many discrete components and moving parts, all of these parts revolve around a central model. This document explains that model, then explores the major mechanisms of dep as they relate to it. -## Functional flow +## States and flows -Dep's operation centers around the idea of the "four state system" - a model for organizing the on-disk state a package manager deals with, originally articulated in [this (very long) article](https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527). Those states are: +Dep is centered around the idea of the "four state system" - a model for classifying and organizing the on-disk state with which a package manager interacts. This was first articulated as a coherent, general model in [this (long) article](https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527), though many of the principles in the four state model were derived from existing package managers. + +Briefly, the four states are: 1. The [current project's](glossary.md#current-project) source code. -2. A [manifest](glossary.md#manifest) - a file describing the current project's dependency requirements. In dep, this is the `Gopkg.toml` file. -3. A [lock](glossary.md#lock) - a file containing a transitively-complete, reproducible description of the dependency graph. In dep, this is the `Gopkg.lock` file. +2. A [manifest](glossary.md#manifest) - a file describing the current project's dependency requirements. In dep, this is the [`Gopkg.toml`](Gopkg.toml.md) file. +3. A [lock](glossary.md#lock) - a file containing a transitively-complete, reproducible description of the dependency graph. In dep, this is the [`Gopkg.lock`](Gopkg.lock.md) file. 4. The source code of the dependences themselves. In dep's current design, this is the `vendor/` directory. -Let's visually represent these four states as follows: +We can visually represent these four states as follows: ![dep's four states](img/four-states.png) -It's best to think of `dep ensure` as a unidirectional series of functions, analyzing and transforming inputs into outputs. Specifically, there are two functions: +### Functional flow + +It's useful to think of dep as a system that imposes a unidirectional, functional flow on the relationships between these states. These functions treat the above states as inputs and outputs, moving them from left to right. Specifically, there are two functions: * A _solving function_, that takes as its input the set of imports in the current project and the rules in `Gopkg.toml`, and returns as its output a transitively-complete, immutable dependency graph - the information in a `Gopkg.lock`. * A _vendoring function_, that takes the information in a `Gopkg.lock` as its input and ensures an on-disk arrangement of source files such that the compiler will use the versions designated in the lock. @@ -26,6 +30,8 @@ We can represent these two functions visually: ![dep's two main functions](img/annotated-func-arrows.png) +This is `dep ensure` - the typical flow, used when a `Gopkg.toml` already exists. When a project does not yet have a `Gopkg.toml`, `dep init` can generate one. The essential flow remains the same, but with changed inputs: instead of reading from an existing `Gopkg.toml` file, `dep init` constructs one out of data inferred from the user's GOPATH, and/or [a metadata file from another tool](). (In other words, `dep init` automatically migrates a project from other approaches to organizing dependencies.) + This diagram directly corresponds directly to code, as well. The solving function is actually split into a constructor and a method - we first create a [`Solver`](https://godoc.org/github.com/golang/dep/gps#Solver) type, then call its `Solve()` method. The inputs to the constructor are wrapped up in a [`SolveParameters`](https://godoc.org/github.com/golang/dep/gps#SolveParameters), which should look familiar: ```go @@ -36,36 +42,26 @@ type SolveParameters struct { } ``` -The vendoring function is [`gps.WriteDepTree()`](https://godoc.org/github.com/golang/dep/gps#WriteDepTree). It takes a handful of arguments, but the key one is a [`Lock`](https://godoc.org/github.com/golang/dep/gps#Lock) - that is, the data held in `Gopkg.lock`. +The vendoring function is [`gps.WriteDepTree()`](https://godoc.org/github.com/golang/dep/gps#WriteDepTree). While it takes a handful of arguments, the relevant one is a [`gps.Lock`](https://godoc.org/github.com/golang/dep/gps#Lock) - an interface representing an abstracted form of the data held in a `Gopkg.lock`. -Almost all of dep's behaviors are best understood with respect to this functional model. If you want to understand dep's mechanics, keep this model centered in your mind. +The four state system, and these functional flows through it, are the foundation on which all of dep's behavior is built. If you want to understand dep's mechanics, keep this model at the forefront of your mind. -## Functional optimizations +### Staying in sync -It is one of dep's foundational design goals that both of its functions do as little work as possible, and result in as little change for their outputs as possible. Consequently, both "functions" peek ahead at the their current result to understand what work, if any, actually needs to be done: +One of dep's design goals is that both of its "functions" minimize both the work they do, and the change they induce in their respective results. (Note: "minimize" is not currently formally defined with respect to a cost function.) Consequently, both functions peek ahead at the pre-existing result to understand what work actually needs to be done: * The solving function checks the existing `Gopkg.lock` to determine if all of its inputs (project import statements + `Gopkg.toml` rules) are satisfied. If they are, the solving function can be bypassed entirely. If not, the solving function proceeds, but attempts to change as few of the selections in `Gopkg.lock` as possible. * WIP: The current implementation's check relies on a coarse heuristic check that can be wrong in some cases. There is a [plan to fix this](https://github.com/golang/dep/issues/1496). * The vendoring function hashes each discrete project already in `vendor/` to see if the code present on disk is what `Gopkg.lock` indicates it should be. Only projects that deviate from expectations are written out. * WIP: the hashing check is generally referred to as "vendor verification," and [is not yet complete](https://github.com/golang/dep/issues/121). Without this verification, dep is blind to whether code in `vendor/` is correct or not; as such, dep must defensively re-write all projects to ensure the state of `vendor/` is correct. -## Sync - -It's easy to think about - - - -## Imports, and the package tree - - - -## Flags and behavior variations - -Each of `dep ensure`'s various flags affects the behavior of these functions - or even whether they run at all. +Of course, it's possible that, in peeking ahead, either function might discover that the pre-existing result is already correct - so no work need be done at all. Either way, when each function completes, we can be sure that the output, changed or not, is correct with respect to the inputs. In other words, the inputs and outputs are "in sync." Indeed, being in sync is the "known good state" of dep; `dep ensure` (without flags) guarantees that if it exits 0, all four states in the project are in sync. +## `dep ensure` flags and behavior variations +Each of `dep ensure`'s various flags affects the behavior of the solving and vendoring functions - or even whether they run at all. Some flags can also marginally push the project out of sync, temporarily. Thinking about these effects in the context of dep's basic model is the fastest path to understanding. -## `-no-vendor` and `-vendor-only` +### `-no-vendor` and `-vendor-only` These two flags are mutually exclusive, and determine which of `dep ensure`'s two functions are actually performed. Passing `-no-vendor` will cause only the solving function to be run, resulting in the creation of a new `Gopkg.lock`; `-vendor-only` will skip solving and run only the vendoring function, causing `vendor/` to be repopulated from the pre-existing `Gopkg.lock`. @@ -73,7 +69,7 @@ These two flags are mutually exclusive, and determine which of `dep ensure`'s tw Passing `-no-vendor` has the additional effect of causing the solving function to run unconditionally, bypassing the pre-check ordinarily made against `Gopkg.lock` to see if it already satisfies all inputs. -## `-add` +### `-add` The general purpose of `dep ensure -add` is to facilitate the introduction of new dependencies into the depgraph. Whereas `-update` is restricted to [source roots](glossary.md#source-root), (e.g. `github.com/foo/bar`), `-add` can take any package import path as an argument (e.g. `github.com/foo/bar` OR `github.com/foo/bar/baz`). @@ -123,17 +119,17 @@ $ dep ensure -add github.com/foo/bar If you run "dep ensure" again before actually importing it, it will disappear from Gopkg.lock and vendor/. ``` -## `-update` +### `-update` The behavior of `dep ensure -update` is intimately linked to the behavior of the solver itself. Full detail on that is a topic for the [solver reference material](the-solver.md), but for the purposes of understanding `-update`, we can simplify a bit. -First, to solidify an implication in the discussion of [functional optimizations](#functional-optimizations), the solving function actually takes into account the pre-existing `Gopkg.lock` when it runs: +First, to solidify an implication in the discussion of [functional optimizations](#staying-in-sync), the solving function actually takes into account the pre-existing `Gopkg.lock` when it runs: ![Pre-existing lock feeds back into solving function](img/lock-back.png) Injecting `Gopkg.lock` into the solver is a necessity. If we want the solver to preserve previously-selected versions by default, then the solver has to learn about the existing `Gopkg.lock` from somewhere. Otherwise, it wouldn't know what to preserve! -As such, the lock is another one of the properties encoded onto the [previously-discussed](#functional-flow) `SolveParameters` struct. That, plus two other properties, are the salient ones for `-update`: +As such, the lock is another one of the properties encoded onto the [previously-discussed]() `SolveParameters` struct. That, plus two other properties, are the salient ones for `-update`: ```go type SolveParameters struct { @@ -173,7 +169,7 @@ And `v1.1.0` will be selected again, unless some other condition is presented th So, barring some other conflict, `v1.2.0` is selected, resulting in the desired update. -### `-update` and constraint types +#### `-update` and constraint types Continuing with our example, it's important to note that updates with `-update` are achieved incidentally - the solver never explicitly targets a newer version. It just skips adding a hint from the lock, then selects the first version in the queue that satisfies constraints. Consequently, `-update` is only effective with certain types of constraints. diff --git a/docs/failure-modes.md b/docs/failure-modes.md index ceeb6ba57c..7039f8cc8a 100644 --- a/docs/failure-modes.md +++ b/docs/failure-modes.md @@ -16,6 +16,8 @@ In general, these problems aren't things we can reasonably program around in dep ### Network failures +> **Remediation tl;dr:** most network issues are ephemeral, even if they may last for a few minutes, and can be addressed simply by re-running the same command. Always try this before attempting more invasive solutions. + dep talks to the network at several different points. These vary somewhat depending on source (VCS) type and local disk state, but this list of operations is generally instructive: * When dep cannot [statically deduce](deduction.md#static-deduction) the source root of an import path, it issues a `go-get` HTTP metadata request to a URL constructed from the import path. @@ -29,12 +31,11 @@ Network failures that you actually may observe are biased towards the earlier it #### Persistent network failures -Most of the time, errors from the above list will be ephemeral, and **simply re-running the command will result in success**. However, there are three well-defined cases where that's not true: +Although most network failures are ephemeral, there are three well-defined cases where that's not true. These are those cases, and their respective remediations: * **The network on which the source resides is permanently unreachable from the user's location:** in practice, this generally means one of two things: you've forgotten to log into your company VPN, or you're behind [the GFW](https://en.wikipedia.org/wiki/Great_Firewall). In the latter case, setting the *de facto* standard HTTP proxy environment variables that [`http.ProxyFromEnvironment()`](https://golang.org/pkg/net/http/#ProxyFromEnvironment) respects will cause dep's `go-get` HTTP metadata requests, as well as git, bzr, and hg subcommands, to utilize the proxy. - -* * Remediation is also exactly the same when the custom `go-get` HTTP metadata service for a source is similarly unreachable. The failure messages, however, will look like [deduction failures](#deduction-failures). + * Remediation is also exactly the same when the custom `go-get` HTTP metadata service for a source is similarly unreachable. The failure messages, however, will look like [deduction failures](#deduction-failures). * **The source has been permanently deleted or moved:** these are [left-pad](https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/) events, though note that [GitHub automatically redirects traffic after renames](https://help.github.com/articles/renaming-a-repository/), mitigating the rename problem. But, if an upstream source is removed, dep will be unable to proceed until a new upstream source is established for the import path. To that end: @@ -50,6 +51,8 @@ The exact error text will vary depending on which of the operations is running, #### Hangs +> **Remediation tl;dr:** hangs are almost always network congestion, or sheer amount of network data to fetch. Wait, or cancel and try again with `-v` to try to get more context. + Almost any case where a dep command, run with `-v`, hangs for more than ten minutes will ultimately be a bug. However, the most common explanation for an apparent dep hangs is actually normal behavior: because dep's operation requires that it keep its own copies of upstream sources hidden away in the [local cache](glossary.md#local-cache), the first run of dep against a project, especially large projects, can take a long time while it populates the cache. The only known case where dep may hang indefinitely is if one of the underlying VCS binaries it calls is prompting for some kind of input. Typically this means credentials (though not always - make sure to accept remote hosts' SSH keys into your known hosts!), and dep's normal assumption is that necessary credentials have been provided via environmental mechanisms - [configuration files or daemons](FAQ.md#how-do-i-get-dep-to-authenticate-to-a-git-repo), SSH agents, etc. This assumption is necessary for dep's concurrent network activity to work. If your use case absolutely cannot support the use of any such environmental caching mechanism, [please weigh in on this issue](). @@ -58,6 +61,8 @@ Unfortunately, until dep [improves the observability of its ongoing I/O operatio ### Bad local cache state +> **Remediation tl;dr:** Remove the local cache dir: `rm -rf $GOPATH/pkg/dep/sources`. + It is possible for parts of the [local cache](glossary.md#local-cache) maintained by dep to get into a bad state. This primarily happens when dep processes are forcibly terminated (e.g. Ctrl-C). This can, for example, terminate a `git` command partway through, leaving bad state on disk. By dep's definition, a [dirty git working copy]() is bad state. The error messages arising from bad local cache state often do not include full paths, so it may not be immediately obvious that problems are originating in the local cache. If full paths aren't included, then the best hint tends to be that the errors look like local VCS errors, but they're not on files from your own project. @@ -72,7 +77,7 @@ There are no known cases where, in the course of normal operations, dep can irre ### `vendor` write errors -dep may encounter errors while attempting to write out the `vendor` directory itself (any such errors will result in a full rollback; causing no changes to be made to disk). To help pinpoint where the problem may be, know that this is the flow for populating `vendor`: +Dep may encounter errors while attempting to write out the `vendor` directory itself (any such errors will result in a full rollback; causing no changes to be made to disk). To help pinpoint where the problem may be, know that this is the flow for populating `vendor`: 1. Allocate a new temporary directory within the system temporary directory. 2. Rename the existing `vendor` directory to `vendor.orig`. Do this within the current project's root directory if possible; if not, rename and move it to the tempdir. @@ -117,6 +122,8 @@ In all of these cases, your last recourse will be to add a [`source`](Gopkg.toml #### Undeducible paths +> **Remediation tl;dr:** You made a typo; fix it. If not, you may need a `source`, but be sparing with those. + The most likely cause of deduction failure is minor user error. Specifically, the user is the _current_ user (you), and the error is there is a mistyped import path somewhere in the current (your) project. The problem may be in your `Gopkg.toml`, or one of your imports, but the error message should point you directly at the problem, and the solution is usually obvious - e.g., "gihtub". Validation of the inputs from the current project are made fast and up front in dep, so these errors will tend to present themselves immediately. Between this fast validation, and the fact that projects are typically uncompilable, or at least not `go get`-able, with these kinds of errors, they tend to be caught early. This is why truly undeducible paths pop up primarily as temporary accidents while hacking on your own projects - you have to fix them to move on. @@ -142,6 +149,8 @@ If you think you've encountered a defunct metadata service, try probing the doma #### Static rule changes +> **Remediation tl;dr:** make sure you have the latest released version of dep. + Static rule changes are very unlikely to be the cause of your deduction failures. It is plausible that dep will add new static deduction rules in the future. And it is possible that, if you have an older version of dep, and you collaborate with or pull in code from someone using a newer version of dep, then their code may take advantage of new import path patterns that your dep doesn't know about yet. But very, very few static rules additions are likely to ever be made to dep over its lifetime - and getting access to them is just a question of updating once. @@ -168,13 +177,28 @@ init failed: unable to solve the dependency graph: Solving failure: No versions master: (another error) ``` -It means that the solver was unable to find a combination of versions for all dependencies that satisfy all the rules enforced by the solver. These rules are described in detail in the section on [solver invariants](the-solver.md#solving-invariants), but here's a summary: +_Note: all three of the other hard failure types can sometimes be reported as the errors for individual versions in a list like this. This primarily happens because dep is in need of a [thorough refactor of its error handling](https://github.com/golang/dep/issues/288)._ + +It means that the solver was unable to find a combination of versions for all dependencies that satisfy all the rules enforced by the solver. It is crucial to note that, just because dep provides a big list of reasons why each version failed _doesn't mean_ you have to address each one! That's just dep telling you why it ultimately couldn't use each of those versions in a solution. + +These rules, and specific remediations for failing to meet them, are described in detail in the section on [solver invariants](the-solver.md#solving-invariants). This section is about the steps to take when solving failures occur in general. But, to set context, here's a quick summary: * **`[[constraint]]` conflicts:** when projects in the dependency graph disagree on what [versions](gopkg.toml.md#version-rules) are acceptable for a project, or where to [source](gopkg.toml.md#source) it from. -* **Package validity failure:** when an imported package is quite obviously not capable of being built. + * Remediation will usually be either changing a `[[constraint]]` or adding an `[[override]]`, but genuine conflicts may require forking and hacking code. +* **Package validity failure:** when an imported package is quite obviously not capable of being built. + * There usually isn't much remediation here beyond "stop importing that," as it indicates something broken at a particular version. * **Import comment failure:** when the import path used to address a package differs from the [import comment](https://golang.org/cmd/go/#hdr-Import_path_checking) the package uses to specify how it should be imported. + * Remediation is to use the specified import path, instead of whichever one you used. * **Case-only import variation failure:** when two equal-except-for-case imports exist in the same build. + * Remediation is to pick one case variation to use throughout your project, then manually update all projects in your depgraph to use the new casing. +Let's break down the process of addressing a solving failure into a series of steps: +1. First, look through the failed versions list for a version of the dependency that works for you (or a failure that seems fixable), then try to work that one out. Often enough, you'll see a single failure repeated across the entire version list, which makes it pretty clear what problem you need to solve. +2. Take the remediation steps specific to that failure. +3. Re-run the same command you ran that produced the failure. There are three possible outcomes: + 1. Success! + 2. Your fix was ineffective - the same failure re-occurs. Either re-examine your fix (step 2), or look for a new failure to fix (step 1). + 3. Your fix was effective, but some new failure arose. Return to step 1 with the new failure list. diff --git a/docs/glossary.md b/docs/glossary.md index a8e5f72ad8..d9e4bbaf06 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -11,6 +11,7 @@ dep uses some specialized terminology. Learn about it here! * [Current Project](#current-project) * [Deduction](#deduction) * [Direct Dependency](#direct-dependency) +* [External Import](#external-import) * [GPS](#gps) * [Local cache](#local-cache) * [Lock](#lock) @@ -57,6 +58,10 @@ Deduction is the process of determining the subset of an import path that corres A project's direct dependencies are those that it imports from one or more of its packages, or includes in its [`required`](Gopkg.toml.md#required) list in `Gopkg.toml`. If each letter in `A -> B -> C -> D` represents a project, then only `B` is `A`'s direct dependency. +## External Import + +An `import` statement that points to a package in a project other than the one in which it originates. For example, an `import` in package `github.com/foo/bar` will be considered an external import if it points to anything _other_ than stdlib or `github.com/foo/bar/*`. + ## GPS Stands for "Go packaging solver", it is [a subtree of library-style packages within dep](https://godoc.org/github.com/golang/dep/gps), and is the engine around which dep is built. Most commonly referred to as "gps." @@ -118,9 +123,9 @@ The portion of an import path that corresponds to the network location of a sour ## Sync -dep's interaction model is based around the idea of maintaining a well-defined relationship between your project's import statements and `Gopkg.toml`, and your project's `Gopkg.lock` - keeping them "in sync". When the `Gopkg.lock` has more or fewer entries than are necessary, or entries that are incompatible with constraint rules established in `Gopkg.toml`, your project is "out of sync". +Dep's interaction model is based around the idea of maintaining a well-defined relationship between your project's import statements and `Gopkg.toml`, and your project's `Gopkg.lock` - keeping them "in sync". When the `Gopkg.lock` has more or fewer entries than are necessary, or entries that are incompatible with constraint rules established in `Gopkg.toml`, your project is "out of sync". -When your project is out of sync, running `dep ensure` will always either fail with an informative message, or bring your project back in sync. +This concept is explored in detail on [the ensure mechanics reference page](ensure-mechanics.md#staying-in-sync). ## Transitive Dependency diff --git a/docs/introduction.md b/docs/introduction.md index 6e2fb8e4a7..83df675ad5 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -4,6 +4,11 @@ title: Getting Started --- -Welcome! This is documentation for dep, the "official experiment" dependency management tool for the Go language. dep is a tool intended primarily for use by developers, to support the work of actually writing and shipping code. It is not intended for end users who are installing Go software - that's what go get does. +Welcome! This is documentation for dep, the "official experiment" dependency management tool for the Go language. Dep is a tool intended primarily for use by developers, to support the work of actually writing and shipping code. It is not intended for end users who are installing Go software - that's what `go get` does. -This documentation contains both guides and reference material. The guides are practical explanations of how to actually do things with dep, whereas the reference material provides deeper dives on specific topics. Of particular note is the [glossary](#glossary.md) - if you're unfamiliar with terminology used in this documentation, make sure to check there! +This site has both guides and reference documents. The guides are practical explanations of how to actually do things with dep, whereas the reference material provides deeper dives on specific topics. Of particular note is the [glossary](#glossary.md) - if you're unfamiliar with terminology used in this documentation, make sure to check there! + + + +* link to guides +* installing dep \ No newline at end of file diff --git a/docs/migrating.md b/docs/migrating.md index cf196a32ae..bc6443170b 100644 --- a/docs/migrating.md +++ b/docs/migrating.md @@ -9,13 +9,13 @@ $ cd $GOPATH/src/path/to/project/root $ dep init ``` -For many projects, this will just work. `dep init` will make educated guesses about what versions to use for your dependencies, generate sane `Gopkg.toml`, `Gopkg.lock`, and `vendor/`, and if your tests pass and builds work, then you're probably all done. +For many projects, this will just work. `dep init` will make educated guesses about what versions to use for your dependencies, generate sane `Gopkg.toml`, `Gopkg.lock`, and `vendor/`, and if your tests pass and builds work, then you're probably done. (Congratulations! You should check out [Daily Dep](daily-dep.md) next.) The migration process is still difficult for some projects. If you're trying dep for the first time, this can be particularly frustrating, as you're trying to simultaneously learn how to use dep, and how your project *should* be managed in dep. The good news is, `dep init` is usually the big difficulty hump; once you're over it, things get much easier. The goal of this guide is to provide enough information for you to reason about what's happening during `dep init`, so that you can at least understand what class of problems you're encountering, and what steps you might take to address them. To that end, we'll start with an overview of what `dep init` is doing. -One advisory up front, though: the first run of `dep init` can take quite a long time, as dep is creating fresh clones of all your dependencies into a special location, `$GOPATH/pkg/dep/sources/`. This is necessary for dep's normal operations, and is a one-time cost. +> Note: the first run of `dep init` can take quite a long time, as dep is creating fresh clones of all your dependencies into a special location, `$GOPATH/pkg/dep/sources/`. This is necessary for dep's normal operations, and is a one-time cost. ## `dep init` mechanics @@ -63,7 +63,7 @@ First and foremost, make sure that you're running `dep init` with the `-v` flag. While dep contributors have invested enormous effort into creating automated migration paths into dep, these paths will always best-effort and imprecise. It's simply not always possible to convert from other tools or GOPATH with full fidelity. dep is an opinionated tool, with a correspondingly opinionated model, and that model does sometimes fundamentally differ from that of other tools. Sometimes these model mismatches result in hard failures, sometimes soft, and sometimes there's no harm at all. -Because these are deep assumptions, their symptoms can be varied and surprising. Keeping these assumptions in mind could save you some hair-pulling later on. +Because these are deep assumptions, their symptoms can be varied and surprising. Keeping these assumptions in mind could save you some hair-pulling later on. - dep does not allow nested `vendor/` directories; it flattens all dependencies to the topmost `vendor/` directory, at the root of your project. This is foundational to dep's model, and cannot be disabled. - dep wholly controls `vendor`, and will blow away any manual changes or additions made to it that deviate from the version of an upstream source dep selects. @@ -75,43 +75,23 @@ A small number of projects that have reported being unable, thus far, to find a ### Hard failures -Hard failures come in four flavors: +Hard failures involve actual -* Deduction failures -* Local cache errors -* Network errors -* Solving failures +All of these failure modes are covered extensively in the reference on [failure modes](failure-modes.md) -Deduction failures occur when dep can't figure out what remote source corresponds to an import path it encounters in either your project, or one of your dependencies. As dep [follows the same rules for deduction as `go get`](), these types of errors generally only occur if a project contains dependencies that cannot be fetched by `go get`. This primarily occurs only when your project was relying on a capability provided by your previous tool to specify an alternate source location. This is [currently a problem in dep](https://github.com/golang/dep/issues/860), as the `source` field can only specify an alternate location for import paths that are already deducible. If this is a hard requirement for your case, then unfortunately, you will need to wait for this to be fixed before migrating - or, you need a server that properly responds to `go-get` HTTP metadata requests. +Because the solver, and all its possible failures, are the same for `dep init` as for `dep ensure`, there's a separate section for understanding and dealing with them: [dealing with solving failures](failure-modes.md#solving-failures). It can be trickier with `dep init`, however, as many remediations require tweaking `Gopkg.toml`. -Local cache errors occur when dep somehow mishandles the state of its local repository cache (`$GOPATH/pkg/dep/sources` by default). They generally manifest as VCS complaints about some files existing when they shouldn't, or vice-versa. These errors are quite rare now, as dep has implemented adaptive recovery logic that kicks in when it detects such problems. If an issue does occur, it's always safe to `rm -rf $GOPATH/pkg/dep/sources`; dep will automatically reconstruct it on the next run. (Also, please file an issue!) +Unfortunately, `dep init` does not write out a partial `Gopkg.toml` when it fails. This is a known, critical problem, and [we have an open issue (help wanted!)](https://github.com/golang/dep/issues/909). -Network problems are almost always transient, so re-executing the command will usually fix them. They may manifest as hangs, or as network i/o timeouts (though these usually indicate non-ephemeral firewall issues), or underlying VCS (usually git) errors. The ephemeral issues, especially hangs, occur a disproportionately high percentage of the time on `dep init`, as your local cache tends to be empty, which means dep has a lot of cloning to do. - -Other hard failures are most likely going to be actual solving failures. These occur when some invariant that dep enforces (e.g. version constraints are met, imported packages have Go code, [et al.]() SOLVER MODEL LINK) prevent dep from finding a solution - that is, a transitively complete dependency graph. The CLI output of solving failures looks something like this: - -``` -$ dep init -init failed: unable to solve the dependency graph: Solving failure: No versions of github.com/foo/bar met constraints: - v1.0.1: Could not introduce github.com/foo/bar@v1.13.1, as its subpackage github.com/foo/bar/foo is missing. (Package is required by (root).) - v1.0.0: Could not introduce github.com/foo/bar@v1.13.0, as... - v0.1.0: (another error) - master: (another error) -``` - -_Note: all three of the other hard failure types can sometimes be reported as the errors for individual versions in a list like this. This primarily happens because dep is in need of a [thorough refactor of its error handling](https://github.com/golang/dep/issues/288)._ - -Because the solver, and all its possible failures, are the same for `dep init` as for `dep ensure`, there's a separate section for understanding and dealing with them: [dealing with solving failures](). It can be trickier with `dep init`, however, as many remediations require tweaking `Gopkg.toml`. - -Unfortunately, `dep init` does not write out a partial `Gopkg.toml` when it fails ([though we are working on this](https://github.com/golang/dep/issues/909)), so if the particular errors you are encountering do entail such tweaks, you may need to skip `dep init` entirely, create an empty `Gopkg.toml`, and populate it with rules by hand; the [`Gopkg.toml` reference documentation](#gopkg.toml.md) explains the various properties. Before resorting to that, make sure you've run `dep init` with various combinations of the inferencing flags (`-skip-tools` and `-gopath`) to see if they can at least give you something to start from. +In the meantime, if the particular errors you are encountering do entail `Gopkg.toml` tweaks, you unfortunately may have to do without the automation of `dep init`: create an empty [`Gopkg.toml`](Gopkg.toml.md), and populate it with rules by hand. Before resorting to that, make sure you've run `dep init` with various combinations of the inferencing flags (`-skip-tools` and `-gopath`) to see if they can at least give you something to start from. ### Soft failures -Soft failures are usually obvious: `dep init` exits cleanly, but subsequent builds or tests fail. dep's soft failures are usually more drastically than subtly wrong - an explosion of type errors when you try to build, because a wildly incorrect version for some dependency got selected. +Soft failures are cases where `dep init` appears to exit cleanly, but a subsequent `go build` or `go test` fails. Dep's soft failures are usually more drastically than subtly wrong - e.g., an explosion of type errors when you try to build, because a wildly incorrect version for some dependency got selected. If you do encounter problems like this, `dep status` is your first diagnostic step; it will report what versions were selected for all your dependencies. It may be clear which dependencies are a problem simply from your building or testing error messages. If not, compare the `dep status` list against the versions recorded by your previous tool to find the differences. -Once you've identified the problematic dependenc(ies), the next step is exerting appropriate controls over them via `Gopkg.toml`. (Note - this advice is intentionally terse; look at [Zen of Constraints and Locks]() if you want a deeper understanding of how to optimally utilize dep's controls) +Once you've identified the problematic dependenc(ies), the next step is exerting appropriate controls over them via `Gopkg.toml`. (Note - this advice is intentionally terse; check out [Zen of Dep]() if you want a deeper understanding of how to optimally utilize dep's controls) For each of the following items, assume that you should run `dep ensure` after making the suggested change. If that fails, consult [dealing with solving failures](). diff --git a/docs/new-project.md b/docs/new-project.md index 6df0831a5b..ce4ef8e435 100644 --- a/docs/new-project.md +++ b/docs/new-project.md @@ -1,5 +1,5 @@ --- -title: Creating a new project +title: Creating a New Project --- First, we need a working Go workspace and GOPATH. If you're unfamiliar with Go workspaces and GOPATH, have a look at [the language documentation](https://golang.org/doc/code.html#Organization) and get your local workspace set up. (dep's model could eventually lead to being able to work without GOPATH, but we're not there yet.) @@ -8,8 +8,8 @@ Next, we need to pick a root directory for our project. This is primarily about 1. A project that is now or eventually may be shared with or imported by other projects/people. In this case, pick the import path corresponding to the VCS root of its intended network location, e.g., `$GOPATH/src/github.com/golang/dep`. 2. An entirely local project - one that you have no intention of pushing to a central server (like GitHub). In this case, any subdirectory beneath `$GOPATH/src` will do. -3. A project that needs to live within a large repository, such as a company monorepo. This is possible, but gets more complicated - see [dep in monorepos](). -4. Treat the entire GOPATH as a single project, where `$GOPATH/src` is the root. dep does not currently support this - it needs a non-empty import path to treat as the root of the import namespace. +3. A project that needs to live within a large repository, such as a company monorepo. This may be possible, but gets more complicated. (Unfortunately, no docs on this yet - coming soon!) +4. Treat the entire GOPATH as a single project, where `$GOPATH/src` is the root. dep [does not currently support this](https://github.com/golang/dep/issues/417) - it needs a non-empty import path to treat as the root of your project's import namespace. We'll assume the first case, as it's the most common. Create and move into the directory: @@ -26,7 +26,9 @@ $ ls Gopkg.toml Gopkg.lock vendor/ ``` -In a new project like this one, both files and the `vendor` directory will be effectively empty. +In a new project like this one, both files and the `vendor` directory will be effectively empty. + +This would also be a good time to set up a version control, such as [git](https://git-scm.com/). While dep in no way requires version control for your project, it can make inspecting the changes made by normal dep operations easier. Plus, it's basically best practice #1 of modern software development! At this point, we're initialized and ready to start writing code! You can open up a `.go` file in an editor and start hacking away. Or, if you already know some projects you'll need, you can pre-populate your `vendor` directory with them: @@ -34,6 +36,4 @@ At this point, we're initialized and ready to start writing code! You can open u $ dep ensure -add github.com/foo/bar github.com/baz/quux ``` -Note that, because of how `dep ensure -add` works, you'll have to list all dependencies you want to add in a single `dep ensure -add` execution, rather than running it repeatedly. But the `-add` approach is ultimately equivalent to just jumping directly into editing `.go` files, so this needn't be a huge problem. - -The [day-to-day dep]() guide is a good next stop now that your project is set up, and has more detail on these `-add` patterns. \ No newline at end of file +Great, your project's all set up! You're ready to move on to [Daily Dep](daily-dep.md). \ No newline at end of file diff --git a/docs/the-solver.md b/docs/the-solver.md index ff9748e354..43f173d3fb 100644 --- a/docs/the-solver.md +++ b/docs/the-solver.md @@ -4,7 +4,7 @@ title: The Solver At the heart of dep is a constraint solving engine - a [CDCL]()-style [SMT]() solver, tailored specifically to the domain of Go package management. It lives in the `github.com/golang/dep/gps` package, and is where the work of determining a valid, transitively complete dependency graph (aka, the contents of `Gopkg.lock`) is performed. -This page will eventually detail the solver's mechanics, but in the meantime, there are [docs for an older version of the solver]() that are still accurate enough to provide a rough picture of its behavior. +This page will eventually detail the solver's mechanics, but in the meantime, there are [docs for an older version of the solver](https://github.com/sdboyer/gps/wiki/gps-for-Contributors) that are still accurate enough to provide a rough picture of its behavior. ## Solving invariants @@ -19,7 +19,7 @@ The solver is an iterative algorithm, working its way project-by-project through ### `[[constraint]]` rules -As described in the `Gopkg.toml` docs, each [`[[constraint]]`](gopkg.toml.md#constraint) stanza is associated with a single project, and each stanza can contain both [a version rule](gopkg.toml.md#version-rules) and a [source rule](gopkg.toml.md#source). For any given project `P`, all dependers on `P` whose constraint rules are "activated" must express mutually compatible rules. That means: +As described in the `Gopkg.toml` docs, each [`[[constraint]]`](gopkg.toml.md#constraint) stanza is associated with a single project, and each stanza can contain both [a version rule](Gopkg.toml.md#version-rules) and a [source rule](Gopkg.toml.md#source). For any given project `P`, all dependers on `P` whose constraint rules are "activated" must express mutually compatible rules. That means: * For version rules, all activated constraints on `P` must [intersect](https://en.wikipedia.org/wiki/Intersection_(set_theory)), and and there must be at least one published version must exist in the intersecting space. Intersection varies depending on version rule type: * For `revision` and `branch`, it must be a string-literal match. @@ -69,7 +69,9 @@ will result in an error, as `C` imports a package that will necessarily result i Go 1.4 introduced [import comments](https://golang.org/cmd/go/#hdr-Import_path_checking), which allow a package to specify the import path that must be used when addressing it. For example, `import "github.com/golang/net/dict"` would point to a valid package, but because [it uses an import comment](https://github.com/golang/net/blob/42fe2e1c20de1054d3d30f82cc9fb5b41e2e3767/dict/dict.go#L7) to enforce that it must be imported as `golang.org/x/net/dict`, dep would reject any project attempting to import it directly through its github address. -**Remediation:** Because most projects are consistent about their import comment use over time, this issue typically only occurs when adding a new dependency or attempting to revive an older project. However, if you do encounter it, your only recourse is to change the code by fixing the offending import paths. If the offending import paths are in a dependency, not your/the current project, that may entail forking the dependency. +Because most projects are consistent about their import comment use over time, this issue typically only occurs when adding a new dependency or attempting to revive an older project. + +**Remediation:** change the code by fixing the offending import paths. If the offending import paths are not in the current project and you don't directly control the dependency, you'll have to fork and fix it yourself, then use `source` to point to your fork. ### Import path casing @@ -77,17 +79,4 @@ The standard Go toolchain compiler [does not](https://github.com/golang/go/issue The solver keeps track of the accepted case variant for each import path it's processed. Any subsequent projects it sees that introduces a case-only variation for a known import path will be rejected. -**Remediation:** - ---- - - - -The solving algorithm works by iteratively constructing a depgraph, working one project at a time. For each project, it walks through a [sorted queue]() of the project's published versions, searching for a version that satisfies all of the these invariants. The first version encountered that satisfies all invariants will be selected. - -At any given point in the algorithm, it is impossible to know _a priori_ if all the rules that will ultimately be discovered for a given project have been discovered. As such, it is possible that, if new dependencies are discovered on an already-selected - -whether all rules that will eventually be needed for a given project are known at the time that project is visited, it is possible that a project for which a version is selected may need to be revisited later, through a backtracking process. - -This process is complicated by the fact that, for any given project being evaluated by the algorithm, it cannot be known _a priori_ whether we know all of the invariants for a project. - +**Remediation:** Pick a casing variation (all lowercase is usually the right answer), and enforce it universally across the depgraph. As it has to be respected in all dependencies, as well, this may necessitate pull requests and possibly forking of dependencies, if you don't control them directly. \ No newline at end of file From 7ae1fda48dd9da628c37a086b1ab1dd862830211 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 16 Jan 2018 23:47:42 -0800 Subject: [PATCH 08/13] docs: Fix up README, polish deduction and intro --- README.md | 236 +------------------------------------------ docs/Gopkg.toml.md | 41 ++++++-- docs/deduction.md | 35 ++----- docs/introduction.md | 5 +- 4 files changed, 46 insertions(+), 271 deletions(-) diff --git a/README.md b/README.md index 86d713c08b..848f016b8e 100644 --- a/README.md +++ b/README.md @@ -7,38 +7,15 @@ ## Dep -`dep` is a prototype dependency management tool for Go. It requires Go 1.8 or newer to compile. +`dep` is a prototype dependency management tool for Go. It requires Go 1.8 or newer to compile. **`dep` is safe for production use.** `dep` is the official _experiment_, but not yet the official tool. Check out the [Roadmap](https://github.com/golang/dep/wiki/Roadmap) for more on what this means! -## Current status +For guides and reference materials about `dep`, see [the documentation](https://golang.github.io/dep). -`dep` is safe for production use. That means two things: +## Installation -* Any valid metadata file (`Gopkg.toml` and `Gopkg.lock`) will be readable and considered valid by any future version of `dep`. -* The CLI UI is mostly stable. `dep init` and `dep ensure` are mostly set; `dep status` is likely to change a fair bit, and `dep prune` is [going to be absorbed into `dep ensure`](https://github.com/golang/dep/issues/944). - -That said, keep in mind the following: - -* `dep init` on an existing project can be a rocky experience - we try to automatically convert from other tools' metadata files, and that process is often complex and murky. Once your project is converted and you're using `dep ensure`, its behavior is quite stable. -* `dep` still has nasty bugs, but in general these are comparable to or fewer than other tools out there. -* `dep` is [pretty slow right now](https://github.com/golang/dep/blob/master/docs/FAQ.md#why-is-dep-slow), especially on the first couple times you run it. Just know that there is a _lot_ of headroom for improvement, and work is actively underway. -* `dep` is still changing rapidly. If you need stability (e.g. for CI), it's best to rely on a released version, not tip. -* `dep`'s exported API interface will continue to change in unpredictable, backwards-incompatible ways until we tag a v1.0.0 release. - -## Context - -- [The Saga of Go Dependency Management](https://blog.gopheracademy.com/advent-2016/saga-go-dependency-management/) -- Official Google Docs - - [Go Packaging Proposal Process](https://docs.google.com/document/d/18tNd8r5DV0yluCR7tPvkMTsWD_lYcRO7NhpNSDymRr8/edit) - - [User Stories](https://docs.google.com/document/d/1wT8e8wBHMrSRHY4UF_60GCgyWGqvYye4THvaDARPySs/edit) - - [Features](https://docs.google.com/document/d/1JNP6DgSK-c6KqveIhQk-n_HAw3hsZkL-okoleM43NgA/edit) - - [Design Space](https://docs.google.com/document/d/1TpQlQYovCoX9FkpgsoxzdvZplghudHAiQOame30A-v8/edit) -- [Frequently Asked Questions](docs/FAQ.md) - -## Setup - -Grab the latest binary from the [releases](https://github.com/golang/dep/releases) page. +Unless you are hacking on dep, it is strongly recommended that you use a released version. You can grab the latest binary from the [releases](https://github.com/golang/dep/releases) page. On macOS you can install or upgrade to the latest released version with Homebrew: @@ -53,217 +30,12 @@ If you're interested in hacking on `dep`, you can install via `go get`: go get -u github.com/golang/dep/cmd/dep ``` -To start managing dependencies using dep, run the following from your project's root directory: - -```sh -$ dep init -``` - -This does the following: - -1. Look for [existing dependency management files](docs/FAQ.md#what-external-tools-are-supported) to convert -1. Check if your dependencies use dep -1. Identify your dependencies -1. Back up your existing `vendor/` directory (if you have one) to -`_vendor-TIMESTAMP/` -1. Pick the highest compatible version for each dependency -1. Generate [`Gopkg.toml`](docs/Gopkg.toml.md) ("manifest") and `Gopkg.lock` files -1. Install the dependencies in `vendor/` - -## Usage - -There is one main subcommand you will use: `dep ensure`. `ensure` first checks that `Gopkg.lock` is consistent with `Gopkg.toml` and the `import`s in your code. If any -changes are detected, `dep`'s solver works out a new `Gopkg.lock`. Then, `dep` checks if the contents of `vendor/` are what `Gopkg.lock` (the new one if applicable, else the existing one) says it should be, and rewrites `vendor/` as needed to bring it into line. - -In essence, `dep ensure` [works in two phases to keep four buckets of state in sync](https://youtu.be/5LtMb090AZI?t=20m4s): - -states-flow - - -_Note: until we ship [vendor verification](https://github.com/golang/dep/issues/121), we can't efficiently perform the `Gopkg.lock` <-> `vendor/` comparison, so `dep ensure` unconditionally regenerates all of `vendor/` to be safe._ - -`dep ensure` is safe to run early and often. See the help text for more detailed -usage instructions. - -```sh -$ dep help ensure -``` - -### Installing dependencies - -(if your `vendor/` directory isn't [checked in with your code](docs/FAQ.md#should-i-commit-my-vendor-directory)) - - - -```sh -$ dep ensure -``` - -If a dependency already exists in your `vendor/` folder, dep will ensure it -matches the constraints from the manifest. If the dependency is missing from -`vendor/`, the latest version allowed by your manifest will be installed. - -### Adding a dependency - -```sh -$ dep ensure -add github.com/foo/bar -``` - -This adds a version constraint to your `Gopkg.toml`, and updates `Gopkg.lock` and `vendor/`. Now, import and use the package in your code! ✨ - -`dep ensure -add` has some subtle behavior variations depending on the project or package named, and the state of your tree. See `dep ensure -examples` for more information. - -### Changing dependencies - -If you want to: - -* Change the allowed `version`/`branch`/`revision` -* Switch to using a fork - -for one or more dependencies, do the following: - -1. Manually edit your `Gopkg.toml`. -1. Run - - ```sh - $ dep ensure - ``` - -### Checking the status of dependencies - -Run `dep status` to see the current status of all your dependencies. - -```sh -$ dep status -PROJECT CONSTRAINT VERSION REVISION LATEST -github.com/Masterminds/semver branch 2.x branch 2.x 139cc09 c2e7f6c -github.com/Masterminds/vcs ^1.11.0 v1.11.1 3084677 3084677 -github.com/armon/go-radix * branch master 4239b77 4239b77 -``` - -On top of that, if you have added new imports to your project or modified `Gopkg.toml` without running `dep ensure` again, `dep status` will tell you there is a mismatch between `Gopkg.lock` and the current status of the project. - -```sh -$ dep status -Lock inputs-digest mismatch due to the following packages missing from the lock: - -PROJECT MISSING PACKAGES -github.com/Masterminds/goutils [github.com/Masterminds/goutils] - -This happens when a new import is added. Run `dep ensure` to install the missing packages. -``` - -As `dep status` suggests, run `dep ensure` to update your lockfile. Then run `dep status` again, and the lock mismatch should go away. - -### Visualizing dependencies - -Generate a visual representation of the dependency tree by piping the output of `dep status -dot` to [graphviz](http://www.graphviz.org/). -#### Linux -``` -$ sudo apt-get install graphviz -$ dep status -dot | dot -T png | display -``` -#### MacOS -``` -$ brew install graphviz -$ dep status -dot | dot -T png | open -f -a /Applications/Preview.app -``` -#### Windows -``` -> choco install graphviz.portable -> dep status -dot | dot -T png -o status.png; start status.png -``` -

- -### Updating dependencies - -Updating brings the version of a dependency in `Gopkg.lock` and `vendor/` to the latest version allowed by the constraints in `Gopkg.toml`. - -You can update just a targeted subset of dependencies (recommended): - -```sh -$ dep ensure -update github.com/some/project github.com/other/project -$ dep ensure -update github.com/another/project -``` - -Or you can update all your dependencies at once: - -```sh -$ dep ensure -update -``` - -"Latest" means different things depending on the type of constraint in use. If you're depending on a `branch`, `dep` will update to the latest tip of that branch. If you're depending on a `version` using [a semver range](#semantic-versioning), it will update to the latest version in that range. - -### Removing dependencies - -1. Remove the `import`s and all usage from your code. -1. Remove `[[constraint]]` rules from `Gopkg.toml` (if any). -1. Run - - ```sh - $ dep ensure - ``` - -### Testing changes to a dependency - -Making changes in your `vendor/` directory directly is not recommended, as dep -will overwrite any changes. Instead: - -1. Delete the dependency from the `vendor/` directory. - - ```sh - rm -rf vendor/ - ``` - -1. Add that dependency to your `GOPATH`, if it isn't already. - - ```sh - $ go get - ``` - -1. Modify the dependency in `$GOPATH/src/`. -1. Test, build, etc. - -Don't run `dep ensure` until you're done. `dep ensure` will reinstall the -dependency into `vendor/` based on your manifest, as if you were installing from -scratch. - -This solution works for short-term use, but for something long-term, take a look -at [virtualgo](https://github.com/GetStream/vg). - -To test out code that has been pushed as a new version, or to a branch or fork, -see [changing dependencies](#changing-dependencies). - -## Semantic Versioning - -`dep ensure` uses an external [semver library](https://github.com/Masterminds/semver) to interpret the version constraints you specify in the manifest. The comparison operators are: - -* `=`: equal -* `!=`: not equal -* `>`: greater than -* `<`: less than -* `>=`: greater than or equal to -* `<=`: less than or equal to -* `-`: literal range. Eg: 1.2 - 1.4.5 is equivalent to >= 1.2, <= 1.4.5 -* `~`: minor range. Eg: ~1.2.3 is equivalent to >= 1.2.3, < 1.3.0 -* `^`: major range. Eg: ^1.2.3 is equivalent to >= 1.2.3, < 2.0.0 -* `[xX*]`: wildcard. Eg: 1.2.x is equivalent to >= 1.2.0, < 1.3.0 - -You might, for example, include a constraint in your manifest that specifies `version = "=2.0.0"` to pin a dependency to version 2.0.0, or constrain to minor releases with: `version = "2.*"`. Refer to the [semver library](https://github.com/Masterminds/semver) documentation for more info. - -**Note**: When you specify a version *without an operator*, `dep` automatically uses the `^` operator by default. `dep ensure` will interpret the given version as the min-boundary of a range, for example: - -* `1.2.3` becomes the range `>=1.2.3, <2.0.0` -* `0.2.3` becomes the range `>=0.2.3, <0.3.0` -* `0.0.3` becomes the range `>=0.0.3, <0.1.0` - ## Feedback Feedback is greatly appreciated. At this stage, the maintainers are most interested in feedback centered on the user experience (UX) of the tool. Do you have workflows that the tool supports well, or doesn't support at all? Do any of the commands have surprising effects, output, or results? -Please check the existing issues and [FAQ](docs/FAQ.md) to see if your feedback has already been reported. If not, please file an issue, describing what you did or wanted to do, what you expected to happen, and what actually happened. ## Contributing diff --git a/docs/Gopkg.toml.md b/docs/Gopkg.toml.md index 7eca5ab72f..9f69beefe5 100644 --- a/docs/Gopkg.toml.md +++ b/docs/Gopkg.toml.md @@ -120,21 +120,34 @@ system2-data = "value that is used by another system" ----- +## Version rules +Version rules can be used in either `[[constraint]]` or `[[override]]` stanzas. There are three types of version rules - `version`, `branch`, and `revision`. At most one of the three types can be specified. +### `version` -## Version rules +`version` is a property of `constraint`s and `override`s. It is used to specify version constraint of a specific dependency. It can be used to target an arbitrary VCS tag, or a semantic version, or a range of semantic versions. -Version rules can be used in either `[[constraint]]` or `[[override]]` stanzas. There are three types of version rules - `version`, `branch`, and `revision`. At most one of the three types can be specified. +Specifying semantic version ranges can be done using the following operators: -TODOOOOOOOOOOOOO +* `=`: equal +* `!=`: not equal +* `>`: greater than +* `<`: less than +* `>=`: greater than or equal to +* `<=`: less than or equal to +* `-`: literal range. Eg: 1.2 - 1.4.5 is equivalent to >= 1.2, <= 1.4.5 +* `~`: minor range. Eg: ~1.2.3 is equivalent to >= 1.2.3, < 1.3.0 +* `^`: major range. Eg: ^1.2.3 is equivalent to >= 1.2.3, < 2.0.0 +* `[xX*]`: wildcard. Eg: 1.2.x is equivalent to >= 1.2.0, < 1.3.0 -### `version` +You might, for example, include a rule that specifies `version = "=2.0.0"` to pin a dependency to version 2.0.0, or constrain to minor releases with: `version = "~2.1.0"`. Refer to the [semver library](https://github.com/Masterminds/semver) documentation for more info. -`version` is a property of `constraint`s and `override`s. It is used to specify version constraint of a specific dependency. +**Note**: When you specify a version *without an operator*, `dep` automatically uses the `^` operator by default. `dep ensure` will interpret the given version as the min-boundary of a range, for example: -Internally, dep uses [Masterminds/semver](https://github.com/Masterminds/semver) to work with semver versioning. +* `1.2.3` becomes the range `>=1.2.3, <2.0.0` +* `0.2.3` becomes the range `>=0.2.3, <0.3.0` +* `0.0.3` becomes the range `>=0.0.3, <0.1.0` `~` and `=` operators can be used with the versions. When a version is specified without any operator, `dep` automatically adds a caret operator, `^`. The caret operator pins the left-most non-zero digit in the version. For example: ``` @@ -150,11 +163,21 @@ To pin a version of direct dependency in manifest, prefix the version with `=`. version = "=0.8.0" ``` -[Why is dep ignoring a version constraint in the manifest?](FAQ.md#why-is-dep-ignoring-a-version-constraint-in-the-manifest) +### `branch` + +Using a `branch` constraint will cause dep to use the named branch (e.g., `branch = "master"`) for a particular dependency. The revision at the tip of the branch will be recorded into `Gopkg.lock`, and almost always remain the same until a change is requested, via `dep ensure -update`. + +In general, you should prefer semantic versions to branches, when a project has made them available. + +### `revision` + +A `revision` is the underlying immutable identifier - like a git commit SHA1. While it is allowed to constrain to a `revision`, doing so is almost always an antipattern. + +Usually, folks are inclined to pin to a revision because they feel it will somehow improve their project's reproducibility. That is not a good reason. `Gopkg.lock` provides reproducibility. Only use `revision` if you have a good reason to believe that _no_ other version of that dependency _could_ work. # Example -Here's an example of a sample Gopkg.toml with most of the elements +A sample `Gopkg.toml` with most elements present: ```toml required = ["github.com/user/thing/cmd/thing"] diff --git a/docs/deduction.md b/docs/deduction.md index acfc16b939..246d08635b 100644 --- a/docs/deduction.md +++ b/docs/deduction.md @@ -7,37 +7,20 @@ Deduction is dep's algorithm for looking at an import path and determining the p - `github.com/golang/dep/gps` -> `github.com/golang/dep` - `bitbucket.org/foo/bar/baz` -> `bitbucket.org/foo/bar` -The set of hosts supported by static deduction are the same as [those supported by `go get`](). +The set of hosts supported by static deduction are the same as [those supported by `go get`](https://golang.org/cmd/go/#hdr-Remote_import_paths): -If the static logic cannot identify the root for a given import path, the algorithm continues to a dynamic component, where it makes an HTTP(S) request to the import path, and a server is expected to return a response that indicates the root import path. This, again, is equivalent to the behavior of `go get`. +* GitHub +* Bitbucket +* Launchpad +* IBM DevOps Services +In addition, dep also handles [gopkg.in](http://gopkg.in) directly with static deduction because, owing to internal implementation details, it is the easiest way of also attaching filters to adapt the versioning semantics of gopkg.in import paths into dep's versioning model. This turns out fine, as gopkg.in's rules mapping rules are themselves entirely static. +If the static logic cannot identify the root for a given import path, the algorithm continues to a dynamic component: dep makes an HTTP(S) request to the import path, and a server is expected to send back the root import path embedded within the HTML response. Again, this directly emulates the behavior of `go get`. Import path deduction is applied to all of the following: * `import` statements found in all `.go` files -* Import paths named in the [`required`](gopkg.toml.md#required) property in `Gopkg.toml` -* `name` properties in both [`[[constraint]]`](Gopkg.toml.md#constraint) and [`[[override]]`](Gopkg.toml.md#override) stanzas in `Gopkg.toml`. This is solely for validation purposes, enforcing that these names correspond strictly to source roots. +* Import paths in the [`required`](gopkg.toml.md#required) list in `Gopkg.toml` +* `name` properties in both [`[[constraint]]`](Gopkg.toml.md#constraint) and [`[[override]]`](Gopkg.toml.md#override) stanzas in `Gopkg.toml`. This is solely for validation purposes, enforcing that these names correspond only to project/source roots. - - - -The results of import path deduction are, in practice, almost entirely fixed; it's easy to imagine why. In the public ecosystem, even dynamic deductions rarely change in practice, as it would either require: - -- a `go-get` metadata service to intentionally change its mappings, or -- a `go-get` metadata service to disappear. - -`go get` itself is only partially resilient to these cases, but each is potentially catastrophic for a package's retrievability across the ecosystem, sooner rather than later. This steep and abrupt downside makes it nearly impossible for projects only accessible via an unreliable metadata service to ever become popular or widely used in the ecosystem. Thus, in the public ecosystem, we almost only ever see reliable, well-behaved services. - - - - - - - - - - -Because deduction has a dynamic component, the deducibility of any given path necessarily cannot be fixed. However, because the - -## Static deduction \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md index 83df675ad5..bd3c6995ad 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -8,7 +8,4 @@ Welcome! This is documentation for dep, the "official experiment" dependency man This site has both guides and reference documents. The guides are practical explanations of how to actually do things with dep, whereas the reference material provides deeper dives on specific topics. Of particular note is the [glossary](#glossary.md) - if you're unfamiliar with terminology used in this documentation, make sure to check there! - - -* link to guides -* installing dep \ No newline at end of file +If you're trying dep for the first time, check out [Creating a New Project](new-project.md), or [Migrating to dep](migrating.md) if you have an existing Go project that you want to manage with dep. \ No newline at end of file From 5e064a583f1f6aec4dad34881e38616f25b5e033 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 23 Jan 2018 09:38:36 -0500 Subject: [PATCH 09/13] docs: Add installation.md, lots of tweaks Assorted edits and wording tweaks, as well as including bash as type on most of the fenced code blocks. Also relocated assets into docs/assets from docs/img in order to accommodate docusaurus' expected layout. --- README.md | 6 +-- docs/FAQ.md | 15 +----- docs/Gopkg.lock.md | 10 +++- docs/assets | 1 - docs/{img => assets}/DigbyFlat.png | Bin docs/{img => assets}/DigbyFlat.svg | 0 docs/{img => assets}/DigbyFlatScene2.png | Bin docs/{img => assets}/DigbyFlatScene2.svg | 0 docs/{img => assets}/DigbyScene2Flat.png | Bin docs/{img => assets}/DigbyScene2Flat.svg | 0 docs/{img => assets}/DigbyScene2Shadows.png | Bin docs/{img => assets}/DigbyScene2Shadows.svg | 0 docs/{img => assets}/DigbyShadows.png | Bin docs/{img => assets}/DigbyShadows.svg | 0 docs/{img => assets}/DigbyShadowsScene2.png | Bin docs/{img => assets}/DigbyShadowsScene2.svg | 0 docs/{img => assets}/StatusGraph.png | Bin .../{img => assets}/annotated-func-arrows.png | Bin docs/{img => assets}/base-arrows.png | Bin docs/{img => assets}/four-states.png | Bin docs/{img => assets}/func-toggles.png | Bin docs/assets/in-sync.png | Bin 0 -> 34774 bytes docs/{img => assets}/lock-back.png | Bin docs/{img => assets}/required-arrows.png | Bin docs/{day-to-day-dep.md => daily-dep.md} | 12 ++--- docs/deduction.md | 2 +- docs/ensure-mechanics.md | 32 ++++++------- docs/failure-modes.md | 10 ++-- docs/glossary.md | 43 +++++++++--------- docs/installation.md | 19 ++++++++ docs/introduction.md | 4 +- docs/migrating.md | 15 +++--- docs/new-project.md | 14 +++--- 33 files changed, 97 insertions(+), 86 deletions(-) delete mode 120000 docs/assets rename docs/{img => assets}/DigbyFlat.png (100%) rename docs/{img => assets}/DigbyFlat.svg (100%) rename docs/{img => assets}/DigbyFlatScene2.png (100%) rename docs/{img => assets}/DigbyFlatScene2.svg (100%) rename docs/{img => assets}/DigbyScene2Flat.png (100%) rename docs/{img => assets}/DigbyScene2Flat.svg (100%) rename docs/{img => assets}/DigbyScene2Shadows.png (100%) rename docs/{img => assets}/DigbyScene2Shadows.svg (100%) rename docs/{img => assets}/DigbyShadows.png (100%) rename docs/{img => assets}/DigbyShadows.svg (100%) rename docs/{img => assets}/DigbyShadowsScene2.png (100%) rename docs/{img => assets}/DigbyShadowsScene2.svg (100%) rename docs/{img => assets}/StatusGraph.png (100%) rename docs/{img => assets}/annotated-func-arrows.png (100%) rename docs/{img => assets}/base-arrows.png (100%) rename docs/{img => assets}/four-states.png (100%) rename docs/{img => assets}/func-toggles.png (100%) create mode 100644 docs/assets/in-sync.png rename docs/{img => assets}/lock-back.png (100%) rename docs/{img => assets}/required-arrows.png (100%) rename docs/{day-to-day-dep.md => daily-dep.md} (97%) create mode 100644 docs/installation.md diff --git a/README.md b/README.md index 848f016b8e..49e407dfda 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -

+

+ +
+ {siteConfig.copyright} +
+
+ ); + } +} + +module.exports = Footer; diff --git a/website/i18n/en.json b/website/i18n/en.json new file mode 100644 index 0000000000..caf77a3dba --- /dev/null +++ b/website/i18n/en.json @@ -0,0 +1,30 @@ +{ + "_comment": "This file is auto-generated by write-translations.js", + "localized-strings": { + "next": "Next", + "previous": "Previous", + "tagline": "Dependency management for Go", + "daily-dep": "Daily Dep", + "deduction": "Import Path Deduction", + "ensure-mechanics": "Models and Mechanisms", + "failure-modes": "Failure Modes", + "FAQ": "FAQ", + "glossary": "Glossary", + "Gopkg.lock": "Gopkg.lock", + "Gopkg.toml": "Gopkg.toml", + "installation": "Installation", + "introduction": "Getting Started", + "migrating": "Migrating to Dep", + "new-project": "Creating a New Project", + "the-solver": "The Solver", + "Documentation": "Documentation", + "Blog": "Blog", + "Guides": "Guides", + "References": "References" + }, + "pages-strings": { + "Help Translate|recruit community translators for your project": "Help Translate", + "Edit this Doc|recruitment message asking to edit the doc source": "Edit", + "Translate this Doc|recruitment message asking to translate the docs": "Translate" + } +} diff --git a/website/package.json b/website/package.json new file mode 100644 index 0000000000..81abc9c558 --- /dev/null +++ b/website/package.json @@ -0,0 +1,14 @@ +{ + "scripts": { + "examples": "docusaurus-examples", + "start": "docusaurus-start", + "build": "docusaurus-build", + "publish-gh-pages": "docusaurus-publish", + "write-translations": "docusaurus-write-translations", + "version": "docusaurus-version", + "rename-version": "docusaurus-rename-version" + }, + "devDependencies": { + "docusaurus": "^1.0.3" + } +} diff --git a/website/pages/en/help.js b/website/pages/en/help.js new file mode 100755 index 0000000000..0a63c19e49 --- /dev/null +++ b/website/pages/en/help.js @@ -0,0 +1,43 @@ +const React = require('react'); + +const CompLibrary = require('../../core/CompLibrary.js'); +const Container = CompLibrary.Container; +const GridBlock = CompLibrary.GridBlock; + +const siteConfig = require(process.cwd() + '/siteConfig.js'); + +class Help extends React.Component { + render() { + const supportLinks = [ + { + content: + 'Learn more using the [documentation on this site.](/test-site/docs/en/doc1.html)', + title: 'Browse Docs', + }, + { + content: 'Ask questions about the documentation and project', + title: 'Join the community', + }, + { + content: "Find out what's new with this project", + title: 'Stay up to date', + }, + ]; + + return ( +
+ +
+
+

Need help?

+
+

This project is maintained by a dedicated group of people.

+ +
+
+
+ ); + } +} + +module.exports = Help; diff --git a/website/pages/en/index.js b/website/pages/en/index.js new file mode 100755 index 0000000000..44c664e580 --- /dev/null +++ b/website/pages/en/index.js @@ -0,0 +1,91 @@ +const React = require('react'); + +const CompLibrary = require('../../core/CompLibrary.js'); +const MarkdownBlock = CompLibrary.MarkdownBlock; /* Used to read markdown */ +const Container = CompLibrary.Container; +const GridBlock = CompLibrary.GridBlock; + +const siteConfig = require(process.cwd() + '/siteConfig.js'); + +class Button extends React.Component { + render() { + return ( + + ); + } +} + +Button.defaultProps = { + target: '_self', +}; + +class HomeSplash extends React.Component { + render() { + return ( +
+
+
+
+ +
+
+

+ {siteConfig.title} + {siteConfig.tagline} +

+
+
+
+ + +
+
+
+
+
+
+
+ ); + } +} + +class Index extends React.Component { + render() { + let language = this.props.language || 'en'; + const showcase = siteConfig.users + .filter(user => { + return user.pinned; + }) + .map(user => { + return ( + + + + ); + }); + + return ( +
+ +
+ ); + } +} + +module.exports = Index; diff --git a/website/pages/en/users.js b/website/pages/en/users.js new file mode 100644 index 0000000000..b94c4bc6e8 --- /dev/null +++ b/website/pages/en/users.js @@ -0,0 +1,40 @@ +const React = require('react'); + +const CompLibrary = require('../../core/CompLibrary.js'); +const Container = CompLibrary.Container; + +const siteConfig = require(process.cwd() + '/siteConfig.js'); + +class Users extends React.Component { + render() { + const showcase = siteConfig.users.map((user, i) => { + return ( + + + + ); + }); + + return ( +
+ +
+
+

Who's Using This?

+

This project is used by many folks

+
+
{showcase}
+

Are you using this project?

+ + Add your company + +
+
+
+ ); + } +} + +module.exports = Users; diff --git a/website/pages/en/versions.js b/website/pages/en/versions.js new file mode 100644 index 0000000000..192d3ac3d9 --- /dev/null +++ b/website/pages/en/versions.js @@ -0,0 +1,88 @@ +const React = require('react'); + +const CompLibrary = require('../../core/CompLibrary'); +const Container = CompLibrary.Container; +const GridBlock = CompLibrary.GridBlock; + +const CWD = process.cwd(); + +const siteConfig = require(CWD + '/siteConfig.js'); +const versions = require(CWD + '/versions.json'); + +class Versions extends React.Component { + render() { + const latestVersion = versions[0]; + return ( + + ); + } +} + +module.exports = Versions; diff --git a/website/sidebars.json b/website/sidebars.json new file mode 100644 index 0000000000..962d2bc622 --- /dev/null +++ b/website/sidebars.json @@ -0,0 +1,6 @@ +{ + "docs": { + "Guides": ["introduction", "installation", "new-project", "migrating", "daily-dep"], + "References": ["ensure-mechanics", "failure-modes", "the-solver", "deduction", "Gopkg.toml", "Gopkg.lock", "FAQ", "glossary"] + } +} diff --git a/website/siteConfig.js b/website/siteConfig.js new file mode 100644 index 0000000000..8d60c0e602 --- /dev/null +++ b/website/siteConfig.js @@ -0,0 +1,42 @@ +/* List of projects/orgs using your project for the users page */ +const users = [ +]; + +const siteConfig = { + title: 'dep' /* title for your website */, + tagline: 'Dependency management for Go', + url: 'https://golang.github.io' /* your website url */, + baseUrl: '/dep/' /* base url for your project */, + editURL: 'https://github.com/golang/dep/edit/master/docs/', + projectName: 'dep', + headerLinks: [ + {doc: 'introduction', label: 'Documentation'}, + {blog: true, label: 'Blog'}, + ], + users, + /* path to images for header/footer */ + headerIcon: 'docs/assets/DigbyFlat.svg', + footerIcon: 'docs/assets/DigbyShadowsScene2.svg', + favicon: 'docs/assets/DigbyScene2Flat.png', + /* colors for website */ + colors: { + secondaryColor: '#E0EBF5', + primaryColor: '#375EAB', + }, + // This copyright info is used in /core/Footer.js and blog rss/atom feeds. + copyright: + 'Copyright © ' + + new Date().getFullYear() + + ' The Go Authors', + organizationName: 'golang', // or set an env variable ORGANIZATION_NAME + projectName: 'dep', // or set an env variable PROJECT_NAME + highlight: { + // Highlight.js theme to use for syntax highlighting in code blocks + theme: 'default', + }, + scripts: ['https://buttons.github.io/buttons.js'], + // You may provide arbitrary config keys to be used as needed by your template. + repoUrl: 'https://github.com/golang/dep', +}; + +module.exports = siteConfig; diff --git a/website/static/css/custom.css b/website/static/css/custom.css new file mode 100644 index 0000000000..220c1dde7d --- /dev/null +++ b/website/static/css/custom.css @@ -0,0 +1,16 @@ +/* your custom css */ + +@media only screen and (min-device-width: 360px) and (max-device-width: 736px) { +} + +@media only screen and (min-width: 1024px) { +} + +@media only screen and (max-width: 1023px) { +} + +@media only screen and (min-width: 1400px) { +} + +@media only screen and (min-width: 1500px) { +} \ No newline at end of file diff --git a/website/yarn.lock b/website/yarn.lock new file mode 100644 index 0000000000..adadf47c31 --- /dev/null +++ b/website/yarn.lock @@ -0,0 +1,1741 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@~1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" + dependencies: + mime-types "~2.1.16" + negotiator "0.6.1" + +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +argparse@~0.1.15: + version "0.1.16" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-0.1.16.tgz#cfd01e0fbba3d6caed049fbd758d40f65196f57c" + dependencies: + underscore "~1.7.0" + underscore.string "~2.4.0" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +autolinker@~0.15.0: + version "0.15.3" + resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-0.15.3.tgz#342417d8f2f3461b14cf09088d5edf8791dc9832" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.0" + debug "^2.6.8" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.7" + slash "^1.0.0" + source-map "^0.5.6" + +babel-generator@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.0.tgz#ac1ae20070b79f6e3ca1d3269613053774f20dc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.6" + trim-right "^1.0.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-builder-react-jsx@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz#39ff8313b75c8b65dceff1f31d383e0ff2a408a0" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + esutils "^2.0.2" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-flow@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz#0d8394029b7dc6abe1a97ef181e00758dd2e5d8a" + dependencies: + babel-plugin-transform-strict-mode "^6.24.1" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-types "^6.26.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-flow-strip-types@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-display-name@^6.23.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-self@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-source@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3" + dependencies: + babel-helper-builder-react-jsx "^6.24.1" + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-preset-env@^1.6.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.6.1.tgz#a18b564cc9b9afdf4aae57ae3c1b0d99188e6f48" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.23.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^2.1.2" + invariant "^2.2.2" + semver "^5.3.0" + +babel-preset-flow@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" + dependencies: + babel-plugin-transform-flow-strip-types "^6.22.0" + +babel-preset-react@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" + dependencies: + babel-plugin-syntax-jsx "^6.3.13" + babel-plugin-transform-react-display-name "^6.23.0" + babel-plugin-transform-react-jsx "^6.24.1" + babel-plugin-transform-react-jsx-self "^6.22.0" + babel-plugin-transform-react-jsx-source "^6.22.0" + babel-preset-flow "^6.23.0" + +babel-register@^6.24.1, babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.24.1, babel-traverse@^6.25.0, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.17.4, babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +body-parser@1.18.2: + version "1.18.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.2.tgz#87678a19d84b47d859b83199bd59bce222b10454" + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.1" + http-errors "~1.6.2" + iconv-lite "0.4.19" + on-finished "~2.3.0" + qs "6.5.1" + raw-body "2.3.2" + type-is "~1.6.15" + +boom@4.x.x: + version "4.3.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31" + dependencies: + hoek "4.x.x" + +boom@5.x.x: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + dependencies: + hoek "4.x.x" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +browserslist@^2.1.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.10.0.tgz#bac5ee1cc69ca9d96403ffb8a3abdc5b6aed6346" + dependencies: + caniuse-lite "^1.0.30000780" + electron-to-chromium "^1.3.28" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + +caniuse-lite@^1.0.30000780: + version "1.0.30000784" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz#129ced74e9a1280a441880b6cd2bce30ef59e6c0" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + +classnames@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.1.tgz#c1261107aeb2f294ebffec9ed9ecad529a6097ed" + dependencies: + color-name "^1.1.1" + +color-name@^1.0.0, color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +color-string@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.2.tgz#26e45814bc3c9a7cbd6751648a41434514a773a9" + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color/-/color-2.0.1.tgz#e4ed78a3c4603d0891eba5430b04b86314f4c839" + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@^2.11.0: + version "2.12.2" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + +convert-source-map@^1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-js@^2.4.0, core-js@^2.5.0: + version "2.5.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" + +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +create-react-class@^15.6.0: + version "15.6.2" + resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.2.tgz#cf1ed15f12aad7f14ef5f2dfe05e6c42f91ef02a" + dependencies: + fbjs "^0.8.9" + loose-envify "^1.3.1" + object-assign "^4.1.1" + +crowdin-cli@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/crowdin-cli/-/crowdin-cli-0.3.0.tgz#eac9989a6fe7feaaf33090397afc187c67b46191" + dependencies: + request "^2.53.0" + yamljs "^0.2.1" + yargs "^2.3.0" + +cryptiles@3.x.x: + version "3.1.2" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe" + dependencies: + boom "5.x.x" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +debug@0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" + +debug@2.6.9, debug@^2.6.8: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +deep-is@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.2.tgz#9ced65ea0bc0b09f42a6d79c1b1903f9d913cc18" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +depd@1.1.1, depd@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +docusaurus@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/docusaurus/-/docusaurus-1.0.3.tgz#6ee1cc463a7e4462fd40207d323ace2ee6b1dfd6" + dependencies: + babel-preset-env "^1.6.0" + babel-preset-react "^6.24.1" + babel-register "^6.24.1" + babel-traverse "^6.25.0" + babylon "^6.17.4" + chalk "^2.1.0" + classnames "^2.2.5" + color "^2.0.1" + commander "^2.11.0" + crowdin-cli "^0.3.0" + escape-string-regexp "^1.0.5" + express "^4.15.3" + feed "^1.1.0" + fs-extra "^3.0.1" + glob "^7.1.2" + highlight.js "^9.12.0" + react "^15.5.4" + react-dom "^15.5.4" + react-dom-factories "^1.0.1" + remarkable "^1.7.1" + request "^2.81.0" + shelljs "^0.7.8" + sitemap "^1.13.0" + tcp-port-used "^0.1.2" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +electron-releases@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e" + +electron-to-chromium@^1.3.28: + version "1.3.30" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz#9666f532a64586651fc56a72513692e820d06a80" + dependencies: + electron-releases "^2.1.0" + +encodeurl@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + +express@^4.15.3: + version "4.16.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c" + dependencies: + accepts "~1.3.4" + array-flatten "1.1.1" + body-parser "1.18.2" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.1" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.0" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.2" + qs "6.5.1" + range-parser "~1.2.0" + safe-buffer "5.1.1" + send "0.16.1" + serve-static "1.13.1" + setprototypeof "1.1.0" + statuses "~1.3.1" + type-is "~1.6.15" + utils-merge "1.0.1" + vary "~1.1.2" + +extend@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fbjs@^0.8.16, fbjs@^0.8.9: + version "0.8.16" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +feed@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/feed/-/feed-1.1.1.tgz#914897517e94fa327cc6f73bb585a47c4a9ed321" + dependencies: + xml "^1.0.1" + +finalhandler@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.0.tgz#ce0b6855b45853e791b2fcc680046d88253dd7f5" + dependencies: + debug "2.6.9" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.3.1" + unpipe "~1.0.0" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + +fs-extra@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^3.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +glob@^7.0.0, glob@^7.0.5, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +hawk@~6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038" + dependencies: + boom "4.x.x" + cryptiles "3.x.x" + hoek "4.x.x" + sntp "2.x.x" + +highlight.js@^9.12.0: + version "9.12.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" + +hoek@4.x.x: + version "4.2.0" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +http-errors@1.6.2, http-errors@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" + dependencies: + depd "1.1.1" + inherits "2.0.3" + setprototypeof "1.0.3" + statuses ">= 1.3.1 < 2" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +iconv-lite@0.4.19, iconv-lite@~0.4.13: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +interpret@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + +invariant@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +ipaddr.js@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.5.2.tgz#d4b505bde9946987ccf0fc58d9010ff9607e3fa0" + +is-arrayish@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.1.tgz#c2dfc386abaa0c3e33c48db3fe87059e69065efd" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is2@0.0.9: + version "0.0.9" + resolved "https://registry.yarnpkg.com/is2/-/is2-0.0.9.tgz#119556d1d1651a41ba105af803267c80b299f629" + dependencies: + deep-is "0.1.2" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonfile@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" + optionalDependencies: + graceful-fs "^4.1.6" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +lodash@^4.17.4: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + +mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + +mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.17: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + dependencies: + mime-db "~1.30.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +private@^0.1.6, private@^0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + dependencies: + asap "~2.0.3" + +prop-types@^15.5.10: + version "15.6.0" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.3.1" + object-assign "^4.1.1" + +proxy-addr@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec" + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.5.2" + +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +q@0.9.7: + version "0.9.7" + resolved "https://registry.yarnpkg.com/q/-/q-0.9.7.tgz#4de2e6cb3b29088c9e4cbc03bf9d42fb96ce2f75" + +qs@6.5.1, qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +raw-body@2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.2.tgz#bcd60c77d3eb93cde0050295c3f379389bc88f89" + dependencies: + bytes "3.0.0" + http-errors "1.6.2" + iconv-lite "0.4.19" + unpipe "1.0.0" + +react-dom-factories@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/react-dom-factories/-/react-dom-factories-1.0.2.tgz#eb7705c4db36fb501b3aa38ff759616aa0ff96e0" + +react-dom@^15.5.4: + version "15.6.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.2.tgz#41cfadf693b757faf2708443a1d1fd5a02bef730" + dependencies: + fbjs "^0.8.9" + loose-envify "^1.1.0" + object-assign "^4.1.0" + prop-types "^15.5.10" + +react@^15.5.4: + version "15.6.2" + resolved "https://registry.yarnpkg.com/react/-/react-15.6.2.tgz#dba0434ab439cfe82f108f0f511663908179aa72" + dependencies: + create-react-class "^15.6.0" + fbjs "^0.8.9" + loose-envify "^1.1.0" + object-assign "^4.1.0" + prop-types "^15.5.10" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +regenerate@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.3.tgz#0c336d3980553d755c39b586ae3b20aa49c82b7f" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +remarkable@^1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.1.tgz#aaca4972100b66a642a63a1021ca4bac1be3bff6" + dependencies: + argparse "~0.1.15" + autolinker "~0.15.0" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request@^2.53.0, request@^2.81.0: + version "2.83.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + har-validator "~5.0.3" + hawk "~6.0.2" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + stringstream "~0.0.5" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +resolve@^1.1.6: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + dependencies: + path-parse "^1.0.5" + +safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +semver@^5.3.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + +send@0.16.1: + version "0.16.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.1.tgz#a70e1ca21d1382c11d0d9f6231deb281080d7ab3" + dependencies: + debug "2.6.9" + depd "~1.1.1" + destroy "~1.0.4" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.3.1" + +serve-static@1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.1.tgz#4c57d53404a761d8f2e7c1e8a18a47dbf278a719" + dependencies: + encodeurl "~1.0.1" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.1" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +setprototypeof@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + +shelljs@^0.7.8: + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + dependencies: + is-arrayish "^0.3.1" + +sitemap@^1.13.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/sitemap/-/sitemap-1.13.0.tgz#569cbe2180202926a62a266cd3de09c9ceb43f83" + dependencies: + underscore "^1.7.0" + url-join "^1.1.0" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +sntp@2.x.x: + version "2.1.0" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8" + dependencies: + hoek "4.x.x" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +sshpk@^1.7.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +"statuses@>= 1.3.1 < 2": + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + +statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +stringstream@~0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^4.0.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.5.0.tgz#be7a0de484dec5c5cddf8b3d59125044912f635b" + dependencies: + has-flag "^2.0.0" + +tcp-port-used@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/tcp-port-used/-/tcp-port-used-0.1.2.tgz#9450e8768c83b416fd4d1a6a9449eeccbf496c29" + dependencies: + debug "0.7.4" + is2 "0.0.9" + q "0.9.7" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +tough-cookie@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561" + dependencies: + punycode "^1.4.1" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-is@~1.6.15: + version "1.6.15" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.15" + +ua-parser-js@^0.7.9: + version "0.7.17" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" + +underscore.string@~2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-2.4.0.tgz#8cdd8fbac4e2d2ea1e7e2e8097c42f442280f85b" + +underscore@^1.7.0: + version "1.8.3" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022" + +underscore@~1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.7.0.tgz#6bbaf0877500d36be34ecaa584e0db9fef035209" + +universalify@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.1.tgz#fa71badd4437af4c148841e3b3b165f9e9e590b7" + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +url-join@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + +uuid@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +whatwg-fetch@>=0.10.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +xml@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5" + +yamljs@^0.2.1: + version "0.2.10" + resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.2.10.tgz#481cc7c25ca73af59f591f0c96e3ce56c757a40f" + dependencies: + argparse "^1.0.7" + glob "^7.0.5" + +yargs@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-2.3.0.tgz#e900c87250ec5cd080db6009fe3dd63156f1d7fb" + dependencies: + wordwrap "0.0.2" From f10e951c7c1b51aa0c37b760f674898f583ecec0 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 23 Jan 2018 12:57:42 -0500 Subject: [PATCH 11/13] docs: Templates and CSS tweaks to docusaurus --- docs/failure-modes.md | 6 +-- website/core/Footer.js | 12 ++++- website/package.json | 2 +- website/pages/en/index.js | 97 ++++++++++++++++++----------------- website/static/css/custom.css | 37 ++++++++++++- website/yarn.lock | 70 ++++++++++++------------- 6 files changed, 134 insertions(+), 90 deletions(-) diff --git a/docs/failure-modes.md b/docs/failure-modes.md index dfd864b080..f06acca0a7 100644 --- a/docs/failure-modes.md +++ b/docs/failure-modes.md @@ -6,7 +6,7 @@ Like all complex, network-oriented software, dep has known failure modes. These ## I/O errors -dep reads from the network, and reads and writes to disk, and is thus subject to all the typical errors that are possible with such activities: full disks, failed disks, lack of permissions, network partitions, firewalls, etc. However, there are three specific classes of I/O errors that are worth addressing specifically: +dep reads from the network, and reads and writes to disk, and is thus subject to all the typical errors that are possible with such activities: full disks, failed disks, lack of permissions, network partitions, firewalls, etc. However, there are three classes of I/O errors that are worth addressing specifically: * Network failures * Bad local cache state @@ -100,10 +100,10 @@ Some of these failures can be as straightforward as typos, and are just as easil ### Deduction failures -Import path deduction, as detailed in the [deduction reference](deduction.md), has both static and dynamic phases. When neither of these phases is able to determine the source root for a given import path, it is considered to be a deduction failure. Deduction failures all have this key error text: +Import path deduction, as detailed in the [deduction reference](deduction.md), has both static and dynamic phases. When neither of these phases is able to determine the source root for a given import path, it is considered to be a deduction failure. Deduction failures all contain this key error text: ```bash -unable to deduce repository and source type for ""... +...unable to deduce repository and source type for ""... ``` _Note: there are [more varied error messages for the small subset of cases](#malformed-import-paths) where an import path appears to be deducible, but is somehow malformed._ diff --git a/website/core/Footer.js b/website/core/Footer.js index cc5efeb5c6..98956ad5ec 100644 --- a/website/core/Footer.js +++ b/website/core/Footer.js @@ -7,10 +7,20 @@ class Footer extends React.Component { const currentYear = new Date().getFullYear(); return ( ); } diff --git a/website/package.json b/website/package.json index 81abc9c558..ec2e7d7460 100644 --- a/website/package.json +++ b/website/package.json @@ -9,6 +9,6 @@ "rename-version": "docusaurus-rename-version" }, "devDependencies": { - "docusaurus": "^1.0.3" + "docusaurus": "^1.0.5" } } diff --git a/website/pages/en/index.js b/website/pages/en/index.js index 44c664e580..11437ae9af 100755 --- a/website/pages/en/index.js +++ b/website/pages/en/index.js @@ -19,71 +19,72 @@ class Button extends React.Component { } } +function assetUrl(img) { + return siteConfig.baseUrl + 'docs/assets/' + img; +} + +function docUrl(doc, language) { + return siteConfig.baseUrl + 'docs/' + (language ? language + '/' : '') + doc; +} + Button.defaultProps = { target: '_self', }; +const SplashContainer = props => ( +
+
+
{props.children}
+
+
+); + +const Logo = props => ( +
+ +
+); + +const ProjectTitle = props => ( +

+ {siteConfig.title} + {siteConfig.tagline} +

+); + +const PromoSection = props => ( +
+
+
{props.children}
+
+
+); + class HomeSplash extends React.Component { render() { + let language = this.props.language || ''; return ( -
-
-
-
- -
-
-

- {siteConfig.title} - {siteConfig.tagline} -

-
-
-
- - -
-
-
-
-
+ + +
+ + + + + +
-
+ ); } } class Index extends React.Component { render() { - let language = this.props.language || 'en'; - const showcase = siteConfig.users - .filter(user => { - return user.pinned; - }) - .map(user => { - return ( - - - - ); - }); + let language = this.props.language || ''; return ( -
-
); } } diff --git a/website/static/css/custom.css b/website/static/css/custom.css index 220c1dde7d..03809dde1f 100644 --- a/website/static/css/custom.css +++ b/website/static/css/custom.css @@ -4,6 +4,41 @@ } @media only screen and (min-width: 1024px) { + .homeContainer { + flex: 1 0 auto; + padding-bottom: 1em; + } + + .docMainWrapper { + flex: 1 0 auto; + padding-bottom: 1em; + } + + .homeContainer .homeWrapper .projectLogo { + justify-content: center; + position: relative; + padding: 2em; + } + + .homeContainer .homeWrapper .projectLogo img { + max-height: 360px; + } + + body { + display: flex; + flex-direction: column; + } + + div.navPusher { + display: flex; + flex-direction: column; + } + + .footer-logo { + padding-top: 1em; + display: flex; + justify-content: center; + } } @media only screen and (max-width: 1023px) { @@ -13,4 +48,4 @@ } @media only screen and (min-width: 1500px) { -} \ No newline at end of file +} diff --git a/website/yarn.lock b/website/yarn.lock index adadf47c31..cb5417d7df 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -648,19 +648,19 @@ brace-expansion@^1.1.7: concat-map "0.0.1" browserslist@^2.1.2: - version "2.10.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.10.0.tgz#bac5ee1cc69ca9d96403ffb8a3abdc5b6aed6346" + version "2.11.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.11.3.tgz#fe36167aed1bbcde4827ebfe71347a2cc70b99b2" dependencies: - caniuse-lite "^1.0.30000780" - electron-to-chromium "^1.3.28" + caniuse-lite "^1.0.30000792" + electron-to-chromium "^1.3.30" bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" -caniuse-lite@^1.0.30000780: - version "1.0.30000784" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000784.tgz#129ced74e9a1280a441880b6cd2bce30ef59e6c0" +caniuse-lite@^1.0.30000792: + version "1.0.30000792" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000792.tgz#d0cea981f8118f3961471afbb43c9a1e5bbf0332" caseless@~0.12.0: version "0.12.0" @@ -723,8 +723,8 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: delayed-stream "~1.0.0" commander@^2.11.0: - version "2.12.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555" + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" concat-map@0.0.1: version "0.0.1" @@ -808,10 +808,14 @@ delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" -depd@1.1.1, depd@~1.1.1: +depd@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" +depd@~1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -822,9 +826,9 @@ detect-indent@^4.0.0: dependencies: repeating "^2.0.0" -docusaurus@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/docusaurus/-/docusaurus-1.0.3.tgz#6ee1cc463a7e4462fd40207d323ace2ee6b1dfd6" +docusaurus@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/docusaurus/-/docusaurus-1.0.5.tgz#a2d75690e8dde50987a44cc836d6375b6130c8b7" dependencies: babel-preset-env "^1.6.0" babel-preset-react "^6.24.1" @@ -839,7 +843,7 @@ docusaurus@^1.0.3: escape-string-regexp "^1.0.5" express "^4.15.3" feed "^1.1.0" - fs-extra "^3.0.1" + fs-extra "^5.0.0" glob "^7.1.2" highlight.js "^9.12.0" react "^15.5.4" @@ -861,19 +865,13 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -electron-releases@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/electron-releases/-/electron-releases-2.1.0.tgz#c5614bf811f176ce3c836e368a0625782341fd4e" - -electron-to-chromium@^1.3.28: - version "1.3.30" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz#9666f532a64586651fc56a72513692e820d06a80" - dependencies: - electron-releases "^2.1.0" +electron-to-chromium@^1.3.30: + version "1.3.31" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.31.tgz#00d832cba9fe2358652b0c48a8816c8e3a037e9f" encodeurl@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" encoding@^0.1.11: version "0.1.12" @@ -1002,12 +1000,12 @@ fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" -fs-extra@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291" +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" dependencies: graceful-fs "^4.1.2" - jsonfile "^3.0.0" + jsonfile "^4.0.0" universalify "^0.1.0" fs.realpath@^1.0.0: @@ -1197,9 +1195,9 @@ json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" -jsonfile@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-3.0.1.tgz#a5ecc6f65f53f662c4415c7675a0331d0992ec66" +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" optionalDependencies: graceful-fs "^4.1.6" @@ -1495,8 +1493,8 @@ safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" semver@^5.3.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" send@0.16.1: version "0.16.1" @@ -1696,8 +1694,8 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" uuid@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" + version "3.2.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" vary@~1.1.2: version "1.1.2" From 64d7f61a833bf54f9811c4a69fa8dc53196d0be7 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 23 Jan 2018 16:37:25 -0500 Subject: [PATCH 12/13] docs: new release announcement, CSS fixes --- docs/the-solver.md | 4 +- website/blog/2018-01-23-announce-v0.4.0.md | 34 ++++++++- website/pages/en/versions.js | 88 ---------------------- website/static/css/custom.css | 71 ++++++++--------- 4 files changed, 72 insertions(+), 125 deletions(-) delete mode 100644 website/pages/en/versions.js diff --git a/docs/the-solver.md b/docs/the-solver.md index 43f173d3fb..25854dbd5f 100644 --- a/docs/the-solver.md +++ b/docs/the-solver.md @@ -69,7 +69,9 @@ will result in an error, as `C` imports a package that will necessarily result i Go 1.4 introduced [import comments](https://golang.org/cmd/go/#hdr-Import_path_checking), which allow a package to specify the import path that must be used when addressing it. For example, `import "github.com/golang/net/dict"` would point to a valid package, but because [it uses an import comment](https://github.com/golang/net/blob/42fe2e1c20de1054d3d30f82cc9fb5b41e2e3767/dict/dict.go#L7) to enforce that it must be imported as `golang.org/x/net/dict`, dep would reject any project attempting to import it directly through its github address. -Because most projects are consistent about their import comment use over time, this issue typically only occurs when adding a new dependency or attempting to revive an older project. +Because most projects are consistent about their import comment use over time, this issue typically only occurs when adding a new dependency or attempting to revive an older project. + +> Note: dep does not currently enforce this rule, but [it needs to](https://github.com/golang/dep/issues/902). **Remediation:** change the code by fixing the offending import paths. If the offending import paths are not in the current project and you don't directly control the dependency, you'll have to fork and fix it yourself, then use `source` to point to your fork. diff --git a/website/blog/2018-01-23-announce-v0.4.0.md b/website/blog/2018-01-23-announce-v0.4.0.md index 55528512d2..ad94a0927b 100644 --- a/website/blog/2018-01-23-announce-v0.4.0.md +++ b/website/blog/2018-01-23-announce-v0.4.0.md @@ -4,4 +4,36 @@ author: sam boyer authorURL: http://twitter.com/sdboyer --- -This blog post will test file name parsing issues when periods are present. +v0.4.0 of dep [has been released](https://github.com/golang/dep/releases/tag/v0.4.0) - and along with it, this site for documentation and announcements about dep! And, being that it's been nearly six months since [the last dep status update](https://sdboyer.io/dep-status/2017-08-17/) (which are now officially discontinued, in favor of this blog), and the roadmap hasn't been substantially updated in even longer, we'll use this release as an excuse to bring a bunch of things up to speed. + +### A new dep release! + +After three months of work, the next version of dep is stable and ready for public use. The big headline changes are: + +* `dep prune` no longer exists as a separate command. It has been absorbed into `dep ensure`, and its behavior can now be more granularly controlled by [directives in `Gopkg.toml`](https://golang.github.io/dep/docs/Gopkg.toml.html#prune). Calls to `dep prune` will not fail now, but will in future versions, so update your scripts! +* Support for govendor and glock have been added; `dep init` can now read their metadata files and attempt to automatically convert projects managed by those tools. + +Additional information is available in [the release notes](https://github.com/golang/dep/releases/tag/v0.4.0). The other major addition is this documentation site! + +### Docs docs docs + +Dep has had a documentation problem for a while. Having a single-command interface helped us get by with having only an FAQ, but as time wore on, it became increasingly clear that we needed a comprehensive set of documentation if people were to really feel comfortable with the tool. + +This site, which is automatically generated from the [docs directory](https://github.com/golang/dep/tree/master/docs) within the dep repository by [docusaurus](http://docusaurus.io/), is now that comprehensive source of docs. More so than any individual bit of information, it provides some broader benefits: + +* New user guides - reference documentation is not what folks need when starting with a new tool. Step-by-step instructions are. Now [we have that](https://golang.github.io/dep/docs/introduction.html), and it caters to users who are not only new to dep, but also to Go in general. +* Thematic organization of content - up until now, we were somewhat haphazardly flinging information into the FAQ. The body of documentation here is organized from the ground up, which will hopefully make it both more useful and easier to maintain. +* Versioning - all of the docs are snapshotted on each release, and users can [select the version of the docs](https://golang.github.io/dep/versions.html) they want to view. Ideally, everyone should always be able to use the latest version, but this at least means you're not penalized if that's not feasible for you/your organization. +* A blog - you're reading it! This is great, as it provides us a canonical place to circulate information about what's happening with the project. + +At the same time, the docs aren't quite comprehensive _yet_. There's more reference material and guides to be written. For example, we're still missing a guide for project maintainers on how to make releases that align well with dep's happy path. + +Also, now that we have this whole docs apparatus, it would be particularly awesome if someone were to step up to help as a [docs maintainer](https://github.com/golang/dep/issues/629#issuecomment-359922251)! Also also, the CSS on this site is terrible, and + +### The future + +Right now, there's two aspects to the future of dep. One is the roadmap of changes and features that make sense for dep as it exists today, in this standalone context. The other is the roadmap for moving dep into the toolchain. + +For the former, we have a fair bit of work underway that, now that this release is out the door, we can move on quickly. That includes major performance improvements, solver improvements to pick a sane version more of the time with less manual intervention, allowing the `source` field to work the way [most people expect it to](https://github.com/golang/dep/issues/860), and others. The goal is also to move dep towards a more regular release schedule. + +With respect to dep's movement towards the toolchain, discussions have already been ongoing between dep folks and the Go team for months. Movement into the toolchain is not a simple process. Some rules that dep, as a standalone tool, had to accept as law, become negotiable (for example, the semantics of vendor directories). There's also the question of how to best fit dep's commands themselves into the `go` tool. These present both interesting design opportunities and considerable risk. More information and opportunities for comment will be coming as we move into the Go 1.10 cycle. As has always been the plan, though, dep will continue to exist as a standalone tool until the toolchain has evolved sufficiently to supplant it. \ No newline at end of file diff --git a/website/pages/en/versions.js b/website/pages/en/versions.js deleted file mode 100644 index 192d3ac3d9..0000000000 --- a/website/pages/en/versions.js +++ /dev/null @@ -1,88 +0,0 @@ -const React = require('react'); - -const CompLibrary = require('../../core/CompLibrary'); -const Container = CompLibrary.Container; -const GridBlock = CompLibrary.GridBlock; - -const CWD = process.cwd(); - -const siteConfig = require(CWD + '/siteConfig.js'); -const versions = require(CWD + '/versions.json'); - -class Versions extends React.Component { - render() { - const latestVersion = versions[0]; - return ( - - ); - } -} - -module.exports = Versions; diff --git a/website/static/css/custom.css b/website/static/css/custom.css index 03809dde1f..097e466ac5 100644 --- a/website/static/css/custom.css +++ b/website/static/css/custom.css @@ -1,44 +1,45 @@ /* your custom css */ +.homeContainer { + flex: 1 0 auto; + padding-bottom: 1em; +} + +.docMainWrapper { + flex: 1 0 auto; + padding-bottom: 1em; +} + +.homeContainer .homeWrapper .projectLogo { + justify-content: center; + position: relative; + padding: 2em; +} + +.homeContainer .homeWrapper .projectLogo img { + max-height: 360px; +} + +body { + display: flex; + flex-direction: column; +} + +div.navPusher { + display: flex; + flex-direction: column; +} + +.footer-logo { + padding-top: 1em; + display: flex; + justify-content: center; +} + @media only screen and (min-device-width: 360px) and (max-device-width: 736px) { } @media only screen and (min-width: 1024px) { - .homeContainer { - flex: 1 0 auto; - padding-bottom: 1em; - } - - .docMainWrapper { - flex: 1 0 auto; - padding-bottom: 1em; - } - - .homeContainer .homeWrapper .projectLogo { - justify-content: center; - position: relative; - padding: 2em; - } - - .homeContainer .homeWrapper .projectLogo img { - max-height: 360px; - } - - body { - display: flex; - flex-direction: column; - } - - div.navPusher { - display: flex; - flex-direction: column; - } - - .footer-logo { - padding-top: 1em; - display: flex; - justify-content: center; - } } @media only screen and (max-width: 1023px) { From 879f6ca58a065951a7045745f514f524581a7f69 Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 23 Jan 2018 22:59:22 -0500 Subject: [PATCH 13/13] docs: Rework Gopkg.toml docs significantly This was nominally to incorporate prune docs, but it became a broader rewrite that was really needed, anyway. --- docs/Gopkg.lock.md | 2 +- docs/Gopkg.toml.md | 199 +++++++++++++++++++++++++----------------- docs/glossary.md | 12 ++- website/siteConfig.js | 6 +- 4 files changed, 136 insertions(+), 83 deletions(-) diff --git a/docs/Gopkg.lock.md b/docs/Gopkg.lock.md index 68e91b223e..c68fdc0128 100644 --- a/docs/Gopkg.lock.md +++ b/docs/Gopkg.lock.md @@ -12,7 +12,7 @@ The `Gopkg.lock` file is generated by `dep ensure` and `dep init`. It is the out `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. +`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. ## `[[project]]` diff --git a/docs/Gopkg.toml.md b/docs/Gopkg.toml.md index 9f69beefe5..84ff9d3f1a 100644 --- a/docs/Gopkg.toml.md +++ b/docs/Gopkg.toml.md @@ -4,25 +4,32 @@ title: Gopkg.toml The `Gopkg.toml` file is initially generated by `dep init`, and is primarily hand-edited. It contains several types of rule declarations that govern dep's behavior: -* [`constraints`](#constraint) and [`overrides`](#override) allow the user to specify which versions of dependencies are acceptable, and where they should be retrieved from. -* [`required`](#required) and [`ignored`](#ignored) allow the user to manipulate the import graph by including or excluding import paths, respectively. -* [`metadata`](#metadata) is a user-defined map of key-value pairs that dep will preserve and ignore. -* [`prune`](#prune) settings govern what files and directories can be deemed unnecessary, and thus automatically removed from `vendor/`. +* _Dependency rules:_ [`constraints`](#constraint) and [`overrides`](#override) allow the user to specify which versions of dependencies are acceptable, and where they should be retrieved from. +* _Package graph rules:_ [`required`](#required) and [`ignored`](#ignored) allow the user to manipulate the import graph by including or excluding import paths, respectively. +* [`metadata`](#metadata) are a user-defined maps of key-value pairs that dep will ignore. They provide a data sidecar for tools building on top of dep. +* [`prune`](#prune) settings determine what files and directories can be deemed unnecessary, and thus automatically removed from `vendor/`. Note that because TOML does not adhere to a tree structure, the `required` and `ignored` fields must be declared before any `[[constraint]]` or `[[override]]`. ---- +There is a full [example](#example) `Gopkg.toml` file at the bottom of this document. `dep init` will also, by default, generate a `Gopkg.toml` containing some example values, for guidance. + +## Dependency rules: `[[constraint]]` and `[[override]]` -## `constraint` +Most of the rule declarations in a `Gopkg.toml` will be either `[[constraint]]` or `[[override]]` stanzas. Both of these types of stanzas allow exactly the same types of values, but dep interprets them differently. Each allows the following values: -A `constraint` provides rules for how a [direct dependency](FAQ.md#what-is-a-direct-or-transitive-dependency) may be incorporated into the dependency graph. dep respects these declarations from the current project's `Gopkg.toml`, as well as that of all dependencies. +* `name` - the import path corresponding to the [source root](glossary.md#source-root) of a dependency (generally: where the VCS root is) +* At most one [version rule](#version-rules) +* An optional [`source` rule](#source) +* [`metadata`](#metadata) that is specific to the `name`'d project + +A full example (invalid, actually, as it has more than one version rule, for illustrative purposes) of either one of these stanzas looks like this: ```toml [[constraint]] # Required: the root import path of the project being constrained. name = "github.com/user/project" # Recommended: the version constraint to enforce for the project. - # Only one of "branch", "version" or "revision" can be specified. + # Note that only one of "branch", "version" or "revision" can be specified. version = "1.0.0" branch = "master" revision = "abc123" @@ -37,33 +44,86 @@ A `constraint` provides rules for how a [direct dependency](FAQ.md#what-is-a-dir system2-data = "value that is used by another system" ``` +### `[[constraint]]` + +A `[[constraint]]` stanza defines rules for how a [direct dependency](glossary.md#direct-dependency) must be incorporated into the dependency graph. Dep respects these declarations from the current project's `Gopkg.toml`, as well as the `Gopkg.toml` files found in any dependencies. + **Use this for:** having a [direct dependency](FAQ.md#what-is-a-direct-or-transitive-dependency) use a specific branch, version range, revision, or alternate source (such as a fork). -## `override` +### `[[override]]` -An `override` has the same structure as a `constraint` declaration, but supersede all `constraint` declarations from all projects. Only `override` declarations from the current project's `Gopkg.toml` are applied. +An `[[override]]` stanza differs from a `[[constraint]]` in that it applies to all dependencies, [direct](glossary.md#direct-dependency) and [transitive](glossary.md#transitive-dependency), and supersedes all other `[[constraint]]` declarations for that project. However, only overrides from the current project's `Gopkg.toml` are incorporated. -```toml -[[override]] - # Required: the root import path of the project being constrained. - name = "github.com/user/project" - # Optional: specifying a version constraint override will cause all other constraints on this project to be ignored; only the overridden constraint needs to be satisfied. Again, only one of "branch", "version" or "revision" can be specified. - version = "1.0.0" - branch = "master" - revision = "abc123" - # Optional: specifying an alternate source location as an override will enforce that the alternate location is used for that project, regardless of what source location any dependent projects specify. - source = "https://github.com/myfork/package.git" +**Use this for:** Overrides are primarily intended as a way of eliminating disagreements between multiple irreconcilable `[[constraint]]` declarations on a single dependency. However, they will also be your primary recourse if you need to [constrain a transitive dependency's version?](FAQ.md#how-do-i-constrain-a-transitive-dependencys-version) - # Optional: metadata about the constraint or override that could be used by other independent systems - [metadata] - key1 = "value that convey data to other systems" - system1-data = "value that is used by a system" - system2-data = "value that is used by another system" +Overrides should be used cautiously and temporarily, when possible. + +### `source` + +A `source` rule can specify an alternate location from which the `name`'d project should be retrieved. It is primarily useful for temporarily specifying a fork for a repository. + +`source` rules are generally brittle and should only be used when there is no other recourse. Using them to try to circumvent network reachability issues is typically an antipattern. + +### Version rules + +Version rules can be used in either `[[constraint]]` or `[[override]]` stanzas. There are three types of version rules - `version`, `branch`, and `revision`. At most one of the three types can be specified. + +#### `version` + +`version` is a property of `constraint`s and `override`s. It is used to specify version constraint of a specific dependency. It can be used to target an arbitrary VCS tag, or a semantic version, or a range of semantic versions. + +Specifying semantic version ranges can be done using the following operators: + +* `=`: equal +* `!=`: not equal +* `>`: greater than +* `<`: less than +* `>=`: greater than or equal to +* `<=`: less than or equal to +* `-`: literal range. Eg: 1.2 - 1.4.5 is equivalent to >= 1.2, <= 1.4.5 +* `~`: minor range. Eg: ~1.2.3 is equivalent to >= 1.2.3, < 1.3.0 +* `^`: major range. Eg: ^1.2.3 is equivalent to >= 1.2.3, < 2.0.0 +* `[xX*]`: wildcard. Eg: 1.2.x is equivalent to >= 1.2.0, < 1.3.0 + +You might, for example, include a rule that specifies `version = "=2.0.0"` to pin a dependency to version 2.0.0, or constrain to minor releases with: `version = "~2.1.0"`. Refer to the [semver library](https://github.com/Masterminds/semver) documentation for more info. + +**Note**: When you specify a version *without an operator*, `dep` automatically uses the `^` operator by default. `dep ensure` will interpret the given version as the min-boundary of a range, for example: + +* `1.2.3` becomes the range `>=1.2.3, <2.0.0` +* `0.2.3` becomes the range `>=0.2.3, <0.3.0` +* `0.0.3` becomes the range `>=0.0.3, <0.1.0` + +`~` and `=` operators can be used with the versions. When a version is specified without any operator, `dep` automatically adds a caret operator, `^`. The caret operator pins the left-most non-zero digit in the version. For example: +``` +^1.2.3 means 1.2.3 <= X < 2.0.0 +^0.2.3 means 0.2.3 <= X < 0.3.0 +^0.0.3 means 0.0.3 <= X < 0.1.0 +``` + +To pin a version of direct dependency in manifest, prefix the version with `=`. For example: +```toml +[[constraint]] + name = "github.com/pkg/errors" + version = "=0.8.0" ``` -**Use this for:** all the same things as a [`constraint`](#constraint), but for [transitive dependencies](FAQ.md#what-is-a-direct-or-transitive-dependency). See [How do I constrain a transitive dependency's version?](FAQ.md#how-do-i-constrain-a-transitive-dependencys-version) for more details on how overrides differ from `constraint`s. _Overrides should be used cautiously, sparingly, and temporarily._ +#### `branch` -## `required` +Using a `branch` constraint will cause dep to use the named branch (e.g., `branch = "master"`) for a particular dependency. The revision at the tip of the branch will be recorded into `Gopkg.lock`, and almost always remain the same until a change is requested, via `dep ensure -update`. + +In general, you should prefer semantic versions to branches, when a project has made them available. + +#### `revision` + +A `revision` is the underlying immutable identifier - like a git commit SHA1. While it is allowed to constrain to a `revision`, doing so is almost always an antipattern. + +Usually, folks are inclined to pin to a revision because they feel it will somehow improve their project's reproducibility. That is not a good reason. `Gopkg.lock` provides reproducibility. Only use `revision` if you have a good reason to believe that _no_ other version of that dependency _could_ work. + +## Package graph rules: `required` and `ignored` + +As part of normal operation, dep analyzes import statements in Go code. These import statements connect packages together, ultimately forming a graph. The `required` and `ignored` rules manipulate that graph, in ways that are roughly dual to each other: `required` adds import paths to the graph, and `ignored` removes them. + +### `required` `required` lists a set of packages (not projects) that must be included in Gopkg.lock. This list is merged with the set of packages imported by the current project. ```toml @@ -74,7 +134,7 @@ required = ["github.com/user/thing/cmd/thing"] * Are needed by your project * Aren't `import`ed by your project, [directly or transitively](FAQ.md#what-is-a-direct-or-transitive-dependency) -* You don't want put in your `GOPATH`, and/or you want to lock the version +* You don't want to put them in your `GOPATH`, and/or you want to lock the version Please note that this only pulls in the sources of these dependencies. It does not install or compile them. So, if you need the tool to be installed you should still run the following (manually or from a `Makefile`) after each `dep ensure`: @@ -92,18 +152,21 @@ export PATH=$GOBIN:$PATH You might also try [virtualgo](https://github.com/GetStream/vg), which installs dependencies in the `required` list automatically in a project specific `GOBIN`. -## `ignored` + +### `ignored` `ignored` lists a set of packages (not projects) that are ignored when dep statically analyzes source code. Ignored packages can be in this project, or in a dependency. + ```toml ignored = ["github.com/user/project/badpkg"] ``` -Use wildcard character (*) to define a package prefix to be ignored. Use this to ignore any package and their subpackages. +Use `*` to define a package prefix to be ignored. This will cause any lexical wildcard match to be ignored, including the literal string prior to the `*`. + ```toml ignored = ["github.com/user/project/badpkg*"] ``` -**Use this for:** preventing a package and any of that package's unique dependencies from being installed. +**Use this for:** preventing a package, and any of that package's unique dependencies, from being incorporated in `Gopkg.lock`. ## `metadata` `metadata` can exist at the root as well as under `constraint` and `override` declarations. @@ -118,63 +181,35 @@ system1-data = "value that is used by a system" system2-data = "value that is used by another system" ``` +## `prune` +`prune` defines the global and per-project prune options for dependencies. The options determine which files are discarded when writing the `vendor/` tree. -## Version rules - -Version rules can be used in either `[[constraint]]` or `[[override]]` stanzas. There are three types of version rules - `version`, `branch`, and `revision`. At most one of the three types can be specified. +The following are the current available options: +* `unused-packages` indicates that files from directories that do not appear in the package import graph should be pruned. +* `non-go` prunes files that are not used by Go. +* `go-tests` prunes Go test files. -### `version` - -`version` is a property of `constraint`s and `override`s. It is used to specify version constraint of a specific dependency. It can be used to target an arbitrary VCS tag, or a semantic version, or a range of semantic versions. - -Specifying semantic version ranges can be done using the following operators: - -* `=`: equal -* `!=`: not equal -* `>`: greater than -* `<`: less than -* `>=`: greater than or equal to -* `<=`: less than or equal to -* `-`: literal range. Eg: 1.2 - 1.4.5 is equivalent to >= 1.2, <= 1.4.5 -* `~`: minor range. Eg: ~1.2.3 is equivalent to >= 1.2.3, < 1.3.0 -* `^`: major range. Eg: ^1.2.3 is equivalent to >= 1.2.3, < 2.0.0 -* `[xX*]`: wildcard. Eg: 1.2.x is equivalent to >= 1.2.0, < 1.3.0 +Out of an abundance of caution, dep non-optionally preserves files that may have legal significance. -You might, for example, include a rule that specifies `version = "=2.0.0"` to pin a dependency to version 2.0.0, or constrain to minor releases with: `version = "~2.1.0"`. Refer to the [semver library](https://github.com/Masterminds/semver) documentation for more info. - -**Note**: When you specify a version *without an operator*, `dep` automatically uses the `^` operator by default. `dep ensure` will interpret the given version as the min-boundary of a range, for example: - -* `1.2.3` becomes the range `>=1.2.3, <2.0.0` -* `0.2.3` becomes the range `>=0.2.3, <0.3.0` -* `0.0.3` becomes the range `>=0.0.3, <0.1.0` - -`~` and `=` operators can be used with the versions. When a version is specified without any operator, `dep` automatically adds a caret operator, `^`. The caret operator pins the left-most non-zero digit in the version. For example: -``` -^1.2.3 means 1.2.3 <= X < 2.0.0 -^0.2.3 means 0.2.3 <= X < 0.3.0 -^0.0.3 means 0.0.3 <= X < 0.1.0 -``` - -To pin a version of direct dependency in manifest, prefix the version with `=`. For example: +Pruning is disabled by default. It can be enabled by setting them to `true` at the root level. ```toml -[[constraint]] - name = "github.com/pkg/errors" - version = "=0.8.0" +[prune] + non-go = true ``` -### `branch` - -Using a `branch` constraint will cause dep to use the named branch (e.g., `branch = "master"`) for a particular dependency. The revision at the tip of the branch will be recorded into `Gopkg.lock`, and almost always remain the same until a change is requested, via `dep ensure -update`. - -In general, you should prefer semantic versions to branches, when a project has made them available. +The same prune options can be defined per-project. An addtional `name` field is required and, as with should represent a project and not a package. -### `revision` -A `revision` is the underlying immutable identifier - like a git commit SHA1. While it is allowed to constrain to a `revision`, doing so is almost always an antipattern. - -Usually, folks are inclined to pin to a revision because they feel it will somehow improve their project's reproducibility. That is not a good reason. `Gopkg.lock` provides reproducibility. Only use `revision` if you have a good reason to believe that _no_ other version of that dependency _could_ work. +```toml +[prune] + non-go = true + [[prune.project]] + name = "github.com/project/name" + go-tests = true + non-go = false +``` # Example A sample `Gopkg.toml` with most elements present: @@ -190,6 +225,14 @@ ignored = [ [metadata] codename = "foo" +[prune] + non-go = true + + [[prune.project]] + name = "github.com/project/name" + go-tests = true + non-go = false + [[constraint]] name = "github.com/user/project" version = "1.0.0" diff --git a/docs/glossary.md b/docs/glossary.md index a931ad361d..0cb3aab932 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -57,7 +57,11 @@ Deduction is the process of determining the subset of an import path that corres ### Direct Dependency -A project's direct dependencies are those that it imports from one or more of its packages, or includes in its [`required`](Gopkg.toml.md#required) list in `Gopkg.toml`. If each letter in `A -> B -> C -> D` represents a project, then only `B` is `A`'s direct dependency. +A project's direct dependencies are those that it _imports_ from one or more of its packages, or includes in its [`required`](Gopkg.toml.md#required) list in `Gopkg.toml`. + + If each letter in `A -> B -> C -> D` represents a distinct project containing only a single package, and `->` indicates an import statement, then `B` is `A`'s direct dependency, whereas `C` and `D` are [transitive dependencies](#transitive-dependency) of `A`. + +Dep only incorporates the `required` rules from the [current project's](#current-project) `Gopkg.toml`. Therefore, if `=>` represents `required` rather than a standard import, and `A -> B => C`, then `C` is a direct dependency of `B` _only_ when `B` is the current project. Because the `B`-to-`C` link does not exist when `A` is the current project, then `C` won't actually be in the graph at all. ### External Import @@ -120,7 +124,7 @@ The remote entities that hold versioned code. Sources are specifically the entit ### Source Root -The portion of an import path that corresponds to the network location of a source. This is similar to [Project Root](#project-root), but refers strictly to the second definition, network-oriented. +The portion of an import path that corresponds to the network location of a source. This is similar to [Project Root](#project-root), but refers strictly to the second, network-oriented definition. ### Sync @@ -130,4 +134,6 @@ This concept is explored in detail on [the ensure mechanics reference page](ensu ### Transitive Dependency -A project's transitive dependencies are those dependencies that it does not import itself, but are imported by one of its dependencies. If each letter in `A -> B -> C -> D` represents a project, then `C` and `D` are `A`'s transitive dependencies. \ No newline at end of file +A project's transitive dependencies are those dependencies that it does not import itself, but are imported by one of its dependencies. + +If each letter in `A -> B -> C -> D` represents a distinct project containing only a single package, and `->` indicates an import statement, then `C` and `D` are `A`'s transitive dependencies, whereas `B` is a [direct dependency](#transitive-dependency) of `A`. \ No newline at end of file diff --git a/website/siteConfig.js b/website/siteConfig.js index 8d60c0e602..41acaecab2 100644 --- a/website/siteConfig.js +++ b/website/siteConfig.js @@ -7,7 +7,7 @@ const siteConfig = { tagline: 'Dependency management for Go', url: 'https://golang.github.io' /* your website url */, baseUrl: '/dep/' /* base url for your project */, - editURL: 'https://github.com/golang/dep/edit/master/docs/', + editUrl: 'https://github.com/golang/dep/edit/master/docs/', projectName: 'dep', headerLinks: [ {doc: 'introduction', label: 'Documentation'}, @@ -23,6 +23,10 @@ const siteConfig = { secondaryColor: '#E0EBF5', primaryColor: '#375EAB', }, + //algolia: { + //apiKey: "f2e26cf744b3d81c7e57499075753104", + //indexName: "dep-docs" + //}, // This copyright info is used in /core/Footer.js and blog rss/atom feeds. copyright: 'Copyright © ' +

Build Status Windows Build Status @@ -15,9 +15,9 @@ For guides and reference materials about `dep`, see [the documentation](https:// ## Installation -Unless you are hacking on dep, it is strongly recommended that you use a released version. You can grab the latest binary from the [releases](https://github.com/golang/dep/releases) page. +It is strongly recommended that you use a released version. Release binaries are available on the [releases](https://github.com/golang/dep/releases) page. -On macOS you can install or upgrade to the latest released version with Homebrew: +On MacOS you can install or upgrade to the latest released version with Homebrew: ```sh $ brew install dep diff --git a/docs/FAQ.md b/docs/FAQ.md index a8c9f309f3..f588d477c5 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -1,19 +1,8 @@ --- -id: faq.md ---- - - - title: FAQ --- - -# FAQ - -_The first rule of FAQ is don't bikeshed the FAQ, leave that for -[Create structure for managing docs](https://github.com/golang/dep/issues/331)._ +--- -Please contribute to the FAQ! Found an explanation in an issue or pull request helpful? -Summarize the question and quote the reply, linking back to the original comment. +The FAQ predated the introduction of the rest of the documentation. If something in here conflicts with other guides or reference documents, it's probably here that it's wrong - please file a PR! ## Concepts * [Does `dep` replace `go get`?](#does-dep-replace-go-get) diff --git a/docs/Gopkg.lock.md b/docs/Gopkg.lock.md index ac38519ff5..68e91b223e 100644 --- a/docs/Gopkg.lock.md +++ b/docs/Gopkg.lock.md @@ -2,7 +2,13 @@ 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]`. +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. That means: + +* Every package a project needs to compile +* Plus any [`required`](Gopkg.toml.md#required) packages +* Less any [`ignored`](Gopkg.toml.md#ignored) packages + +`Gopkg.lock` 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. @@ -73,7 +79,7 @@ The same general principles of version-bumping apply to the solver version: if t ### `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: +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 value to be generated directly: ``` dep hash-inputs | tr -d “\n” | shasum -a256 diff --git a/docs/assets b/docs/assets deleted file mode 120000 index cf2d7699c6..0000000000 --- a/docs/assets +++ /dev/null @@ -1 +0,0 @@ -img \ No newline at end of file diff --git a/docs/img/DigbyFlat.png b/docs/assets/DigbyFlat.png similarity index 100% rename from docs/img/DigbyFlat.png rename to docs/assets/DigbyFlat.png diff --git a/docs/img/DigbyFlat.svg b/docs/assets/DigbyFlat.svg similarity index 100% rename from docs/img/DigbyFlat.svg rename to docs/assets/DigbyFlat.svg diff --git a/docs/img/DigbyFlatScene2.png b/docs/assets/DigbyFlatScene2.png similarity index 100% rename from docs/img/DigbyFlatScene2.png rename to docs/assets/DigbyFlatScene2.png diff --git a/docs/img/DigbyFlatScene2.svg b/docs/assets/DigbyFlatScene2.svg similarity index 100% rename from docs/img/DigbyFlatScene2.svg rename to docs/assets/DigbyFlatScene2.svg diff --git a/docs/img/DigbyScene2Flat.png b/docs/assets/DigbyScene2Flat.png similarity index 100% rename from docs/img/DigbyScene2Flat.png rename to docs/assets/DigbyScene2Flat.png diff --git a/docs/img/DigbyScene2Flat.svg b/docs/assets/DigbyScene2Flat.svg similarity index 100% rename from docs/img/DigbyScene2Flat.svg rename to docs/assets/DigbyScene2Flat.svg diff --git a/docs/img/DigbyScene2Shadows.png b/docs/assets/DigbyScene2Shadows.png similarity index 100% rename from docs/img/DigbyScene2Shadows.png rename to docs/assets/DigbyScene2Shadows.png diff --git a/docs/img/DigbyScene2Shadows.svg b/docs/assets/DigbyScene2Shadows.svg similarity index 100% rename from docs/img/DigbyScene2Shadows.svg rename to docs/assets/DigbyScene2Shadows.svg diff --git a/docs/img/DigbyShadows.png b/docs/assets/DigbyShadows.png similarity index 100% rename from docs/img/DigbyShadows.png rename to docs/assets/DigbyShadows.png diff --git a/docs/img/DigbyShadows.svg b/docs/assets/DigbyShadows.svg similarity index 100% rename from docs/img/DigbyShadows.svg rename to docs/assets/DigbyShadows.svg diff --git a/docs/img/DigbyShadowsScene2.png b/docs/assets/DigbyShadowsScene2.png similarity index 100% rename from docs/img/DigbyShadowsScene2.png rename to docs/assets/DigbyShadowsScene2.png diff --git a/docs/img/DigbyShadowsScene2.svg b/docs/assets/DigbyShadowsScene2.svg similarity index 100% rename from docs/img/DigbyShadowsScene2.svg rename to docs/assets/DigbyShadowsScene2.svg diff --git a/docs/img/StatusGraph.png b/docs/assets/StatusGraph.png similarity index 100% rename from docs/img/StatusGraph.png rename to docs/assets/StatusGraph.png diff --git a/docs/img/annotated-func-arrows.png b/docs/assets/annotated-func-arrows.png similarity index 100% rename from docs/img/annotated-func-arrows.png rename to docs/assets/annotated-func-arrows.png diff --git a/docs/img/base-arrows.png b/docs/assets/base-arrows.png similarity index 100% rename from docs/img/base-arrows.png rename to docs/assets/base-arrows.png diff --git a/docs/img/four-states.png b/docs/assets/four-states.png similarity index 100% rename from docs/img/four-states.png rename to docs/assets/four-states.png diff --git a/docs/img/func-toggles.png b/docs/assets/func-toggles.png similarity index 100% rename from docs/img/func-toggles.png rename to docs/assets/func-toggles.png diff --git a/docs/assets/in-sync.png b/docs/assets/in-sync.png new file mode 100644 index 0000000000000000000000000000000000000000..094148a5c04c92d363c4cf3fcf86ab70f9a9f495 GIT binary patch literal 34774 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"... ``` @@ -168,7 +168,7 @@ For the most part, static ("is it one of the handful of hosts we know?") and dyn When `dep ensure` or `dep init` exit with an error message looking something like this: -``` +```bash $ dep init init failed: unable to solve the dependency graph: Solving failure: No versions of github.com/foo/bar met constraints: v1.0.1: Could not introduce github.com/foo/bar@v1.13.1, as its subpackage github.com/foo/bar/foo is missing. (Package is required by (root).) @@ -181,7 +181,7 @@ _Note: all three of the other hard failure types can sometimes be reported as th It means that the solver was unable to find a combination of versions for all dependencies that satisfy all the rules enforced by the solver. It is crucial to note that, just because dep provides a big list of reasons why each version failed _doesn't mean_ you have to address each one! That's just dep telling you why it ultimately couldn't use each of those versions in a solution. -These rules, and specific remediations for failing to meet them, are described in detail in the section on [solver invariants](the-solver.md#solving-invariants). This section is about the steps to take when solving failures occur in general. But, to set context, here's a quick summary: +These rules, and specific remediations for failing to meet them, are described in detail in the section on [solver invariants](the-solver.md#solving-invariants). This section is about the steps to take when solving failures occur in general. But, to set context, here's a summary: * **`[[constraint]]` conflicts:** when projects in the dependency graph disagree on what [versions](gopkg.toml.md#version-rules) are acceptable for a project, or where to [source](gopkg.toml.md#source) it from. * Remediation will usually be either changing a `[[constraint]]` or adding an `[[override]]`, but genuine conflicts may require forking and hacking code. diff --git a/docs/glossary.md b/docs/glossary.md index d9e4bbaf06..a931ad361d 100644 --- a/docs/glossary.md +++ b/docs/glossary.md @@ -9,6 +9,7 @@ dep uses some specialized terminology. Learn about it here! * [Cache lock](#cache-lock) * [Constraint](#constraint) * [Current Project](#current-project) +* [Deducible](#deducible) * [Deduction](#deduction) * [Direct Dependency](#direct-dependency) * [External Import](#external-import) @@ -28,59 +29,59 @@ dep uses some specialized terminology. Learn about it here! --- -## Atom +### Atom Atoms are a source at a particular version. In practice, this means a two-tuple of [project root](#project-root) and version, e.g. `github.com/foo/bar@master`. Atoms are primarily internal to the [solver](#solver), and the term is rarely used elsewhere. -## Cache lock +### Cache lock Also "cache lock file." A file, named `sm.lock`, used to ensure only a single dep process operates on the [local cache](#local-cache) at a time, as it is unsafe in dep's current design for multiple processes to access the local cache. -## Constraint +### Constraint Constraints have both a narrow and a looser meaning. The narrow sense refers to a [`[[constraint]]`](Gopkg.toml.md#constraint) stanza in `Gopkg.toml`. However, in some contexts, the word may be used more loosely to refer to the idea of applying rules and requirements to dependency management in general. -## Current Project +### Current Project The project on which dep is operating - writing its `Gopkg.lock` and populating its `vendor` directory. Also called the "root project." -## Deducible +### Deducible A shorthand way of referring to whether or not import path [deduction](#deduction) will return successfully for a given import path. "Undeducible" is also often used, to refer to an import path for which deduction fails. -## Deduction +### Deduction Deduction is the process of determining the subset of an import path that corresponds to a source root. Some patterns are known a priori (static); others must be discovered via network requests (dynamic). See the reference on [import path deduction](deduction.md) for specifics. -## Direct Dependency +### Direct Dependency A project's direct dependencies are those that it imports from one or more of its packages, or includes in its [`required`](Gopkg.toml.md#required) list in `Gopkg.toml`. If each letter in `A -> B -> C -> D` represents a project, then only `B` is `A`'s direct dependency. -## External Import +### External Import An `import` statement that points to a package in a project other than the one in which it originates. For example, an `import` in package `github.com/foo/bar` will be considered an external import if it points to anything _other_ than stdlib or `github.com/foo/bar/*`. -## GPS +### GPS Stands for "Go packaging solver", it is [a subtree of library-style packages within dep](https://godoc.org/github.com/golang/dep/gps), and is the engine around which dep is built. Most commonly referred to as "gps." -## Local cache +### Local cache dep maintains its own, pristine set of upstream sources (so, generally, git repository clones). This is kept separate from `$GOPATH/src` so that there is no obligation to maintain disk state within `$GOPATH`, as dep frequently needs to change disk state in order to do its work. By default, the local cache lives at `$GOPATH/pkg/dep`. If you have multiple `$GOPATH` entries, dep will use whichever is the logical parent of the process' working directory. Alternatively, the location can be forced via the `DEPCACHEDIR` environment variable. -## Lock +### Lock A generic term, used across many language package managers, for the kind of information dep keeps in a `Gopkg.lock` file. -## Manifest +### Manifest A generic term, used across many language package managers, for the kind of information dep keeps in a `Gopkg.toml` file. -## Metadata Service +### Metadata Service An HTTP service that, when it receives an HTTP request containing a `go-get=1` in the query string, treats interprets the path portion of the request as an import path, and responds by embedding data in HTML `` tags that indicate the type and URL of of the underlying source root. This is the server-side component of dynamic [deduction](#deduction). @@ -88,15 +89,15 @@ The behavior of metadata services is defined in the [Go documentation on remote Variously referenced as "HTTP metadata service", "`go-get` HTTP metadata service", "`go-get` service", etc. -## Override +### Override An override is a [`[[override]]`](Gopkg.toml.md#override) stanza in `Gopkg.toml`. -## Project +### Project A project is a tree of Go packages. Projects cannot be nested. See [Project Root](#project-root) for more information about how the root of the tree is determined. -## Project Root +### Project Root The root import path for a project. A project root is defined as: @@ -107,26 +108,26 @@ These are generally one and the same, though not always. When using dep inside a This may also be referred to as the "import root" or "root import path." -## Solver +### Solver "The solver" is a reference to the domain-specific SAT solver contained in [gps](#gps). More detail can be found on its [reference page](the-solver.md). -## Source +### Source The remote entities that hold versioned code. Sources are specifically the entity containing the code, not any particular version of thecode itself. "Source" is used in lieu of "VCS" because Go package management tools will soon learn to use more than just VCS systems. -## Source Root +### Source Root The portion of an import path that corresponds to the network location of a source. This is similar to [Project Root](#project-root), but refers strictly to the second definition, network-oriented. -## Sync +### Sync Dep's interaction model is based around the idea of maintaining a well-defined relationship between your project's import statements and `Gopkg.toml`, and your project's `Gopkg.lock` - keeping them "in sync". When the `Gopkg.lock` has more or fewer entries than are necessary, or entries that are incompatible with constraint rules established in `Gopkg.toml`, your project is "out of sync". This concept is explored in detail on [the ensure mechanics reference page](ensure-mechanics.md#staying-in-sync). -## Transitive Dependency +### Transitive Dependency A project's transitive dependencies are those dependencies that it does not import itself, but are imported by one of its dependencies. If each letter in `A -> B -> C -> D` represents a project, then `C` and `D` are `A`'s transitive dependencies. \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000000..75171815b8 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,19 @@ +--- +title: Installation +--- + +It is strongly recommended that you use a released version of dep. While tip is never purposefully broken, its stability is not guaranteed. + +Pre-compiled binaries are available on the [releases](https://github.com/golang/dep/releases) page. On MacOS, you can also install or upgrade to the latest released version with Homebrew: + +```sh +$ brew install dep +$ brew upgrade dep +``` + +If you want to hack on dep, you can install via `go get`: + +```sh +go get -u github.com/golang/dep/cmd/dep +``` +Note that dep requires a functioning Go workspace and GOPATH. If you're unfamiliar with Go workspaces and GOPATH, have a look at [the language documentation](https://golang.org/doc/code.html#Organization) and get your local workspace set up. Dep's model could lead to being able to work without GOPATH, but we're not there yet. \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md index bd3c6995ad..c52d93473f 100644 --- a/docs/introduction.md +++ b/docs/introduction.md @@ -4,8 +4,8 @@ title: Getting Started --- -Welcome! This is documentation for dep, the "official experiment" dependency management tool for the Go language. Dep is a tool intended primarily for use by developers, to support the work of actually writing and shipping code. It is not intended for end users who are installing Go software - that's what `go get` does. +Welcome! This is documentation for dep, the "official experiment" dependency management tool for the Go language. Dep is a tool intended primarily for use by developers, to support the work of actually writing and shipping code. It is _not_ intended for end users who are installing Go software - that's what `go get` does. This site has both guides and reference documents. The guides are practical explanations of how to actually do things with dep, whereas the reference material provides deeper dives on specific topics. Of particular note is the [glossary](#glossary.md) - if you're unfamiliar with terminology used in this documentation, make sure to check there! -If you're trying dep for the first time, check out [Creating a New Project](new-project.md), or [Migrating to dep](migrating.md) if you have an existing Go project that you want to manage with dep. \ No newline at end of file +After [installing dep](installation.md), if you're using it for the first time, check out [Creating a New Project](new-project.md). Or, if you have an existing Go project that you want to convert to dep, [Migrating to Dep](migrating.md) is probably the place to start. \ No newline at end of file diff --git a/docs/migrating.md b/docs/migrating.md index bc6443170b..c48843b7d3 100644 --- a/docs/migrating.md +++ b/docs/migrating.md @@ -1,21 +1,21 @@ --- -title: Migrating to dep +title: Migrating to Dep --- Ideally, migrating an existing Go project to dep is straightforward: -``` +```bash $ cd $GOPATH/src/path/to/project/root $ dep init ``` -For many projects, this will just work. `dep init` will make educated guesses about what versions to use for your dependencies, generate sane `Gopkg.toml`, `Gopkg.lock`, and `vendor/`, and if your tests pass and builds work, then you're probably done. (Congratulations! You should check out [Daily Dep](daily-dep.md) next.) +For many projects, this will just work. `dep init` will make educated guesses about what versions to use for your dependencies, generate sane `Gopkg.toml`, `Gopkg.lock`, and `vendor/`, and if your tests pass and builds work, then you're probably done. (If so, congratulations! You should check out [Daily Dep](daily-dep.md) next.) The migration process is still difficult for some projects. If you're trying dep for the first time, this can be particularly frustrating, as you're trying to simultaneously learn how to use dep, and how your project *should* be managed in dep. The good news is, `dep init` is usually the big difficulty hump; once you're over it, things get much easier. The goal of this guide is to provide enough information for you to reason about what's happening during `dep init`, so that you can at least understand what class of problems you're encountering, and what steps you might take to address them. To that end, we'll start with an overview of what `dep init` is doing. -> Note: the first run of `dep init` can take quite a long time, as dep is creating fresh clones of all your dependencies into a special location, `$GOPATH/pkg/dep/sources/`. This is necessary for dep's normal operations, and is a one-time cost. +> Note: the first run of `dep init` can take quite a long time, as dep is creating fresh clones of all your dependencies into a special location, `$GOPATH/pkg/dep/sources/`. This is necessary for dep's normal operations, and is largely a one-time cost. ## `dep init` mechanics @@ -70,14 +70,13 @@ Because these are deep assumptions, their symptoms can be varied and surprising. - dep requires that all packages from a given project/repository be at the same version. - dep generally does not care about what's on your GOPATH; it deals exclusively with projects sourced from remote network locations. (Hint inference is the only exception to this; once solving begins, GOPATH - and any custom changes you've made to code therein - is ignored.) - dep generally prefers semantic versioning-tagged releases to branches (when not given any additional rules). This is a significant shift from the "default branch" model of `go get` and some other tools. It can result in dep making surprising choices for dependencies for which it could not infer a rule. +- dep assumes that all generated code exists, and has been committed to the source. A small number of projects that have reported being unable, thus far, to find a reasonable way of adapting to these requirements. If you can't figure out how to make your project fit, please file an issue - while dep necessarily cannot accommodate every single existing approach, it is dep's goal is define rules to which all Go projects can reasonably adapt. ### Hard failures -Hard failures involve actual - -All of these failure modes are covered extensively in the reference on [failure modes](failure-modes.md) +All of the hard failure modes are covered extensively in the reference on [failure modes](failure-modes.md). Because the solver, and all its possible failures, are the same for `dep init` as for `dep ensure`, there's a separate section for understanding and dealing with them: [dealing with solving failures](failure-modes.md#solving-failures). It can be trickier with `dep init`, however, as many remediations require tweaking `Gopkg.toml`. @@ -91,7 +90,7 @@ Soft failures are cases where `dep init` appears to exit cleanly, but a subseque If you do encounter problems like this, `dep status` is your first diagnostic step; it will report what versions were selected for all your dependencies. It may be clear which dependencies are a problem simply from your building or testing error messages. If not, compare the `dep status` list against the versions recorded by your previous tool to find the differences. -Once you've identified the problematic dependenc(ies), the next step is exerting appropriate controls over them via `Gopkg.toml`. (Note - this advice is intentionally terse; check out [Zen of Dep]() if you want a deeper understanding of how to optimally utilize dep's controls) +Once you've identified the problematic dependenc(ies), the next step is exerting appropriate controls over them via `Gopkg.toml`. For each of the following items, assume that you should run `dep ensure` after making the suggested change. If that fails, consult [dealing with solving failures](). diff --git a/docs/new-project.md b/docs/new-project.md index ce4ef8e435..63beb68b6c 100644 --- a/docs/new-project.md +++ b/docs/new-project.md @@ -2,9 +2,7 @@ title: Creating a New Project --- -First, we need a working Go workspace and GOPATH. If you're unfamiliar with Go workspaces and GOPATH, have a look at [the language documentation](https://golang.org/doc/code.html#Organization) and get your local workspace set up. (dep's model could eventually lead to being able to work without GOPATH, but we're not there yet.) - -Next, we need to pick a root directory for our project. This is primarily about picking the right root import path, and corresponding directory beneath `$GOPATH/src`, at which to situate your project. There are four basic possibilities: +Once you have [dep installed](installation.md), we need to pick a root directory for our project. This is primarily about picking the right root import path, and corresponding directory beneath `$GOPATH/src`, at which to situate your project. There are four basic possibilities: 1. A project that is now or eventually may be shared with or imported by other projects/people. In this case, pick the import path corresponding to the VCS root of its intended network location, e.g., `$GOPATH/src/github.com/golang/dep`. 2. An entirely local project - one that you have no intention of pushing to a central server (like GitHub). In this case, any subdirectory beneath `$GOPATH/src` will do. @@ -13,14 +11,14 @@ Next, we need to pick a root directory for our project. This is primarily about We'll assume the first case, as it's the most common. Create and move into the directory: -``` +```bash $ mkdir -p $GOPATH/src/github.com/me/example $ cd $GOPATH/src/github.com/me/example ``` Now, we'll initialize the project: -``` +```bash $ dep init $ ls Gopkg.toml Gopkg.lock vendor/ @@ -30,10 +28,10 @@ In a new project like this one, both files and the `vendor` directory will be ef This would also be a good time to set up a version control, such as [git](https://git-scm.com/). While dep in no way requires version control for your project, it can make inspecting the changes made by normal dep operations easier. Plus, it's basically best practice #1 of modern software development! -At this point, we're initialized and ready to start writing code! You can open up a `.go` file in an editor and start hacking away. Or, if you already know some projects you'll need, you can pre-populate your `vendor` directory with them: +At this point, our project is initialized, and we're ready to start writing code. You can open up a `.go` file in an editor and start hacking away. Or, if you already know some projects you'll need, you can pre-populate your `vendor` directory with them: -``` +```bash $ dep ensure -add github.com/foo/bar github.com/baz/quux ``` -Great, your project's all set up! You're ready to move on to [Daily Dep](daily-dep.md). \ No newline at end of file +Now you're ready to move on to [Daily Dep](daily-dep.md)! \ No newline at end of file From 430c48a3db41a84f0badec41b18da691a3c33efe Mon Sep 17 00:00:00 2001 From: sam boyer Date: Tue, 23 Jan 2018 09:55:06 -0500 Subject: [PATCH 10/13] docs: First pass on docusaurus --- website/.gitignore | 11 + website/blog/2018-01-23-announce-v0.4.0.md | 7 + website/core/Footer.js | 19 + website/i18n/en.json | 30 + website/package.json | 14 + website/pages/en/help.js | 43 + website/pages/en/index.js | 91 + website/pages/en/users.js | 40 + website/pages/en/versions.js | 88 + website/sidebars.json | 6 + website/siteConfig.js | 42 + website/static/css/custom.css | 16 + website/yarn.lock | 1741 ++++++++++++++++++++ 13 files changed, 2148 insertions(+) create mode 100644 website/.gitignore create mode 100644 website/blog/2018-01-23-announce-v0.4.0.md create mode 100644 website/core/Footer.js create mode 100644 website/i18n/en.json create mode 100644 website/package.json create mode 100755 website/pages/en/help.js create mode 100755 website/pages/en/index.js create mode 100644 website/pages/en/users.js create mode 100644 website/pages/en/versions.js create mode 100644 website/sidebars.json create mode 100644 website/siteConfig.js create mode 100644 website/static/css/custom.css create mode 100644 website/yarn.lock diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000000..aeedda9bfc --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,11 @@ +node_modules +.DS_Store +lib/core/metadata.js +lib/core/MetadataBlog.js +website/translated_docs +website/build/ +website/yarn.lock +website/node_modules + +website/i18n/* +!website/i18n/en.json diff --git a/website/blog/2018-01-23-announce-v0.4.0.md b/website/blog/2018-01-23-announce-v0.4.0.md new file mode 100644 index 0000000000..55528512d2 --- /dev/null +++ b/website/blog/2018-01-23-announce-v0.4.0.md @@ -0,0 +1,7 @@ +--- +title: Announcing dep v0.4.0 (with docs!) +author: sam boyer +authorURL: http://twitter.com/sdboyer +--- + +This blog post will test file name parsing issues when periods are present. diff --git a/website/core/Footer.js b/website/core/Footer.js new file mode 100644 index 0000000000..cc5efeb5c6 --- /dev/null +++ b/website/core/Footer.js @@ -0,0 +1,19 @@ +const React = require('react'); + +const siteConfig = require(process.cwd() + '/siteConfig.js'); + +class Footer extends React.Component { + render() { + const currentYear = new Date().getFullYear(); + return ( +