mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-28 11:20:36 +00:00
Stabilize default-run
This commit is contained in:
parent
142603ae22
commit
7d7fe6797a
@ -10,7 +10,7 @@ use std::fs;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use cargo::core::shell::Shell;
|
use cargo::core::shell::Shell;
|
||||||
use cargo::util::{self, command_prelude, lev_distance, CargoResult, CliResult, Config};
|
use cargo::util::{self, closest_msg, command_prelude, CargoResult, CliResult, Config};
|
||||||
use cargo::util::{CliError, ProcessError};
|
use cargo::util::{CliError, ProcessError};
|
||||||
|
|
||||||
mod cli;
|
mod cli;
|
||||||
@ -113,18 +113,6 @@ fn list_commands(config: &Config) -> BTreeSet<CommandInfo> {
|
|||||||
commands
|
commands
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_closest(config: &Config, cmd: &str) -> Option<String> {
|
|
||||||
let cmds = list_commands(config);
|
|
||||||
// Only consider candidates with a lev_distance of 3 or less so we don't
|
|
||||||
// suggest out-of-the-blue options.
|
|
||||||
cmds.into_iter()
|
|
||||||
.map(|c| c.name())
|
|
||||||
.map(|c| (lev_distance(&c, cmd), c))
|
|
||||||
.filter(|&(d, _)| d < 4)
|
|
||||||
.min_by_key(|a| a.0)
|
|
||||||
.map(|slot| slot.1)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&str]) -> CliResult {
|
fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&str]) -> CliResult {
|
||||||
let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
|
let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
|
||||||
let path = search_directories(config)
|
let path = search_directories(config)
|
||||||
@ -134,14 +122,9 @@ fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&str]) -> Cli
|
|||||||
let command = match path {
|
let command = match path {
|
||||||
Some(command) => command,
|
Some(command) => command,
|
||||||
None => {
|
None => {
|
||||||
let err = match find_closest(config, cmd) {
|
let cmds = list_commands(config);
|
||||||
Some(closest) => failure::format_err!(
|
let did_you_mean = closest_msg(cmd, cmds.iter(), |c| c.name());
|
||||||
"no such subcommand: `{}`\n\n\tDid you mean `{}`?\n",
|
let err = failure::format_err!("no such subcommand: `{}`{}", cmd, did_you_mean);
|
||||||
cmd,
|
|
||||||
closest
|
|
||||||
),
|
|
||||||
None => failure::format_err!("no such subcommand: `{}`", cmd),
|
|
||||||
};
|
|
||||||
return Err(CliError::new(err, 101));
|
return Err(CliError::new(err, 101));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -196,7 +196,7 @@ features! {
|
|||||||
[unstable] namespaced_features: bool,
|
[unstable] namespaced_features: bool,
|
||||||
|
|
||||||
// "default-run" manifest option,
|
// "default-run" manifest option,
|
||||||
[unstable] default_run: bool,
|
[stable] default_run: bool,
|
||||||
|
|
||||||
// Declarative build scripts.
|
// Declarative build scripts.
|
||||||
[unstable] metabuild: bool,
|
[unstable] metabuild: bool,
|
||||||
|
@ -518,12 +518,6 @@ impl Manifest {
|
|||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.default_run.is_some() {
|
|
||||||
self.features
|
|
||||||
.require(Feature::default_run())
|
|
||||||
.chain_err(|| failure::format_err!("the `default-run` manifest key is unstable"))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ use crate::ops;
|
|||||||
use crate::util::config::PackageCacheLock;
|
use crate::util::config::PackageCacheLock;
|
||||||
use crate::util::errors::{CargoResult, CargoResultExt, HttpNot200};
|
use crate::util::errors::{CargoResult, CargoResultExt, HttpNot200};
|
||||||
use crate::util::network::Retry;
|
use crate::util::network::Retry;
|
||||||
use crate::util::{self, internal, lev_distance, Config, Progress, ProgressStyle};
|
use crate::util::{self, internal, Config, Progress, ProgressStyle};
|
||||||
|
|
||||||
/// Information about a package that is available somewhere in the file system.
|
/// Information about a package that is available somewhere in the file system.
|
||||||
///
|
///
|
||||||
@ -193,21 +193,6 @@ impl Package {
|
|||||||
self.targets().iter().any(|t| t.is_custom_build())
|
self.targets().iter().any(|t| t.is_custom_build())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_closest_target(
|
|
||||||
&self,
|
|
||||||
target: &str,
|
|
||||||
is_expected_kind: fn(&Target) -> bool,
|
|
||||||
) -> Option<&Target> {
|
|
||||||
let targets = self.targets();
|
|
||||||
|
|
||||||
let matches = targets
|
|
||||||
.iter()
|
|
||||||
.filter(|t| is_expected_kind(t))
|
|
||||||
.map(|t| (lev_distance(target, t.name()), t))
|
|
||||||
.filter(|&(d, _)| d < 4);
|
|
||||||
matches.min_by_key(|t| t.0).map(|t| t.1)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_source(self, to_replace: SourceId, replace_with: SourceId) -> Package {
|
pub fn map_source(self, to_replace: SourceId, replace_with: SourceId) -> Package {
|
||||||
Package {
|
Package {
|
||||||
manifest: self.manifest.map_source(to_replace, replace_with),
|
manifest: self.manifest.map_source(to_replace, replace_with),
|
||||||
|
@ -7,9 +7,8 @@ use crate::core::compiler::CompileMode;
|
|||||||
use crate::core::interning::InternedString;
|
use crate::core::interning::InternedString;
|
||||||
use crate::core::{Features, PackageId, PackageIdSpec, PackageSet, Shell};
|
use crate::core::{Features, PackageId, PackageIdSpec, PackageSet, Shell};
|
||||||
use crate::util::errors::CargoResultExt;
|
use crate::util::errors::CargoResultExt;
|
||||||
use crate::util::lev_distance::lev_distance;
|
|
||||||
use crate::util::toml::{ProfilePackageSpec, StringOrBool, TomlProfile, TomlProfiles, U32OrBool};
|
use crate::util::toml::{ProfilePackageSpec, StringOrBool, TomlProfile, TomlProfiles, U32OrBool};
|
||||||
use crate::util::{CargoResult, Config};
|
use crate::util::{closest_msg, CargoResult, Config};
|
||||||
|
|
||||||
/// Collection of all user profiles.
|
/// Collection of all user profiles.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@ -290,23 +289,12 @@ impl ProfileMaker {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
if name_matches.is_empty() {
|
if name_matches.is_empty() {
|
||||||
let suggestion = packages
|
let suggestion =
|
||||||
.package_ids()
|
closest_msg(&spec.name(), packages.package_ids(), |p| p.name().as_str());
|
||||||
.map(|p| (lev_distance(&*spec.name(), &p.name()), p.name()))
|
shell.warn(format!(
|
||||||
.filter(|&(d, _)| d < 4)
|
"profile override spec `{}` did not match any packages{}",
|
||||||
.min_by_key(|p| p.0)
|
spec, suggestion
|
||||||
.map(|p| p.1);
|
))?;
|
||||||
match suggestion {
|
|
||||||
Some(p) => shell.warn(format!(
|
|
||||||
"profile override spec `{}` did not match any packages\n\n\
|
|
||||||
Did you mean `{}`?",
|
|
||||||
spec, p
|
|
||||||
))?,
|
|
||||||
None => shell.warn(format!(
|
|
||||||
"profile override spec `{}` did not match any packages",
|
|
||||||
spec
|
|
||||||
))?,
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
shell.warn(format!(
|
shell.warn(format!(
|
||||||
"version or URL in profile override spec `{}` does not \
|
"version or URL in profile override spec `{}` does not \
|
||||||
|
@ -35,7 +35,7 @@ use crate::core::{Package, Target};
|
|||||||
use crate::core::{PackageId, PackageIdSpec, TargetKind, Workspace};
|
use crate::core::{PackageId, PackageIdSpec, TargetKind, Workspace};
|
||||||
use crate::ops;
|
use crate::ops;
|
||||||
use crate::util::config::Config;
|
use crate::util::config::Config;
|
||||||
use crate::util::{lev_distance, profile, CargoResult};
|
use crate::util::{closest_msg, profile, CargoResult};
|
||||||
|
|
||||||
/// Contains information about how a package should be compiled.
|
/// Contains information about how a package should be compiled.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -906,26 +906,18 @@ fn find_named_targets<'a>(
|
|||||||
let filter = |t: &Target| t.name() == target_name && is_expected_kind(t);
|
let filter = |t: &Target| t.name() == target_name && is_expected_kind(t);
|
||||||
let proposals = filter_targets(packages, filter, true, mode);
|
let proposals = filter_targets(packages, filter, true, mode);
|
||||||
if proposals.is_empty() {
|
if proposals.is_empty() {
|
||||||
let suggestion = packages
|
let targets = packages.iter().flat_map(|pkg| {
|
||||||
.iter()
|
pkg.targets()
|
||||||
.flat_map(|pkg| {
|
.iter()
|
||||||
pkg.targets()
|
.filter(|target| is_expected_kind(target))
|
||||||
.iter()
|
});
|
||||||
.filter(|target| is_expected_kind(target))
|
let suggestion = closest_msg(target_name, targets, |t| t.name());
|
||||||
})
|
failure::bail!(
|
||||||
.map(|target| (lev_distance(target_name, target.name()), target))
|
"no {} target named `{}`{}",
|
||||||
.filter(|&(d, _)| d < 4)
|
target_desc,
|
||||||
.min_by_key(|t| t.0)
|
target_name,
|
||||||
.map(|t| t.1);
|
suggestion
|
||||||
match suggestion {
|
);
|
||||||
Some(s) => failure::bail!(
|
|
||||||
"no {} target named `{}`\n\nDid you mean `{}`?",
|
|
||||||
target_desc,
|
|
||||||
target_name,
|
|
||||||
s.name()
|
|
||||||
),
|
|
||||||
None => failure::bail!("no {} target named `{}`", target_desc, target_name),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Ok(proposals)
|
Ok(proposals)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use std::ffi::OsString;
|
|||||||
use std::iter;
|
use std::iter;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use crate::core::{nightly_features_allowed, TargetKind, Workspace};
|
use crate::core::{TargetKind, Workspace};
|
||||||
use crate::ops;
|
use crate::ops;
|
||||||
use crate::util::{CargoResult, ProcessError};
|
use crate::util::{CargoResult, ProcessError};
|
||||||
|
|
||||||
@ -55,22 +55,13 @@ pub fn run(
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_pkg, target)| target.name())
|
.map(|(_pkg, target)| target.name())
|
||||||
.collect();
|
.collect();
|
||||||
if nightly_features_allowed() {
|
failure::bail!(
|
||||||
failure::bail!(
|
"`cargo run` could not determine which binary to run. \
|
||||||
"`cargo run` could not determine which binary to run. \
|
Use the `--bin` option to specify a binary, \
|
||||||
Use the `--bin` option to specify a binary, \
|
or the `default-run` manifest key.\n\
|
||||||
or (on nightly) the `default-run` manifest key.\n\
|
available binaries: {}",
|
||||||
available binaries: {}",
|
names.join(", ")
|
||||||
names.join(", ")
|
)
|
||||||
)
|
|
||||||
} else {
|
|
||||||
failure::bail!(
|
|
||||||
"`cargo run` requires that a package only have one \
|
|
||||||
executable; use the `--bin` option to specify which one \
|
|
||||||
to run\navailable binaries: {}",
|
|
||||||
names.join(", ")
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
failure::bail!(
|
failure::bail!(
|
||||||
"`cargo run` can run at most one executable, but \
|
"`cargo run` can run at most one executable, but \
|
||||||
|
@ -514,10 +514,10 @@ pub enum CommandInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CommandInfo {
|
impl CommandInfo {
|
||||||
pub fn name(&self) -> String {
|
pub fn name(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
CommandInfo::BuiltIn { name, .. } => name.to_string(),
|
CommandInfo::BuiltIn { name, .. } => &name,
|
||||||
CommandInfo::External { name, .. } => name.to_string(),
|
CommandInfo::External { name, .. } => &name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,34 @@ pub fn lev_distance(me: &str, t: &str) -> usize {
|
|||||||
dcol[t_last + 1]
|
dcol[t_last + 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Find the closest element from `iter` matching `choice`. The `key` callback
|
||||||
|
/// is used to select a `&str` from the iterator to compare against `choice`.
|
||||||
|
pub fn closest<'a, T>(
|
||||||
|
choice: &str,
|
||||||
|
iter: impl Iterator<Item = T>,
|
||||||
|
key: impl Fn(&T) -> &'a str,
|
||||||
|
) -> Option<T> {
|
||||||
|
// Only consider candidates with a lev_distance of 3 or less so we don't
|
||||||
|
// suggest out-of-the-blue options.
|
||||||
|
iter.map(|e| (lev_distance(choice, key(&e)), e))
|
||||||
|
.filter(|&(d, _)| d < 4)
|
||||||
|
.min_by_key(|t| t.0)
|
||||||
|
.map(|t| t.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Version of `closest` that returns a common "suggestion" that can be tacked
|
||||||
|
/// onto the end of an error message.
|
||||||
|
pub fn closest_msg<'a, T>(
|
||||||
|
choice: &str,
|
||||||
|
iter: impl Iterator<Item = T>,
|
||||||
|
key: impl Fn(&T) -> &'a str,
|
||||||
|
) -> String {
|
||||||
|
match closest(choice, iter, &key) {
|
||||||
|
Some(e) => format!("\n\n\tDid you mean `{}`?", key(&e)),
|
||||||
|
None => String::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_lev_distance() {
|
fn test_lev_distance() {
|
||||||
use std::char::{from_u32, MAX};
|
use std::char::{from_u32, MAX};
|
||||||
|
@ -12,7 +12,7 @@ pub use self::graph::Graph;
|
|||||||
pub use self::hex::{hash_u64, short_hash, to_hex};
|
pub use self::hex::{hash_u64, short_hash, to_hex};
|
||||||
pub use self::into_url::IntoUrl;
|
pub use self::into_url::IntoUrl;
|
||||||
pub use self::into_url_with_base::IntoUrlWithBase;
|
pub use self::into_url_with_base::IntoUrlWithBase;
|
||||||
pub use self::lev_distance::lev_distance;
|
pub use self::lev_distance::{closest, closest_msg, lev_distance};
|
||||||
pub use self::lockserver::{LockServer, LockServerClient, LockServerStarted};
|
pub use self::lockserver::{LockServer, LockServerClient, LockServerStarted};
|
||||||
pub use self::paths::{bytes2path, dylib_path, join_paths, path2bytes};
|
pub use self::paths::{bytes2path, dylib_path, join_paths, path2bytes};
|
||||||
pub use self::paths::{dylib_path_envvar, normalize_path};
|
pub use self::paths::{dylib_path_envvar, normalize_path};
|
||||||
|
@ -21,8 +21,7 @@ use crate::core::{Edition, EitherManifest, Feature, Features, VirtualManifest};
|
|||||||
use crate::core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, WorkspaceRootConfig};
|
use crate::core::{GitReference, PackageIdSpec, SourceId, WorkspaceConfig, WorkspaceRootConfig};
|
||||||
use crate::sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY};
|
use crate::sources::{CRATES_IO_INDEX, CRATES_IO_REGISTRY};
|
||||||
use crate::util::errors::{CargoResult, CargoResultExt, ManifestError};
|
use crate::util::errors::{CargoResult, CargoResultExt, ManifestError};
|
||||||
use crate::util::paths;
|
use crate::util::{self, paths, validate_package_name, Config, IntoUrl};
|
||||||
use crate::util::{self, validate_package_name, Config, IntoUrl};
|
|
||||||
|
|
||||||
mod targets;
|
mod targets;
|
||||||
use self::targets::targets;
|
use self::targets::targets;
|
||||||
@ -1052,6 +1051,18 @@ impl TomlManifest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(run) = &project.default_run {
|
||||||
|
if !targets
|
||||||
|
.iter()
|
||||||
|
.filter(|t| t.is_bin())
|
||||||
|
.any(|t| t.name() == run)
|
||||||
|
{
|
||||||
|
let suggestion =
|
||||||
|
util::closest_msg(&run, targets.iter().filter(|t| t.is_bin()), |t| t.name());
|
||||||
|
bail!("default-run target `{}` not found{}", run, suggestion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let custom_metadata = project.metadata.clone();
|
let custom_metadata = project.metadata.clone();
|
||||||
let mut manifest = Manifest::new(
|
let mut manifest = Manifest::new(
|
||||||
summary,
|
summary,
|
||||||
|
@ -29,7 +29,8 @@ include::options-package.adoc[]
|
|||||||
|
|
||||||
When no target selection options are given, `cargo run` will run the binary
|
When no target selection options are given, `cargo run` will run the binary
|
||||||
target. If there are multiple binary targets, you must pass a target flag to
|
target. If there are multiple binary targets, you must pass a target flag to
|
||||||
choose one.
|
choose one. Or, the `default-run` field may be specified in the `[package]`
|
||||||
|
section of `Cargo.toml` to choose the name of the binary to run by default.
|
||||||
|
|
||||||
*--bin* _NAME_::
|
*--bin* _NAME_::
|
||||||
Run the specified binary.
|
Run the specified binary.
|
||||||
|
@ -48,7 +48,8 @@ the SPEC format.</p>
|
|||||||
<div class="paragraph">
|
<div class="paragraph">
|
||||||
<p>When no target selection options are given, <code>cargo run</code> will run the binary
|
<p>When no target selection options are given, <code>cargo run</code> will run the binary
|
||||||
target. If there are multiple binary targets, you must pass a target flag to
|
target. If there are multiple binary targets, you must pass a target flag to
|
||||||
choose one.</p>
|
choose one. Or, the <code>default-run</code> field may be specified in the <code>[package]</code>
|
||||||
|
section of <code>Cargo.toml</code> to choose the name of the binary to run by default.</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="dlist">
|
<div class="dlist">
|
||||||
<dl>
|
<dl>
|
||||||
|
@ -21,7 +21,7 @@ when listed as a dependency in another package, and as the default name of
|
|||||||
inferred lib and bin targets.
|
inferred lib and bin targets.
|
||||||
|
|
||||||
The name must not be empty, use only [alphanumeric] characters or `-` or `_`.
|
The name must not be empty, use only [alphanumeric] characters or `-` or `_`.
|
||||||
Note that `cargo new` and `cargo init` impose some additional restrictions on
|
Note that [`cargo new`] and [`cargo init`] impose some additional restrictions on
|
||||||
the package name, such as enforcing that it is a valid Rust identifier and not
|
the package name, such as enforcing that it is a valid Rust identifier and not
|
||||||
a keyword. [crates.io][cratesio] imposes even more restrictions, such as
|
a keyword. [crates.io][cratesio] imposes even more restrictions, such as
|
||||||
enforcing only ASCII characters, not a reserved name, not a special Windows
|
enforcing only ASCII characters, not a reserved name, not a special Windows
|
||||||
@ -66,7 +66,7 @@ edition = '2018'
|
|||||||
```
|
```
|
||||||
|
|
||||||
The `edition` key affects which edition your package is compiled with. Cargo
|
The `edition` key affects which edition your package is compiled with. Cargo
|
||||||
will always generate packages via `cargo new` with the `edition` key set to the
|
will always generate packages via [`cargo new`] with the `edition` key set to the
|
||||||
latest edition. Setting the `edition` key in `[package]` will affect all
|
latest edition. Setting the `edition` key in `[package]` will affect all
|
||||||
targets/crates in the package, including test suites, benchmarks, binaries,
|
targets/crates in the package, including test suites, benchmarks, binaries,
|
||||||
examples, etc.
|
examples, etc.
|
||||||
@ -364,6 +364,17 @@ package-name = "my-awesome-android-app"
|
|||||||
assets = "path/to/static"
|
assets = "path/to/static"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### The `default-run` field
|
||||||
|
|
||||||
|
The `default-run` field in the `[package]` section of the manifest can be used
|
||||||
|
to specify a default binary picked by [`cargo run`]. For example, when there is
|
||||||
|
both `src/bin/a.rs` and `src/bin/b.rs`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[package]
|
||||||
|
default-run = "a"
|
||||||
|
```
|
||||||
|
|
||||||
### Dependency sections
|
### Dependency sections
|
||||||
|
|
||||||
See the [specifying dependencies page](reference/specifying-dependencies.html) for
|
See the [specifying dependencies page](reference/specifying-dependencies.html) for
|
||||||
@ -629,8 +640,8 @@ A crate may either specify `package.workspace` or specify `[workspace]`. That
|
|||||||
is, a crate cannot both be a root crate in a workspace (contain `[workspace]`)
|
is, a crate cannot both be a root crate in a workspace (contain `[workspace]`)
|
||||||
and also be a member crate of another workspace (contain `package.workspace`).
|
and also be a member crate of another workspace (contain `package.workspace`).
|
||||||
|
|
||||||
Most of the time workspaces will not need to be dealt with as `cargo new` and
|
Most of the time workspaces will not need to be dealt with as [`cargo new`] and
|
||||||
`cargo init` will handle workspace configuration automatically.
|
[`cargo init`] will handle workspace configuration automatically.
|
||||||
|
|
||||||
[globs]: https://docs.rs/glob/0.2.11/glob/struct.Pattern.html
|
[globs]: https://docs.rs/glob/0.2.11/glob/struct.Pattern.html
|
||||||
|
|
||||||
@ -643,7 +654,7 @@ manifest*.
|
|||||||
|
|
||||||
#### Package selection
|
#### Package selection
|
||||||
|
|
||||||
In a workspace, package-related cargo commands like `cargo build` apply to
|
In a workspace, package-related cargo commands like [`cargo build`] apply to
|
||||||
packages selected by `-p` / `--package` or `--all` command-line parameters.
|
packages selected by `-p` / `--package` or `--all` command-line parameters.
|
||||||
When neither is specified, the optional `default-members` configuration is used:
|
When neither is specified, the optional `default-members` configuration is used:
|
||||||
|
|
||||||
@ -733,7 +744,7 @@ You can build individual library examples with the command `cargo build
|
|||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
When you run `cargo test`, Cargo will:
|
When you run [`cargo test`], Cargo will:
|
||||||
|
|
||||||
* compile and run your library’s unit tests, which are in the files reachable
|
* compile and run your library’s unit tests, which are in the files reachable
|
||||||
from `lib.rs` (naturally, any sections marked with `#[cfg(test)]` will be
|
from `lib.rs` (naturally, any sections marked with `#[cfg(test)]` will be
|
||||||
@ -745,7 +756,7 @@ When you run `cargo test`, Cargo will:
|
|||||||
|
|
||||||
#### Integration tests
|
#### Integration tests
|
||||||
|
|
||||||
Each file in `tests/*.rs` is an integration test. When you run `cargo test`,
|
Each file in `tests/*.rs` is an integration test. When you run [`cargo test`],
|
||||||
Cargo will compile each of these files as a separate crate. The crate can link
|
Cargo will compile each of these files as a separate crate. The crate can link
|
||||||
to your library by using `extern crate <library-name>`, like any other code that
|
to your library by using `extern crate <library-name>`, like any other code that
|
||||||
depends on it.
|
depends on it.
|
||||||
@ -966,6 +977,11 @@ source (e.g., git or a local path).
|
|||||||
More information about overriding dependencies can be found in the [overriding
|
More information about overriding dependencies can be found in the [overriding
|
||||||
dependencies][replace] section of the documentation.
|
dependencies][replace] section of the documentation.
|
||||||
|
|
||||||
|
[`cargo build`]: commands/cargo-build.html
|
||||||
|
[`cargo init`]: commands/cargo-init.html
|
||||||
|
[`cargo new`]: commands/cargo-new.html
|
||||||
|
[`cargo run`]: commands/cargo-run.html
|
||||||
|
[`cargo test`]: commands/cargo-test.html
|
||||||
[spdx-2.1-license-expressions]: https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60
|
[spdx-2.1-license-expressions]: https://spdx.org/spdx-specification-21-web-version#h.jxpfx0ykyb60
|
||||||
[spdx-license-list]: https://spdx.org/licenses/
|
|
||||||
[spdx-license-list-2.4]: https://github.com/spdx/license-list-data/tree/v2.4
|
[spdx-license-list-2.4]: https://github.com/spdx/license-list-data/tree/v2.4
|
||||||
|
[spdx-license-list]: https://spdx.org/licenses/
|
||||||
|
@ -155,18 +155,6 @@ Example:
|
|||||||
cargo +nightly build --build-plan -Z unstable-options
|
cargo +nightly build --build-plan -Z unstable-options
|
||||||
```
|
```
|
||||||
|
|
||||||
### default-run
|
|
||||||
* Original issue: [#2200](https://github.com/rust-lang/cargo/issues/2200)
|
|
||||||
|
|
||||||
The `default-run` option in the `[package]` section of the manifest can be used
|
|
||||||
to specify a default binary picked by `cargo run`. For example, when there is
|
|
||||||
both `src/bin/a.rs` and `src/bin/b.rs`:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[package]
|
|
||||||
default-run = "a"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Metabuild
|
### Metabuild
|
||||||
* Tracking Issue: [rust-lang/rust#49803](https://github.com/rust-lang/rust/issues/49803)
|
* Tracking Issue: [rust-lang/rust#49803](https://github.com/rust-lang/rust/issues/49803)
|
||||||
* RFC: [#2196](https://github.com/rust-lang/rfcs/blob/master/text/2196-metabuild.md)
|
* RFC: [#2196](https://github.com/rust-lang/rfcs/blob/master/text/2196-metabuild.md)
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
.\" Title: cargo-run
|
.\" Title: cargo-run
|
||||||
.\" Author: [see the "AUTHOR(S)" section]
|
.\" Author: [see the "AUTHOR(S)" section]
|
||||||
.\" Generator: Asciidoctor 1.5.8
|
.\" Generator: Asciidoctor 1.5.8
|
||||||
.\" Date: 2019-05-08
|
.\" Date: 2019-06-21
|
||||||
.\" Manual: \ \&
|
.\" Manual: \ \&
|
||||||
.\" Source: \ \&
|
.\" Source: \ \&
|
||||||
.\" Language: English
|
.\" Language: English
|
||||||
.\"
|
.\"
|
||||||
.TH "CARGO\-RUN" "1" "2019-05-08" "\ \&" "\ \&"
|
.TH "CARGO\-RUN" "1" "2019-06-21" "\ \&" "\ \&"
|
||||||
.ie \n(.g .ds Aq \(aq
|
.ie \n(.g .ds Aq \(aq
|
||||||
.el .ds Aq '
|
.el .ds Aq '
|
||||||
.ss \n[.ss] 0
|
.ss \n[.ss] 0
|
||||||
@ -54,7 +54,8 @@ the SPEC format.
|
|||||||
.sp
|
.sp
|
||||||
When no target selection options are given, \fBcargo run\fP will run the binary
|
When no target selection options are given, \fBcargo run\fP will run the binary
|
||||||
target. If there are multiple binary targets, you must pass a target flag to
|
target. If there are multiple binary targets, you must pass a target flag to
|
||||||
choose one.
|
choose one. Or, the \fBdefault\-run\fP field may be specified in the \fB[package]\fP
|
||||||
|
section of \fBCargo.toml\fP to choose the name of the binary to run by default.
|
||||||
.sp
|
.sp
|
||||||
\fB\-\-bin\fP \fINAME\fP
|
\fB\-\-bin\fP \fINAME\fP
|
||||||
.RS 4
|
.RS 4
|
||||||
|
@ -936,7 +936,7 @@ fn cargo_compile_with_filename() {
|
|||||||
"\
|
"\
|
||||||
[ERROR] no bin target named `a.rs`
|
[ERROR] no bin target named `a.rs`
|
||||||
|
|
||||||
Did you mean `a`?",
|
<tab>Did you mean `a`?",
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
@ -951,7 +951,7 @@ Did you mean `a`?",
|
|||||||
"\
|
"\
|
||||||
[ERROR] no example target named `a.rs`
|
[ERROR] no example target named `a.rs`
|
||||||
|
|
||||||
Did you mean `a`?",
|
<tab>Did you mean `a`?",
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -4417,7 +4417,7 @@ fn target_filters_workspace() {
|
|||||||
"\
|
"\
|
||||||
[ERROR] no example target named `ex`
|
[ERROR] no example target named `ex`
|
||||||
|
|
||||||
Did you mean `ex1`?",
|
<tab>Did you mean `ex1`?",
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ fn profile_override_warnings() {
|
|||||||
[WARNING] version or URL in profile override spec `bar:1.2.3` does not match any of the packages: bar v0.5.0 ([..])
|
[WARNING] version or URL in profile override spec `bar:1.2.3` does not match any of the packages: bar v0.5.0 ([..])
|
||||||
[WARNING] profile override spec `bart` did not match any packages
|
[WARNING] profile override spec `bart` did not match any packages
|
||||||
|
|
||||||
Did you mean `bar`?
|
<tab>Did you mean `bar`?
|
||||||
[WARNING] profile override spec `no-suggestion` did not match any packages
|
[WARNING] profile override spec `no-suggestion` did not match any packages
|
||||||
[COMPILING] [..]
|
[COMPILING] [..]
|
||||||
",
|
",
|
||||||
|
@ -1154,8 +1154,8 @@ fn run_default_multiple_required_features() {
|
|||||||
.with_status(101)
|
.with_status(101)
|
||||||
.with_stderr(
|
.with_stderr(
|
||||||
"\
|
"\
|
||||||
error: `cargo run` requires that a package only have one executable; \
|
error: `cargo run` could not determine which binary to run[..]
|
||||||
use the `--bin` option to specify which one to run\navailable binaries: foo1, foo2",
|
available binaries: foo1, foo2",
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
@ -168,22 +168,11 @@ fn too_many_bins() {
|
|||||||
|
|
||||||
// Using [..] here because the order is not stable
|
// Using [..] here because the order is not stable
|
||||||
p.cargo("run")
|
p.cargo("run")
|
||||||
.with_status(101)
|
|
||||||
.with_stderr(
|
|
||||||
"[ERROR] `cargo run` requires that a package only \
|
|
||||||
have one executable; use the `--bin` option \
|
|
||||||
to specify which one to run\navailable binaries: [..]\n",
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
|
|
||||||
// Using [..] here because the order is not stable
|
|
||||||
p.cargo("run")
|
|
||||||
.masquerade_as_nightly_cargo()
|
|
||||||
.with_status(101)
|
.with_status(101)
|
||||||
.with_stderr(
|
.with_stderr(
|
||||||
"[ERROR] `cargo run` could not determine which binary to run. \
|
"[ERROR] `cargo run` could not determine which binary to run. \
|
||||||
Use the `--bin` option to specify a binary, or (on \
|
Use the `--bin` option to specify a binary, or the \
|
||||||
nightly) the `default-run` manifest key.\
|
`default-run` manifest key.\
|
||||||
\navailable binaries: [..]\n",
|
\navailable binaries: [..]\n",
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
@ -241,8 +230,6 @@ fn specify_default_run() {
|
|||||||
.file(
|
.file(
|
||||||
"Cargo.toml",
|
"Cargo.toml",
|
||||||
r#"
|
r#"
|
||||||
cargo-features = ["default-run"]
|
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "foo"
|
name = "foo"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
@ -255,18 +242,9 @@ fn specify_default_run() {
|
|||||||
.file("src/bin/b.rs", r#"fn main() { println!("hello B"); }"#)
|
.file("src/bin/b.rs", r#"fn main() { println!("hello B"); }"#)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
p.cargo("run")
|
p.cargo("run").with_stdout("hello A").run();
|
||||||
.masquerade_as_nightly_cargo()
|
p.cargo("run --bin a").with_stdout("hello A").run();
|
||||||
.with_stdout("hello A")
|
p.cargo("run --bin b").with_stdout("hello B").run();
|
||||||
.run();
|
|
||||||
p.cargo("run --bin a")
|
|
||||||
.masquerade_as_nightly_cargo()
|
|
||||||
.with_stdout("hello A")
|
|
||||||
.run();
|
|
||||||
p.cargo("run --bin b")
|
|
||||||
.masquerade_as_nightly_cargo()
|
|
||||||
.with_stdout("hello B")
|
|
||||||
.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
@ -275,8 +253,6 @@ fn bogus_default_run() {
|
|||||||
.file(
|
.file(
|
||||||
"Cargo.toml",
|
"Cargo.toml",
|
||||||
r#"
|
r#"
|
||||||
cargo-features = ["default-run"]
|
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "foo"
|
name = "foo"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
@ -288,61 +264,17 @@ fn bogus_default_run() {
|
|||||||
.file("src/bin/a.rs", r#"fn main() { println!("hello A"); }"#)
|
.file("src/bin/a.rs", r#"fn main() { println!("hello A"); }"#)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
p.cargo("run")
|
|
||||||
.masquerade_as_nightly_cargo()
|
|
||||||
.with_status(101)
|
|
||||||
.with_stderr("error: no bin target named `b`\n\nDid you mean [..]?")
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cargo_test]
|
|
||||||
fn default_run_unstable() {
|
|
||||||
let p = project()
|
|
||||||
.file(
|
|
||||||
"Cargo.toml",
|
|
||||||
r#"
|
|
||||||
[project]
|
|
||||||
name = "foo"
|
|
||||||
version = "0.0.1"
|
|
||||||
authors = []
|
|
||||||
default-run = "a"
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.file("src/bin/a.rs", r#"fn main() { println!("hello A"); }"#)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
p.cargo("run")
|
p.cargo("run")
|
||||||
.with_status(101)
|
.with_status(101)
|
||||||
.with_stderr(
|
.with_stderr(
|
||||||
r#"error: failed to parse manifest at [..]
|
"\
|
||||||
|
[ERROR] failed to parse manifest at `[..]/foo/Cargo.toml`
|
||||||
|
|
||||||
Caused by:
|
Caused by:
|
||||||
the `default-run` manifest key is unstable
|
default-run target `b` not found
|
||||||
|
|
||||||
Caused by:
|
<tab>Did you mean `a`?
|
||||||
feature `default-run` is required
|
",
|
||||||
|
|
||||||
this Cargo does not support nightly features, but if you
|
|
||||||
switch to nightly channel you can add
|
|
||||||
`cargo-features = ["default-run"]` to enable this feature
|
|
||||||
"#,
|
|
||||||
)
|
|
||||||
.run();
|
|
||||||
|
|
||||||
p.cargo("run")
|
|
||||||
.masquerade_as_nightly_cargo()
|
|
||||||
.with_status(101)
|
|
||||||
.with_stderr(
|
|
||||||
r#"error: failed to parse manifest at [..]
|
|
||||||
|
|
||||||
Caused by:
|
|
||||||
the `default-run` manifest key is unstable
|
|
||||||
|
|
||||||
Caused by:
|
|
||||||
feature `default-run` is required
|
|
||||||
|
|
||||||
consider adding `cargo-features = ["default-run"]` to the manifest
|
|
||||||
"#,
|
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -586,7 +518,7 @@ fn run_with_filename() {
|
|||||||
"\
|
"\
|
||||||
[ERROR] no bin target named `a.rs`
|
[ERROR] no bin target named `a.rs`
|
||||||
|
|
||||||
Did you mean `a`?",
|
<tab>Did you mean `a`?",
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
@ -601,7 +533,7 @@ Did you mean `a`?",
|
|||||||
"\
|
"\
|
||||||
[ERROR] no example target named `a.rs`
|
[ERROR] no example target named `a.rs`
|
||||||
|
|
||||||
Did you mean `a`?",
|
<tab>Did you mean `a`?",
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
@ -1103,7 +1035,7 @@ fn run_workspace() {
|
|||||||
.with_status(101)
|
.with_status(101)
|
||||||
.with_stderr(
|
.with_stderr(
|
||||||
"\
|
"\
|
||||||
[ERROR] `cargo run` requires that a package only have one executable[..]
|
[ERROR] `cargo run` could not determine which binary to run[..]
|
||||||
available binaries: a, b",
|
available binaries: a, b",
|
||||||
)
|
)
|
||||||
.run();
|
.run();
|
||||||
@ -1123,8 +1055,6 @@ fn default_run_workspace() {
|
|||||||
.file(
|
.file(
|
||||||
"a/Cargo.toml",
|
"a/Cargo.toml",
|
||||||
r#"
|
r#"
|
||||||
cargo-features = ["default-run"]
|
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "a"
|
name = "a"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
@ -1136,10 +1066,7 @@ fn default_run_workspace() {
|
|||||||
.file("b/src/main.rs", r#"fn main() {println!("run-b");}"#)
|
.file("b/src/main.rs", r#"fn main() {println!("run-b");}"#)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
p.cargo("run")
|
p.cargo("run").with_stdout("run-a").run();
|
||||||
.masquerade_as_nightly_cargo()
|
|
||||||
.with_stdout("run-a")
|
|
||||||
.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cargo_test]
|
#[cargo_test]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user