Auto merge of #5152 - matklad:clap, r=alexcrichton

Clap

Reopening of #5129

So, looks like all tests are 🍏 on my machine!

I definitely want to refactor it some more, and also manually checked that we haven't regressed any help messages, but all the major parts are in place already.
This commit is contained in:
bors 2018-03-13 14:46:45 +00:00
commit 3cfb23bc56
87 changed files with 2190 additions and 3159 deletions

View File

@ -22,7 +22,6 @@ crates-io = { path = "src/crates-io", version = "0.16" }
crossbeam = "0.3"
crypto-hash = "0.3"
curl = "0.4.6"
docopt = "0.8.1"
env_logger = "0.5"
failure = "0.1.1"
filetime = "0.1"
@ -54,6 +53,7 @@ tempdir = "0.3"
termcolor = "0.3"
toml = "0.4"
url = "1.1"
clap = "2.27.0"
[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = { version = "0.5.1", features = ["mac_os_10_7_support"] }

View File

@ -1,159 +0,0 @@
use std::env;
use cargo::core::Workspace;
use cargo::ops::{self, MessageFormat, Packages};
use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};
#[derive(Deserialize)]
pub struct Options {
flag_no_run: bool,
flag_package: Vec<String>,
flag_jobs: Option<u32>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_no_default_features: bool,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_lib: bool,
flag_bin: Vec<String>,
flag_bins: bool,
flag_example: Vec<String>,
flag_examples: bool,
flag_test: Vec<String>,
flag_tests: bool,
flag_bench: Vec<String>,
flag_benches: bool,
flag_all_targets: bool,
flag_no_fail_fast: bool,
flag_frozen: bool,
flag_locked: bool,
arg_args: Vec<String>,
flag_all: bool,
flag_exclude: Vec<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
#[serde(rename = "arg_BENCHNAME")]
arg_benchname: Option<String>,
}
pub const USAGE: &'static str = "
Execute all benchmarks of a local package
Usage:
cargo bench [options] [BENCHNAME] [--] [<args>...]
Options:
BENCHNAME If specified, only run benches containing this string in their names
-h, --help Print this message
--lib Benchmark only this package's library
--bin NAME ... Benchmark only the specified binary
--bins Benchmark all binaries
--example NAME ... Benchmark only the specified example
--examples Benchmark all examples
--test NAME ... Benchmark only the specified test target
--tests Benchmark all tests
--bench NAME ... Benchmark only the specified bench target
--benches Benchmark all benches
--all-targets Benchmark all targets (default)
--no-run Compile, but don't run benchmarks
-p SPEC, --package SPEC ... Package to run benchmarks for
--all Benchmark all packages in the workspace
--exclude SPEC ... Exclude packages from the benchmark
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--features FEATURES Space-separated list of features to also build
--all-features Build all available features
--no-default-features Do not build the `default` feature
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest to build benchmarks for
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--no-fail-fast Run all benchmarks regardless of failure
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
All of the trailing arguments are passed to the benchmark binaries generated
for filtering benchmarks and generally providing options configuring how they
run.
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be benchmarked. If it is not given, then
the current package is benchmarked. For more information on SPEC and its format,
see the `cargo help pkgid` command.
All packages in the workspace are benchmarked if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
The --jobs argument affects the building of the benchmark executable but does
not affect how many jobs are used when running the benchmarks.
Compilation can be customized with the `bench` profile in the manifest.
";
pub fn execute(mut options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-bench; args={:?}",
env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let ws = Workspace::new(&root, config)?;
let spec = Packages::from_flags(options.flag_all,
&options.flag_exclude,
&options.flag_package)?;
let ops = ops::TestOptions {
no_run: options.flag_no_run,
no_fail_fast: options.flag_no_fail_fast,
only_doc: false,
compile_opts: ops::CompileOptions {
config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|s| &s[..]),
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec,
release: true,
mode: ops::CompileMode::Bench,
filter: ops::CompileFilter::new(options.flag_lib,
&options.flag_bin, options.flag_bins,
&options.flag_test, options.flag_tests,
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,
options.flag_all_targets),
message_format: options.flag_message_format,
target_rustdoc_args: None,
target_rustc_args: None,
},
};
if let Some(test) = options.arg_benchname.take() {
options.arg_args.insert(0, test);
}
let err = ops::run_benches(&ws, &ops, &options.arg_args)?;
match err {
None => Ok(()),
Some(err) => {
Err(match err.exit.as_ref().and_then(|e| e.code()) {
Some(i) => CliError::new(format_err!("bench failed"), i),
None => CliError::new(err.into(), 101)
})
}
}
}

View File

@ -1,133 +0,0 @@
use std::env;
use cargo::core::Workspace;
use cargo::ops::{self, CompileOptions, MessageFormat, Packages};
use cargo::util::important_paths::{find_root_manifest_for_wd};
use cargo::util::{CliResult, Config};
#[derive(Deserialize)]
pub struct Options {
flag_package: Vec<String>,
flag_jobs: Option<u32>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_no_default_features: bool,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_release: bool,
flag_lib: bool,
flag_bin: Vec<String>,
flag_bins: bool,
flag_example: Vec<String>,
flag_examples: bool,
flag_test: Vec<String>,
flag_tests: bool,
flag_bench: Vec<String>,
flag_benches: bool,
flag_all_targets: bool,
flag_locked: bool,
flag_frozen: bool,
flag_all: bool,
flag_exclude: Vec<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Compile a local package and all of its dependencies
Usage:
cargo build [options]
Options:
-h, --help Print this message
-p SPEC, --package SPEC ... Package to build
--all Build all packages in the workspace
--exclude SPEC ... Exclude packages from the build
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--lib Build only this package's library
--bin NAME Build only the specified binary
--bins Build all binaries
--example NAME Build only the specified example
--examples Build all examples
--test NAME Build only the specified test target
--tests Build all tests
--bench NAME Build only the specified bench target
--benches Build all benches
--all-targets Build all targets (lib and bin targets by default)
--release Build artifacts in release mode, with optimizations
--features FEATURES Space-separated list of features to also build
--all-features Build all available features
--no-default-features Do not build the `default` feature
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest to compile
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be built. If it is not given, then the
current package is built. For more information on SPEC and its format, see the
`cargo help pkgid` command.
All packages in the workspace are built if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
Compilation can be configured via the use of profiles which are configured in
the manifest. The default profile for this command is `dev`, but passing
the --release flag will use the `release` profile instead.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-build; args={:?}",
env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let mut ws = Workspace::new(&root, config)?;
if config.cli_unstable().avoid_dev_deps {
ws.set_require_optional_deps(false);
}
let spec = Packages::from_flags(options.flag_all,
&options.flag_exclude,
&options.flag_package)?;
let opts = CompileOptions {
config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| &t[..]),
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec,
mode: ops::CompileMode::Build,
release: options.flag_release,
filter: ops::CompileFilter::new(options.flag_lib,
&options.flag_bin, options.flag_bins,
&options.flag_test, options.flag_tests,
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,
options.flag_all_targets),
message_format: options.flag_message_format,
target_rustdoc_args: None,
target_rustc_args: None,
};
ops::compile(&ws, &opts)?;
Ok(())
}

View File

@ -4,75 +4,25 @@ extern crate env_logger;
extern crate failure;
extern crate git2_curl;
extern crate toml;
#[macro_use]
extern crate log;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate clap;
use std::collections::BTreeSet;
use std::collections::HashMap;
use std::env;
use std::fs;
use std::path::{Path, PathBuf};
use std::collections::BTreeSet;
use cargo::core::shell::{Shell, Verbosity};
use cargo::core::shell::Shell;
use cargo::util::{self, CliResult, lev_distance, Config, CargoResult};
use cargo::util::{CliError, ProcessError};
#[derive(Deserialize)]
pub struct Flags {
flag_list: bool,
flag_version: bool,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_explain: Option<String>,
arg_command: String,
arg_args: Vec<String>,
flag_locked: bool,
flag_frozen: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
mod cli;
mod command_prelude;
mod commands;
const USAGE: &'static str = "
Rust's package manager
Usage:
cargo <command> [<args>...]
cargo [options]
Options:
-h, --help Display this message
-V, --version Print version info and exit
--list List installed commands
--explain CODE Run `rustc --explain CODE`
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
Some common cargo commands are (see all commands with --list):
build Compile the current project
check Analyze the current project and report errors, but don't build object files
clean Remove the target directory
doc Build this project's and its dependencies' documentation
new Create a new cargo project
init Create a new cargo project in an existing directory
run Build and execute src/main.rs
test Run the tests
bench Run the benchmarks
update Update dependencies listed in Cargo.lock
search Search registry for crates
publish Package and upload this project to the registry
install Install a Rust binary
uninstall Uninstall a Rust binary
See 'cargo help <command>' for more information on a specific command.
";
fn main() {
env_logger::init();
@ -85,17 +35,11 @@ fn main() {
}
};
let result = (|| {
let args: Vec<_> = try!(env::args_os()
.map(|s| {
s.into_string().map_err(|s| {
format_err!("invalid unicode in argument: {:?}", s)
})
})
.collect());
let rest = &args;
cargo::call_main_without_stdin(execute, &mut config, USAGE, rest, true)
})();
let result = {
init_git_transports(&mut config);
let _token = cargo::util::job::setup();
cli::main(&mut config)
};
match result {
Err(e) => cargo::exit_with_error(e, &mut *config.shell()),
@ -103,180 +47,6 @@ fn main() {
}
}
macro_rules! each_subcommand{
($mac:ident) => {
$mac!(bench);
$mac!(build);
$mac!(check);
$mac!(clean);
$mac!(doc);
$mac!(fetch);
$mac!(generate_lockfile);
$mac!(git_checkout);
$mac!(help);
$mac!(init);
$mac!(install);
$mac!(locate_project);
$mac!(login);
$mac!(metadata);
$mac!(new);
$mac!(owner);
$mac!(package);
$mac!(pkgid);
$mac!(publish);
$mac!(read_manifest);
$mac!(run);
$mac!(rustc);
$mac!(rustdoc);
$mac!(search);
$mac!(test);
$mac!(uninstall);
$mac!(update);
$mac!(verify_project);
$mac!(version);
$mac!(yank);
}
}
macro_rules! declare_mod {
($name:ident) => ( pub mod $name; )
}
each_subcommand!(declare_mod);
/**
The top-level `cargo` command handles configuration and project location
because they are fundamental (and intertwined). Other commands can rely
on this top-level information.
*/
fn execute(flags: Flags, config: &mut Config) -> CliResult {
config.configure(flags.flag_verbose,
flags.flag_quiet,
&flags.flag_color,
flags.flag_frozen,
flags.flag_locked,
&flags.flag_z)?;
init_git_transports(config);
let _token = cargo::util::job::setup();
if flags.flag_version {
let version = cargo::version();
println!("{}", version);
if flags.flag_verbose > 0 {
println!("release: {}.{}.{}",
version.major,
version.minor,
version.patch);
if let Some(ref cfg) = version.cfg_info {
if let Some(ref ci) = cfg.commit_info {
println!("commit-hash: {}", ci.commit_hash);
println!("commit-date: {}", ci.commit_date);
}
}
}
return Ok(());
}
if flags.flag_list {
println!("Installed Commands:");
for command in list_commands(config) {
let (command, path) = command;
if flags.flag_verbose > 0 {
match path {
Some(p) => println!(" {:<20} {}", command, p),
None => println!(" {:<20}", command),
}
} else {
println!(" {}", command);
}
}
return Ok(());
}
if let Some(ref code) = flags.flag_explain {
let mut procss = config.rustc()?.process();
procss.arg("--explain").arg(code).exec()?;
return Ok(());
}
let args = match &flags.arg_command[..] {
// For the commands `cargo` and `cargo help`, re-execute ourselves as
// `cargo -h` so we can go through the normal process of printing the
// help message.
"" | "help" if flags.arg_args.is_empty() => {
config.shell().set_verbosity(Verbosity::Verbose);
let args = &["cargo".to_string(), "-h".to_string()];
return cargo::call_main_without_stdin(execute, config, USAGE, args, false);
}
// For `cargo help -h` and `cargo help --help`, print out the help
// message for `cargo help`
"help" if flags.arg_args[0] == "-h" || flags.arg_args[0] == "--help" => {
vec!["cargo".to_string(), "help".to_string(), "-h".to_string()]
}
// For `cargo help foo`, print out the usage message for the specified
// subcommand by executing the command with the `-h` flag.
"help" => vec!["cargo".to_string(), flags.arg_args[0].clone(), "-h".to_string()],
// For all other invocations, we're of the form `cargo foo args...`. We
// use the exact environment arguments to preserve tokens like `--` for
// example.
_ => {
let mut default_alias = HashMap::new();
default_alias.insert("b", "build".to_string());
default_alias.insert("t", "test".to_string());
default_alias.insert("r", "run".to_string());
let mut args: Vec<String> = env::args().collect();
if let Some(new_command) = default_alias.get(&args[1][..]) {
args[1] = new_command.clone();
}
args
}
};
if let Some(r) = try_execute_builtin_command(config, &args) {
return r;
}
let alias_list = aliased_command(config, &args[1])?;
let args = match alias_list {
Some(alias_command) => {
let chain = args.iter()
.take(1)
.chain(alias_command.iter())
.chain(args.iter().skip(2))
.map(|s| s.to_string())
.collect::<Vec<_>>();
if let Some(r) = try_execute_builtin_command(config, &chain) {
return r;
} else {
chain
}
}
None => args,
};
execute_external_subcommand(config, &args[1], &args)
}
fn try_execute_builtin_command(config: &mut Config, args: &[String]) -> Option<CliResult> {
macro_rules! cmd {
($name:ident) => (if args[1] == stringify!($name).replace("_", "-") {
config.shell().set_verbosity(Verbosity::Verbose);
let r = cargo::call_main_without_stdin($name::execute,
config,
$name::USAGE,
&args,
false);
return Some(r);
})
}
each_subcommand!(cmd);
None
}
fn aliased_command(config: &Config, command: &str) -> CargoResult<Option<Vec<String>>> {
let alias_name = format!("alias.{}", command);
let mut result = Ok(None);
@ -304,6 +74,43 @@ fn aliased_command(config: &Config, command: &str) -> CargoResult<Option<Vec<Str
result
}
/// List all runnable commands
fn list_commands(config: &Config) -> BTreeSet<(String, Option<String>)> {
let prefix = "cargo-";
let suffix = env::consts::EXE_SUFFIX;
let mut commands = BTreeSet::new();
for dir in search_directories(config) {
let entries = match fs::read_dir(dir) {
Ok(entries) => entries,
_ => continue,
};
for entry in entries.filter_map(|e| e.ok()) {
let path = entry.path();
let filename = match path.file_name().and_then(|s| s.to_str()) {
Some(filename) => filename,
_ => continue,
};
if !filename.starts_with(prefix) || !filename.ends_with(suffix) {
continue;
}
if is_executable(entry.path()) {
let end = filename.len() - suffix.len();
commands.insert(
(filename[prefix.len()..end].to_string(),
Some(path.display().to_string()))
);
}
}
}
for cmd in commands::builtin() {
commands.insert((cmd.get_name().to_string(), None));
}
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
@ -316,7 +123,7 @@ fn find_closest(config: &Config, cmd: &str) -> Option<String> {
filtered.get(0).map(|slot| slot.1.clone())
}
fn execute_external_subcommand(config: &Config, cmd: &str, args: &[String]) -> CliResult {
fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&str]) -> CliResult {
let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
let path = search_directories(config)
.iter()
@ -354,42 +161,6 @@ fn execute_external_subcommand(config: &Config, cmd: &str, args: &[String]) -> C
Err(CliError::new(err, 101))
}
/// List all runnable commands
fn list_commands(config: &Config) -> BTreeSet<(String, Option<String>)> {
let prefix = "cargo-";
let suffix = env::consts::EXE_SUFFIX;
let mut commands = BTreeSet::new();
for dir in search_directories(config) {
let entries = match fs::read_dir(dir) {
Ok(entries) => entries,
_ => continue,
};
for entry in entries.filter_map(|e| e.ok()) {
let path = entry.path();
let filename = match path.file_name().and_then(|s| s.to_str()) {
Some(filename) => filename,
_ => continue,
};
if !filename.starts_with(prefix) || !filename.ends_with(suffix) {
continue;
}
if is_executable(entry.path()) {
let end = filename.len() - suffix.len();
commands.insert(
(filename[prefix.len()..end].to_string(),
Some(path.display().to_string()))
);
}
}
}
macro_rules! add_cmd {
($cmd:ident) => ({ commands.insert((stringify!($cmd).replace("_", "-"), None)); })
}
each_subcommand!(add_cmd);
commands
}
#[cfg(unix)]
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
use std::os::unix::prelude::*;

View File

@ -1,146 +0,0 @@
use std::env;
use cargo::core::Workspace;
use cargo::ops::{self, CompileOptions, MessageFormat, Packages};
use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::find_root_manifest_for_wd;
pub const USAGE: &'static str = "
Check a local package and all of its dependencies for errors
Usage:
cargo check [options]
Options:
-h, --help Print this message
-p SPEC, --package SPEC ... Package(s) to check
--all Check all packages in the workspace
--exclude SPEC ... Exclude packages from the check
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--lib Check only this package's library
--bin NAME Check only the specified binary
--bins Check all binaries
--example NAME Check only the specified example
--examples Check all examples
--test NAME Check only the specified test target
--tests Check all tests
--bench NAME Check only the specified bench target
--benches Check all benches
--all-targets Check all targets (lib and bin targets by default)
--release Check artifacts in release mode, with optimizations
--profile PROFILE Profile to build the selected target for
--features FEATURES Space-separated list of features to also check
--all-features Check all available features
--no-default-features Do not check the `default` feature
--target TRIPLE Check for the target triple
--manifest-path PATH Path to the manifest to compile
-v, --verbose ... Use verbose output
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be built. If it is not given, then the
current package is built. For more information on SPEC and its format, see the
`cargo help pkgid` command.
All packages in the workspace are checked if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
Compilation can be configured via the use of profiles which are configured in
the manifest. The default profile for this command is `dev`, but passing
the --release flag will use the `release` profile instead.
The `--profile test` flag can be used to check unit tests with the
`#[cfg(test)]` attribute.
";
#[derive(Deserialize)]
pub struct Options {
flag_package: Vec<String>,
flag_jobs: Option<u32>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_no_default_features: bool,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_release: bool,
flag_lib: bool,
flag_bin: Vec<String>,
flag_bins: bool,
flag_example: Vec<String>,
flag_examples: bool,
flag_test: Vec<String>,
flag_tests: bool,
flag_bench: Vec<String>,
flag_benches: bool,
flag_all_targets: bool,
flag_locked: bool,
flag_frozen: bool,
flag_all: bool,
flag_exclude: Vec<String>,
flag_profile: Option<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-check; args={:?}",
env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let ws = Workspace::new(&root, config)?;
let spec = Packages::from_flags(options.flag_all,
&options.flag_exclude,
&options.flag_package)?;
let test = match options.flag_profile.as_ref().map(|t| &t[..]) {
Some("test") => true,
None => false,
Some(profile) => {
let err = format_err!("unknown profile: `{}`, only `test` is \
currently supported", profile);
return Err(CliError::new(err, 101))
}
};
let opts = CompileOptions {
config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| &t[..]),
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec,
mode: ops::CompileMode::Check{test },
release: options.flag_release,
filter: ops::CompileFilter::new(options.flag_lib,
&options.flag_bin, options.flag_bins,
&options.flag_test, options.flag_tests,
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,
options.flag_all_targets),
message_format: options.flag_message_format,
target_rustdoc_args: None,
target_rustc_args: None,
};
ops::compile(&ws, &opts)?;
Ok(())
}

