Skip to content

Commit

Permalink
Stabilize publish-lockfile.
Browse files Browse the repository at this point in the history
  • Loading branch information
ehuss committed Jun 10, 2019
1 parent 28adaba commit 34307c6
Show file tree
Hide file tree
Showing 20 changed files with 270 additions and 218 deletions.
15 changes: 8 additions & 7 deletions src/bin/cargo/commands/install.rs
Expand Up @@ -68,15 +68,16 @@ pub fn cli() -> App {
)
.after_help(
"\
This command manages Cargo's local set of installed binary crates. Only packages
which have [[bin]] targets can be installed, and all binaries are installed into
the installation root's `bin` folder. The installation root is determined, in
order of precedence, by `--root`, `$CARGO_INSTALL_ROOT`, the `install.root`
configuration key, and finally the home directory (which is either
`$CARGO_HOME` if set or `$HOME/.cargo` by default).
This command manages Cargo's local set of installed binary crates. Only
packages which have executable [[bin]] or [[example]] targets can be
installed, and all executables are installed into the installation root's
`bin` folder. The installation root is determined, in order of precedence, by
`--root`, `$CARGO_INSTALL_ROOT`, the `install.root` configuration key, and
finally the home directory (which is either `$CARGO_HOME` if set or
`$HOME/.cargo` by default).
There are multiple sources from which a crate can be installed. The default
location is crates.io but the `--git`, `--path`, and `registry` flags can
location is crates.io but the `--git`, `--path`, and `--registry` flags can
change this source. If the source contains more than one package (such as
crates.io or a git repository with multiple crates) the `<crate>` argument is
required to indicate which crate should be installed.
Expand Down
1 change: 1 addition & 0 deletions src/cargo/core/features.rs
Expand Up @@ -186,6 +186,7 @@ features! {
[stable] rename_dependency: bool,

// Whether a lock file is published with this crate
// This is deprecated, and will likely be removed in a future version.
[unstable] publish_lockfile: bool,

// Overriding profiles for dependencies.
Expand Down
3 changes: 0 additions & 3 deletions src/cargo/core/manifest.rs
Expand Up @@ -478,9 +478,6 @@ impl Manifest {
pub fn publish(&self) -> &Option<Vec<String>> {
&self.publish
}
pub fn publish_lockfile(&self) -> bool {
self.publish_lockfile
}
pub fn replace(&self) -> &[(PackageIdSpec, Dependency)] {
&self.replace
}
Expand Down
3 changes: 1 addition & 2 deletions src/cargo/core/package.rs
Expand Up @@ -240,8 +240,7 @@ impl Package {

/// Returns if package should include `Cargo.lock`.
pub fn include_lockfile(&self) -> bool {
self.manifest().publish_lockfile()
&& self.targets().iter().any(|t| t.is_example() || t.is_bin())
self.targets().iter().any(|t| t.is_example() || t.is_bin())
}
}

Expand Down
10 changes: 7 additions & 3 deletions src/cargo/ops/cargo_package.rs
Expand Up @@ -42,8 +42,12 @@ pub struct PackageOpts<'cfg> {
static VCS_INFO_FILE: &'static str = ".cargo_vcs_info.json";

pub fn package(ws: &Workspace<'_>, opts: &PackageOpts<'_>) -> CargoResult<Option<FileLock>> {
// Make sure the Cargo.lock is up-to-date and valid.
ops::resolve_ws(ws)?;
if ws.root().join("Cargo.lock").exists() {
// Make sure the Cargo.lock is up-to-date and valid.
ops::resolve_ws(ws)?;
// If Cargo.lock does not exist, it will be generated by `build_lock`
// below, and will be validated during the verification step.
}
let pkg = ws.current()?;
let config = ws.config();

Expand Down Expand Up @@ -615,7 +619,7 @@ fn run_verify(ws: &Workspace<'_>, tar: &FileLock, opts: &PackageOpts<'_>) -> Car
};

let exec: Arc<dyn Executor> = Arc::new(DefaultExecutor);
ops::compile_ws(
ops::compile_with_exec(
&ws,
&ops::CompileOptions {
config,
Expand Down
5 changes: 5 additions & 0 deletions src/cargo/util/toml/mod.rs
Expand Up @@ -1034,6 +1034,11 @@ impl TomlManifest {
let publish_lockfile = match project.publish_lockfile {
Some(b) => {
features.require(Feature::publish_lockfile())?;
warnings.push(
"The `publish-lockfile` feature is deprecated and currently \
has no effect. It may be removed in a future version."
.to_string(),
);
b
}
None => features.is_enabled(Feature::publish_lockfile()),
Expand Down
23 changes: 19 additions & 4 deletions src/doc/man/cargo-install.adoc
Expand Up @@ -17,14 +17,15 @@ cargo-install - Build and install a Rust binary

== DESCRIPTION

This command manages Cargo's local set of installed binary crates. Only packages
which have `\[[bin]]` targets can be installed, and all binaries are installed into
the installation root's `bin` folder.
This command manages Cargo's local set of installed binary crates. Only
packages which have executable `\[[bin]]` or `\[[example]]` targets can be
installed, and all executables are installed into the installation root's
`bin` folder.

include::description-install-root.adoc[]

There are multiple sources from which a crate can be installed. The default
location is crates.io but the `--git`, `--path`, and `registry` flags can
location is crates.io but the `--git`, `--path`, and `--registry` flags can
change this source. If the source contains more than one package (such as
crates.io or a git repository with multiple crates) the _CRATE_ argument is
required to indicate which crate should be installed.
Expand All @@ -42,6 +43,20 @@ specified by setting the `CARGO_TARGET_DIR` environment variable to a relative
path. In particular, this can be useful for caching build artifacts on
continuous integration systems.

By default, the `Cargo.lock` file that is included with the package will be
ignored. This means that Cargo will recompute which versions of dependencies
to use, possibly using newer versions that have been released since the
package was published. The `--locked` flag can be used to force Cargo to use
the packaged `Cargo.lock` file if it is available. This may be useful for
ensuring reproducible builds, to use the exact same set of dependencies that
were available when the package was published. It may also be useful if a
newer version of a dependency is published that no longer builds on your
system, or has other problems. The downside to using `--locked` is that you
will not receive any fixes or updates to any dependency. Note that Cargo did
not start publishing `Cargo.lock` files until version 1.37, which means
packages published with prior versions will not have a `Cargo.lock` file
available.

== OPTIONS

=== Install Options
Expand Down
3 changes: 3 additions & 0 deletions src/doc/man/cargo-package.adoc
Expand Up @@ -25,6 +25,9 @@ steps:
- The original `Cargo.toml` file is rewritten and normalized.
- `[patch]`, `[replace]`, and `[workspace]` sections are removed from the
manifest.
- `Cargo.lock` is automatically included if the package contains an
executable binary or example target. man:cargo-install[1] will use the
packaged lock file if the `--locked` flag is used.
- A `.cargo_vcs_info.json` file is included that contains information
about the current VCS checkout hash if available (not included with
`--allow-dirty`).
Expand Down
24 changes: 20 additions & 4 deletions src/doc/man/generated/cargo-install.html
Expand Up @@ -17,9 +17,10 @@ <h2 id="cargo_install_synopsis">SYNOPSIS</h2>
<h2 id="cargo_install_description">DESCRIPTION</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This command manages Cargo&#8217;s local set of installed binary crates. Only packages
which have <code>[[bin]]</code> targets can be installed, and all binaries are installed into
the installation root&#8217;s <code>bin</code> folder.</p>
<p>This command manages Cargo&#8217;s local set of installed binary crates. Only
packages which have executable <code>[[bin]]</code> or <code>[[example]]</code> targets can be
installed, and all executables are installed into the installation root&#8217;s
<code>bin</code> folder.</p>
</div>
<div class="paragraph">
<p>The installation root is determined, in order of precedence:</p>
Expand All @@ -45,7 +46,7 @@ <h2 id="cargo_install_description">DESCRIPTION</h2>
</div>
<div class="paragraph">
<p>There are multiple sources from which a crate can be installed. The default
location is crates.io but the <code>--git</code>, <code>--path</code>, and <code>registry</code> flags can
location is crates.io but the <code>--git</code>, <code>--path</code>, and <code>--registry</code> flags can
change this source. If the source contains more than one package (such as
crates.io or a git repository with multiple crates) the <em>CRATE</em> argument is
required to indicate which crate should be installed.</p>
Expand All @@ -65,6 +66,21 @@ <h2 id="cargo_install_description">DESCRIPTION</h2>
path. In particular, this can be useful for caching build artifacts on
continuous integration systems.</p>
</div>
<div class="paragraph">
<p>By default, the <code>Cargo.lock</code> file that is included with the package will be
ignored. This means that Cargo will recompute which versions of dependencies
to use, possibly using newer versions that have been released since the
package was published. The <code>--locked</code> flag can be used to force Cargo to use
the packaged <code>Cargo.lock</code> file if it is available. This may be useful for
ensuring reproducible builds, to use the exact same set of dependencies that
were available when the package was published. It may also be useful if a
newer version of a dependency is published that no longer builds on your
system, or has other problems. The downside to using <code>--locked</code> is that you
will not receive any fixes or updates to any dependency. Note that Cargo did
not start publishing <code>Cargo.lock</code> files until version 1.37, which means
packages published with prior versions will not have a <code>Cargo.lock</code> file
available.</p>
</div>
</div>
</div>
<div class="sect1">
Expand Down
5 changes: 5 additions & 0 deletions src/doc/man/generated/cargo-package.html
Expand Up @@ -44,6 +44,11 @@ <h2 id="cargo_package_description">DESCRIPTION</h2>
manifest.</p>
</li>
<li>
<p><code>Cargo.lock</code> is automatically included if the package contains an
executable binary or example target. <a href="commands/cargo-install.html">cargo-install(1)</a> will use the
packaged lock file if the <code>--locked</code> flag is used.</p>
</li>
<li>
<p>A <code>.cargo_vcs_info.json</code> file is included that contains information
about the current VCS checkout hash if available (not included with
<code>--allow-dirty</code>).</p>
Expand Down
109 changes: 68 additions & 41 deletions src/doc/src/reference/publishing.md
Expand Up @@ -13,50 +13,79 @@ limit to the number of versions which can be published, however.
First thing’s first, you’ll need an account on [crates.io] to acquire
an API token. To do so, [visit the home page][crates.io] and log in via a GitHub
account (required for now). After this, visit your [Account
Settings](https://crates.io/me) page and run the `cargo login` command
Settings](https://crates.io/me) page and run the [`cargo login`] command
specified.

```console
$ cargo login abcdefghijklmnopqrstuvwxyz012345
```

This command will inform Cargo of your API token and store it locally in your
`~/.cargo/credentials` (previously it was `~/.cargo/config`). Note that this
token is a **secret** and should not be shared with anyone else. If it leaks for
any reason, you should regenerate it immediately.
`~/.cargo/credentials`. Note that this token is a **secret** and should not be
shared with anyone else. If it leaks for any reason, you should regenerate it
immediately.

### Before publishing a new crate

Keep in mind that crate names on [crates.io] are allocated on a first-come-first-
serve basis. Once a crate name is taken, it cannot be used for another crate.

Check out the [metadata you can
specify](reference/manifest.html#package-metadata) in `Cargo.toml` to ensure
your crate can be discovered more easily! Before publishing, make sure you have
filled out the following fields:

- `authors`
- `license` or `license-file`
- `description`
- `homepage`
- `documentation`
- `repository`

It would also be a good idea to include some `keywords` and `categories`,
though they are not required.

If you are publishing a library, you may also want to consult the [Rust API
Guidelines].

#### Packaging a crate

The next step is to package up your crate into a format that can be uploaded to
[crates.io]. For this we’ll use the `cargo package` subcommand. This will take
our entire crate and package it all up into a `*.crate` file in the
`target/package` directory.
The next step is to package up your crate and upload it to [crates.io]. For
this we’ll use the [`cargo publish`] subcommand. This command performs the following
steps:

1. Perform some verification checks on your package.
2. Compress your source code into a `.crate` file.
3. Extract the `.crate` file into a temporary directory and verify that it
compiles.
4. Upload the `.crate` file to [crates.io].
5. The registry will perform some additional checks on the uploaded package
before adding it.

It is recommended that you first run `cargo publish --dry-run` (or [`cargo
package`] which is equivalent) to ensure there aren't any warnings or errors
before publishing. This will perform the first three steps listed above.

```console
$ cargo package
$ cargo publish --dry-run
```

As an added bonus, the `*.crate` will be verified independently of the current
source tree. After the `*.crate` is created, it’s unpacked into
`target/package` and then built from scratch to ensure that all necessary files
are there for the build to succeed. This behavior can be disabled with the
`--no-verify` flag.
You can inspect the generated `.crate` file in the `target/package` directory.
[crates.io] currently has a 10MB size limit on the `.crate` file. You may want
to check the size of the `.crate` file to ensure you didn't accidentally
package up large assets that are not required to build your package, such as
test data, website documentation, or code generation. You can check which
files are included with the following command:

Now’s a good time to take a look at the `*.crate` file to make sure you didn’t
accidentally package up that 2GB video asset, or large data files used for code
generation, integration tests, or benchmarking. There is currently a 10MB
upload size limit on `*.crate` files. So, if the size of `tests` and `benches`
directories and their dependencies are up to a couple of MBs, you can keep them
in your package; otherwise, better to exclude them.
```console
$ cargo package --list
```

Cargo will automatically ignore files ignored by your version control system
when packaging, but if you want to specify an extra set of files to ignore you
can use the `exclude` key in the manifest:
can use the [`exclude`
key](reference/manifest.html#the-exclude-and-include-fields-optional) in the
manifest:

```toml
[package]
Expand All @@ -67,10 +96,8 @@ exclude = [
]
```

The syntax of each element in this array is what
[rust-lang/glob](https://github.com/rust-lang/glob) accepts. If you’d rather
roll with a whitelist instead of a blacklist, Cargo also supports an `include`
key, which if set, overrides the `exclude` key:
If you’d rather explicitly list the files to include, Cargo also supports an
`include` key, which if set, overrides the `exclude` key:

```toml
[package]
Expand All @@ -83,28 +110,22 @@ include = [

### Uploading the crate

Now that we’ve got a `*.crate` file ready to go, it can be uploaded to
[crates.io] with the `cargo publish` command. And that’s it, you’ve now published
your first crate!
When you are ready to publish, use the [`cargo publish`] command
to upload to [crates.io]:

```console
$ cargo publish
```

If you’d like to skip the `cargo package` step, the `cargo publish` subcommand
will automatically package up the local crate if a copy isn’t found already.

Be sure to check out the [metadata you can
specify](reference/manifest.html#package-metadata) to ensure your crate can be
discovered more easily!
And that’s it, you’ve now published your first crate!

### Publishing a new version of an existing crate

In order to release a new version, change the `version` value specified in your
`Cargo.toml` manifest. Keep in mind [the semver
rules](reference/manifest.html#the-version-field). Then optionally run `cargo package` if
you want to inspect the `*.crate` file for the new version before publishing,
and run `cargo publish` to upload the new version.
In order to release a new version, change the `version` value specified in
your `Cargo.toml` manifest. Keep in mind [the semver
rules](reference/manifest.html#the-version-field), and consult [RFC 1105] for
what constitutes a semver-breaking change. Then run [`cargo publish`] as
described above to upload the new version.

### Managing a crates.io-based crate

Expand Down Expand Up @@ -176,7 +197,7 @@ is likely for you to encounter the following message when working with them:
> It looks like you don’t have permission to query a necessary property from
GitHub to complete this request. You may need to re-authenticate on [crates.io]
to grant permission to read GitHub org memberships. Just go to
https://crates.io/login
<https://crates.io/login>.

This is basically a catch-all for “you tried to query a team, and one of the
five levels of membership access control denied this”. That is not an
Expand All @@ -195,7 +216,7 @@ you will get the error above. You may also see this error if you ever try to
publish a crate that you don’t own at all, but otherwise happens to have a team.

If you ever change your mind, or just aren’t sure if [crates.io] has sufficient
permission, you can always go to https://crates.io/login, which will prompt you
permission, you can always go to <https://crates.io/login>, which will prompt you
for permission if [crates.io] doesn’t have all the scopes it would like to.

An additional barrier to querying GitHub is that the organization may be
Expand All @@ -218,5 +239,11 @@ the “Grant Access” button next to its name:

![Authentication Access Control](images/auth-level-acl.png)

[RFC 1105]: https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md
[Rust API Guidelines]: https://rust-lang-nursery.github.io/api-guidelines/
[`cargo login`]: commands/cargo-login.html
[`cargo package`]: commands/cargo-package.html
[`cargo publish`]: commands/cargo-publish.html
[crates.io]: https://crates.io/
[oauth-scopes]: https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/

0 comments on commit 34307c6

Please sign in to comment.