Skip to content

Commit

Permalink
docs: edits for git/path dependency sections rust-lang#9624
Browse files Browse the repository at this point in the history
* rephrasing for readability
* added more examples
* added sub-headings
* rearranged paragraphs for readability
  • Loading branch information
rimutaka committed Mar 5, 2024
1 parent 7bb7b53 commit 3349527
Showing 1 changed file with 117 additions and 53 deletions.
170 changes: 117 additions & 53 deletions src/doc/src/reference/specifying-dependencies.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ 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 following section.

## Version requirement syntax

Expand Down Expand Up @@ -158,16 +158,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].
Expand All @@ -183,69 +184,112 @@ 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, then looks for
`Cargo.toml` file for the requested crate anywhere inside the `git` repository.
For example, `cpp` and `cpp_common` are members of `rust-cpp` repo
and can be referred to by the repo's root URL (`https://github.com/mystor/rust-cpp`).

```toml
cpp = { git = "https://github.com/mystor/rust-cpp" }
cpp_common = { git = "https://github.com/mystor/rust-cpp" }
```

The above rule does not apply to local paths specified via `path` attribute.

#### Choice of commit

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`:
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", tag = "1.10.3" }

# a commit by its SHA1 hash
regex = { git = "https://github.com/rust-lang/regex", rev = "0c0990399270277832fbb5b91a1fa118e6f63dba" }

# HEAD commit of PR 493
regex = { git = "https://github.com/rust-lang/regex", 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 _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", 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
> ([dev-dependencies] are ignored). See the [Multiple
> 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

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/
$ 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
Expand All @@ -254,30 +298,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.

#### 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 `cpp` and `cpp_common` are members of a locally cloned `rust-cpp` 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]
cpp = { git = "https://github.com/mystor/rust-cpp" }
cpp_common = { git = "https://github.com/mystor/rust-cpp" }

# path key requires the member name to be included in the local path
[dependencies]
cpp = { path = "../rust-cpp/cpp" }
cpp_common = { path = "../rust-cpp/cpp_common" }
```

#### Local paths in published crates

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

Expand Down

0 comments on commit 3349527

Please sign in to comment.