View File

@ -1,67 +0,0 @@
use std::env;
use cargo::core::Workspace;
use cargo::ops;
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};
#[derive(Deserialize)]
pub struct Options {
flag_package: Vec<String>,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_release: bool,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Remove artifacts that cargo has generated in the past
Usage:
cargo clean [options]
Options:
-h, --help Print this message
-p SPEC, --package SPEC ... Package to clean artifacts for
--manifest-path PATH Path to the manifest to the package to clean
--target TRIPLE Target triple to clean output for (default all)
--release Whether or not to clean release artifacts
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
If the --package argument is given, then SPEC is a package id specification
which indicates which package's artifacts should be cleaned out. If it is not
given, then all packages' artifacts are removed. For more information on SPEC
and its format, see the `cargo help pkgid` command.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-clean; args={:?}", env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let opts = ops::CleanOptions {
config,
spec: &options.flag_package,
target: options.flag_target.as_ref().map(|s| &s[..]),
release: options.flag_release,
};
let ws = Workspace::new(&root, config)?;
ops::clean(&ws, &opts)?;
Ok(())
}

169
src/bin/cli.rs Normal file
View File

@ -0,0 +1,169 @@
extern crate clap;
use clap::{AppSettings, Arg, ArgMatches};
use cargo::{self, Config, CliResult};
use super::list_commands;
use super::commands;
use command_prelude::*;
pub fn main(config: &mut Config) -> CliResult {
let args = cli().get_matches_safe()?;
let is_verbose = args.occurrences_of("verbose") > 0;
if args.is_present("version") {
let version = cargo::version();
println!("{}", version);
if is_verbose {
println!("release: {}.{}.{}",
version.major,
version.minor,
version.patch);
if let Some(ref cfg) = version.cfg_info {
if let Some(ref ci) = cfg.commit_info {
println!("commit-hash: {}", ci.commit_hash);
println!("commit-date: {}", ci.commit_date);
}
}
}
return Ok(());
}
if let Some(ref code) = args.value_of("explain") {
let mut procss = config.rustc()?.process();
procss.arg("--explain").arg(code).exec()?;
return Ok(());
}
if args.is_present("list") {
println!("Installed Commands:");
for command in list_commands(config) {
let (command, path) = command;
if is_verbose {
match path {
Some(p) => println!(" {:<20} {}", command, p),
None => println!(" {:<20}", command),
}
} else {
println!(" {}", command);
}
}
return Ok(());
}
if args.subcommand_name().is_none() {
}
execute_subcommand(config, args)
}
fn execute_subcommand(config: &mut Config, args: ArgMatches) -> CliResult {
config.configure(
args.occurrences_of("verbose") as u32,
if args.is_present("quiet") { Some(true) } else { None },
&args.value_of("color").map(|s| s.to_string()),
args.is_present("frozen"),
args.is_present("locked"),
&args.values_of_lossy("unstable-features").unwrap_or_default(),
)?;
let (cmd, args) = match args.subcommand() {
(cmd, Some(args)) => (cmd, args),
_ => {
cli().print_help()?;
return Ok(());
}
};
if let Some(exec) = commands::builtin_exec(cmd) {
return exec(config, args);
}
if let Some(mut alias) = super::aliased_command(config, cmd)? {
alias.extend(args.values_of("").unwrap_or_default().map(|s| s.to_string()));
let args = cli()
.setting(AppSettings::NoBinaryName)
.get_matches_from_safe(alias)?;
return execute_subcommand(config, args);
}
let mut ext_args: Vec<&str> = vec![cmd];
ext_args.extend(args.values_of("").unwrap_or_default());
super::execute_external_subcommand(config, cmd, &ext_args)
}
fn cli() -> App {
let app = App::new("cargo")
.settings(&[
AppSettings::UnifiedHelpMessage,
AppSettings::DeriveDisplayOrder,
AppSettings::VersionlessSubcommands,
AppSettings::AllowExternalSubcommands,
])
.about("")
.template("\
Rust's package manager
USAGE:
{usage}
OPTIONS:
{unified}
Some common cargo commands are (see all commands with --list):
build Compile the current project
check Analyze the current project and report errors, but don't build object files
clean Remove the target directory
doc Build this project's and its dependencies' documentation
new Create a new cargo project
init Create a new cargo project in an existing directory
run Build and execute src/main.rs
test Run the tests
bench Run the benchmarks
update Update dependencies listed in Cargo.lock
search Search registry for crates
publish Package and upload this project to the registry
install Install a Rust binary
uninstall Uninstall a Rust binary
See 'cargo help <command>' for more information on a specific command."
)
.arg(
opt("version", "Print version info and exit")
.short("V")
)
.arg(
opt("list", "List installed commands")
)
.arg(
opt("explain", "Run `rustc --explain CODE`")
.value_name("CODE")
)
.arg(
opt("verbose", "Use verbose output (-vv very verbose/build.rs output)")
.short("v").multiple(true).global(true)
)
.arg(
opt("quiet", "No output printed to stdout")
.short("q").global(true)
)
.arg(
opt("color", "Coloring: auto, always, never")
.value_name("WHEN").global(true)
)
.arg(
opt("frozen", "Require Cargo.lock and cache are up to date")
.global(true)
)
.arg(
opt("locked", "Require Cargo.lock is up to date")
.global(true)
)
.arg(
Arg::with_name("unstable-features").help("Unstable (nightly-only) flags to Cargo")
.short("Z").value_name("FLAG").multiple(true).global(true)
)
.subcommands(commands::builtin())
;
app
}

348
src/bin/command_prelude.rs Normal file
View File

@ -0,0 +1,348 @@
use std::path::PathBuf;
use clap::{self, SubCommand};
use cargo::CargoResult;
use cargo::core::Workspace;
use cargo::ops::{CompileMode, CompileOptions, CompileFilter, Packages, MessageFormat,
VersionControl, NewOptions};
use cargo::util::important_paths::find_root_manifest_for_wd;
pub use clap::{Arg, ArgMatches, AppSettings};
pub use cargo::{Config, CliResult, CliError};
pub type App = clap::App<'static, 'static>;
pub trait AppExt: Sized {
fn _arg(self, arg: Arg<'static, 'static>) -> Self;
fn arg_package(self, package: &'static str, all: &'static str, exclude: &'static str) -> Self {
self._arg(opt("package", package).short("p").value_name("SPEC").multiple(true))
._arg(opt("all", all))
._arg(opt("exclude", exclude).value_name("SPEC").multiple(true))
}
fn arg_single_package(self, package: &'static str) -> Self {
self._arg(opt("package", package).short("p").value_name("SPEC"))
}
fn arg_jobs(self) -> Self {
self._arg(
opt("jobs", "Number of parallel jobs, defaults to # of CPUs")
.short("j").value_name("N")
)
}
fn arg_targets_all(
self,
lib: &'static str,
bin: &'static str,
bins: &'static str,
examle: &'static str,
examles: &'static str,
test: &'static str,
tests: &'static str,
bench: &'static str,
benchs: &'static str,
all: &'static str,
) -> Self {
self.arg_targets_lib_bin(lib, bin, bins)
._arg(opt("example", examle).value_name("NAME").multiple(true))
._arg(opt("examples", examles))
._arg(opt("test", test).value_name("NAME").multiple(true))
._arg(opt("tests", tests))
._arg(opt("bench", bench).value_name("NAME").multiple(true))
._arg(opt("benches", benchs))
._arg(opt("all-targets", all))
}
fn arg_targets_lib_bin(
self,
lib: &'static str,
bin: &'static str,
bins: &'static str,
) -> Self {
self._arg(opt("lib", lib))
._arg(opt("bin", bin).value_name("NAME").multiple(true))
._arg(opt("bins", bins))
}
fn arg_targets_bins_examples(
self,
bin: &'static str,
bins: &'static str,
example: &'static str,
examples: &'static str,
) -> Self {
self._arg(opt("bin", bin).value_name("NAME").multiple(true))
._arg(opt("bins", bins))
._arg(opt("example", example).value_name("NAME").multiple(true))
._arg(opt("examples", examples))
}
fn arg_targets_bin_example(
self,
bin: &'static str,
example: &'static str,
) -> Self {
self._arg(opt("bin", bin).value_name("NAME").multiple(true))
._arg(opt("example", example).value_name("NAME").multiple(true))
}
fn arg_features(self) -> Self {
self
._arg(
opt("features", "Space-separated list of features to activate")
.value_name("FEATURES")
)
._arg(opt("all-features", "Activate all available features"))
._arg(opt("no-default-features", "Do not activate the `default` feature"))
}
fn arg_release(self, release: &'static str) -> Self {
self._arg(opt("release", release))
}
fn arg_target_triple(self, target: &'static str) -> Self {
self._arg(opt("target", target).value_name("TRIPLE"))
}
fn arg_manifest_path(self) -> Self {
self._arg(opt("manifest-path", "Path to Cargo.toml").value_name("PATH"))
}
fn arg_message_format(self) -> Self {
self._arg(
opt("message-format", "Error format")
.value_name("FMT")
.case_insensitive(true)
.possible_values(&["human", "json"]).default_value("human")
)
}
fn arg_new_opts(self) -> Self {
self._arg(
opt("vcs", "\
Initialize a new repository for the given version \
control system (git, hg, pijul, or fossil) or do not \
initialize any version control at all (none), overriding \
a global configuration.")
.value_name("VCS")
.possible_values(&["git", "hg", "pijul", "fossil", "none"])
)
._arg(opt("bin", "Use a binary (application) template [default]"))
._arg(opt("lib", "Use a library template"))
._arg(
opt("name", "Set the resulting package name, defaults to the directory name")
.value_name("NAME")
)
}
fn arg_index(self) -> Self {
self
._arg(
opt("index", "Registry index to upload the package to")
.value_name("INDEX")
)
._arg(
opt("host", "DEPRECATED, renamed to '--index'")
.value_name("HOST")
.hidden(true)
)
}
}
impl AppExt for App {
fn _arg(self, arg: Arg<'static, 'static>) -> Self {
self.arg(arg)
}
}
pub fn opt(name: &'static str, help: &'static str) -> Arg<'static, 'static> {
Arg::with_name(name).long(name).help(help)
}
pub fn subcommand(name: &'static str) -> App {
SubCommand::with_name(name)
.settings(&[
AppSettings::UnifiedHelpMessage,
AppSettings::DeriveDisplayOrder,
AppSettings::DontCollapseArgsInUsage,
])
}
pub trait ArgMatchesExt {
fn value_of_u32(&self, name: &str) -> CargoResult<Option<u32>> {
let arg = match self._value_of(name) {
None => None,
Some(arg) => Some(arg.parse::<u32>().map_err(|_| {
clap::Error::value_validation_auto(
format!("could not parse `{}` as a number", arg)
)
})?)
};
Ok(arg)
}
fn root_manifest(&self, config: &Config) -> CargoResult<PathBuf> {
let manifest_path = self._value_of("manifest-path");
find_root_manifest_for_wd(manifest_path, config.cwd())
}
fn workspace<'a>(&self, config: &'a Config) -> CargoResult<Workspace<'a>> {
let root = self.root_manifest(config)?;
let mut ws = Workspace::new(&root, config)?;
if config.cli_unstable().avoid_dev_deps {
ws.set_require_optional_deps(false);
}
Ok(ws)
}
fn jobs(&self) -> CargoResult<Option<u32>> {
self.value_of_u32("jobs")
}
fn target(&self) -> Option<String> {
self._value_of("target").map(|s| s.to_string())
}
fn compile_options<'a>(
&self,
config: &'a Config,
mode: CompileMode
) -> CargoResult<CompileOptions<'a>> {
let spec = Packages::from_flags(
self._is_present("all"),
self._values_of("exclude"),
self._values_of("package"),
)?;
let message_format = match self._value_of("message-format") {
None => MessageFormat::Human,
Some(f) => {
if f.eq_ignore_ascii_case("json") {
MessageFormat::Json
} else if f.eq_ignore_ascii_case("human") {
MessageFormat::Human
} else {
panic!("Impossible message format: {:?}", f)
}
}
};
let opts = CompileOptions {
config,
jobs: self.jobs()?,
target: self.target(),
features: self._values_of("features"),
all_features: self._is_present("all-features"),
no_default_features: self._is_present("no-default-features"),
spec,
mode,
release: self._is_present("release"),
filter: CompileFilter::new(self._is_present("lib"),
self._values_of("bin"), self._is_present("bins"),
self._values_of("test"), self._is_present("tests"),
self._values_of("example"), self._is_present("examples"),
self._values_of("bench"), self._is_present("benches"),
self._is_present("all-targets")),
message_format,
target_rustdoc_args: None,
target_rustc_args: None,
};
Ok(opts)
}
fn compile_options_for_single_package<'a>(
&self,
config: &'a Config,
mode: CompileMode
) -> CargoResult<CompileOptions<'a>> {
let mut compile_opts = self.compile_options(config, mode)?;
compile_opts.spec = Packages::Packages(self._values_of("package"));
Ok(compile_opts)
}
fn new_options(&self) -> CargoResult<NewOptions> {
let vcs = self._value_of("vcs").map(|vcs| match vcs {
"git" => VersionControl::Git,
"hg" => VersionControl::Hg,
"pijul" => VersionControl::Pijul,
"fossil" => VersionControl::Fossil,
"none" => VersionControl::NoVcs,
vcs => panic!("Impossible vcs: {:?}", vcs),
});
NewOptions::new(vcs,
self._is_present("bin"),
self._is_present("lib"),
self._value_of("path").unwrap().to_string(),
self._value_of("name").map(|s| s.to_string()))
}
fn registry(&self, config: &Config) -> CargoResult<Option<String>> {
match self._value_of("registry") {
Some(registry) => {
if !config.cli_unstable().unstable_options {
return Err(format_err!("registry option is an unstable feature and \
requires -Zunstable-options to use.").into());
}
Ok(Some(registry.to_string()))
}
None => Ok(None),
}
}
fn index(&self, config: &Config) -> CargoResult<Option<String>> {
// TODO: Deprecated
// remove once it has been decided --host can be removed
// We may instead want to repurpose the host flag, as
// mentioned in this issue
// https://github.com/rust-lang/cargo/issues/4208
let msg = "The flag '--host' is no longer valid.
Previous versions of Cargo accepted this flag, but it is being
deprecated. The flag is being renamed to 'index', as the flag
wants the location of the index. Please use '--index' instead.
This will soon become a hard error, so it's either recommended
to update to a fixed version or contact the upstream maintainer
about this warning.";
let index = match self._value_of("host") {
Some(host) => {
config.shell().warn(&msg)?;
Some(host.to_string())
}
None => self._value_of("index").map(|s| s.to_string())
};
Ok(index)
}
fn _value_of(&self, name: &str) -> Option<&str>;
fn _values_of(&self, name: &str) -> Vec<String>;
fn _is_present(&self, name: &str) -> bool;
}
impl<'a> ArgMatchesExt for ArgMatches<'a> {
fn _value_of(&self, name: &str) -> Option<&str> {
self.value_of(name)
}
fn _values_of(&self, name: &str) -> Vec<String> {
self.values_of(name).unwrap_or_default()
.map(|s| s.to_string())
.collect()
}
fn _is_present(&self, name: &str) -> bool {
self.is_present(name)
}
}
pub fn values(args: &ArgMatches, name: &str) -> Vec<String> {
args.values_of(name).unwrap_or_default()
.map(|s| s.to_string())
.collect()
}

96
src/bin/commands/bench.rs Normal file
View File

