diff --git a/Cargo.toml b/Cargo.toml index 477a044f688..fcc0c3517b7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] } diff --git a/src/bin/bench.rs b/src/bin/bench.rs deleted file mode 100644 index f42e5a73eb6..00000000000 --- a/src/bin/bench.rs +++ /dev/null @@ -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, - flag_jobs: Option, - flag_features: Vec, - flag_all_features: bool, - flag_no_default_features: bool, - flag_target: Option, - flag_manifest_path: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_message_format: MessageFormat, - flag_lib: bool, - flag_bin: Vec, - flag_bins: bool, - flag_example: Vec, - flag_examples: bool, - flag_test: Vec, - flag_tests: bool, - flag_bench: Vec, - flag_benches: bool, - flag_all_targets: bool, - flag_no_fail_fast: bool, - flag_frozen: bool, - flag_locked: bool, - arg_args: Vec, - flag_all: bool, - flag_exclude: Vec, - #[serde(rename = "flag_Z")] - flag_z: Vec, - #[serde(rename = "arg_BENCHNAME")] - arg_benchname: Option, -} - -pub const USAGE: &'static str = " -Execute all benchmarks of a local package - -Usage: - cargo bench [options] [BENCHNAME] [--] [...] - -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::>()); - - 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) - }) - } - } -} diff --git a/src/bin/build.rs b/src/bin/build.rs deleted file mode 100644 index 19ec21e5d84..00000000000 --- a/src/bin/build.rs +++ /dev/null @@ -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, - flag_jobs: Option, - flag_features: Vec, - flag_all_features: bool, - flag_no_default_features: bool, - flag_target: Option, - flag_manifest_path: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_message_format: MessageFormat, - flag_release: bool, - flag_lib: bool, - flag_bin: Vec, - flag_bins: bool, - flag_example: Vec, - flag_examples: bool, - flag_test: Vec, - flag_tests: bool, - flag_bench: Vec, - flag_benches: bool, - flag_all_targets: bool, - flag_locked: bool, - flag_frozen: bool, - flag_all: bool, - flag_exclude: Vec, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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::>()); - 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(()) -} diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs index 1f282f82d3e..5765125a5e7 100644 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -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, - flag_color: Option, - flag_explain: Option, - arg_command: String, - arg_args: Vec, - flag_locked: bool, - flag_frozen: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -const USAGE: &'static str = " -Rust's package manager - -Usage: - cargo [...] - 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 +mod cli; +mod command_prelude; +mod commands; -See 'cargo help ' 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 = 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::>(); - 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 { - 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>> { let alias_name = format!("alias.{}", command); let mut result = Ok(None); @@ -304,6 +74,43 @@ fn aliased_command(config: &Config, command: &str) -> CargoResult BTreeSet<(String, Option)> { + 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 { 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 { 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)> { - 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>(path: P) -> bool { use std::os::unix::prelude::*; diff --git a/src/bin/check.rs b/src/bin/check.rs deleted file mode 100644 index 53e8128e163..00000000000 --- a/src/bin/check.rs +++ /dev/null @@ -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, - flag_jobs: Option, - flag_features: Vec, - flag_all_features: bool, - flag_no_default_features: bool, - flag_target: Option, - flag_manifest_path: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_message_format: MessageFormat, - flag_release: bool, - flag_lib: bool, - flag_bin: Vec, - flag_bins: bool, - flag_example: Vec, - flag_examples: bool, - flag_test: Vec, - flag_tests: bool, - flag_bench: Vec, - flag_benches: bool, - flag_all_targets: bool, - flag_locked: bool, - flag_frozen: bool, - flag_all: bool, - flag_exclude: Vec, - flag_profile: Option, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -pub fn execute(options: Options, config: &mut Config) -> CliResult { - debug!("executing; cmd=cargo-check; args={:?}", - env::args().collect::>()); - - 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(()) -} diff --git a/src/bin/clean.rs b/src/bin/clean.rs deleted file mode 100644 index fc226b4adc6..00000000000 --- a/src/bin/clean.rs +++ /dev/null @@ -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, - flag_target: Option, - flag_manifest_path: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_release: bool, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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::>()); - 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(()) -} diff --git a/src/bin/cli.rs b/src/bin/cli.rs new file mode 100644 index 00000000000..5d21d020c3a --- /dev/null +++ b/src/bin/cli.rs @@ -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 ' 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 +} diff --git a/src/bin/command_prelude.rs b/src/bin/command_prelude.rs new file mode 100644 index 00000000000..6f55ac19b65 --- /dev/null +++ b/src/bin/command_prelude.rs @@ -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> { + let arg = match self._value_of(name) { + None => None, + Some(arg) => Some(arg.parse::().map_err(|_| { + clap::Error::value_validation_auto( + format!("could not parse `{}` as a number", arg) + ) + })?) + }; + Ok(arg) + } + + fn root_manifest(&self, config: &Config) -> CargoResult { + 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> { + 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> { + self.value_of_u32("jobs") + } + + fn target(&self) -> Option { + self._value_of("target").map(|s| s.to_string()) + } + + fn compile_options<'a>( + &self, + config: &'a Config, + mode: CompileMode + ) -> CargoResult> { + 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> { + 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 { + 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> { + 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> { + // 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; + + 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 { + 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 { + args.values_of(name).unwrap_or_default() + .map(|s| s.to_string()) + .collect() +} diff --git a/src/bin/commands/bench.rs b/src/bin/commands/bench.rs new file mode 100644 index 00000000000..e396e2bc70f --- /dev/null +++ b/src/bin/commands/bench.rs @@ -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) + }) + } + } +} diff --git a/src/bin/commands/build.rs b/src/bin/commands/build.rs new file mode 100644 index 00000000000..a7312a03354 --- /dev/null +++ b/src/bin/commands/build.rs @@ -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(()) +} diff --git a/src/bin/commands/check.rs b/src/bin/commands/check.rs new file mode 100644 index 00000000000..7b141bb02dc --- /dev/null +++ b/src/bin/commands/check.rs @@ -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(()) +} diff --git a/src/bin/commands/clean.rs b/src/bin/commands/clean.rs new file mode 100644 index 00000000000..7159e2dfe08 --- /dev/null +++ b/src/bin/commands/clean.rs @@ -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(()) +} diff --git a/src/bin/commands/doc.rs b/src/bin/commands/doc.rs new file mode 100644 index 00000000000..5059457321c --- /dev/null +++ b/src/bin/commands/doc.rs @@ -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(()) +} diff --git a/src/bin/commands/fetch.rs b/src/bin/commands/fetch.rs new file mode 100644 index 00000000000..1ccc2893f33 --- /dev/null +++ b/src/bin/commands/fetch.rs @@ -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(()) +} diff --git a/src/bin/commands/generate_lockfile.rs b/src/bin/commands/generate_lockfile.rs new file mode 100644 index 00000000000..e1ad63bcd3c --- /dev/null +++ b/src/bin/commands/generate_lockfile.rs @@ -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(()) +} diff --git a/src/bin/commands/git_checkout.rs b/src/bin/commands/git_checkout.rs new file mode 100644 index 00000000000..1125e9b422a --- /dev/null +++ b/src/bin/commands/git_checkout.rs @@ -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(()) +} diff --git a/src/bin/commands/init.rs b/src/bin/commands/init.rs new file mode 100644 index 00000000000..24929000c39 --- /dev/null +++ b/src/bin/commands/init.rs @@ -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(()) +} diff --git a/src/bin/commands/install.rs b/src/bin/commands/install.rs new file mode 100644 index 00000000000..813487950af --- /dev/null +++ b/src/bin/commands/install.rs @@ -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 `` 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 `. + +As a special convenience, omitting the 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::>(); + + 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(()) +} diff --git a/src/bin/commands/locate_project.rs b/src/bin/commands/locate_project.rs new file mode 100644 index 00000000000..b4662930cce --- /dev/null +++ b/src/bin/commands/locate_project.rs @@ -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(()) +} diff --git a/src/bin/commands/login.rs b/src/bin/commands/login.rs new file mode 100644 index 00000000000..7f26ea2e8f0 --- /dev/null +++ b/src/bin/commands/login.rs @@ -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(()) +} diff --git a/src/bin/commands/metadata.rs b/src/bin/commands/metadata.rs new file mode 100644 index 00000000000..e3ebaff82ef --- /dev/null +++ b/src/bin/commands/metadata.rs @@ -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(()) +} diff --git a/src/bin/commands/mod.rs b/src/bin/commands/mod.rs new file mode 100644 index 00000000000..6d8cb64a4ec --- /dev/null +++ b/src/bin/commands/mod.rs @@ -0,0 +1,101 @@ +use command_prelude::*; + +pub fn builtin() -> Vec { + 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 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; diff --git a/src/bin/commands/new.rs b/src/bin/commands/new.rs new file mode 100644 index 00000000000..d41f8cce42c --- /dev/null +++ b/src/bin/commands/new.rs @@ -0,0 +1,18 @@ +use command_prelude::*; + +use cargo::ops; + +pub fn cli() -> App { + subcommand("new") + .about("Create a new cargo package at ") + .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(()) +} diff --git a/src/bin/commands/owner.rs b/src/bin/commands/owner.rs new file mode 100644 index 00000000000..41823de9e36 --- /dev/null +++ b/src/bin/commands/owner.rs @@ -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(()) +} diff --git a/src/bin/commands/package.rs b/src/bin/commands/package.rs new file mode 100644 index 00000000000..eb2306192a4 --- /dev/null +++ b/src/bin/commands/package.rs @@ -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(()) +} diff --git a/src/bin/commands/pkgid.rs b/src/bin/commands/pkgid.rs new file mode 100644 index 00000000000..9777915d07e --- /dev/null +++ b/src/bin/commands/pkgid.rs @@ -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 argument, print out the fully qualified package id specifier. +This command will generate an error if is ambiguous as to which package +it refers to in the dependency graph. If no 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(()) +} diff --git a/src/bin/commands/publish.rs b/src/bin/commands/publish.rs new file mode 100644 index 00000000000..31c7c952292 --- /dev/null +++ b/src/bin/commands/publish.rs @@ -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(()) +} diff --git a/src/bin/commands/read_manifest.rs b/src/bin/commands/read_manifest.rs new file mode 100644 index 00000000000..d89fe5b7a01 --- /dev/null +++ b/src/bin/commands/read_manifest.rs @@ -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(()) +} diff --git a/src/bin/commands/run.rs b/src/bin/commands/run.rs new file mode 100644 index 00000000000..535ae5addf5 --- /dev/null +++ b/src/bin/commands/run.rs @@ -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) + }) + } + } +} diff --git a/src/bin/commands/rustc.rs b/src/bin/commands/rustc.rs new file mode 100644 index 00000000000..ea4c71b6183 --- /dev/null +++ b/src/bin/commands/rustc.rs @@ -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 +... 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 ... +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(()) +} diff --git a/src/bin/commands/rustdoc.rs b/src/bin/commands/rustdoc.rs new file mode 100644 index 00000000000..5b4fbd68885 --- /dev/null +++ b/src/bin/commands/rustdoc.rs @@ -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 ... 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 ... 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(()) +} diff --git a/src/bin/commands/search.rs b/src/bin/commands/search.rs new file mode 100644 index 00000000000..9b28e1f7855 --- /dev/null +++ b/src/bin/commands/search.rs @@ -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(()) +} diff --git a/src/bin/commands/test.rs b/src/bin/commands/test.rs new file mode 100644 index 00000000000..83be8de2420 --- /dev/null +++ b/src/bin/commands/test.rs @@ -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), + }) + } + }; +} diff --git a/src/bin/commands/uninstall.rs b/src/bin/commands/uninstall.rs new file mode 100644 index 00000000000..cf62c4c79d3 --- /dev/null +++ b/src/bin/commands/uninstall.rs @@ -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(()) +} diff --git a/src/bin/commands/update.rs b/src/bin/commands/update.rs new file mode 100644 index 00000000000..c857234bffe --- /dev/null +++ b/src/bin/commands/update.rs @@ -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 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(()) +} diff --git a/src/bin/commands/verify_project.rs b/src/bin/commands/verify_project.rs new file mode 100644 index 00000000000..93afa4bef3e --- /dev/null +++ b/src/bin/commands/verify_project.rs @@ -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::().is_err() { + fail("invalid", "invalid-format"); + } + + let mut h = HashMap::new(); + h.insert("success".to_string(), "true".to_string()); + print_json(&h); + Ok(()) +} diff --git a/src/bin/commands/version.rs b/src/bin/commands/version.rs new file mode 100644 index 00000000000..9f753886654 --- /dev/null +++ b/src/bin/commands/version.rs @@ -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(()) +} diff --git a/src/bin/commands/yank.rs b/src/bin/commands/yank.rs new file mode 100644 index 00000000000..2defd080c3b --- /dev/null +++ b/src/bin/commands/yank.rs @@ -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(()) +} diff --git a/src/bin/doc.rs b/src/bin/doc.rs deleted file mode 100644 index d4124fc089c..00000000000 --- a/src/bin/doc.rs +++ /dev/null @@ -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, - flag_features: Vec, - flag_all_features: bool, - flag_jobs: Option, - flag_manifest_path: Option, - flag_no_default_features: bool, - flag_no_deps: bool, - flag_open: bool, - flag_release: bool, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_message_format: MessageFormat, - flag_package: Vec, - flag_lib: bool, - flag_bin: Vec, - flag_bins: bool, - flag_frozen: bool, - flag_locked: bool, - flag_all: bool, - flag_exclude: Vec, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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::>()); - - 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(()) -} diff --git a/src/bin/fetch.rs b/src/bin/fetch.rs deleted file mode 100644 index 880b77eb60e..00000000000 --- a/src/bin/fetch.rs +++ /dev/null @@ -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, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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(()) -} - diff --git a/src/bin/generate_lockfile.rs b/src/bin/generate_lockfile.rs deleted file mode 100644 index 11cc83639d3..00000000000 --- a/src/bin/generate_lockfile.rs +++ /dev/null @@ -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, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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::>()); - 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(()) -} diff --git a/src/bin/git_checkout.rs b/src/bin/git_checkout.rs deleted file mode 100644 index ec3ae7a5b11..00000000000 --- a/src/bin/git_checkout.rs +++ /dev/null @@ -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, - flag_color: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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(()) -} diff --git a/src/bin/help.rs b/src/bin/help.rs deleted file mode 100644 index 409247c614e..00000000000 --- a/src/bin/help.rs +++ /dev/null @@ -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 - 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)) -} diff --git a/src/bin/init.rs b/src/bin/init.rs deleted file mode 100644 index 7d2a8593cda..00000000000 --- a/src/bin/init.rs +++ /dev/null @@ -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, - flag_color: Option, - flag_bin: bool, - flag_lib: bool, - arg_path: Option, - flag_name: Option, - flag_vcs: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -pub const USAGE: &'static str = " -Create a new cargo package in an existing directory - -Usage: - cargo init [options] [] - 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::>()); - 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(()) -} - diff --git a/src/bin/install.rs b/src/bin/install.rs deleted file mode 100644 index af18a839c59..00000000000 --- a/src/bin/install.rs +++ /dev/null @@ -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, - flag_features: Vec, - flag_all_features: bool, - flag_no_default_features: bool, - flag_debug: bool, - flag_bin: Vec, - flag_bins: bool, - flag_example: Vec, - flag_examples: bool, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_root: Option, - flag_list: bool, - flag_force: bool, - flag_frozen: bool, - flag_locked: bool, - - arg_crate: Vec, - flag_vers: Option, - flag_version: Option, - - flag_git: Option, - flag_branch: Option, - flag_tag: Option, - flag_rev: Option, - - flag_path: Option, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -pub const USAGE: &'static str = " -Install a Rust binary - -Usage: - cargo install [options] [...] - 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 `` 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 `. - -As a special convenience, omitting the 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::>(); - 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(()) -} diff --git a/src/bin/locate_project.rs b/src/bin/locate_project.rs deleted file mode 100644 index 7065938c0c9..00000000000 --- a/src/bin/locate_project.rs +++ /dev/null @@ -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, -} - -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(()) -} diff --git a/src/bin/login.rs b/src/bin/login.rs deleted file mode 100644 index e363507ba25..00000000000 --- a/src/bin/login.rs +++ /dev/null @@ -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, - arg_token: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, - flag_registry: Option, -} - -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] [] - -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(()) -} diff --git a/src/bin/metadata.rs b/src/bin/metadata.rs deleted file mode 100644 index d10fe8c445e..00000000000 --- a/src/bin/metadata.rs +++ /dev/null @@ -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, - flag_features: Vec, - flag_all_features: bool, - flag_format_version: Option, - flag_manifest_path: Option, - flag_no_default_features: bool, - flag_no_deps: bool, - flag_quiet: Option, - flag_verbose: u32, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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(()) -} diff --git a/src/bin/new.rs b/src/bin/new.rs deleted file mode 100644 index e18dcf8c27b..00000000000 --- a/src/bin/new.rs +++ /dev/null @@ -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, - flag_color: Option, - flag_bin: bool, - flag_lib: bool, - arg_path: String, - flag_name: Option, - flag_vcs: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -pub const USAGE: &'static str = " -Create a new cargo package at - -Usage: - cargo new [options] - 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 - -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::>()); - 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(()) -} - diff --git a/src/bin/owner.rs b/src/bin/owner.rs deleted file mode 100644 index 5708985ea82..00000000000 --- a/src/bin/owner.rs +++ /dev/null @@ -1,77 +0,0 @@ -use cargo::ops; -use cargo::util::{CliResult, Config}; - -#[derive(Deserialize)] -pub struct Options { - arg_crate: Option, - flag_token: Option, - flag_add: Option>, - flag_remove: Option>, - flag_index: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_list: bool, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, - flag_registry: Option, -} - -pub const USAGE: &'static str = " -Manage the owners of a crate on the registry - -Usage: - cargo owner [options] [] - -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(()) -} - diff --git a/src/bin/package.rs b/src/bin/package.rs deleted file mode 100644 index 4db0db86f46..00000000000 --- a/src/bin/package.rs +++ /dev/null @@ -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, - flag_color: Option, - flag_target: Option, - flag_manifest_path: Option, - flag_no_verify: bool, - flag_no_metadata: bool, - flag_list: bool, - flag_allow_dirty: bool, - flag_jobs: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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(()) -} diff --git a/src/bin/pkgid.rs b/src/bin/pkgid.rs deleted file mode 100644 index 01f8a8f6ba5..00000000000 --- a/src/bin/pkgid.rs +++ /dev/null @@ -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, - flag_color: Option, - flag_manifest_path: Option, - flag_frozen: bool, - flag_locked: bool, - flag_package: Option, - arg_spec: Option, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -pub const USAGE: &'static str = " -Print a fully qualified package specification - -Usage: - cargo pkgid [options] [] - -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 argument, print out the fully qualified package id specifier. -This command will generate an error if is ambiguous as to which package -it refers to in the dependency graph. If no 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(()) -} - diff --git a/src/bin/publish.rs b/src/bin/publish.rs deleted file mode 100644 index 71d7efc537b..00000000000 --- a/src/bin/publish.rs +++ /dev/null @@ -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, - flag_host: Option, // TODO: Deprecated, remove - flag_token: Option, - flag_target: Option, - flag_manifest_path: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_no_verify: bool, - flag_allow_dirty: bool, - flag_jobs: Option, - flag_dry_run: bool, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, - flag_registry: Option, -} - -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(()) -} diff --git a/src/bin/read_manifest.rs b/src/bin/read_manifest.rs deleted file mode 100644 index eee2210d835..00000000000 --- a/src/bin/read_manifest.rs +++ /dev/null @@ -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, - flag_color: Option, -} - -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::>()); - 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(()) -} diff --git a/src/bin/run.rs b/src/bin/run.rs deleted file mode 100644 index 92ccb90dbc7..00000000000 --- a/src/bin/run.rs +++ /dev/null @@ -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, - flag_example: Option, - flag_package: Option, - flag_jobs: Option, - flag_features: Vec, - flag_all_features: bool, - flag_no_default_features: bool, - flag_target: Option, - flag_manifest_path: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_message_format: MessageFormat, - flag_release: bool, - flag_frozen: bool, - flag_locked: bool, - arg_args: Vec, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -pub const USAGE: &'static str = " -Run the main binary of the local package (src/main.rs) - -Usage: - cargo run [options] [--] [...] - -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) - }) - } - } -} diff --git a/src/bin/rustc.rs b/src/bin/rustc.rs deleted file mode 100644 index a73e47ddcff..00000000000 --- a/src/bin/rustc.rs +++ /dev/null @@ -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>, - flag_package: Option, - flag_jobs: Option, - flag_features: Vec, - flag_all_features: bool, - flag_no_default_features: bool, - flag_target: Option, - flag_manifest_path: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_message_format: MessageFormat, - flag_release: bool, - flag_lib: bool, - flag_bin: Vec, - flag_bins: bool, - flag_example: Vec, - flag_examples: bool, - flag_test: Vec, - flag_tests: bool, - flag_bench: Vec, - flag_benches: bool, - flag_all_targets: bool, - flag_profile: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -pub const USAGE: &'static str = " -Compile a package and all of its dependencies - -Usage: - cargo rustc [options] [--] [...] - -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 -... 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 ... -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::>()); - 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(()) -} - diff --git a/src/bin/rustdoc.rs b/src/bin/rustdoc.rs deleted file mode 100644 index f10354619a9..00000000000 --- a/src/bin/rustdoc.rs +++ /dev/null @@ -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, - flag_target: Option, - flag_features: Vec, - flag_all_features: bool, - flag_jobs: Option, - flag_manifest_path: Option, - flag_no_default_features: bool, - flag_open: bool, - flag_verbose: u32, - flag_release: bool, - flag_quiet: Option, - flag_color: Option, - flag_message_format: MessageFormat, - flag_package: Option, - flag_lib: bool, - flag_bin: Vec, - flag_bins: bool, - flag_example: Vec, - flag_examples: bool, - flag_test: Vec, - flag_tests: bool, - flag_bench: Vec, - flag_benches: bool, - flag_all_targets: bool, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -pub const USAGE: &'static str = " -Build a package's documentation, using specified custom flags. - -Usage: - cargo rustdoc [options] [--] [...] - -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 ... 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 ... 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(()) -} diff --git a/src/bin/search.rs b/src/bin/search.rs deleted file mode 100644 index fabfdf402f6..00000000000 --- a/src/bin/search.rs +++ /dev/null @@ -1,90 +0,0 @@ -use cargo::ops; -use cargo::util::{CliResult, Config}; - -use std::cmp; - -#[derive(Deserialize)] -pub struct Options { - flag_index: Option, - flag_host: Option, // TODO: Deprecated, remove - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_limit: Option, - flag_frozen: bool, - flag_locked: bool, - arg_query: Vec, - #[serde(rename = "flag_Z")] - flag_z: Vec, - flag_registry: Option, -} - -pub const USAGE: &'static str = " -Search packages in crates.io - -Usage: - cargo search [options] ... - 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(()) -} diff --git a/src/bin/test.rs b/src/bin/test.rs deleted file mode 100644 index 1262894ceb4..00000000000 --- a/src/bin/test.rs +++ /dev/null @@ -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, - flag_features: Vec, - flag_all_features: bool, - flag_jobs: Option, - flag_manifest_path: Option, - flag_no_default_features: bool, - flag_no_run: bool, - flag_package: Vec, - flag_target: Option, - flag_lib: bool, - flag_doc: bool, - flag_bin: Vec, - flag_bins: bool, - flag_example: Vec, - flag_examples: bool, - flag_test: Vec, - flag_tests: bool, - flag_bench: Vec, - flag_benches: bool, - flag_all_targets: bool, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_message_format: MessageFormat, - flag_release: bool, - flag_no_fail_fast: bool, - flag_frozen: bool, - flag_locked: bool, - flag_all: bool, - flag_exclude: Vec, - #[serde(rename = "flag_Z")] - flag_z: Vec, - #[serde(rename = "arg_TESTNAME")] - arg_testname: Option, -} - -pub const USAGE: &'static str = " -Execute all unit and integration tests of a local package - -Usage: - cargo test [options] [TESTNAME] [--] [...] - -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::>()); - - 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), - }) - } - } -} diff --git a/src/bin/uninstall.rs b/src/bin/uninstall.rs deleted file mode 100644 index 3774f0c31fb..00000000000 --- a/src/bin/uninstall.rs +++ /dev/null @@ -1,57 +0,0 @@ -use cargo::ops; -use cargo::util::{CliResult, Config}; - -#[derive(Deserialize)] -pub struct Options { - flag_bin: Vec, - flag_root: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, - - arg_spec: Vec, -} - -pub const USAGE: &'static str = " -Remove a Rust binary - -Usage: - cargo uninstall [options] ... - 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::>(); - - ops::uninstall(root, specs, &options.flag_bin, config)?; - Ok(()) -} - diff --git a/src/bin/update.rs b/src/bin/update.rs deleted file mode 100644 index 1de78a23eef..00000000000 --- a/src/bin/update.rs +++ /dev/null @@ -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, - flag_aggressive: bool, - flag_precise: Option, - flag_manifest_path: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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 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::>()); - 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(()) -} diff --git a/src/bin/verify_project.rs b/src/bin/verify_project.rs deleted file mode 100644 index a054470263b..00000000000 --- a/src/bin/verify_project.rs +++ /dev/null @@ -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, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, -} - -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::().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) -} diff --git a/src/bin/version.rs b/src/bin/version.rs deleted file mode 100644 index 6d3772f1c97..00000000000 --- a/src/bin/version.rs +++ /dev/null @@ -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::>()); - - println!("{}", cargo::version()); - - Ok(()) -} diff --git a/src/bin/yank.rs b/src/bin/yank.rs deleted file mode 100644 index 293beec21e1..00000000000 --- a/src/bin/yank.rs +++ /dev/null @@ -1,72 +0,0 @@ -use cargo::ops; -use cargo::util::{CliResult, Config}; - -#[derive(Deserialize)] -pub struct Options { - arg_crate: Option, - flag_token: Option, - flag_vers: Option, - flag_index: Option, - flag_verbose: u32, - flag_quiet: Option, - flag_color: Option, - flag_undo: bool, - flag_frozen: bool, - flag_locked: bool, - #[serde(rename = "flag_Z")] - flag_z: Vec, - flag_registry: Option, -} - -pub static USAGE: &'static str = " -Remove a pushed crate from the index - -Usage: - cargo yank [options] [] - -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(()) -} - diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 5a5c3991166..01a61ab6b7c 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -13,10 +13,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; @@ -46,9 +46,7 @@ extern crate core_foundation; use std::fmt; -use serde::de::DeserializeOwned; use serde::ser; -use docopt::Docopt; use failure::Error; use core::Shell; @@ -109,26 +107,6 @@ impl fmt::Display for VersionInfo { } } -pub fn call_main_without_stdin( - 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(obj: &T) { let encoded = serde_json::to_string(&obj).unwrap(); println!("{}", encoded); @@ -136,6 +114,11 @@ pub fn print_json(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_err.exit() + } + } let CliError { error, exit_code, unknown } = err; // exit_code == 0 is non-fatal error, e.g. docopt version info diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index 647aa1d3657..7ba7757a218 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -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, + pub target: Option, 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)?; diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 484c0d32a33..ba2e05e00db 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -41,18 +41,18 @@ pub struct CompileOptions<'a> { /// Number of concurrent jobs to use. pub jobs: Option, /// The target platform to compile for (example: `i686-unknown-linux-gnu`). - pub target: Option<&'a str>, + pub target: Option, /// Extra features to build for the root package - pub features: &'a [String], + pub features: Vec, /// 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>, /// 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>, } 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), + Packages(Vec), } -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, package: Vec) -> CargoResult { 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> { - let specs = match self { + pub fn into_package_id_specs(&self, ws: &Workspace) -> CargoResult> { + 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::>>()? } 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), } #[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) -> CargoResult> { - 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, 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> { 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, all_bins: bool, + tsts: Vec, all_tsts: bool, + exms: Vec, all_exms: bool, + bens: Vec, 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>> { - 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 }; diff --git a/src/cargo/ops/cargo_doc.rs b/src/cargo/ops/cargo_doc.rs index d747b42d098..ced9140fe1f 100644 --- a/src/cargo/ops/cargo_doc.rs +++ b/src/cargo/ops/cargo_doc.rs @@ -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"); diff --git a/src/cargo/ops/cargo_generate_lockfile.rs b/src/cargo/ops/cargo_generate_lockfile.rs index d08c11b1662..e968460f999 100644 --- a/src/cargo/ops/cargo_generate_lockfile.rs +++ b/src/cargo/ops/cargo_generate_lockfile.rs @@ -12,7 +12,7 @@ use util::CargoResult; pub struct UpdateOptions<'a> { pub config: &'a Config, - pub to_update: &'a [String], + pub to_update: Vec, 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, diff --git a/src/cargo/ops/cargo_install.rs b/src/cargo/ops/cargo_install.rs index 40037e74e4e..126dfae0902 100644 --- a/src/cargo/ops/cargo_install.rs +++ b/src/cargo/ops/cargo_install.rs @@ -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 = bins.try_collect().unwrap_or_else(|| { pkg.targets().iter().filter(|t| t.is_bin()) .map(|t| t.name().to_string()) diff --git a/src/cargo/ops/cargo_new.rs b/src/cargo/ops/cargo_new.rs index fa370b47c38..a9594d6ecf9 100644 --- a/src/cargo/ops/cargo_new.rs +++ b/src/cargo/ops/cargo_new.rs @@ -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, pub kind: NewProjectKind, - pub path: &'a str, - pub name: Option<&'a str>, + pub path: String, + pub name: Option, } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -64,29 +61,12 @@ struct MkOptions<'a> { bin: bool, } -impl<'de> Deserialize<'de> for VersionControl { - fn deserialize>(d: D) -> Result { - 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, bin: bool, lib: bool, - path: &'a str, - name: Option<&'a str>) -> CargoResult> { + path: String, + name: Option) -> CargoResult { 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() { diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index b1fe6e76759..c42c5dc0356 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -23,7 +23,7 @@ pub struct PackageOpts<'cfg> { pub allow_dirty: bool, pub verify: bool, pub jobs: Option, - pub target: Option<&'cfg str>, + pub target: Option, pub registry: Option, } @@ -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, diff --git a/src/cargo/ops/cargo_run.rs b/src/cargo/ops/cargo_run.rs index 81ac7790844..cfd26e7524b 100644 --- a/src/cargo/ops/cargo_run.rs +++ b/src/cargo/ops/cargo_run.rs @@ -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]) diff --git a/src/cargo/ops/registry.rs b/src/cargo/ops/registry.rs index fb776d61bf8..9edd720f209 100644 --- a/src/cargo/ops/registry.rs +++ b/src/cargo/ops/registry.rs @@ -34,7 +34,7 @@ pub struct PublishOpts<'cfg> { pub verify: bool, pub allow_dirty: bool, pub jobs: Option, - pub target: Option<&'cfg str>, + pub target: Option, pub dry_run: bool, pub registry: Option, } @@ -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, - limit: u8, + limit: u32, reg: Option) -> CargoResult<()> { fn truncate_with_ellipsis(s: &str, max_width: usize) -> String { // We should truncate at grapheme-boundary and compute character-widths, diff --git a/src/cargo/util/errors.rs b/src/cargo/util/errors.rs index e552069d034..e5bc2bad8fd 100644 --- a/src/cargo/util/errors.rs +++ b/src/cargo/util/errors.rs @@ -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 = Result; @@ -169,6 +170,13 @@ impl From for CliError { } } +impl From for CliError { + fn from(err: clap::Error) -> CliError { + let code = if err.use_stderr() { 1 } else { 0 }; + CliError::new(err.into(), code) + } +} + // ============================================================================= // Construction helpers diff --git a/src/cargo/util/important_paths.rs b/src/cargo/util/important_paths.rs index faa5dfe9b0c..4371de4b92c 100644 --- a/src/cargo/util/important_paths.rs +++ b/src/cargo/util/important_paths.rs @@ -35,7 +35,7 @@ pub fn find_project_manifest(pwd: &Path, file: &str) -> CargoResult { } /// Find the root Cargo.toml -pub fn find_root_manifest_for_wd(manifest_path: Option, cwd: &Path) +pub fn find_root_manifest_for_wd(manifest_path: Option<&str>, cwd: &Path) -> CargoResult { match manifest_path { Some(path) => { diff --git a/src/crates-io/lib.rs b/src/crates-io/lib.rs index 637fa430398..a68a5119ad2 100644 --- a/src/crates-io/lib.rs +++ b/src/crates-io/lib.rs @@ -202,10 +202,10 @@ impl Registry { }) } - pub fn search(&mut self, query: &str, limit: u8) -> Result<(Vec, u32)> { - let formated_query = percent_encode(query.as_bytes(), QUERY_ENCODE_SET); + pub fn search(&mut self, query: &str, limit: u32) -> Result<(Vec, 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 )?; diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index 669c17d4153..2987b9db164 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -3250,8 +3250,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 ' +[possible values: human, json] +")); } #[test] @@ -4315,3 +4317,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 +")); +} diff --git a/tests/testsuite/cargo_command.rs b/tests/testsuite/cargo_command.rs index 8ca737c7db0..955905c3eba 100644 --- a/tests/testsuite/cargo_command.rs +++ b/tests/testsuite/cargo_command.rs @@ -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` - -Did you mean `build`? - + execs().with_status(1) + .with_stderr_contains("\ +error: The subcommand 'biuld' wasn't recognized +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")); } diff --git a/tests/testsuite/init.rs b/tests/testsuite/init.rs index 5aebd1e69a8..8f79ae6b4c0 100644 --- a/tests/testsuite/init.rs +++ b/tests/testsuite/init.rs @@ -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] [] - cargo init -h | --help + .with_stderr_contains("\ +error: Found argument '--flag' which wasn't expected, or isn't valid in this context ")); } diff --git a/tests/testsuite/install.rs b/tests/testsuite/install.rs index d8308ce5cb9..ad5f3d60f10 100644 --- a/tests/testsuite/install.rs +++ b/tests/testsuite/install.rs @@ -3,7 +3,6 @@ use std::fs::{self, File, OpenOptions}; use std::io::prelude::*; use cargo::util::ProcessBuilder; -use cargotest::ChannelChanger; use cargotest::install::{cargo_home, has_installed_exe}; use cargotest::support::git; use cargotest::support::paths; @@ -989,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 ' was provided more than once, \ +but cannot be used multiple times ")); } diff --git a/tests/testsuite/metadata.rs b/tests/testsuite/metadata.rs index c5c11cea23c..a7711659801 100644 --- a/tests/testsuite/metadata.rs +++ b/tests/testsuite/metadata.rs @@ -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 ' +[possible values: 1] +")); } #[test] diff --git a/tests/testsuite/new.rs b/tests/testsuite/new.rs index 134cc7244f4..bc541821066 100644 --- a/tests/testsuite/new.rs +++ b/tests/testsuite/new.rs @@ -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] - cargo new -h | --help + .with_stderr_contains("\ +error: The following required arguments were not provided: + ")); } @@ -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 ")); } diff --git a/tests/testsuite/publish.rs b/tests/testsuite/publish.rs index 38e3b06ecf0..b5ecd91830f 100644 --- a/tests/testsuite/publish.rs +++ b/tests/testsuite/publish.rs @@ -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 diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index 5841e1dd994..b3d38f25655 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -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 ' was provided more than once, but cannot be used multiple times +")); assert_that(cargo().arg("-p").arg("d3"), execs() diff --git a/tests/testsuite/rustc.rs b/tests/testsuite/rustc.rs index 7cc037c2569..ab5cb8d7bb6 100644 --- a/tests/testsuite/rustc.rs +++ b/tests/testsuite/rustc.rs @@ -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] [--] [...]")); + execs().with_status(1).with_stderr_contains("\ +error: The argument '--package ' was provided more than once, \ + but cannot be used multiple times +")); } #[test] diff --git a/tests/testsuite/search.rs b/tests/testsuite/search.rs index 70e00f9cbfe..1adbaf1b270 100644 --- a/tests/testsuite/search.rs +++ b/tests/testsuite/search.rs @@ -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