diff --git a/src/doc/src/reference/specifying-dependencies.md b/src/doc/src/reference/specifying-dependencies.md index bdede1e1d32..9ef98e22a01 100644 --- a/src/doc/src/reference/specifying-dependencies.md +++ b/src/doc/src/reference/specifying-dependencies.md @@ -51,7 +51,9 @@ versions before 1.0.0. While SemVer says there is no compatibility before and `x > 0`. It is possible to further tweak the logic for selecting compatible versions -using special operators, though it shouldn't be necessary most of the time. +using special operators as described in the [Version requirement syntax](#version-requirement-syntax) section. + +Use the default version requirement strategy, e.g. `log = "1.2.3"` where possible to maximize compatibility. ## Version requirement syntax @@ -158,16 +160,17 @@ separated with a comma, e.g., `>= 1.2, < 1.5`. ## Specifying dependencies from other registries -To specify a dependency from a registry other than [crates.io], first the -registry must be configured in a `.cargo/config.toml` file. See the [registries -documentation] for more information. In the dependency, set the `registry` key -to the name of the registry to use. +To specify a dependency from a registry other than [crates.io] set the `registry` key +to the name of the registry to use: ```toml [dependencies] some-crate = { version = "1.0", registry = "my-registry" } ``` +where `my-registry` is the registry name configured in `.cargo/config.toml` file. +See the [registries documentation] for more information. + > **Note**: [crates.io] does not allow packages to be published with > dependencies on code published outside of [crates.io]. @@ -183,45 +186,87 @@ you need to specify is the location of the repository with the `git` key: regex = { git = "https://github.com/rust-lang/regex.git" } ``` -Cargo will fetch the `git` repository at this location then look for a -`Cargo.toml` for the requested crate anywhere inside the `git` repository -(not necessarily at the root --- for example, specifying a member crate name -of a workspace and setting `git` to the repository containing the workspace). +Cargo fetches the `git` repository at that location and traverses the file tree to find +`Cargo.toml` file for the requested crate anywhere inside the `git` repository. +For example, `regex-lite` and `regex-syntax` are members of `rust-lang/regex` repo +and can be referred to by the repo's root URL (`https://github.com/rust-lang/regex.git`) +regardless of where in the file tree they reside. + +```toml +regex-lite = { git = "https://github.com/rust-lang/regex.git" } +regex-syntax = { git = "https://github.com/rust-lang/regex.git" } +``` + +The above rule does not apply to [`path` dependencies](#specifying-path-dependencies). -Since we haven’t specified any other information, Cargo assumes that -we intend to use the latest commit on the default branch to build -our package, which may not necessarily be the main branch. -You can combine the `git` key with the `rev`, `tag`, or `branch` keys to -specify something else. Here's an example of specifying that you want to use -the latest commit on a branch named `next`: +### Choice of commit + +Cargo assumes that we intend to use the latest commit on the default branch to build +our package if we only specify the repo URL, as in the examples above. + +You can combine the `git` key with the `rev`, `tag`, or `branch` keys to be more specific about +which commit to use. Here's an example of using the latest commit on a branch named `next`: ```toml [dependencies] regex = { git = "https://github.com/rust-lang/regex.git", branch = "next" } ``` -Anything that is not a branch or tag falls under `rev`. This can be a commit +Anything that is not a branch or a tag falls under `rev` key. This can be a commit hash like `rev = "4c59b707"`, or a named reference exposed by the remote -repository such as `rev = "refs/pull/493/head"`. What references are available -varies by where the repo is hosted; GitHub in particular exposes a reference to -the most recent commit of every pull request as shown, but other git hosts often -provide something equivalent, possibly under a different naming scheme. - -Once a `git` dependency has been added, Cargo will lock that dependency to the -latest commit at the time. New commits will not be pulled down automatically -once the lock is in place. However, they can be pulled down manually with -`cargo update`. - -See [Git Authentication] for help with git authentication for private repos. - -> **Note**: Neither the `git` key nor the `path` key changes the meaning of the -> `version` key: the `version` key always implies that the package is available -> in a registry. `version`, `git`, and `path` keys are considered [separate -> locations](#multiple-locations) for resolving the dependency. -> -> When the dependency is retrieved from `git`, the `version` key will _not_ -> affect which commit is used, but the version information in the dependency's -> `Cargo.toml` file will still be validated against the `version` requirement. +repository such as `rev = "refs/pull/493/head"`. + +What references are available for the `rev` key varies by where the repo is hosted. +GitHub exposes a reference to the most recent commit of every pull request as in the example above. +Other git hosts may provide something equivalent under a different naming scheme. + +**More `git` dependency examples:** + +```toml +# .git suffix can be omitted if the host accepts such URLs - both examples work the same +regex = { git = "https://github.com/rust-lang/regex" } +regex = { git = "https://github.com/rust-lang/regex.git" } + +# a commit with a particular tag +regex = { git = "https://github.com/rust-lang/regex.git", tag = "1.10.3" } + +# a commit by its SHA1 hash +regex = { git = "https://github.com/rust-lang/regex.git", rev = "0c0990399270277832fbb5b91a1fa118e6f63dba" } + +# HEAD commit of PR 493 +regex = { git = "https://github.com/rust-lang/regex.git", rev = "refs/pull/493/head" } + +# INVALID EXAMPLES + +# specifying the commit after # ignores the commit ID and generates a warning +regex = { git = "https://github.com/rust-lang/regex.git#4c59b70" } + +# git and path cannot be used at the same time +regex = { git = "https://github.com/rust-lang/regex.git#4c59b70", path = "../regex" } +``` + +Cargo locks the commits of `git` dependencies in `Cargo.lock` file at the time of their addition +and checks for updates only when you run `cargo update` command. + +### The role of the `version` key + +The `version` key always implies that the package is available in a registry, +regardless of the presence of `git` or `path` keys. + +The `version` key does _not_ affect which commit is used when Cargo retrieves the `git` dependency, +but Cargo checks the version information in the dependency's `Cargo.toml` file +against the `version` key and raises an error if the check fails. + +In this example, Cargo retrieves the HEAD commit of the branch called `next` from Git and checks if the crate's version +is compatible with `version = "1.10.3"`: + +```toml +[dependencies] +regex = { version = "1.10.3", git = "https://github.com/rust-lang/regex.git", branch = "next" } +``` + +`version`, `git`, and `path` keys are considered separate locations for resolving the dependency. +See [Multiple locations](#multiple-locations) section below for detailed explanations. > **Note**: [crates.io] does not allow packages to be published with > dependencies on code published outside of [crates.io] itself @@ -229,7 +274,9 @@ See [Git Authentication] for help with git authentication for private repos. > locations](#multiple-locations) section for a fallback alternative for `git` > and `path` dependencies. -[Git Authentication]: ../appendix/git-authentication.md +### Accessing private Git repositories + +See [Git Authentication](../appendix/git-authentication.md) for help with Git authentication for private repos. ## Specifying path dependencies @@ -237,7 +284,7 @@ Over time, our `hello_world` package from [the guide](../guide/index.md) has grown significantly in size! It’s gotten to the point that we probably want to split out a separate crate for others to use. To do this Cargo supports **path dependencies** which are typically sub-crates that live within one repository. -Let’s start off by making a new crate inside of our `hello_world` package: +Let’s start by making a new crate inside of our `hello_world` package: ```console # inside of hello_world/ @@ -245,7 +292,7 @@ $ cargo new hello_utils ``` This will create a new folder `hello_utils` inside of which a `Cargo.toml` and -`src` folder are ready to be configured. In order to tell Cargo about this, open +`src` folder are ready to be configured. To tell Cargo about this, open up `hello_world/Cargo.toml` and add `hello_utils` to your dependencies: ```toml @@ -254,30 +301,50 @@ hello_utils = { path = "hello_utils" } ``` This tells Cargo that we depend on a crate called `hello_utils` which is found -in the `hello_utils` folder (relative to the `Cargo.toml` it’s written in). +in the `hello_utils` folder, relative to the `Cargo.toml` file it’s written in. + +The next `cargo build` will automatically build `hello_utils` and +all of its dependencies. -And that’s it! The next `cargo build` will automatically build `hello_utils` and -all of its own dependencies, and others can also start using the crate as well. -However, crates that use dependencies specified with only a path are not -permitted on [crates.io]. If we wanted to publish our `hello_world` crate, we -would need to publish a version of `hello_utils` to [crates.io] -and specify its version in the dependencies line as well: +### No local path traversal + +The local paths must point to the exact folder with the dependency's `Cargo.toml`. +Unlike with `git` dependencies, Cargo does not traverse local paths. +For example, if `regex-lite` and `regex-syntax` are members of a +locally cloned `rust-lang/regex` repo, they have to be referred to by the full path: + +```toml +# git key accepts the repo root URL and Cargo traverses the tree to find the crate +[dependencies] +regex-lite = { git = "https://github.com/rust-lang/regex.git" } +regex-syntax = { git = "https://github.com/rust-lang/regex.git" } + +# path key requires the member name to be included in the local path +[dependencies] +regex-lite = { path = "../regex/regex-lite" } +regex-syntax = { path = "../regex/regex-syntax" } +``` + +### Local paths in published crates + +Crates that use dependencies specified with only a path are not +permitted on [crates.io]. + +If we wanted to publish our `hello_world` crate, +we would need to publish a version of `hello_utils` to [crates.io] as a separate crate +and specify its version in the dependencies line of `hello_world`: ```toml [dependencies] hello_utils = { path = "hello_utils", version = "0.1.0" } ``` -> **Note**: Neither the `git` key nor the `path` key changes the meaning of the -> `version` key: the `version` key always implies that the package is available -> in a registry. `version`, `git`, and `path` keys are considered [separate -> locations](#multiple-locations) for resolving the dependency. +The use of `path` and `version` keys together is explained in the [Multiple locations](#multiple-locations) section. > **Note**: [crates.io] does not allow packages to be published with -> dependencies on code published outside of [crates.io] itself -> ([dev-dependencies] are ignored). See the [Multiple -> locations](#multiple-locations) section for a fallback alternative for `git` -> and `path` dependencies. +> dependencies on code outside of [crates.io], except for [dev-dependencies]. +> See the [Multiple locations](#multiple-locations) section +> for a fallback alternative for `git` and `path` dependencies. ## Multiple locations