@ -0,0 +1,96 @@
use command_prelude::*;
use cargo::ops::{self, CompileMode, TestOptions};
pub fn cli() -> App {
subcommand("bench")
.setting(AppSettings::TrailingVarArg)
.about("Execute all benchmarks of a local package")
.arg(
Arg::with_name("BENCHNAME").help(
"If specified, only run benches containing this string in their names"
)
)
.arg(
Arg::with_name("args").help(
"Arguments for the bench binary"
).multiple(true).last(true)
)
.arg_targets_all(
"Benchmark only this package's library",
"Benchmark only the specified binary",
"Benchmark all binaries",
"Benchmark only the specified example",
"Benchmark all examples",
"Benchmark only the specified test target",
"Benchmark all tests",
"Benchmark only the specified bench target",
"Benchmark all benches",
"Benchmark all targets (default)",
)
.arg(
opt("no-run", "Compile, but don't run benchmarks")
)
.arg_package(
"Package to run benchmarks for",
"Benchmark all packages in the workspace",
"Exclude packages from the benchmark",
)
.arg_jobs()
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_manifest_path()
.arg_message_format()
.arg(
opt("no-fail-fast", "Run all benchmarks regardless of failure")
)
.after_help("\
All of the trailing arguments are passed to the benchmark binaries generated
for filtering benchmarks and generally providing options configuring how they
run.
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be benchmarked. If it is not given, then
the current package is benchmarked. For more information on SPEC and its format,
see the `cargo help pkgid` command.
All packages in the workspace are benchmarked if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
The --jobs argument affects the building of the benchmark executable but does
not affect how many jobs are used when running the benchmarks.
Compilation can be customized with the `bench` profile in the manifest.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let mut compile_opts = args.compile_options(config, CompileMode::Bench)?;
compile_opts.release = true;
let ops = TestOptions {
no_run: args.is_present("no-run"),
no_fail_fast: args.is_present("no-fail-fast"),
only_doc: false,
compile_opts,
};
let mut bench_args = vec![];
bench_args.extend(args.value_of("BENCHNAME").into_iter().map(|s| s.to_string()));
bench_args.extend(args.values_of("args").unwrap_or_default().map(|s| s.to_string()));
let err = ops::run_benches(&ws, &ops, &bench_args)?;
match err {
None => Ok(()),
Some(err) => {
Err(match err.exit.as_ref().and_then(|e| e.code()) {
Some(i) => CliError::new(format_err!("bench failed"), i),
None => CliError::new(err.into(), 101)
})
}
}
}

53
src/bin/commands/build.rs Normal file
View File

@ -0,0 +1,53 @@
use command_prelude::*;
use cargo::ops::{self, CompileMode};
pub fn cli() -> App {
subcommand("build").alias("b")
.about("Compile a local package and all of its dependencies")
.arg_package(
"Package to build",
"Build all packages in the workspace",
"Exclude packages from the build",
)
.arg_jobs()
.arg_targets_all(
"Build only this package's library",
"Build only the specified binary",
"Build all binaries",
"Build only the specified example",
"Build all examples",
"Build only the specified test target",
"Build all tests",
"Build only the specified bench target",
"Build all benches",
"Build all targets (lib and bin targets by default)",
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_manifest_path()
.arg_message_format()
.after_help("\
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be built. If it is not given, then the
current package is built. For more information on SPEC and its format, see the
`cargo help pkgid` command.
All packages in the workspace are built if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
Compilation can be configured via the use of profiles which are configured in
the manifest. The default profile for this command is `dev`, but passing
the --release flag will use the `release` profile instead.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let compile_opts = args.compile_options(config, CompileMode::Build)?;
ops::compile(&ws, &compile_opts)?;
Ok(())
}

69
src/bin/commands/check.rs Normal file
View File

@ -0,0 +1,69 @@
use command_prelude::*;
use cargo::ops::{self, CompileMode};
pub fn cli() -> App {
subcommand("check")
.about("Check a local package and all of its dependencies for errors")
.arg_package(
"Package(s) to check",
"Check all packages in the workspace",
"Exclude packages from the check",
)
.arg_jobs()
.arg_targets_all(
"Check only this package's library",
"Check only the specified binary",
"Check all binaries",
"Check only the specified example",
"Check all examples",
"Check only the specified test target",
"Check all tests",
"Check only the specified bench target",
"Check all benches",
"Check all targets (lib and bin targets by default)",
)
.arg_release("Check artifacts in release mode, with optimizations")
.arg(
opt("profile", "Profile to build the selected target for")
.value_name("PROFILE")
)
.arg_features()
.arg_target_triple("Check for the target triple")
.arg_manifest_path()
.arg_message_format()
.after_help("\
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be built. If it is not given, then the
current package is built. For more information on SPEC and its format, see the
`cargo help pkgid` command.
All packages in the workspace are checked if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
Compilation can be configured via the use of profiles which are configured in
the manifest. The default profile for this command is `dev`, but passing
the --release flag will use the `release` profile instead.
The `--profile test` flag can be used to check unit tests with the
`#[cfg(test)]` attribute.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let test = match args.value_of("profile") {
Some("test") => true,
None => false,
Some(profile) => {
let err = format_err!("unknown profile: `{}`, only `test` is \
currently supported", profile);
return Err(CliError::new(err, 101));
}
};
let mode = CompileMode::Check { test };
let compile_opts = args.compile_options(config, mode)?;
ops::compile(&ws, &compile_opts)?;
Ok(())
}

33
src/bin/commands/clean.rs Normal file
View File

@ -0,0 +1,33 @@
use command_prelude::*;
use cargo::ops::{self, CleanOptions};
pub fn cli() -> App {
subcommand("clean")
.about("Remove artifacts that cargo has generated in the past")
.arg(
opt("package", "Package to clean artifacts for")
.short("p").value_name("SPEC").multiple(true)
)
.arg_manifest_path()
.arg_target_triple("Target triple to clean output for (default all)")
.arg_release("Whether or not to clean release artifacts")
.after_help("\
If the --package argument is given, then SPEC is a package id specification
which indicates which package's artifacts should be cleaned out. If it is not
given, then all packages' artifacts are removed. For more information on SPEC
and its format, see the `cargo help pkgid` command.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let opts = CleanOptions {
config,
spec: values(args, "package"),
target: args.target(),
release: args.is_present("release"),
};
ops::clean(&ws, &opts)?;
Ok(())
}

55
src/bin/commands/doc.rs Normal file
View File

@ -0,0 +1,55 @@
use command_prelude::*;
use cargo::ops::{self, CompileMode, DocOptions};
pub fn cli() -> App {
subcommand("doc")
.about("Build a package's documentation")
.arg(
opt("open", "Opens the docs in a browser after the operation")
)
.arg_package(
"Package to document",
"Document all packages in the workspace",
"Exclude packages from the build",
)
.arg(
opt("no-deps", "Don't build documentation for dependencies")
)
.arg_jobs()
.arg_targets_lib_bin(
"Document only this package's library",
"Document only the specified binary",
"Document all binaries",
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_manifest_path()
.arg_message_format()
.after_help("\
By default the documentation for the local package and all dependencies is
built. The output is all placed in `target/doc` in rustdoc's usual format.
All packages in the workspace are documented if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be documented. If it is not given, then the
current package is documented. For more information on SPEC and its format, see
the `cargo help pkgid` command.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let mode = CompileMode::Doc { deps: !args.is_present("no-deps") };
let compile_opts = args.compile_options(config, mode)?;
let doc_opts = DocOptions {
open_result: args.is_present("open"),
compile_opts,
};
ops::doc(&ws, &doc_opts)?;
Ok(())
}

25
src/bin/commands/fetch.rs Normal file
View File

@ -0,0 +1,25 @@
use command_prelude::*;
use cargo::ops;
pub fn cli() -> App {
subcommand("fetch")
.about("Fetch dependencies of a package from the network")
.arg_manifest_path()
.after_help("\
If a lockfile is available, this command will ensure that all of the git
dependencies and/or registries dependencies are downloaded and locally
available. The network is never touched after a `cargo fetch` unless
the lockfile changes.
If the lockfile is not available, then this is the equivalent of
`cargo generate-lockfile`. A lockfile is generated and dependencies are also
all updated.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
ops::fetch(&ws)?;
Ok(())
}

View File

@ -0,0 +1,25 @@
use command_prelude::*;
use cargo::ops;
pub fn cli() -> App {
subcommand("generate-lockfile")
.about("Generate the lockfile for a project")
.arg_manifest_path()
.after_help("\
If a lockfile is available, this command will ensure that all of the git
dependencies and/or registries dependencies are downloaded and locally
available. The network is never touched after a `cargo fetch` unless
the lockfile changes.
If the lockfile is not available, then this is the equivalent of
`cargo generate-lockfile`. A lockfile is generated and dependencies are also
all updated.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
ops::generate_lockfile(&ws)?;
Ok(())
}

View File

@ -0,0 +1,26 @@
use command_prelude::*;
use cargo::core::{GitReference, SourceId, Source};
use cargo::sources::GitSource;
use cargo::util::ToUrl;
pub fn cli() -> App {
subcommand("git-checkout")
.about("Checkout a copy of a Git repository")
.arg(Arg::with_name("url").long("url").value_name("URL").required(true))
.arg(Arg::with_name("reference").long("reference").value_name("REF").required(true))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let url = args.value_of("url").unwrap().to_url()?;
let reference = args.value_of("reference").unwrap();
let reference = GitReference::Branch(reference.to_string());
let source_id = SourceId::for_git(&url, reference)?;
let mut source = GitSource::new(&source_id, config)?;
source.update()?;
Ok(())
}

17
src/bin/commands/init.rs Normal file
View File

@ -0,0 +1,17 @@
use command_prelude::*;
use cargo::ops;
pub fn cli() -> App {
subcommand("init")
.about("Create a new cargo package in an existing directory")
.arg(Arg::with_name("path").default_value("."))
.arg_new_opts()
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let opts = args.new_options()?;
ops::init(&opts, config)?;
config.shell().status("Created", format!("{} project", opts.kind))?;
Ok(())
}

127
src/bin/commands/install.rs Normal file
View File

@ -0,0 +1,127 @@
use command_prelude::*;
use cargo::core::{GitReference, SourceId};
use cargo::ops::{self, CompileMode};
use cargo::util::ToUrl;
pub fn cli() -> App {
subcommand("install")
.about("Create a new cargo package in an existing directory")
.arg(Arg::with_name("crate").multiple(true))
.arg(
opt("version", "Specify a version to install from crates.io")
.alias("vers").value_name("VERSION")
)
.arg(
opt("git", "Git URL to install the specified crate from")
.value_name("URL")
)
.arg(
opt("branch", "Branch to use when installing from git")
.value_name("BRANCH")
)
.arg(
opt("tag", "Tag to use when installing from git")
.value_name("TAG")
)
.arg(
opt("rev", "Specific commit to use when installing from git")
.value_name("SHA")
)
.arg(
opt("path", "Filesystem path to local crate to install")
.value_name("PATH")
)
.arg(opt("list", "list all installed packages and their versions"))
.arg_jobs()
.arg(
opt("force", "Force overwriting existing crates or binaries")
.short("f")
)
.arg_features()
.arg(opt("debug", "Build in debug mode instead of release mode"))
.arg_targets_bins_examples(
"Install only the specified binary",
"Install all binaries",
"Install only the specified example",
"Install all examples",
)
.arg(
opt("root", "Directory to install packages into")
.value_name("DIR")
)
.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).
There are multiple sources from which a crate can be installed. The default
location is crates.io but the `--git` and `--path` 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.
Crates from crates.io can optionally specify the version they wish to install
via the `--vers` flags, and similarly packages from git repositories can
optionally specify the branch, tag, or revision that should be installed. If a
crate has multiple binaries, the `--bin` argument can selectively install only
one of them, and if you'd rather install examples the `--example` argument can
be used as well.
By default cargo will refuse to overwrite existing binaries. The `--force` flag
enables overwriting existing binaries. Thus you can reinstall a crate with
`cargo install --force <crate>`.
As a special convenience, omitting the <crate> specification entirely will
install the crate in the current directory. That is, `install` is equivalent to
the more explicit `install --path .`.
If the source is crates.io or `--git` then by default the crate will be built
in a temporary target directory. To avoid this, the target directory can be
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.")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let mut compile_opts = args.compile_options(config, CompileMode::Build)?;
compile_opts.release = !args.is_present("debug");
let krates = args.values_of("crate").unwrap_or_default().collect::<Vec<_>>();
let source = if let Some(url) = args.value_of("git") {
let url = url.to_url()?;
let gitref = if let Some(branch) = args.value_of("branch") {
GitReference::Branch(branch.to_string())
} else if let Some(tag) = args.value_of("tag") {
GitReference::Tag(tag.to_string())
} else if let Some(rev) = args.value_of("rev") {
GitReference::Rev(rev.to_string())
} else {
GitReference::Branch("master".to_string())
};
SourceId::for_git(&url, gitref)?
} else if let Some(path) = args.value_of("path") {
SourceId::for_path(&config.cwd().join(path))?
} else if krates.is_empty() {
SourceId::for_path(config.cwd())?
} else {
SourceId::crates_io(config)?
};
let version = args.value_of("version");
let root = args.value_of("root");
if args.is_present("list") {
ops::install_list(root, config)?;
} else {
ops::install(root, krates, &source, version, &compile_opts, args.is_present("force"))?;
}
Ok(())
}

View File

@ -0,0 +1,29 @@
use command_prelude::*;
use cargo::print_json;
pub fn cli() -> App {
subcommand("locate-project")
.about("Checkout a copy of a Git repository")
.arg_manifest_path()
}
#[derive(Serialize)]
pub struct ProjectLocation {
root: String
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let root = args.root_manifest(config)?;
let root = root.to_str()
.ok_or_else(|| format_err!("your project path contains characters \
not representable in Unicode"))
.map_err(|e| CliError::new(e, 1))?
.to_string();
let location = ProjectLocation { root };
print_json(&location);
Ok(())
}

51
src/bin/commands/login.rs Normal file
View File

@ -0,0 +1,51 @@
use command_prelude::*;
use std::io::{self, BufRead};
use cargo::core::{SourceId, Source};
use cargo::sources::RegistrySource;
use cargo::util::{CargoError, CargoResultExt};
use cargo::ops;
pub fn cli() -> App {
subcommand("login")
.about("Save an api token from the registry locally. \
If token is not specified, it will be read from stdin.")
.arg(Arg::with_name("token"))
.arg(opt("host", "Host to set the token for").value_name("HOST"))
.arg(opt("registry", "Registry to use").value_name("REGISTRY"))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let registry = args.registry(config)?;
let token = match args.value_of("token") {
Some(token) => token.to_string(),
None => {
let host = match registry {
Some(ref _registry) => {
return Err(format_err!("token must be provided when \
--registry is provided.").into());
}
None => {
let src = SourceId::crates_io(config)?;
let mut src = RegistrySource::remote(&src, config);
src.update()?;
let config = src.config()?.unwrap();
args.value_of("host").map(|s| s.to_string())
.unwrap_or(config.api.unwrap())
}
};
println!("please visit {}me and paste the API Token below", host);
let mut line = String::new();
let input = io::stdin();
input.lock().read_line(&mut line).chain_err(|| {
"failed to read stdin"
}).map_err(CargoError::from)?;
line.trim().to_string()
}
};
ops::registry_login(config, token, registry)?;
Ok(())
}

View File

@ -0,0 +1,48 @@
use command_prelude::*;
use cargo::ops::{self, OutputMetadataOptions};
use cargo::print_json;
pub fn cli() -> App {
subcommand("metadata")
.about("Output the resolved dependencies of a project, \
the concrete used versions including overrides, \
in machine-readable format")
.arg_features()
.arg(
opt("no-deps", "Output information only about the root package \
and don't fetch dependencies")
)
.arg_manifest_path()
.arg(
opt("format-version", "Format version")
.value_name("VERSION").possible_value("1")
)
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let version = match args.value_of("format-version") {
None => {
config.shell().warn("\
please specify `--format-version` flag explicitly \
to avoid compatibility problems"
)?;
1
}
Some(version) => version.parse().unwrap(),
};
let options = OutputMetadataOptions {
features: values(args, "features"),
all_features: args.is_present("all-features"),
no_default_features: args.is_present("no-default-features"),
no_deps: args.is_present("no-deps"),
version,
};
let result = ops::output_metadata(&ws, &options)?;
print_json(&result);
Ok(())
}

101
src/bin/commands/mod.rs Normal file
View File

@ -0,0 +1,101 @@
use command_prelude::*;
pub fn builtin() -> Vec<App> {
vec![
bench::cli(),
build::cli(),
check::cli(),
clean::cli(),
doc::cli(),
fetch::cli(),
generate_lockfile::cli(),
git_checkout::cli(),
init::cli(),
install::cli(),
locate_project::cli(),
login::cli(),
metadata::cli(),
new::cli(),
owner::cli(),
package::cli(),
pkgid::cli(),
publish::cli(),
read_manifest::cli(),
run::cli(),
rustc::cli(),
rustdoc::cli(),
search::cli(),
test::cli(),
uninstall::cli(),
update::cli(),
verify_project::cli(),
version::cli(),
yank::cli(),
]
}
pub fn builtin_exec(cmd: & str) -> Option<fn(&mut Config, &ArgMatches) -> CliResult> {
let f = match cmd {
"bench" => bench::exec,
"build" => build::exec,
"check" => check::exec,
"clean" => clean::exec,
"doc" => doc::exec,
"fetch" => fetch::exec,
"generate-lockfile" => generate_lockfile::exec,
"git-checkout" => git_checkout::exec,
"init" => init::exec,
"install" => install::exec,
"locate-project" => locate_project::exec,
"login" => login::exec,
"metadata" => metadata::exec,
"new" => new::exec,
"owner" => owner::exec,
"package" => package::exec,
"pkgid" => pkgid::exec,
"publish" => publish::exec,
"read-manifest" => read_manifest::exec,
"run" => run::exec,
"rustc" => rustc::exec,
"rustdoc" => rustdoc::exec,
"search" => search::exec,
"test" => test::exec,
"uninstall" => uninstall::exec,
"update" => update::exec,
"verify-project" => verify_project::exec,
"version" => version::exec,
"yank" => yank::exec,
_ => return None,
};
Some(f)
}
pub mod bench;
pub mod build;
pub mod check;
pub mod clean;
pub mod doc;
pub mod fetch;
pub mod generate_lockfile;
pub mod git_checkout;
pub mod init;
pub mod install;
pub mod locate_project;
pub mod login;
pub mod metadata;
pub mod new;
pub mod owner;
pub mod package;
pub mod pkgid;
pub mod publish;
pub mod read_manifest;
pub mod run;
pub mod rustc;
pub mod rustdoc;
pub mod search;
pub mod test;
pub mod uninstall;
pub mod update;
pub mod verify_project;
pub mod version;
pub mod yank;

18
src/bin/commands/new.rs Normal file
View File

@ -0,0 +1,18 @@
use command_prelude::*;
use cargo::ops;
pub fn cli() -> App {
subcommand("new")
.about("Create a new cargo package at <path>")
.arg(Arg::with_name("path").required(true))
.arg_new_opts()
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let opts = args.new_options()?;
ops::new(&opts, config)?;
let path = args.value_of("path").unwrap();
config.shell().status("Created", format!("{} `{}` project", opts.kind, path))?;
Ok(())
}

47
src/bin/commands/owner.rs Normal file
View File

@ -0,0 +1,47 @@
use command_prelude::*;
use cargo::ops::{self, OwnersOptions};
pub fn cli() -> App {
subcommand("owner")
.about("Manage the owners of a crate on the registry")
.arg(Arg::with_name("crate"))
.arg(
opt("add", "Name of a user or team to add as an owner")
.short("a").value_name("LOGIN").multiple(true)
)
.arg(
opt("remove", "Name of a user or team to remove as an owner")
.short("r").value_name("LOGIN").multiple(true)
)
.arg(opt("list", "List owners of a crate").short("l"))
.arg(opt("index", "Registry index to modify owners for").value_name("INDEX"))
.arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
.arg(opt("registry", "Registry to use").value_name("REGISTRY"))
.after_help("\
This command will modify the owners for a package
on the specified registry(or
default).Note that owners of a package can upload new versions, yank old
versions.Explicitly named owners can also modify the set of owners, so take
caution!
See http://doc.crates.io/crates-io.html#cargo-owner for detailed documentation
and troubleshooting.")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let registry = args.registry(config)?;
let opts = OwnersOptions {
krate: args.value_of("crate").map(|s| s.to_string()),
token: args.value_of("token").map(|s| s.to_string()),
index: args.value_of("index").map(|s| s.to_string()),
to_add: args.values_of("add")
.map(|xs| xs.map(|s| s.to_string()).collect()),
to_remove: args.values_of("remove")
.map(|xs| xs.map(|s| s.to_string()).collect()),
list: args.is_present("list"),
registry,
};
ops::modify_owners(config, &opts)?;
Ok(())
}

View File

@ -0,0 +1,31 @@
use command_prelude::*;
use cargo::ops::{self, PackageOpts};
pub fn cli() -> App {
subcommand("package")
.about("Assemble the local package into a distributable tarball")
.arg(opt("list", "Print files included in a package without making one").short("l"))
.arg(opt("no-verify", "Don't verify the contents by building them"))
.arg(opt("no-metadata", "Ignore warnings about a lack of human-usable metadata"))
.arg(opt("allow-dirty", "Allow dirty working directories to be packaged"))
.arg_target_triple("Build for the target triple")
.arg_manifest_path()
.arg_jobs()
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
ops::package(&ws, &PackageOpts {
config,
verify: !args.is_present("no-verify"),
list: args.is_present("list"),
check_metadata: !args.is_present("no-metadata"),
allow_dirty: args.is_present("allow-dirty"),
target: args.target(),
jobs: args.jobs()?,
registry: None,
})?;
Ok(())
}

39
src/bin/commands/pkgid.rs Normal file
View File

@ -0,0 +1,39 @@
use command_prelude::*;
use cargo::ops;
pub fn cli() -> App {
subcommand("pkgid")
.about("Print a fully qualified package specification")
.arg(Arg::with_name("spec"))
.arg_single_package("Argument to get the package id specifier for")
.arg_manifest_path()
.after_help("\
Given a <spec> argument, print out the fully qualified package id specifier.
This command will generate an error if <spec> is ambiguous as to which package
it refers to in the dependency graph. If no <spec> is given, then the pkgid for
the local package is printed.
This command requires that a lockfile is available and dependencies have been
fetched.
Example Package IDs
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
http://crates.io/foo#1.2.3 | foo | 1.2.3 | http://crates.io/foo
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let spec = args.value_of("spec").or(args.value_of("package"));
let spec = ops::pkgid(&ws, spec)?;
println!("{}", spec);
Ok(())
}

View File

@ -0,0 +1,38 @@
use command_prelude::*;
use cargo::ops::{self, PublishOpts};
pub fn cli() -> App {
subcommand("publish")
.about("Upload a package to the registry")
.arg_index()
.arg(opt("token", "Token to use when uploading").value_name("TOKEN"))
.arg(opt("no-verify", "Don't verify the contents by building them"))
.arg(opt("allow-dirty", "Allow dirty working directories to be packaged"))
.arg_target_triple("Build for the target triple")
.arg_manifest_path()
.arg_jobs()
.arg(
opt("dry-run", "Perform all checks without uploading")
)
.arg(opt("registry", "Registry to publish to").value_name("REGISTRY"))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let registry = args.registry(config)?;
let ws = args.workspace(config)?;
let index = args.index(config)?;
ops::publish(&ws, &PublishOpts {
config,
token: args.value_of("token").map(|s| s.to_string()),
index,
verify: !args.is_present("no-verify"),
allow_dirty: args.is_present("allow-dirty"),
target: args.target(),
jobs: args.jobs()?,
dry_run: args.is_present("dry-run"),
registry,
})?;
Ok(())
}

View File

@ -0,0 +1,18 @@
use command_prelude::*;
use cargo::core::Package;
use cargo::print_json;
pub fn cli() -> App {
subcommand("read-manifest")
.about("Deprecated, use `cargo metadata --no-deps` instead.
Print a JSON representation of a Cargo.toml manifest.")
.arg_manifest_path()
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let root = args.root_manifest(config)?;
let pkg = Package::for_path(&root, config)?;
print_json(&pkg);
Ok(())
}

67
src/bin/commands/run.rs Normal file
View File

@ -0,0 +1,67 @@
use command_prelude::*;
use cargo::core::Verbosity;
use cargo::ops::{self, CompileMode, CompileFilter};
pub fn cli() -> App {
subcommand("run").alias("r")
.setting(AppSettings::TrailingVarArg)
.about("Run the main binary of the local package (src/main.rs)")
.arg(Arg::with_name("args").multiple(true))
.arg_targets_bin_example(
"Name of the bin target to run",
"Name of the example target to run",
)
.arg_single_package("Package with the target to run")
.arg_jobs()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_manifest_path()
.arg_message_format()
.after_help("\
If neither `--bin` nor `--example` are given, then if the project only has one
bin target it will be run. Otherwise `--bin` specifies the bin target to run,
and `--example` specifies the example target to run. At most one of `--bin` or
`--example` can be provided.
All of the trailing arguments are passed to the binary to run. If you're passing
arguments to both Cargo and the binary, the ones after `--` go to the binary,
the ones before go to Cargo.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let mut compile_opts = args.compile_options_for_single_package(
config, CompileMode::Build,
)?;
if !args.is_present("example") && !args.is_present("bin") {
compile_opts.filter = CompileFilter::Default {
required_features_filterable: false,
};
};
match ops::run(&ws, &compile_opts, &values(args, "args"))? {
None => Ok(()),
Some(err) => {
// If we never actually spawned the process then that sounds pretty
// bad and we always want to forward that up.
let exit = match err.exit {
Some(exit) => exit,
None => return Err(CliError::new(err.into(), 101)),
};
// If `-q` was passed then we suppress extra error information about
// a failed process, we assume the process itself printed out enough
// information about why it failed so we don't do so as well
let exit_code = exit.code().unwrap_or(101);
let is_quiet = config.shell().verbosity() == Verbosity::Quiet;
Err(if is_quiet {
CliError::code(exit_code)
} else {
CliError::new(err.into(), exit_code)
})
}
}
}

68
src/bin/commands/rustc.rs Normal file
View File

@ -0,0 +1,68 @@
use command_prelude::*;
use cargo::ops::{self, CompileMode};
pub fn cli() -> App {
subcommand("rustc")
.setting(AppSettings::TrailingVarArg)
.about("Compile a package and all of its dependencies")
.arg(Arg::with_name("args").multiple(true))
.arg_single_package("Package to build")
.arg_jobs()
.arg_targets_all(
"Build only this package's library",
"Build only the specified binary",
"Build all binaries",
"Build only the specified example",
"Build all examples",
"Build only the specified test target",
"Build all tests",
"Build only the specified bench target",
"Build all benches",
"Build all targets (lib and bin targets by default)",
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg(
opt("profile", "Profile to build the selected target for")
.value_name("PROFILE")
)
.arg_features()
.arg_target_triple("Target triple which compiles will be for")
.arg_manifest_path()
.arg_message_format()
.after_help("\
The specified target for the current package (or package specified by SPEC if
provided) will be compiled along with all of its dependencies. The specified
<args>... will all be passed to the final compiler invocation, not any of the
dependencies. Note that the compiler will still unconditionally receive
arguments such as -L, --extern, and --crate-type, and the specified <args>...
will simply be added to the compiler invocation.
This command requires that only one target is being compiled. If more than one
target is available for the current package the filters of --lib, --bin, etc,
must be used to select which target is compiled. To pass flags to all compiler
processes spawned by Cargo, use the $RUSTFLAGS environment variable or the
`build.rustflags` configuration option.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let mode = match args.value_of("profile") {
Some("dev") | None => CompileMode::Build,
Some("test") => CompileMode::Test,
Some("bench") => CompileMode::Bench,
Some("check") => CompileMode::Check { test: false },
Some(mode) => {
let err = format_err!("unknown profile: `{}`, use dev,
test, or bench", mode);
return Err(CliError::new(err, 101));
}
};
let mut compile_opts = args.compile_options_for_single_package(
config, mode,
)?;
compile_opts.target_rustc_args = Some(values(args, "args"));
ops::compile(&ws, &compile_opts)?;
Ok(())
}

View File

@ -0,0 +1,55 @@
use command_prelude::*;
use cargo::ops::{self, CompileMode, DocOptions};
pub fn cli() -> App {
subcommand("rustdoc")
.setting(AppSettings::TrailingVarArg)
.about("Build a package's documentation, using specified custom flags.")
.arg(Arg::with_name("args").multiple(true))
.arg(opt("open", "Opens the docs in a browser after the operation"))
.arg_single_package("Package to document")
.arg_jobs()
.arg_targets_all(
"Build only this package's library",
"Build only the specified binary",
"Build all binaries",
"Build only the specified example",
"Build all examples",
"Build only the specified test target",
"Build all tests",
"Build only the specified bench target",
"Build all benches",
"Build all targets (default)",
)
.arg_release("Build artifacts in release mode, with optimizations")
.arg_manifest_path()
.arg_message_format()
.after_help("\
The specified target for the current package (or package specified by SPEC if
provided) will be documented with the specified <opts>... being passed to the
final rustdoc invocation. Dependencies will not be documented as part of this
command. Note that rustdoc will still unconditionally receive arguments such
as -L, --extern, and --crate-type, and the specified <opts>... will simply be
added to the rustdoc invocation.
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be documented. If it is not given, then the
current package is documented. For more information on SPEC and its format, see
the `cargo help pkgid` command.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let mut compile_opts = args.compile_options_for_single_package(
config, CompileMode::Doc { deps: false },
)?;
compile_opts.target_rustdoc_args = Some(values(args, "args"));
let doc_opts = DocOptions {
open_result: args.is_present("open"),
compile_opts,
};
ops::doc(&ws, &doc_opts)?;
Ok(())
}

View File

@ -0,0 +1,28 @@
use command_prelude::*;
use std::cmp::min;
use cargo::ops;
pub fn cli() -> App {
subcommand("search")
.about("Search packages in crates.io")
.arg(Arg::with_name("query").multiple(true))
.arg_index()
.arg(
opt("limit", "Limit the number of results (default: 10, max: 100)")
.value_name("LIMIT")
)
.arg(opt("registry", "Registry to use").value_name("REGISTRY"))
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let registry = args.registry(config)?;
let index = args.index(config)?;
let limit = args.value_of_u32("limit")?;
let limit = min(100, limit.unwrap_or(10));
let query: Vec<&str> = args.values_of("query").unwrap_or_default().collect();
let query: String = query.join("+");
ops::search(&query, config, index, limit, registry)?;
Ok(())
}

125
src/bin/commands/test.rs Normal file
View File

@ -0,0 +1,125 @@
use command_prelude::*;
use cargo::ops::{self, CompileMode};
pub fn cli() -> App {
subcommand("test").alias("t")
.setting(AppSettings::TrailingVarArg)
.about("Execute all unit and integration tests of a local package")
.arg(
Arg::with_name("TESTNAME").help(
"If specified, only run tests containing this string in their names"
)
)
.arg(
Arg::with_name("args").help(
"Arguments for the test binary"
).multiple(true).last(true)
)
.arg_targets_all(
"Test only this package's library",
"Test only the specified binary",
"Test all binaries",
"Check that the specified examples compile",
"Check that all examples compile",
"Test only the specified test target",
"Test all tests",
"Test only the specified bench target",
"Test all benches",
"Test all targets (default)",
)
.arg(opt("doc", "Test only this library's documentation"))
.arg(
opt("no-run", "Compile, but don't run tests")
)
.arg(
opt("no-fail-fast", "Run all tests regardless of failure")
)
.arg_package(
"Package to run tests for",
"Test all packages in the workspace",
"Exclude packages from the test",
)
.arg_jobs()
.arg_release("Build artifacts in release mode, with optimizations")
.arg_features()
.arg_target_triple("Build for the target triple")
.arg_manifest_path()
.arg_message_format()
.after_help("\
All of the trailing arguments are passed to the test binaries generated for
filtering tests and generally providing options configuring how they run. For
example, this will run all tests with the name `foo` in their name:
cargo test foo
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be tested. If it is not given, then the
current package is tested. For more information on SPEC and its format, see the
`cargo help pkgid` command.
All packages in the workspace are tested if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
The --jobs argument affects the building of the test executable but does
not affect how many jobs are used when running the tests. The default value
for the --jobs argument is the number of CPUs. If you want to control the
number of simultaneous running test cases, pass the `--test-threads` option
to the test binaries:
cargo test -- --test-threads=1
Compilation can be configured via the `test` profile in the manifest.
By default the rust test harness hides output from test execution to
keep results readable. Test output can be recovered (e.g. for debugging)
by passing `--nocapture` to the test binaries:
cargo test -- --nocapture
To get the list of all options available for the test binaries use this:
cargo test -- --help
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let mut compile_opts = args.compile_options(config, CompileMode::Test)?;
let doc = args.is_present("doc");
if doc {
compile_opts.mode = ops::CompileMode::Doctest;
compile_opts.filter = ops::CompileFilter::new(true,
Vec::new(), false,
Vec::new(), false,
Vec::new(), false,
Vec::new(), false,
false);
}
let ops = ops::TestOptions {
no_run: args.is_present("no-run"),
no_fail_fast: args.is_present("no-fail-fast"),
only_doc: doc,
compile_opts,
};
// TESTNAME is actually an argument of the test binary, but it's
// important so we explicitly mention it and reconfigure
let mut test_args = vec![];
test_args.extend(args.value_of("TESTNAME").into_iter().map(|s| s.to_string()));
test_args.extend(args.values_of("args").unwrap_or_default().map(|s| s.to_string()));
let err = ops::run_tests(&ws, &ops, &test_args)?;
return match err {
None => Ok(()),
Some(err) => {
Err(match err.exit.as_ref().and_then(|e| e.code()) {
Some(i) => CliError::new(format_err!("{}", err.hint(&ws)), i),
None => CliError::new(err.into(), 101),
})
}
};
}

View File

@ -0,0 +1,30 @@
use command_prelude::*;
use cargo::ops;
pub fn cli() -> App {
subcommand("uninstall")
.about("Remove a Rust binary")
.arg(Arg::with_name("spec").multiple(true))
.arg(
opt("bin", "Only uninstall the binary NAME")
.value_name("NAME").multiple(true)
)
.arg(
opt("root", "Directory to uninstall packages from")
.value_name("DIR")
)
.after_help("\
The argument SPEC is a package id specification (see `cargo help pkgid`) to
specify which crate should be uninstalled. By default all binaries are
uninstalled for a crate but the `--bin` and `--example` flags can be used to
only uninstall particular binaries.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let root = args.value_of("root");
let specs = args.values_of("spec").unwrap_or_default().collect();
ops::uninstall(root, specs, &values(args, "bin"), config)?;
Ok(())
}

View File

@ -0,0 +1,52 @@
use command_prelude::*;
use cargo::ops::{self, UpdateOptions};
pub fn cli() -> App {
subcommand("update")
.about("Update dependencies as recorded in the local lock file")
.arg(
opt("package", "Package to clean artifacts for")
.short("p").value_name("SPEC").multiple(true)
)
.arg(opt("aggressive", "Force updating all dependencies of <name> as well"))
.arg(
opt("precise", "Update a single dependency to exactly PRECISE")
.value_name("PRECISE")
)
.arg_manifest_path()
.after_help("\
This command requires that a `Cargo.lock` already exists as generated by
`cargo build` or related commands.
If SPEC is given, then a conservative update of the lockfile will be
performed. This means that only the dependency specified by SPEC will be
updated. Its transitive dependencies will be updated only if SPEC cannot be
updated without updating dependencies. All other dependencies will remain
locked at their currently recorded versions.
If PRECISE is specified, then --aggressive must not also be specified. The
argument PRECISE is a string representing a precise revision that the package
being updated should be updated to. For example, if the package comes from a git
repository, then PRECISE would be the exact revision that the repository should
be updated to.
If SPEC is not given, then all dependencies will be re-resolved and
updated.
For more information about package id specifications, see `cargo help pkgid`.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let ws = args.workspace(config)?;
let update_opts = UpdateOptions {
aggressive: args.is_present("aggressive"),
precise: args.value_of("precise"),
to_update: values(args, "package"),
config,
};
ops::update_lockfile(&ws, &update_opts)?;
Ok(())
}

View File

@ -0,0 +1,45 @@
use command_prelude::*;
use std::collections::HashMap;
use std::process;
use std::fs::File;
use std::io::Read;
use toml;
use cargo::print_json;
pub fn cli() -> App {
subcommand("verify-project")
.about("Check correctness of crate manifest")
.arg_manifest_path()
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
fn fail(reason: &str, value: &str) -> ! {
let mut h = HashMap::new();
h.insert(reason.to_string(), value.to_string());
print_json(&h);
process::exit(1)
}
let mut contents = String::new();
let filename = match args.root_manifest(config) {
Ok(filename) => filename,
Err(e) => fail("invalid", &e.to_string()),
};
let file = File::open(&filename);
match file.and_then(|mut f| f.read_to_string(&mut contents)) {
Ok(_) => {}
Err(e) => fail("invalid", &format!("error reading file: {}", e))
};
if contents.parse::<toml::Value>().is_err() {
fail("invalid", "invalid-format");
}
let mut h = HashMap::new();
h.insert("success".to_string(), "true".to_string());
print_json(&h);
Ok(())
}

View File

@ -0,0 +1,13 @@
use command_prelude::*;
use cargo;
pub fn cli() -> App {
subcommand("version")
.about("Show version information")
}
pub fn exec(_config: &mut Config, _args: &ArgMatches) -> CliResult {
println!("{}", cargo::version());
Ok(())
}

38
src/bin/commands/yank.rs Normal file
View File

@ -0,0 +1,38 @@
use command_prelude::*;
use cargo::ops;
pub fn cli() -> App {
subcommand("yank")
.about("Remove a pushed crate from the index")
.arg(Arg::with_name("crate"))
.arg(
opt("vers", "The version to yank or un-yank").value_name("VERSION")
)
.arg(opt("undo", "Undo a yank, putting a version back into the index"))
.arg(opt("index", "Registry index to yank from").value_name("INDEX"))
.arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
.arg(opt("registry", "Registry to use").value_name("REGISTRY"))
.after_help("\
The yank command removes a previously pushed crate's version from the server's
index. This command does not delete any data, and the crate will still be
available for download via the registry's download link.
Note that existing crates locked to a yanked version will still be able to
download the yanked version to use it. Cargo will, however, not allow any new
crates to be locked to any yanked version.
")
}
pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
let registry = args.registry(config)?;
ops::yank(config,
args.value_of("crate").map(|s| s.to_string()),
args.value_of("vers").map(|s| s.to_string()),
args.value_of("token").map(|s| s.to_string()),
args.value_of("index").map(|s| s.to_string()),
args.is_present("undo"),
registry)?;
Ok(())
}

View File

@ -1,126 +0,0 @@
use std::env;
use cargo::core::Workspace;
use cargo::ops::{self, MessageFormat, Packages};
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};
#[derive(Deserialize)]
pub struct Options {
flag_target: Option<String>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_jobs: Option<u32>,
flag_manifest_path: Option<String>,
flag_no_default_features: bool,
flag_no_deps: bool,
flag_open: bool,
flag_release: bool,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_package: Vec<String>,
flag_lib: bool,
flag_bin: Vec<String>,
flag_bins: bool,
flag_frozen: bool,
flag_locked: bool,
flag_all: bool,
flag_exclude: Vec<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Build a package's documentation
Usage:
cargo doc [options]
Options:
-h, --help Print this message
--open Opens the docs in a browser after the operation
-p SPEC, --package SPEC ... Package to document
--all Document all packages in the workspace
--exclude SPEC ... Exclude packages from the build
--no-deps Don't build documentation for dependencies
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--lib Document only this package's library
--bin NAME Document only the specified binary
--bins Document all binaries
--release Build artifacts in release mode, with optimizations
--features FEATURES Space-separated list of features to also build
--all-features Build all available features
--no-default-features Do not build the `default` feature
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest to document
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
By default the documentation for the local package and all dependencies is
built. The output is all placed in `target/doc` in rustdoc's usual format.
All packages in the workspace are documented if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be documented. If it is not given, then the
current package is documented. For more information on SPEC and its format, see
the `cargo help pkgid` command.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-check; args={:?}",
env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let ws = Workspace::new(&root, config)?;
let spec = Packages::from_flags(options.flag_all,
&options.flag_exclude,
&options.flag_package)?;
let empty = Vec::new();
let doc_opts = ops::DocOptions {
open_result: options.flag_open,
compile_opts: ops::CompileOptions {
config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| &t[..]),
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec,
filter: ops::CompileFilter::new(options.flag_lib,
&options.flag_bin, options.flag_bins,
&empty, false,
&empty, false,
&empty, false,
false),
message_format: options.flag_message_format,
release: options.flag_release,
mode: ops::CompileMode::Doc {
deps: !options.flag_no_deps,
},
target_rustc_args: None,
target_rustdoc_args: None,
},
};
ops::doc(&ws, &doc_opts)?;
Ok(())
}

View File

@ -1,56 +0,0 @@
use cargo::core::Workspace;
use cargo::ops;
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::find_root_manifest_for_wd;
#[derive(Deserialize)]
pub struct Options {
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Fetch dependencies of a package from the network.
Usage:
cargo fetch [options]
Options:
-h, --help Print this message
--manifest-path PATH Path to the manifest to fetch dependencies for
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
If a lockfile is available, this command will ensure that all of the git
dependencies and/or registries dependencies are downloaded and locally
available. The network is never touched after a `cargo fetch` unless
the lockfile changes.
If the lockfile is not available, then this is the equivalent of
`cargo generate-lockfile`. A lockfile is generated and dependencies are also
all updated.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let ws = Workspace::new(&root, config)?;
ops::fetch(&ws)?;
Ok(())
}

View File

@ -1,50 +0,0 @@
use std::env;
use cargo::core::Workspace;
use cargo::ops;
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::find_root_manifest_for_wd;
#[derive(Deserialize)]
pub struct Options {
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Generate the lockfile for a project
Usage:
cargo generate-lockfile [options]
Options:
-h, --help Print this message
--manifest-path PATH Path to the manifest to generate a lockfile for
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-generate-lockfile; args={:?}", env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let ws = Workspace::new(&root, config)?;
ops::generate_lockfile(&ws)?;
Ok(())
}

View File

@ -1,54 +0,0 @@
use cargo::core::source::{Source, SourceId, GitReference};
use cargo::sources::git::{GitSource};
use cargo::util::{Config, CliResult, ToUrl};
#[derive(Deserialize)]
pub struct Options {
flag_url: String,
flag_reference: String,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Checkout a copy of a Git repository
Usage:
cargo git-checkout [options] --url=URL --reference=REF
cargo git-checkout -h | --help
Options:
-h, --help Print this message
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let Options { flag_url: url, flag_reference: reference, .. } = options;
let url = url.to_url()?;
let reference = GitReference::Branch(reference.clone());
let source_id = SourceId::for_git(&url, reference)?;
let mut source = GitSource::new(&source_id, config)?;
source.update()?;
Ok(())
}

View File

@ -1,23 +0,0 @@
use cargo::util::{CliResult, CliError, Config};
#[derive(Deserialize)]
pub struct Options;
pub const USAGE: &'static str = "
Get some help with a cargo command.
Usage:
cargo help <command>
cargo help -h | --help
Options:
-h, --help Print this message
";
pub fn execute(_: Options, _: &mut Config) -> CliResult {
// This is a dummy command just so that `cargo help help` works.
// The actual delegation of help flag to subcommands is handled by the
// cargo command.
Err(CliError::new(format_err!("help command should not be executed directly"),
101))
}

View File

@ -1,70 +0,0 @@
use std::env;
use cargo::ops;
use cargo::util::{CliResult, Config};
#[derive(Deserialize)]
pub struct Options {
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_bin: bool,
flag_lib: bool,
arg_path: Option<String>,
flag_name: Option<String>,
flag_vcs: Option<ops::VersionControl>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Create a new cargo package in an existing directory
Usage:
cargo init [options] [<path>]
cargo init -h | --help
Options:
-h, --help Print this message
--vcs VCS Initialize a new repository for the given version
control system (git, hg, pijul, or fossil) or do not
initialize any version control at all (none), overriding
a global configuration.
--bin Use a binary (application) template [default]
--lib Use a library template
--name NAME Set the resulting package name
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-init; args={:?}", env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let Options { flag_bin, flag_lib, arg_path, flag_name, flag_vcs, .. } = options;
let path = &arg_path.unwrap_or_else(|| String::from("."));
let opts = ops::NewOptions::new(flag_vcs,
flag_bin,
flag_lib,
path,
flag_name.as_ref().map(|s| s.as_ref()))?;
ops::init(&opts, config)?;
config.shell().status("Created", format!("{} project", opts.kind))?;
Ok(())
}

View File

@ -1,175 +0,0 @@
use cargo::ops;
use cargo::core::{SourceId, GitReference};
use cargo::util::{CliResult, Config, ToUrl};
#[derive(Deserialize)]
pub struct Options {
flag_jobs: Option<u32>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_no_default_features: bool,
flag_debug: bool,
flag_bin: Vec<String>,
flag_bins: bool,
flag_example: Vec<String>,
flag_examples: bool,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_root: Option<String>,
flag_list: bool,
flag_force: bool,
flag_frozen: bool,
flag_locked: bool,
arg_crate: Vec<String>,
flag_vers: Option<String>,
flag_version: Option<String>,
flag_git: Option<String>,
flag_branch: Option<String>,
flag_tag: Option<String>,
flag_rev: Option<String>,
flag_path: Option<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Install a Rust binary
Usage:
cargo install [options] [<crate>...]
cargo install [options] --list
Specifying what crate to install:
--vers VERSION Specify a version to install from crates.io
--version VERSION
--git URL Git URL to install the specified crate from
--branch BRANCH Branch to use when installing from git
--tag TAG Tag to use when installing from git
--rev SHA Specific commit to use when installing from git
--path PATH Filesystem path to local crate to install
Build and install options:
-h, --help Print this message
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
-f, --force Force overwriting existing crates or binaries
--features FEATURES Space-separated list of features to activate
--all-features Build all available features
--no-default-features Do not build the `default` feature
--debug Build in debug mode instead of release mode
--bin NAME Install only the specified binary
--bins Install all binaries
--example NAME Install only the specified example
--examples Install all examples
--root DIR Directory to install packages into
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet Less output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
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).
There are multiple sources from which a crate can be installed. The default
location is crates.io but the `--git` and `--path` 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.
Crates from crates.io can optionally specify the version they wish to install
via the `--vers` flags, and similarly packages from git repositories can
optionally specify the branch, tag, or revision that should be installed. If a
crate has multiple binaries, the `--bin` argument can selectively install only
one of them, and if you'd rather install examples the `--example` argument can
be used as well.
By default cargo will refuse to overwrite existing binaries. The `--force` flag
enables overwriting existing binaries. Thus you can reinstall a crate with
`cargo install --force <crate>`.
As a special convenience, omitting the <crate> specification entirely will
install the crate in the current directory. That is, `install` is equivalent to
the more explicit `install --path .`.
If the source is crates.io or `--git` then by default the crate will be built
in a temporary target directory. To avoid this, the target directory can be
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.
The `--list` option will list all installed packages (and their versions).
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let compile_opts = ops::CompileOptions {
config,
jobs: options.flag_jobs,
target: None,
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec: ops::Packages::Packages(&[]),
mode: ops::CompileMode::Build,
release: !options.flag_debug,
filter: ops::CompileFilter::new(false,
&options.flag_bin, options.flag_bins,
&[], false,
&options.flag_example, options.flag_examples,
&[], false,
false),
message_format: ops::MessageFormat::Human,
target_rustc_args: None,
target_rustdoc_args: None,
};
let source = if let Some(url) = options.flag_git {
let url = url.to_url()?;
let gitref = if let Some(branch) = options.flag_branch {
GitReference::Branch(branch)
} else if let Some(tag) = options.flag_tag {
GitReference::Tag(tag)
} else if let Some(rev) = options.flag_rev {
GitReference::Rev(rev)
} else {
GitReference::Branch("master".to_string())
};
SourceId::for_git(&url, gitref)?
} else if let Some(path) = options.flag_path {
SourceId::for_path(&config.cwd().join(path))?
} else if options.arg_crate.is_empty() {
SourceId::for_path(config.cwd())?
} else {
SourceId::crates_io(config)?
};
let krates = options.arg_crate.iter().map(|s| &s[..]).collect::<Vec<_>>();
let vers = match (&options.flag_vers, &options.flag_version) {
(&Some(_), &Some(_)) => return Err(format_err!("invalid arguments").into()),
(&Some(ref v), _) | (_, &Some(ref v)) => Some(v.as_ref()),
_ => None,
};
let root = options.flag_root.as_ref().map(|s| &s[..]);
if options.flag_list {
ops::install_list(root, config)?;
} else {
ops::install(root, krates, &source, vers, &compile_opts, options.flag_force)?;
}
Ok(())
}

View File

@ -1,38 +0,0 @@
use cargo;
use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};
#[derive(Deserialize)]
pub struct LocateProjectFlags {
flag_manifest_path: Option<String>,
}
pub const USAGE: &'static str = "
Print a JSON representation of a Cargo.toml file's location
Usage:
cargo locate-project [options]
Options:
--manifest-path PATH Path to the manifest to locate
-h, --help Print this message
";
#[derive(Serialize)]
pub struct ProjectLocation {
root: String
}
pub fn execute(flags: LocateProjectFlags, config: &mut Config) -> CliResult {
let root = find_root_manifest_for_wd(flags.flag_manifest_path, config.cwd())?;
let string = root.to_str()
.ok_or_else(|| format_err!("your project path contains \
characters not representable in \
Unicode"))
.map_err(|e| CliError::new(e, 1))?;
let location = ProjectLocation { root: string.to_string() };
cargo::print_json(&location);
Ok(())
}

View File

@ -1,83 +0,0 @@
use std::io::prelude::*;
use std::io;
use cargo::ops;
use cargo::core::{SourceId, Source};
use cargo::sources::RegistrySource;
use cargo::util::{CliResult, CargoResultExt, Config, CargoError};
#[derive(Deserialize)]
pub struct Options {
flag_host: Option<String>,
arg_token: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}
pub const USAGE: &'static str = "
Save an api token from the registry locally. If token is not specified, it will be read from stdin.
Usage:
cargo login [options] [<token>]
Options:
-h, --help Print this message
--host HOST Host to set the token for
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
--registry REGISTRY Registry to use
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
if options.flag_registry.is_some() && !config.cli_unstable().unstable_options {
return Err(format_err!("registry option is an unstable feature and \
requires -Zunstable-options to use.").into());
}
let token = match options.arg_token {
Some(token) => token,
None => {
let host = match options.flag_registry {
Some(ref _registry) => {
return Err(format_err!("token must be provided when \
--registry is provided.").into())
}
None => {
let src = SourceId::crates_io(config)?;
let mut src = RegistrySource::remote(&src, config);
src.update()?;
let config = src.config()?.unwrap();
options.flag_host.clone().unwrap_or(config.api.unwrap())
}
};
println!("please visit {}me and paste the API Token below", host);
let mut line = String::new();
let input = io::stdin();
input.lock().read_line(&mut line).chain_err(|| {
"failed to read stdin"
}).map_err(CargoError::from)?;
line.trim().to_string()
}
};
ops::registry_login(config, token, options.flag_registry)?;
Ok(())
}

View File

@ -1,75 +0,0 @@
use cargo;
use cargo::core::Workspace;
use cargo::ops::{output_metadata, OutputMetadataOptions};
use cargo::util::important_paths::find_root_manifest_for_wd;
use cargo::util::{CliResult, Config};
#[derive(Deserialize)]
pub struct Options {
flag_color: Option<String>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_format_version: Option<u32>,
flag_manifest_path: Option<String>,
flag_no_default_features: bool,
flag_no_deps: bool,
flag_quiet: Option<bool>,
flag_verbose: u32,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Output the resolved dependencies of a project, the concrete used versions
including overrides, in machine-readable format.
Usage:
cargo metadata [options]
Options:
-h, --help Print this message
--features FEATURES Space-separated list of features
--all-features Build all available features
--no-default-features Do not include the `default` feature
--no-deps Output information only about the root package
and don't fetch dependencies.
--manifest-path PATH Path to the manifest
--format-version VERSION Format version
Valid values: 1
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let manifest = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
if options.flag_format_version.is_none() {
config.shell().warn("please specify `--format-version` flag explicitly to \
avoid compatibility problems")?
}
let options = OutputMetadataOptions {
features: options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
no_deps: options.flag_no_deps,
version: options.flag_format_version.unwrap_or(1),
};
let ws = Workspace::new(&manifest, config)?;
let result = output_metadata(&ws, &options)?;
cargo::print_json(&result);
Ok(())
}

View File

@ -1,69 +0,0 @@
use std::env;
use cargo::ops;
use cargo::util::{CliResult, Config};
#[derive(Deserialize)]
pub struct Options {
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_bin: bool,
flag_lib: bool,
arg_path: String,
flag_name: Option<String>,
flag_vcs: Option<ops::VersionControl>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Create a new cargo package at <path>
Usage:
cargo new [options] <path>
cargo new -h | --help
Options:
-h, --help Print this message
--vcs VCS Initialize a new repository for the given version
control system (git, hg, pijul, or fossil) or do not
initialize any version control at all (none), overriding
a global configuration.
--bin Use a binary (application) template [default]
--lib Use a library template
--name NAME Set the resulting package name, defaults to the value of <path>
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-new; args={:?}", env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let Options { flag_bin, flag_lib, arg_path, flag_name, flag_vcs, .. } = options;
let opts = ops::NewOptions::new(flag_vcs,
flag_bin,
flag_lib,
&arg_path,
flag_name.as_ref().map(|s| s.as_ref()))?;
ops::new(&opts, config)?;
config.shell().status("Created", format!("{} `{}` project", opts.kind, arg_path))?;
Ok(())
}

View File

@ -1,77 +0,0 @@
use cargo::ops;
use cargo::util::{CliResult, Config};
#[derive(Deserialize)]
pub struct Options {
arg_crate: Option<String>,
flag_token: Option<String>,
flag_add: Option<Vec<String>>,
flag_remove: Option<Vec<String>>,
flag_index: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_list: bool,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}
pub const USAGE: &'static str = "
Manage the owners of a crate on the registry
Usage:
cargo owner [options] [<crate>]
Options:
-h, --help Print this message
-a, --add LOGIN Name of a user or team to add as an owner
-r, --remove LOGIN Name of a user or team to remove as an owner
-l, --list List owners of a crate
--index INDEX Registry index to modify owners for
--token TOKEN API token to use when authenticating
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
--registry REGISTRY Registry to use
This command will modify the owners for a package on the specified registry (or
default). Note that owners of a package can upload new versions, yank old
versions. Explicitly named owners can also modify the set of owners, so take
caution!
See http://doc.crates.io/crates-io.html#cargo-owner for detailed documentation
and troubleshooting.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let opts = ops::OwnersOptions {
krate: options.arg_crate,
token: options.flag_token,
index: options.flag_index,
to_add: options.flag_add,
to_remove: options.flag_remove,
list: options.flag_list,
registry: options.flag_registry,
};
if opts.registry.is_some() && !config.cli_unstable().unstable_options {
return Err(format_err!("registry option is an unstable feature and \
requires -Zunstable-options to use.").into())
}
ops::modify_owners(config, &opts)?;
Ok(())
}

View File

@ -1,67 +0,0 @@
use cargo::core::Workspace;
use cargo::ops;
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::find_root_manifest_for_wd;
#[derive(Deserialize)]
pub struct Options {
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_no_verify: bool,
flag_no_metadata: bool,
flag_list: bool,
flag_allow_dirty: bool,
flag_jobs: Option<u32>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Assemble the local package into a distributable tarball
Usage:
cargo package [options]
Options:
-h, --help Print this message
-l, --list Print files included in a package without making one
--no-verify Don't verify the contents by building them
--no-metadata Ignore warnings about a lack of human-usable metadata
--allow-dirty Allow dirty working directories to be packaged
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest to compile
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let ws = Workspace::new(&root, config)?;
ops::package(&ws, &ops::PackageOpts {
config,
verify: !options.flag_no_verify,
list: options.flag_list,
check_metadata: !options.flag_no_metadata,
allow_dirty: options.flag_allow_dirty,
target: options.flag_target.as_ref().map(|t| &t[..]),
jobs: options.flag_jobs,
registry: None,
})?;
Ok(())
}

View File

@ -1,80 +0,0 @@
use cargo::core::Workspace;
use cargo::ops;
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};
#[derive(Deserialize)]
pub struct Options {
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_manifest_path: Option<String>,
flag_frozen: bool,
flag_locked: bool,
flag_package: Option<String>,
arg_spec: Option<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Print a fully qualified package specification
Usage:
cargo pkgid [options] [<spec>]
Options:
-h, --help Print this message
-p SPEC, --package SPEC Argument to get the package id specifier for
--manifest-path PATH Path to the manifest to the package to clean
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
Given a <spec> argument, print out the fully qualified package id specifier.
This command will generate an error if <spec> is ambiguous as to which package
it refers to in the dependency graph. If no <spec> is given, then the pkgid for
the local package is printed.
This command requires that a lockfile is available and dependencies have been
fetched.
Example Package IDs
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
http://crates.io/foo#1.2.3 | foo | 1.2.3 | http://crates.io/foo
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path.clone(), config.cwd())?;
let ws = Workspace::new(&root, config)?;
let spec = if options.arg_spec.is_some() {
options.arg_spec
} else if options.flag_package.is_some() {
options.flag_package
} else {
None
};
let spec = spec.as_ref().map(|s| &s[..]);
let spec = ops::pkgid(&ws, spec)?;
println!("{}", spec);
Ok(())
}

View File

@ -1,113 +0,0 @@
use cargo::core::Workspace;
use cargo::ops;
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::find_root_manifest_for_wd;
#[derive(Deserialize)]
pub struct Options {
flag_index: Option<String>,
flag_host: Option<String>, // TODO: Deprecated, remove
flag_token: Option<String>,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_no_verify: bool,
flag_allow_dirty: bool,
flag_jobs: Option<u32>,
flag_dry_run: bool,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}
pub const USAGE: &'static str = "
Upload a package to the registry
Usage:
cargo publish [options]
Options:
-h, --help Print this message
--index INDEX Registry index to upload the package to
--host HOST DEPRECATED, renamed to '--index'
--token TOKEN Token to use when uploading
--no-verify Don't verify package tarball before publish
--allow-dirty Allow publishing with a dirty source directory
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest of the package to publish
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--dry-run Perform all checks without uploading
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
--registry REGISTRY Registry to publish to
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let Options {
flag_token: token,
flag_index: index,
flag_host: host, // TODO: Deprecated, remove
flag_manifest_path,
flag_no_verify: no_verify,
flag_allow_dirty: allow_dirty,
flag_jobs: jobs,
flag_dry_run: dry_run,
flag_target: target,
flag_registry: registry,
..
} = options;
if registry.is_some() && !config.cli_unstable().unstable_options {
return Err(format_err!("registry option is an unstable feature and \
requires -Zunstable-options to use.").into())
}
// TODO: Deprecated
// remove once it has been decided --host can be removed
// We may instead want to repurpose the host flag, as
// mentioned in this issue
// https://github.com/rust-lang/cargo/issues/4208
let msg = "The flag '--host' is no longer valid.
Previous versions of Cargo accepted this flag, but it is being
deprecated. The flag is being renamed to 'index', as the flag
wants the location of the index to which to publish. Please
use '--index' instead.
This will soon become a hard error, so it's either recommended
to update to a fixed version or contact the upstream maintainer
about this warning.";
let root = find_root_manifest_for_wd(flag_manifest_path.clone(), config.cwd())?;
let ws = Workspace::new(&root, config)?;
ops::publish(&ws, &ops::PublishOpts {
config,
token,
index:
if host.clone().is_none() || host.clone().unwrap().is_empty() { index }
else { config.shell().warn(&msg)?; host }, // TODO: Deprecated, remove
verify: !no_verify,
allow_dirty,
target: target.as_ref().map(|t| &t[..]),
jobs,
dry_run,
registry,
})?;
Ok(())
}

View File

@ -1,39 +0,0 @@
use std::env;
use cargo;
use cargo::core::Package;
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};
#[derive(Deserialize)]
pub struct Options {
flag_manifest_path: Option<String>,
flag_color: Option<String>,
}
pub const USAGE: &'static str = "
Deprecated, use `cargo metadata --no-deps` instead.
Print a JSON representation of a Cargo.toml manifest.
Usage:
cargo read-manifest [options]
cargo read-manifest -h | --help
Options:
-h, --help Print this message
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
--manifest-path PATH Path to the manifest
--color WHEN Coloring: auto, always, never
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-read-manifest; args={:?}",
env::args().collect::<Vec<_>>());
config.shell().set_color_choice(options.flag_color.as_ref().map(|s| &s[..]))?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let pkg = Package::for_path(&root, config)?;
cargo::print_json(&pkg);
Ok(())
}

View File

@ -1,135 +0,0 @@
use std::iter::FromIterator;
use cargo::core::Workspace;
use cargo::ops::{self, MessageFormat, Packages};
use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};
#[derive(Deserialize)]
pub struct Options {
flag_bin: Option<String>,
flag_example: Option<String>,
flag_package: Option<String>,
flag_jobs: Option<u32>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_no_default_features: bool,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_release: bool,
flag_frozen: bool,
flag_locked: bool,
arg_args: Vec<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Run the main binary of the local package (src/main.rs)
Usage:
cargo run [options] [--] [<args>...]
Options:
-h, --help Print this message
--bin NAME Name of the bin target to run
--example NAME Name of the example target to run
-p SPEC, --package SPEC Package with the target to run
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--release Build artifacts in release mode, with optimizations
--features FEATURES Space-separated list of features to also build
--all-features Build all available features
--no-default-features Do not build the `default` feature
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest to execute
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
If neither `--bin` nor `--example` are given, then if the project only has one
bin target it will be run. Otherwise `--bin` specifies the bin target to run,
and `--example` specifies the example target to run. At most one of `--bin` or
`--example` can be provided.
All of the trailing arguments are passed to the binary to run. If you're passing
arguments to both Cargo and the binary, the ones after `--` go to the binary,
the ones before go to Cargo.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let (mut examples, mut bins) = (Vec::new(), Vec::new());
if let Some(s) = options.flag_bin {
bins.push(s);
}
if let Some(s) = options.flag_example {
examples.push(s);
}
let packages = Vec::from_iter(options.flag_package.iter().cloned());
let spec = Packages::Packages(&packages);
let compile_opts = ops::CompileOptions {
config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| &t[..]),
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec,
release: options.flag_release,
mode: ops::CompileMode::Build,
filter: if examples.is_empty() && bins.is_empty() {
ops::CompileFilter::Default { required_features_filterable: false, }
} else {
ops::CompileFilter::new(false,
&bins, false,
&[], false,
&examples, false,
&[], false,
false)
},
message_format: options.flag_message_format,
target_rustdoc_args: None,
target_rustc_args: None,
};
let ws = Workspace::new(&root, config)?;
match ops::run(&ws, &compile_opts, &options.arg_args)? {
None => Ok(()),
Some(err) => {
// If we never actually spawned the process then that sounds pretty
// bad and we always want to forward that up.
let exit = match err.exit {
Some(exit) => exit,
None => return Err(CliError::new(err.into(), 101)),
};
// If `-q` was passed then we suppress extra error information about
// a failed process, we assume the process itself printed out enough
// information about why it failed so we don't do so as well
let exit_code = exit.code().unwrap_or(101);
Err(if options.flag_quiet == Some(true) {
CliError::code(exit_code)
} else {
CliError::new(err.into(), exit_code)
})
}
}
}

View File

@ -1,140 +0,0 @@
use std::env;
use cargo::core::Workspace;
use cargo::ops::{self, CompileOptions, CompileMode, MessageFormat, Packages};
use cargo::util::important_paths::{find_root_manifest_for_wd};
use cargo::util::{CliResult, CliError, Config};
#[derive(Deserialize)]
pub struct Options {
arg_opts: Option<Vec<String>>,
flag_package: Option<String>,
flag_jobs: Option<u32>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_no_default_features: bool,
flag_target: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_release: bool,
flag_lib: bool,
flag_bin: Vec<String>,
flag_bins: bool,
flag_example: Vec<String>,
flag_examples: bool,
flag_test: Vec<String>,
flag_tests: bool,
flag_bench: Vec<String>,
flag_benches: bool,
flag_all_targets: bool,
flag_profile: Option<String>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Compile a package and all of its dependencies
Usage:
cargo rustc [options] [--] [<opts>...]
Options:
-h, --help Print this message
-p SPEC, --package SPEC Package to build
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--lib Build only this package's library
--bin NAME Build only the specified binary
--bins Build all binaries
--example NAME Build only the specified example
--examples Build all examples
--test NAME Build only the specified test target
--tests Build all tests
--bench NAME Build only the specified bench target
--benches Build all benches
--all-targets Build all targets (lib and bin targets by default)
--release Build artifacts in release mode, with optimizations
--profile PROFILE Profile to build the selected target for
--features FEATURES Features to compile for the package
--all-features Build all available features
--no-default-features Do not compile default features for the package
--target TRIPLE Target triple which compiles will be for
--manifest-path PATH Path to the manifest to fetch dependencies for
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
The specified target for the current package (or package specified by SPEC if
provided) will be compiled along with all of its dependencies. The specified
<opts>... will all be passed to the final compiler invocation, not any of the
dependencies. Note that the compiler will still unconditionally receive
arguments such as -L, --extern, and --crate-type, and the specified <opts>...
will simply be added to the compiler invocation.
This command requires that only one target is being compiled. If more than one
target is available for the current package the filters of --lib, --bin, etc,
must be used to select which target is compiled. To pass flags to all compiler
processes spawned by Cargo, use the $RUSTFLAGS environment variable or the
`build.rustflags` configuration option.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-rustc; args={:?}",
env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path,
config.cwd())?;
let mode = match options.flag_profile.as_ref().map(|t| &t[..]) {
Some("dev") | None => CompileMode::Build,
Some("test") => CompileMode::Test,
Some("bench") => CompileMode::Bench,
Some("check") => CompileMode::Check {test: false},
Some(mode) => {
let err = format_err!("unknown profile: `{}`, use dev,
test, or bench", mode);
return Err(CliError::new(err, 101))
}
};
let spec = options.flag_package.map_or_else(Vec::new, |s| vec![s]);
let opts = CompileOptions {
config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| &t[..]),
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec: Packages::Packages(&spec),
mode,
release: options.flag_release,
filter: ops::CompileFilter::new(options.flag_lib,
&options.flag_bin, options.flag_bins,
&options.flag_test, options.flag_tests,
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,
options.flag_all_targets),
message_format: options.flag_message_format,
target_rustdoc_args: None,
target_rustc_args: options.arg_opts.as_ref().map(|a| &a[..]),
};
let ws = Workspace::new(&root, config)?;
ops::compile(&ws, &opts)?;
Ok(())
}

View File

@ -1,127 +0,0 @@
use cargo::core::Workspace;
use cargo::ops::{self, MessageFormat, Packages};
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::{find_root_manifest_for_wd};
#[derive(Deserialize)]
pub struct Options {
arg_opts: Vec<String>,
flag_target: Option<String>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_jobs: Option<u32>,
flag_manifest_path: Option<String>,
flag_no_default_features: bool,
flag_open: bool,
flag_verbose: u32,
flag_release: bool,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_package: Option<String>,
flag_lib: bool,
flag_bin: Vec<String>,
flag_bins: bool,
flag_example: Vec<String>,
flag_examples: bool,
flag_test: Vec<String>,
flag_tests: bool,
flag_bench: Vec<String>,
flag_benches: bool,
flag_all_targets: bool,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Build a package's documentation, using specified custom flags.
Usage:
cargo rustdoc [options] [--] [<opts>...]
Options:
-h, --help Print this message
--open Opens the docs in a browser after the operation
-p SPEC, --package SPEC Package to document
-j N, --jobs N Number of parallel jobs, defaults to # of CPUs
--lib Build only this package's library
--bin NAME Build only the specified binary
--bins Build all binaries
--example NAME Build only the specified example
--examples Build all examples
--test NAME Build only the specified test target
--tests Build all tests
--bench NAME Build only the specified bench target
--benches Build all benches
--all-targets Build all targets (default)
--release Build artifacts in release mode, with optimizations
--features FEATURES Space-separated list of features to also build
--all-features Build all available features
--no-default-features Do not build the `default` feature
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest to document
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
The specified target for the current package (or package specified by SPEC if
provided) will be documented with the specified <opts>... being passed to the
final rustdoc invocation. Dependencies will not be documented as part of this
command. Note that rustdoc will still unconditionally receive arguments such
as -L, --extern, and --crate-type, and the specified <opts>... will simply be
added to the rustdoc invocation.
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be documented. If it is not given, then the
current package is documented. For more information on SPEC and its format, see
the `cargo help pkgid` command.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path,
config.cwd())?;
let spec = options.flag_package.map_or_else(Vec::new, |s| vec![s]);
let doc_opts = ops::DocOptions {
open_result: options.flag_open,
compile_opts: ops::CompileOptions {
config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|t| &t[..]),
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec: Packages::Packages(&spec),
release: options.flag_release,
filter: ops::CompileFilter::new(options.flag_lib,
&options.flag_bin, options.flag_bins,
&options.flag_test, options.flag_tests,
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,
options.flag_all_targets),
message_format: options.flag_message_format,
mode: ops::CompileMode::Doc { deps: false },
target_rustdoc_args: Some(&options.arg_opts),
target_rustc_args: None,
},
};
let ws = Workspace::new(&root, config)?;
ops::doc(&ws, &doc_opts)?;
Ok(())
}

