## Package ID Specifications

### Package ID specifications

Subcommands of Cargo frequently need to refer to a particular package within a
dependency graph for various operations like updating, cleaning, building, etc.
To solve this problem, Cargo supports Package ID Specifications. A specification
is a string which is used to uniquely refer to one package within a graph of
packages.

#### Specification grammar

The formal grammar for a Package Id Specification is:

```notrust
pkgid := pkgname
       | [ proto "://" ] hostname-and-path [ "#" ( pkgname | semver ) ]
pkgname := name [ ":" semver ]

proto := "http" | "git" | ...
```

Here, brackets indicate that the contents are optional.

#### Example specifications

These could all be references to a package `foo` version `1.2.3` from the
registry at `crates.io`

| pkgid                        | name  | version | url                    |
|:-----------------------------|:-----:|:-------:|:----------------------:|
| `foo`                        | `foo` | `*`     | `*`                    |
| `foo:1.2.3`                  | `foo` | `1.2.3` | `*`                    |
| `crates.io/foo`              | `foo` | `*`     | `*://crates.io/foo`    |
| `crates.io/foo#1.2.3`        | `foo` | `1.2.3` | `*://crates.io/foo`    |
| `crates.io/bar#foo:1.2.3`    | `foo` | `1.2.3` | `*://crates.io/bar`    |
| `https://crates.io/foo#1.2.3`| `foo` | `1.2.3` | `https://crates.io/foo` |

#### Brevity of specifications

The goal of this is to enable both succinct and exhaustive syntaxes for
referring to packages in a dependency graph. Ambiguous references may refer to
one or more packages. Most commands generate an error if more than one package
could be referred to with the same specification.