View File

@ -1,90 +0,0 @@
use cargo::ops;
use cargo::util::{CliResult, Config};
use std::cmp;
#[derive(Deserialize)]
pub struct Options {
flag_index: Option<String>,
flag_host: Option<String>, // TODO: Deprecated, remove
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_limit: Option<u32>,
flag_frozen: bool,
flag_locked: bool,
arg_query: Vec<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}
pub const USAGE: &'static str = "
Search packages in crates.io
Usage:
cargo search [options] <query>...
cargo search [-h | --help]
Options:
-h, --help Print this message
--index INDEX Registry index to search in
--host HOST DEPRECATED, renamed to '--index'
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--limit LIMIT Limit the number of results (default: 10, max: 100)
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
--registry REGISTRY Registry to use
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let Options {
flag_index: index,
flag_host: host, // TODO: Deprecated, remove
flag_limit: limit,
arg_query: query,
flag_registry: registry,
..
} = options;
if registry.is_some() && !config.cli_unstable().unstable_options {
return Err(format_err!("registry option is an unstable feature and \
requires -Zunstable-options to use.").into())
}
// TODO: Deprecated
// remove once it has been decided --host can be safely removed
// We may instead want to repurpose the host flag, as
// mentioned in this issue
// https://github.com/rust-lang/cargo/issues/4208
let msg = "The flag '--host' is no longer valid.
Previous versions of Cargo accepted this flag, but it is being
deprecated. The flag is being renamed to 'index', as the flag
wants the location of the index in which to search. Please
use '--index' instead.
This will soon become a hard error, so it's either recommended
to update to a fixed version or contact the upstream maintainer
about this warning.";
let index = if host.clone().is_none() || host.clone().unwrap().is_empty() {
index
} else {
config.shell().warn(&msg)?;
host
};
ops::search(&query.join("+"), config, index, cmp::min(100, limit.unwrap_or(10)) as u8, registry)?;
Ok(())
}

View File

@ -1,194 +0,0 @@
use std::env;
use cargo::core::Workspace;
use cargo::ops::{self, MessageFormat, Packages};
use cargo::util::{CliResult, CliError, Config};
use cargo::util::important_paths::find_root_manifest_for_wd;
#[derive(Deserialize)]
pub struct Options {
arg_args: Vec<String>,
flag_features: Vec<String>,
flag_all_features: bool,
flag_jobs: Option<u32>,
flag_manifest_path: Option<String>,
flag_no_default_features: bool,
flag_no_run: bool,
flag_package: Vec<String>,
flag_target: Option<String>,
flag_lib: bool,
flag_doc: bool,
flag_bin: Vec<String>,
flag_bins: bool,
flag_example: Vec<String>,
flag_examples: bool,
flag_test: Vec<String>,
flag_tests: bool,
flag_bench: Vec<String>,
flag_benches: bool,
flag_all_targets: bool,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_message_format: MessageFormat,
flag_release: bool,
flag_no_fail_fast: bool,
flag_frozen: bool,
flag_locked: bool,
flag_all: bool,
flag_exclude: Vec<String>,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
#[serde(rename = "arg_TESTNAME")]
arg_testname: Option<String>,
}
pub const USAGE: &'static str = "
Execute all unit and integration tests of a local package
Usage:
cargo test [options] [TESTNAME] [--] [<args>...]
Options:
TESTNAME If specified, only run tests containing this string in their names
-h, --help Print this message
--lib Test only this package's library
--doc Test only this library's documentation
--bin NAME ... Test only the specified binary
--bins Test all binaries
--example NAME ... Check that the specified examples compile
--examples Check that all examples compile
--test NAME ... Test only the specified test target
--tests Test all tests
--bench NAME ... Test only the specified bench target
--benches Test all benches
--all-targets Test all targets (default)
--no-run Compile, but don't run tests
-p SPEC, --package SPEC ... Package to run tests for
--all Test all packages in the workspace
--exclude SPEC ... Exclude packages from the test
-j N, --jobs N Number of parallel builds, see below for details
--release Build artifacts in release mode, with optimizations
--features FEATURES Space-separated list of features to also build
--all-features Build all available features
--no-default-features Do not build the `default` feature
--target TRIPLE Build for the target triple
--manifest-path PATH Path to the manifest to build tests for
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--message-format FMT Error format: human, json [default: human]
--no-fail-fast Run all tests regardless of failure
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
All of the trailing arguments are passed to the test binaries generated for
filtering tests and generally providing options configuring how they run. For
example, this will run all tests with the name `foo` in their name:
cargo test foo
If the --package argument is given, then SPEC is a package id specification
which indicates which package should be tested. If it is not given, then the
current package is tested. For more information on SPEC and its format, see the
`cargo help pkgid` command.
All packages in the workspace are tested if the `--all` flag is supplied. The
`--all` flag is automatically assumed for a virtual manifest.
Note that `--exclude` has to be specified in conjunction with the `--all` flag.
The --jobs argument affects the building of the test executable but does
not affect how many jobs are used when running the tests. The default value
for the --jobs argument is the number of CPUs. If you want to control the
number of simultaneous running test cases, pass the `--test-threads` option
to the test binaries:
cargo test -- --test-threads=1
Compilation can be configured via the `test` profile in the manifest.
By default the rust test harness hides output from test execution to
keep results readable. Test output can be recovered (e.g. for debugging)
by passing `--nocapture` to the test binaries:
cargo test -- --nocapture
To get the list of all options available for the test binaries use this:
cargo test -- --help
";
pub fn execute(mut options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-test; args={:?}",
env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let ws = Workspace::new(&root, config)?;
let empty = Vec::new();
let (mode, filter);
if options.flag_doc {
mode = ops::CompileMode::Doctest;
filter = ops::CompileFilter::new(true, &empty, false, &empty, false,
&empty, false, &empty, false,
false);
} else {
mode = ops::CompileMode::Test;
filter = ops::CompileFilter::new(options.flag_lib,
&options.flag_bin, options.flag_bins,
&options.flag_test, options.flag_tests,
&options.flag_example, options.flag_examples,
&options.flag_bench, options.flag_benches,
options.flag_all_targets);
}
let spec = Packages::from_flags(options.flag_all,
&options.flag_exclude,
&options.flag_package)?;
let ops = ops::TestOptions {
no_run: options.flag_no_run,
no_fail_fast: options.flag_no_fail_fast,
only_doc: options.flag_doc,
compile_opts: ops::CompileOptions {
config,
jobs: options.flag_jobs,
target: options.flag_target.as_ref().map(|s| &s[..]),
features: &options.flag_features,
all_features: options.flag_all_features,
no_default_features: options.flag_no_default_features,
spec,
release: options.flag_release,
mode,
filter,
message_format: options.flag_message_format,
target_rustdoc_args: None,
target_rustc_args: None,
},
};
// TESTNAME is actually an argument of the test binary, but it's
// important so we explicitly mention it and reconfigure
if let Some(test) = options.arg_testname.take() {
options.arg_args.insert(0, test);
}
let err = ops::run_tests(&ws, &ops, &options.arg_args)?;
match err {
None => Ok(()),
Some(err) => {
Err(match err.exit.as_ref().and_then(|e| e.code()) {
Some(i) => CliError::new(format_err!("{}", err.hint(&ws)), i),
None => CliError::new(err.into(), 101),
})
}
}
}

View File

@ -1,57 +0,0 @@
use cargo::ops;
use cargo::util::{CliResult, Config};
#[derive(Deserialize)]
pub struct Options {
flag_bin: Vec<String>,
flag_root: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
arg_spec: Vec<String>,
}
pub const USAGE: &'static str = "
Remove a Rust binary
Usage:
cargo uninstall [options] <spec>...
cargo uninstall (-h | --help)
Options:
-h, --help Print this message
--root DIR Directory to uninstall packages from
--bin NAME Only uninstall the binary NAME
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet Less output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
The argument SPEC is a package id specification (see `cargo help pkgid`) to
specify which crate should be uninstalled. By default all binaries are
uninstalled for a crate but the `--bin` and `--example` flags can be used to
only uninstall particular binaries.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = options.flag_root.as_ref().map(|s| &s[..]);
let specs = options.arg_spec.iter().map(|s| &s[..]).collect::<Vec<_>>();
ops::uninstall(root, specs, &options.flag_bin, config)?;
Ok(())
}

View File

@ -1,83 +0,0 @@
use std::env;
use cargo::core::Workspace;
use cargo::ops;
use cargo::util::{CliResult, Config};
use cargo::util::important_paths::find_root_manifest_for_wd;
#[derive(Deserialize)]
pub struct Options {
flag_package: Vec<String>,
flag_aggressive: bool,
flag_precise: Option<String>,
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Update dependencies as recorded in the local lock file.
Usage:
cargo update [options]
Options:
-h, --help Print this message
-p SPEC, --package SPEC ... Package to update
--aggressive Force updating all dependencies of <name> as well
--precise PRECISE Update a single dependency to exactly PRECISE
--manifest-path PATH Path to the crate's manifest
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
This command requires that a `Cargo.lock` already exists as generated by
`cargo build` or related commands.
If SPEC is given, then a conservative update of the lockfile will be
performed. This means that only the dependency specified by SPEC will be
updated. Its transitive dependencies will be updated only if SPEC cannot be
updated without updating dependencies. All other dependencies will remain
locked at their currently recorded versions.
If PRECISE is specified, then --aggressive must not also be specified. The
argument PRECISE is a string representing a precise revision that the package
being updated should be updated to. For example, if the package comes from a git
repository, then PRECISE would be the exact revision that the repository should
be updated to.
If SPEC is not given, then all dependencies will be re-resolved and
updated.
For more information about package id specifications, see `cargo help pkgid`.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-update; args={:?}", env::args().collect::<Vec<_>>());
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
let root = find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())?;
let update_opts = ops::UpdateOptions {
aggressive: options.flag_aggressive,
precise: options.flag_precise.as_ref().map(|s| &s[..]),
to_update: &options.flag_package,
config,
};
let ws = Workspace::new(&root, config)?;
ops::update_lockfile(&ws, &update_opts)?;
Ok(())
}

View File

@ -1,77 +0,0 @@
use std::collections::HashMap;
use std::fs::File;
use std::io::prelude::*;
use std::process;
use cargo;
use cargo::util::important_paths::{find_root_manifest_for_wd};
use cargo::util::{CliResult, Config};
use serde_json;
use toml;
#[derive(Deserialize)]
pub struct Flags {
flag_manifest_path: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
}
pub const USAGE: &'static str = "
Check correctness of crate manifest
Usage:
cargo verify-project [options]
cargo verify-project -h | --help
Options:
-h, --help Print this message
--manifest-path PATH Path to the manifest to verify
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
";
pub fn execute(args: Flags, config: &mut Config) -> CliResult {
config.configure(args.flag_verbose,
args.flag_quiet,
&args.flag_color,
args.flag_frozen,
args.flag_locked,
&args.flag_z)?;
let mut contents = String::new();
let filename = args.flag_manifest_path.unwrap_or_else(|| "Cargo.toml".into());
let filename = match find_root_manifest_for_wd(Some(filename), config.cwd()) {
Ok(manifest_path) => manifest_path,
Err(e) => fail("invalid", &e.to_string()),
};
let file = File::open(&filename);
match file.and_then(|mut f| f.read_to_string(&mut contents)) {
Ok(_) => {},
Err(e) => fail("invalid", &format!("error reading file: {}", e))
};
if contents.parse::<toml::Value>().is_err() {
fail("invalid", "invalid-format");
}
let mut h = HashMap::new();
h.insert("success".to_string(), "true".to_string());
cargo::print_json(&h);
Ok(())
}
fn fail(reason: &str, value: &str) -> ! {
let mut h = HashMap::new();
h.insert(reason.to_string(), value.to_string());
println!("{}", serde_json::to_string(&h).unwrap());
process::exit(1)
}

View File

@ -1,27 +0,0 @@
use std::env;
use cargo;
use cargo::util::{CliResult, Config};
#[derive(Deserialize)]
pub struct Options;
pub const USAGE: &'static str = "
Show version information
Usage:
cargo version [options]
Options:
-h, --help Print this message
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
--color WHEN Coloring: auto, always, never
";
pub fn execute(_: Options, _: &mut Config) -> CliResult {
debug!("executing; cmd=cargo-version; args={:?}", env::args().collect::<Vec<_>>());
println!("{}", cargo::version());
Ok(())
}

View File

@ -1,72 +0,0 @@
use cargo::ops;
use cargo::util::{CliResult, Config};
#[derive(Deserialize)]
pub struct Options {
arg_crate: Option<String>,
flag_token: Option<String>,
flag_vers: Option<String>,
flag_index: Option<String>,
flag_verbose: u32,
flag_quiet: Option<bool>,
flag_color: Option<String>,
flag_undo: bool,
flag_frozen: bool,
flag_locked: bool,
#[serde(rename = "flag_Z")]
flag_z: Vec<String>,
flag_registry: Option<String>,
}
pub static USAGE: &'static str = "
Remove a pushed crate from the index
Usage:
cargo yank [options] [<crate>]
Options:
-h, --help Print this message
--vers VERSION The version to yank or un-yank
--undo Undo a yank, putting a version back into the index
--index INDEX Registry index to yank from
--token TOKEN API token to use when authenticating
-v, --verbose ... Use verbose output (-vv very verbose/build.rs output)
-q, --quiet No output printed to stdout
--color WHEN Coloring: auto, always, never
--frozen Require Cargo.lock and cache are up to date
--locked Require Cargo.lock is up to date
-Z FLAG ... Unstable (nightly-only) flags to Cargo
--registry REGISTRY Registry to use
The yank command removes a previously pushed crate's version from the server's
index. This command does not delete any data, and the crate will still be
available for download via the registry's download link.
Note that existing crates locked to a yanked version will still be able to
download the yanked version to use it. Cargo will, however, not allow any new
crates to be locked to any yanked version.
";
pub fn execute(options: Options, config: &mut Config) -> CliResult {
config.configure(options.flag_verbose,
options.flag_quiet,
&options.flag_color,
options.flag_frozen,
options.flag_locked,
&options.flag_z)?;
if options.flag_registry.is_some() && !config.cli_unstable().unstable_options {
return Err(format_err!("registry option is an unstable feature and \
requires -Zunstable-options to use.").into())
}
ops::yank(config,
options.arg_crate,
options.flag_vers,
options.flag_token,
options.flag_index,
options.flag_undo,
options.flag_registry)?;
Ok(())
}

View File

@ -11,10 +11,10 @@
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate serde_json;
extern crate atty;
extern crate clap;
extern crate crates_io as registry;
extern crate crossbeam;
extern crate curl;
extern crate docopt;
extern crate filetime;
extern crate flate2;
extern crate fs2;
@ -44,9 +44,7 @@ extern crate core_foundation;
use std::fmt;
use serde::de::DeserializeOwned;
use serde::ser;
use docopt::Docopt;
use failure::Error;
use core::Shell;
@ -107,26 +105,6 @@ impl fmt::Display for VersionInfo {
}
}
pub fn call_main_without_stdin<Flags: DeserializeOwned>(
exec: fn(Flags, &mut Config) -> CliResult,
config: &mut Config,
usage: &str,
args: &[String],
options_first: bool) -> CliResult
{
let docopt = Docopt::new(usage).unwrap()
.options_first(options_first)
.argv(args.iter().map(|s| &s[..]))
.help(true);
let flags = docopt.deserialize().map_err(|e| {
let code = if e.fatal() {1} else {0};
CliError::new(e.into(), code)
})?;
exec(flags, config)
}
pub fn print_json<T: ser::Serialize>(obj: &T) {
let encoded = serde_json::to_string(&obj).unwrap();
println!("{}", encoded);
@ -134,6 +112,11 @@ pub fn print_json<T: ser::Serialize>(obj: &T) {
pub fn exit_with_error(err: CliError, shell: &mut Shell) -> ! {
debug!("exit_with_error; err={:?}", err);
if let Some(ref err) = err.error {
if let Some(clap_err) = err.downcast_ref::<clap::Error>() {
clap_err.exit()
}
}
let CliError { error, exit_code, unknown } = err;
// exit_code == 0 is non-fatal error, e.g. docopt version info

View File

@ -9,9 +9,9 @@ use util::paths;
use ops::{self, Context, BuildConfig, Kind, Unit};
pub struct CleanOptions<'a> {
pub spec: &'a [String],
pub target: Option<&'a str>,
pub config: &'a Config,
pub spec: Vec<String>,
pub target: Option<String>,
pub release: bool,
}
@ -37,7 +37,7 @@ pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> {
let mut cx = Context::new(ws, &resolve, &packages, opts.config,
BuildConfig {
host_triple,
requested_target: opts.target.map(|s| s.to_owned()),
requested_target: opts.target.clone(),
release: opts.release,
jobs: 1,
..BuildConfig::default()
@ -45,7 +45,7 @@ pub fn clean(ws: &Workspace, opts: &CleanOptions) -> CargoResult<()> {
profiles)?;
let mut units = Vec::new();
for spec in opts.spec {
for spec in opts.spec.iter() {
// Translate the spec to a Package
let pkgid = resolve.query(spec)?;
let pkg = packages.get(pkgid)?;

View File

@ -41,18 +41,18 @@ pub struct CompileOptions<'a> {
/// Number of concurrent jobs to use.
pub jobs: Option<u32>,
/// The target platform to compile for (example: `i686-unknown-linux-gnu`).
pub target: Option<&'a str>,
pub target: Option<String>,
/// Extra features to build for the root package
pub features: &'a [String],
pub features: Vec<String>,
/// Flag whether all available features should be built for the root package
pub all_features: bool,
/// Flag if the default feature should be built for the root package
pub no_default_features: bool,
/// A set of packages to build.
pub spec: Packages<'a>,
pub spec: Packages,
/// Filter to apply to the root package to select which targets will be
/// built.
pub filter: CompileFilter<'a>,
pub filter: CompileFilter,
/// Whether this is a release build or not
pub release: bool,
/// Mode for this compile.
@ -60,10 +60,10 @@ pub struct CompileOptions<'a> {
/// `--error_format` flag for the compiler.
pub message_format: MessageFormat,
/// Extra arguments to be passed to rustdoc (for main crate and dependencies)
pub target_rustdoc_args: Option<&'a [String]>,
pub target_rustdoc_args: Option<Vec<String>>,
/// The specified target will be compiled with all the available arguments,
/// note that this only accounts for the *final* invocation of rustc
pub target_rustc_args: Option<&'a [String]>,
pub target_rustc_args: Option<Vec<String>>,
}
impl<'a> CompileOptions<'a> {
@ -73,10 +73,10 @@ impl<'a> CompileOptions<'a> {
config,
jobs: None,
target: None,
features: &[],
features: Vec::new(),
all_features: false,
no_default_features: false,
spec: ops::Packages::Packages(&[]),
spec: ops::Packages::Packages(Vec::new()),
mode,
release: false,
filter: CompileFilter::Default { required_features_filterable: false },
@ -97,22 +97,22 @@ pub enum CompileMode {
Doctest,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MessageFormat {
Human,
Json
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Packages<'a> {
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum Packages {
Default,
All,
OptOut(&'a [String]),
Packages(&'a [String]),
OptOut(Vec<String>),
Packages(Vec<String>),
}
impl<'a> Packages<'a> {
pub fn from_flags(all: bool, exclude: &'a [String], package: &'a [String])
impl Packages {
pub fn from_flags(all: bool, exclude: Vec<String>, package: Vec<String>)
-> CargoResult<Self>
{
Ok(match (all, exclude.len(), package.len()) {
@ -124,28 +124,28 @@ impl<'a> Packages<'a> {
})
}
pub fn into_package_id_specs(self, ws: &Workspace) -> CargoResult<Vec<PackageIdSpec>> {
let specs = match self {
pub fn into_package_id_specs(&self, ws: &Workspace) -> CargoResult<Vec<PackageIdSpec>> {
let specs = match *self {
Packages::All => {
ws.members()
.map(Package::package_id)
.map(PackageIdSpec::from_package_id)
.collect()
}
Packages::OptOut(opt_out) => {
Packages::OptOut(ref opt_out) => {
ws.members()
.map(Package::package_id)
.map(PackageIdSpec::from_package_id)
.filter(|p| opt_out.iter().position(|x| *x == p.name()).is_none())
.collect()
}
Packages::Packages(packages) if packages.is_empty() => {
Packages::Packages(ref packages) if packages.is_empty() => {
ws.current_opt()
.map(Package::package_id)
.map(PackageIdSpec::from_package_id)
.into_iter().collect()
}
Packages::Packages(packages) => {
Packages::Packages(ref packages) => {
packages.iter().map(|p| PackageIdSpec::parse(p)).collect::<CargoResult<Vec<_>>>()?
}
Packages::Default => {
@ -166,14 +166,14 @@ impl<'a> Packages<'a> {
}
}
#[derive(Clone, Copy, Debug)]
pub enum FilterRule<'a> {
#[derive(Debug)]
pub enum FilterRule {
All,
Just (&'a [String]),
Just(Vec<String>),
}
#[derive(Debug)]
pub enum CompileFilter<'a> {
pub enum CompileFilter {
Default {
/// Flag whether targets can be safely skipped when required-features are not satisfied.
required_features_filterable: bool,
@ -181,10 +181,10 @@ pub enum CompileFilter<'a> {
Only {
all_targets: bool,
lib: bool,
bins: FilterRule<'a>,
examples: FilterRule<'a>,
tests: FilterRule<'a>,
benches: FilterRule<'a>,
bins: FilterRule,
examples: FilterRule,
tests: FilterRule,
benches: FilterRule,
}
}
@ -217,14 +217,14 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
options: &CompileOptions<'a>,
exec: Arc<Executor>)
-> CargoResult<ops::Compilation<'a>> {
let CompileOptions { config, jobs, target, spec, features,
let CompileOptions { config, jobs, ref target, ref spec, ref features,
all_features, no_default_features,
release, mode, message_format,
ref filter,
ref target_rustdoc_args,
ref target_rustc_args } = *options;
let target = target.map(|s| s.to_string());
let target = target.clone();
if jobs == Some(0) {
bail!("jobs must be at least 1")
@ -257,12 +257,12 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
let mut general_targets = Vec::new();
let mut package_targets = Vec::new();
match (*target_rustc_args, *target_rustdoc_args) {
(Some(..), _) |
(_, Some(..)) if to_builds.len() != 1 => {
match (target_rustc_args, target_rustdoc_args) {
(&Some(..), _) |
(_, &Some(..)) if to_builds.len() != 1 => {
panic!("`rustc` and `rustdoc` should not accept multiple `-p` flags")
}
(Some(args), _) => {
(&Some(ref args), _) => {
let all_features = resolve_all_features(&resolve_with_overrides,
to_builds[0].package_id());
let targets = generate_targets(to_builds[0], profiles,
@ -278,7 +278,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
e.g. `--lib` or `--bin NAME` to specify a single target")
}
}
(None, Some(args)) => {
(&None, &Some(ref args)) => {
let all_features = resolve_all_features(&resolve_with_overrides,
to_builds[0].package_id());
let targets = generate_targets(to_builds[0], profiles,
@ -294,7 +294,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
`--lib` or `--bin NAME` to specify a single target")
}
}
(None, None) => {
(&None, &None) => {
for &to_build in to_builds.iter() {
let all_features = resolve_all_features(&resolve_with_overrides,
to_build.package_id());
@ -353,8 +353,8 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>,
}
}
impl<'a> FilterRule<'a> {
pub fn new(targets: &'a [String], all: bool) -> FilterRule<'a> {
impl FilterRule {
pub fn new(targets: Vec<String>, all: bool) -> FilterRule {
if all {
FilterRule::All
} else {
@ -365,7 +365,7 @@ impl<'a> FilterRule<'a> {
fn matches(&self, target: &Target) -> bool {
match *self {
FilterRule::All => true,
FilterRule::Just(targets) => {
FilterRule::Just(ref targets) => {
targets.iter().any(|x| *x == target.name())
},
}
@ -374,25 +374,25 @@ impl<'a> FilterRule<'a> {
fn is_specific(&self) -> bool {
match *self {
FilterRule::All => true,
FilterRule::Just(targets) => !targets.is_empty(),
FilterRule::Just(ref targets) => !targets.is_empty(),
}
}
pub fn try_collect(&self) -> Option<Vec<String>> {
match *self {
FilterRule::All => None,
FilterRule::Just(targets) => Some(targets.to_vec()),
FilterRule::Just(ref targets) => Some(targets.clone()),
}
}
}
impl<'a> CompileFilter<'a> {
impl CompileFilter {
pub fn new(lib_only: bool,
bins: &'a [String], all_bins: bool,
tsts: &'a [String], all_tsts: bool,
exms: &'a [String], all_exms: bool,
bens: &'a [String], all_bens: bool,
all_targets: bool) -> CompileFilter<'a> {
bins: Vec<String>, all_bins: bool,
tsts: Vec<String>, all_tsts: bool,
exms: Vec<String>, all_exms: bool,
bens: Vec<String>, all_bens: bool,
all_targets: bool) -> CompileFilter {
let rule_bins = FilterRule::new(bins, all_bins);
let rule_tsts = FilterRule::new(tsts, all_tsts);
let rule_exms = FilterRule::new(exms, all_exms);
@ -423,7 +423,7 @@ impl<'a> CompileFilter<'a> {
pub fn need_dev_deps(&self) -> bool {
match *self {
CompileFilter::Default { .. } => true,
CompileFilter::Only { examples, tests, benches, .. } =>
CompileFilter::Only { ref examples, ref tests, ref benches, .. } =>
examples.is_specific() || tests.is_specific() || benches.is_specific()
}
}
@ -431,7 +431,7 @@ impl<'a> CompileFilter<'a> {
pub fn matches(&self, target: &Target) -> bool {
match *self {
CompileFilter::Default { .. } => true,
CompileFilter::Only { lib, bins, examples, tests, benches, .. } => {
CompileFilter::Only { lib, ref bins, ref examples, ref tests, ref benches, .. } => {
let rule = match *target.kind() {
TargetKind::Bin => bins,
TargetKind::Test => tests,
@ -538,11 +538,11 @@ fn generate_auto_targets<'a>(mode: CompileMode, targets: &'a [Target],
/// Given a filter rule and some context, propose a list of targets
fn propose_indicated_targets<'a>(pkg: &'a Package,
rule: FilterRule,
rule: &FilterRule,
desc: &'static str,
is_expected_kind: fn(&Target) -> bool,
profile: &'a Profile) -> CargoResult<Vec<BuildProposal<'a>>> {
match rule {
match *rule {
FilterRule::All => {
let result = pkg.targets().iter().filter(|t| is_expected_kind(t)).map(|t| {
BuildProposal {
@ -553,7 +553,7 @@ fn propose_indicated_targets<'a>(pkg: &'a Package,
});
Ok(result.collect())
}
FilterRule::Just(names) => {
FilterRule::Just(ref names) => {
let mut targets = Vec::new();
for name in names {
let target = pkg.targets().iter().find(|t| {
@ -658,7 +658,7 @@ fn generate_targets<'a>(pkg: &'a Package,
};
generate_auto_targets(mode, pkg.targets(), profile, deps, required_features_filterable)
}
CompileFilter::Only { all_targets, lib, bins, examples, tests, benches } => {
CompileFilter::Only { all_targets, lib, ref bins, ref examples, ref tests, ref benches } => {
let mut targets = Vec::new();
if lib {
@ -678,7 +678,7 @@ fn generate_targets<'a>(pkg: &'a Package,
pkg, examples, "example", Target::is_example, profile)?);
// If --tests was specified, add all targets that would be
// generated by `cargo test`.
let test_filter = match tests {
let test_filter = match *tests {
FilterRule::All => Target::tested,
FilterRule::Just(_) => Target::is_test
};
@ -686,7 +686,7 @@ fn generate_targets<'a>(pkg: &'a Package,
pkg, tests, "test", test_filter, test_profile)?);
// If --benches was specified, add all targets that would be
// generated by `cargo bench`.
let bench_filter = match benches {
let bench_filter = match *benches {
FilterRule::All => Target::benched,
FilterRule::Just(_) => Target::is_bench
};

View File

@ -16,7 +16,7 @@ pub fn doc(ws: &Workspace, options: &DocOptions) -> CargoResult<()> {
let specs = options.compile_opts.spec.into_package_id_specs(ws)?;
let resolve = ops::resolve_ws_precisely(ws,
None,
options.compile_opts.features,
&options.compile_opts.features,
options.compile_opts.all_features,
options.compile_opts.no_default_features,
&specs)?;
@ -68,7 +68,7 @@ pub fn doc(ws: &Workspace, options: &DocOptions) -> CargoResult<()> {
// nothing we can do about it and otherwise if it's getting overwritten
// then that's also ok!
let mut target_dir = ws.target_dir();
if let Some(triple) = options.compile_opts.target {
if let Some(ref triple) = options.compile_opts.target {
target_dir.push(Path::new(triple).file_stem().unwrap());
}
let path = target_dir.join("doc").join(&name).join("index.html");

View File

@ -12,7 +12,7 @@ use util::CargoResult;
pub struct UpdateOptions<'a> {
pub config: &'a Config,
pub to_update: &'a [String],
pub to_update: Vec<String>,
pub precise: Option<&'a str>,
pub aggressive: bool,
}
@ -57,7 +57,7 @@ pub fn update_lockfile(ws: &Workspace, opts: &UpdateOptions)
to_avoid.extend(previous_resolve.iter());
} else {
let mut sources = Vec::new();
for name in opts.to_update {
for name in opts.to_update.iter() {
let dep = previous_resolve.query(name)?;
if opts.aggressive {
fill_with_deps(&previous_resolve, dep, &mut to_avoid,

View File

@ -504,7 +504,7 @@ fn find_duplicates(dst: &Path,
.filter_map(|t| check(t.name().to_string()))
.collect()
}
CompileFilter::Only { bins, examples, .. } => {
CompileFilter::Only { ref bins, ref examples, .. } => {
let all_bins: Vec<String> = bins.try_collect().unwrap_or_else(|| {
pkg.targets().iter().filter(|t| t.is_bin())
.map(|t| t.name().to_string())

View File

@ -4,9 +4,6 @@ use std::fs;
use std::fmt;
use std::path::Path;
use serde::{Deserialize, Deserializer};
use serde::de;
use git2::Config as GitConfig;
use git2::Repository as GitRepository;
@ -22,11 +19,11 @@ use toml;
pub enum VersionControl { Git, Hg, Pijul, Fossil, NoVcs }
#[derive(Debug)]
pub struct NewOptions<'a> {
pub struct NewOptions {
pub version_control: Option<VersionControl>,
pub kind: NewProjectKind,
pub path: &'a str,
pub name: Option<&'a str>,
pub path: String,
pub name: Option<String>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@ -64,29 +61,12 @@ struct MkOptions<'a> {
bin: bool,
}
impl<'de> Deserialize<'de> for VersionControl {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<VersionControl, D::Error> {
Ok(match &String::deserialize(d)?[..] {
"git" => VersionControl::Git,
"hg" => VersionControl::Hg,
"pijul" => VersionControl::Pijul,
"fossil" => VersionControl::Fossil,
"none" => VersionControl::NoVcs,
n => {
let value = de::Unexpected::Str(n);
let msg = "unsupported version control system";
return Err(de::Error::invalid_value(value, &msg));
}
})
}
}
impl<'a> NewOptions<'a> {
impl NewOptions {
pub fn new(version_control: Option<VersionControl>,
bin: bool,
lib: bool,
path: &'a str,
name: Option<&'a str>) -> CargoResult<NewOptions<'a>> {
path: String,
name: Option<String>) -> CargoResult<NewOptions> {
let kind = match (bin, lib) {
(true, true) => bail!("can't specify both lib and binary outputs"),
@ -107,7 +87,7 @@ struct CargoNewConfig {
}
fn get_name<'a>(path: &'a Path, opts: &'a NewOptions) -> CargoResult<&'a str> {
if let Some(name) = opts.name {
if let Some(ref name) = opts.name {
return Ok(name);
}
@ -276,7 +256,7 @@ fn plan_new_source_file(bin: bool, project_name: String) -> SourceFileInformatio
}
pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
let path = config.cwd().join(opts.path);
let path = config.cwd().join(&opts.path);
if fs::metadata(&path).is_ok() {
bail!("destination `{}` already exists\n\n\
Use `cargo init` to initialize the directory\
@ -303,7 +283,7 @@ pub fn new(opts: &NewOptions, config: &Config) -> CargoResult<()> {
}
pub fn init(opts: &NewOptions, config: &Config) -> CargoResult<()> {
let path = config.cwd().join(opts.path);
let path = config.cwd().join(&opts.path);
let cargotoml_path = path.join("Cargo.toml");
if fs::metadata(&cargotoml_path).is_ok() {

View File

@ -23,7 +23,7 @@ pub struct PackageOpts<'cfg> {
pub allow_dirty: bool,
pub verify: bool,
pub jobs: Option<u32>,
pub target: Option<&'cfg str>,
pub target: Option<String>,
pub registry: Option<String>,
}
@ -320,11 +320,11 @@ fn run_verify(ws: &Workspace, tar: &FileLock, opts: &PackageOpts) -> CargoResult
ops::compile_ws(&ws, None, &ops::CompileOptions {
config,
jobs: opts.jobs,
target: opts.target,
features: &[],
target: opts.target.clone(),
features: Vec::new(),
no_default_features: false,
all_features: false,
spec: ops::Packages::Packages(&[]),
spec: ops::Packages::Packages(Vec::new()),
filter: ops::CompileFilter::Default { required_features_filterable: true },
release: false,
message_format: ops::MessageFormat::Human,

View File

@ -13,7 +13,7 @@ pub fn run(ws: &Workspace,
Packages::All |
Packages::Default |
Packages::OptOut(_) => unreachable!("cargo run supports single package only"),
Packages::Packages(xs) => match xs.len() {
Packages::Packages(ref xs) => match xs.len() {
0 => ws.current()?,
1 => ws.members()
.find(|pkg| &*pkg.name() == xs[0])

View File

@ -34,7 +34,7 @@ pub struct PublishOpts<'cfg> {
pub verify: bool,
pub allow_dirty: bool,
pub jobs: Option<u32>,
pub target: Option<&'cfg str>,
pub target: Option<String>,
pub dry_run: bool,
pub registry: Option<String>,
}
@ -76,7 +76,7 @@ pub fn publish(ws: &Workspace, opts: &PublishOpts) -> CargoResult<()> {
list: false,
check_metadata: true,
allow_dirty: opts.allow_dirty,
target: opts.target,
target: opts.target.clone(),
jobs: opts.jobs,
registry: opts.registry.clone(),
})?.unwrap();
@ -486,7 +486,7 @@ pub fn yank(config: &Config,
pub fn search(query: &str,
config: &Config,
index: Option<String>,
limit: u8,
limit: u32,
reg: Option<String>) -> CargoResult<()> {
fn truncate_with_ellipsis(s: &str, max_width: usize) -> String {
// We should truncate at grapheme-boundary and compute character-widths,

View File

@ -6,6 +6,7 @@ use std::str;
use core::{TargetKind, Workspace};
use failure::{Context, Error, Fail};
use clap;
pub use failure::Error as CargoError;
pub type CargoResult<T> = Result<T, Error>;
@ -169,6 +170,13 @@ impl From<CargoError> for CliError {
}
}
impl From<clap::Error> for CliError {
fn from(err: clap::Error) -> CliError {
let code = if err.use_stderr() { 1 } else { 0 };
CliError::new(err.into(), code)
}
}
// =============================================================================
// Construction helpers

View File

@ -35,7 +35,7 @@ pub fn find_project_manifest(pwd: &Path, file: &str) -> CargoResult<PathBuf> {
}
/// Find the root Cargo.toml
pub fn find_root_manifest_for_wd(manifest_path: Option<String>, cwd: &Path)
pub fn find_root_manifest_for_wd(manifest_path: Option<&str>, cwd: &Path)
-> CargoResult<PathBuf> {
match manifest_path {
Some(path) => {

View File

@ -202,10 +202,10 @@ impl Registry {
})
}
pub fn search(&mut self, query: &str, limit: u8) -> Result<(Vec<Crate>, u32)> {
let formated_query = percent_encode(query.as_bytes(), QUERY_ENCODE_SET);
pub fn search(&mut self, query: &str, limit: u32) -> Result<(Vec<Crate>, u32)> {
let formatted_query = percent_encode(query.as_bytes(), QUERY_ENCODE_SET);
let body = self.req(
format!("/crates?q={}&per_page={}", formated_query, limit),
format!("/crates?q={}&per_page={}", formatted_query, limit),
None, Auth::Unauthorized
)?;

View File

@ -3251,8 +3251,10 @@ fn wrong_message_format_option() {
assert_that(p.cargo("build").arg("--message-format").arg("XML"),
execs().with_status(1)
.with_stderr_contains(
r#"[ERROR] Could not match 'xml' with any of the allowed variants: ["Human", "Json"]"#));
.with_stderr_contains("\
error: 'XML' isn't a valid value for '--message-format <FMT>'
<tab>[possible values: human, json]
"));
}
#[test]
@ -4316,3 +4318,16 @@ fn avoid_dev_deps() {
.arg("-Zavoid-dev-deps"),
execs().with_status(0));
}
#[test]
fn invalid_jobs() {
let p = project("foo")
.file("Cargo.toml", &basic_bin_manifest("foo"))
.file("src/foo.rs", &main_file(r#""i am foo""#, &[]))
.build();
assert_that(p.cargo("build").arg("--jobs").arg("over9000"),
execs().with_status(1).with_stderr("\
error: Invalid value: could not parse `over9000` as a number
"));
}

View File

@ -101,11 +101,10 @@ fn find_closest_biuld_to_build() {
pr.arg("biuld");
assert_that(pr,
execs().with_status(101)
.with_stderr("[ERROR] no such subcommand: `biuld`
<tab>Did you mean `build`?
execs().with_status(1)
.with_stderr_contains("\
error: The subcommand 'biuld' wasn't recognized
<tab>Did you mean 'build'?
"));
}
@ -202,8 +201,6 @@ fn cargo_help() {
execs().with_status(0));
assert_that(cargo_process().arg("build").arg("-h"),
execs().with_status(0));
assert_that(cargo_process().arg("help").arg("-h"),
execs().with_status(0));
assert_that(cargo_process().arg("help").arg("help"),
execs().with_status(0));
}
@ -211,5 +208,6 @@ fn cargo_help() {
#[test]
fn explain() {
assert_that(cargo_process().arg("--explain").arg("E0001"),
execs().with_status(0));
execs().with_status(0).with_stdout_contains("\
This error suggests that the expression arm corresponding to the noted pattern"));
}

View File

@ -443,12 +443,8 @@ fn with_argument() {
fn unknown_flags() {
assert_that(cargo_process("init").arg("foo").arg("--flag"),
execs().with_status(1)
.with_stderr("\
[ERROR] Unknown flag: '--flag'
Usage:
cargo init [options] [<path>]
cargo init -h | --help
.with_stderr_contains("\
error: Found argument '--flag' which wasn't expected, or isn't valid in this context
"));
}

View File

@ -988,8 +988,9 @@ fn not_both_vers_and_version() {
pkg("foo", "0.1.2");
assert_that(cargo_process("install").arg("foo").arg("--version").arg("0.1.1").arg("--vers").arg("0.1.2"),
execs().with_status(101).with_stderr_contains("\
error: invalid arguments
execs().with_status(1).with_stderr_contains("\
error: The argument '--version <VERSION>' was provided more than once, \
but cannot be used multiple times
"));
}

View File

@ -752,8 +752,11 @@ fn cargo_metadata_bad_version() {
assert_that(p.cargo("metadata").arg("--no-deps")
.arg("--format-version").arg("2")
.cwd(p.root()),
execs().with_status(101)
.with_stderr("[ERROR] metadata version 2 not supported, only 1 is currently supported"));
execs().with_status(1)
.with_stderr_contains("\
error: '2' isn't a valid value for '--format-version <VERSION>'
<tab>[possible values: 1]
"));
}
#[test]

View File

@ -103,12 +103,9 @@ fn simple_git() {
fn no_argument() {
assert_that(cargo_process("new"),
execs().with_status(1)
.with_stderr("\
[ERROR] Invalid arguments.
Usage:
cargo new [options] <path>
cargo new -h | --help
.with_stderr_contains("\
error: The following required arguments were not provided:
<path>
"));
}
@ -373,12 +370,8 @@ fn subpackage_git_with_vcs_arg() {
fn unknown_flags() {
assert_that(cargo_process("new").arg("foo").arg("--flag"),
execs().with_status(1)
.with_stderr("\
[ERROR] Unknown flag: '--flag'
Usage:
cargo new [..]
cargo new [..]
.with_stderr_contains("\
error: Found argument '--flag' which wasn't expected, or isn't valid in this context
"));
}

View File

@ -156,8 +156,7 @@ fn simple_with_host() {
Previous versions of Cargo accepted this flag, but it is being
deprecated. The flag is being renamed to 'index', as the flag
wants the location of the index to which to publish. Please
use '--index' instead.
wants the location of the index. Please use '--index' instead.
This will soon become a hard error, so it's either recommended
to update to a fixed version or contact the upstream maintainer
@ -224,8 +223,7 @@ fn simple_with_index_and_host() {
Previous versions of Cargo accepted this flag, but it is being
deprecated. The flag is being renamed to 'index', as the flag
wants the location of the index to which to publish. Please
use '--index' instead.
wants the location of the index. Please use '--index' instead.
This will soon become a hard error, so it's either recommended
to update to a fixed version or contact the upstream maintainer

View File

@ -43,9 +43,13 @@ fn simple_quiet() {
.build();
assert_that(p.cargo("run").arg("-q"),
execs().with_status(0).with_stdout("\
hello
")
execs().with_status(0)
.with_stdout("hello")
);
assert_that(p.cargo("run").arg("--quiet"),
execs().with_status(0)
.with_stdout("hello")
);
}
@ -305,7 +309,7 @@ fn run_bins() {
assert_that(p.cargo("run").arg("--bins"),
execs().with_status(1)
.with_stderr_contains("\
[ERROR] Unknown flag: '--bins'. Did you mean '--bin'?"));
error: Found argument '--bins' which wasn't expected, or isn't valid in this context"));
}
#[test]
@ -809,7 +813,9 @@ fn run_multiple_packages() {
assert_that(cargo().arg("-p").arg("d1").arg("-p").arg("d2"),
execs()
.with_status(1)
.with_stderr_contains("[ERROR] Invalid arguments."));
.with_stderr_contains("\
error: The argument '--package <SPEC>' was provided more than once, but cannot be used multiple times
"));
assert_that(cargo().arg("-p").arg("d3"),
execs()

View File

@ -355,11 +355,10 @@ fn fail_with_multiple_packages() {
assert_that(foo.cargo("rustc").arg("-v").arg("-p").arg("bar")
.arg("-p").arg("baz"),
execs().with_status(1).with_stderr("\
[ERROR] Invalid arguments.
Usage:
cargo rustc [options] [--] [<opts>...]"));
execs().with_status(1).with_stderr_contains("\
error: The argument '--package <SPEC>' was provided more than once, \
but cannot be used multiple times
"));
}
#[test]

View File

@ -137,8 +137,7 @@ fn simple_with_host() {
Previous versions of Cargo accepted this flag, but it is being
deprecated. The flag is being renamed to 'index', as the flag
wants the location of the index in which to search. Please
use '--index' instead.
wants the location of the index. Please use '--index' instead.
This will soon become a hard error, so it's either recommended
to update to a fixed version or contact the upstream maintainer
@ -204,8 +203,7 @@ fn simple_with_index_and_host() {
Previous versions of Cargo accepted this flag, but it is being
deprecated. The flag is being renamed to 'index', as the flag
wants the location of the index in which to search. Please
use '--index' instead.
wants the location of the index. Please use '--index' instead.
This will soon become a hard error, so it's either recommended
to update to a fixed version or contact the upstream maintainer