diff --git a/src/bin/bench.rs b/src/bin/bench.rs index 3db26741f4e..9c7e31ee8ef 100644 --- a/src/bin/bench.rs +++ b/src/bin/bench.rs @@ -1,7 +1,7 @@ use cargo::core::Workspace; use cargo::ops; use cargo::util::{CliResult, CliError, Human, Config, human}; -use cargo::util::important_paths::{find_root_manifest_for_wd}; +use cargo::util::important_paths::find_root_manifest_for_wd; #[derive(RustcDecodable)] pub struct Options { @@ -89,6 +89,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { &options.flag_bench), target_rustdoc_args: None, target_rustc_args: None, + compile_check: false, }, }; @@ -99,7 +100,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { Some(err) => { Err(match err.exit.as_ref().and_then(|e| e.code()) { Some(i) => CliError::new(human("bench failed"), i), - None => CliError::new(Box::new(Human(err)), 101) + None => CliError::new(Box::new(Human(err)), 101), }) } } diff --git a/src/bin/build.rs b/src/bin/build.rs index 3fc0fe32e6c..77b798bd05f 100644 --- a/src/bin/build.rs +++ b/src/bin/build.rs @@ -3,7 +3,7 @@ use std::env; use cargo::core::Workspace; use cargo::ops::CompileOptions; use cargo::ops; -use cargo::util::important_paths::{find_root_manifest_for_wd}; +use cargo::util::important_paths::find_root_manifest_for_wd; use cargo::util::{CliResult, Config}; #[derive(RustcDecodable)] @@ -85,6 +85,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { &options.flag_bench), target_rustdoc_args: None, target_rustc_args: None, + compile_check: false, }; let ws = try!(Workspace::new(&root, config)); diff --git a/src/bin/cargo.rs b/src/bin/cargo.rs index 2c267623d2b..5025c2b206d 100644 --- a/src/bin/cargo.rs +++ b/src/bin/cargo.rs @@ -4,12 +4,13 @@ extern crate env_logger; extern crate git2_curl; extern crate rustc_serialize; extern crate toml; -#[macro_use] extern crate log; +#[macro_use] +extern crate log; use std::collections::BTreeSet; use std::env; use std::fs; -use std::path::{Path,PathBuf}; +use std::path::{Path, PathBuf}; use cargo::core::shell::Verbosity; use cargo::execute_main_without_stdin; @@ -47,6 +48,7 @@ Options: Some common cargo commands are (see all commands with --list): build Compile the current project + check Fast compilation to report errors without creating artifacts clean Remove the target directory doc Build this project's and its dependencies' documentation new Create a new cargo project @@ -71,6 +73,7 @@ macro_rules! each_subcommand{ ($mac:ident) => { $mac!(bench); $mac!(build); + $mac!(check); $mac!(clean); $mac!(doc); $mac!(fetch); @@ -112,30 +115,31 @@ each_subcommand!(declare_mod); on this top-level information. */ fn execute(flags: Flags, config: &Config) -> CliResult> { - try!(config.configure_shell(flags.flag_verbose, - flags.flag_quiet, - &flags.flag_color)); + try!(config.configure_shell(flags.flag_verbose, flags.flag_quiet, &flags.flag_color)); init_git_transports(config); cargo::util::job::setup(); if flags.flag_version { println!("{}", cargo::version()); - return Ok(None) + return Ok(None); } if flags.flag_list { println!("Installed Commands:"); for command in list_commands(config) { println!(" {}", command); - }; - return Ok(None) + } + return Ok(None); } if let Some(ref code) = flags.flag_explain { - try!(process(config.rustc()).arg("--explain").arg(code).exec() - .map_err(human)); - return Ok(None) + try!(process(config.rustc()) + .arg("--explain") + .arg(code) + .exec() + .map_err(human)); + return Ok(None); } let args = match &flags.arg_command[..] { @@ -145,23 +149,20 @@ fn execute(flags: Flags, config: &Config) -> CliResult> { "" | "help" if flags.arg_args.is_empty() => { config.shell().set_verbosity(Verbosity::Verbose); let args = &["cargo".to_string(), "-h".to_string()]; - let r = cargo::call_main_without_stdin(execute, config, USAGE, args, - false); + let r = cargo::call_main_without_stdin(execute, config, USAGE, args, false); cargo::process_executed(r, &mut config.shell()); - return Ok(None) + return Ok(None); } // 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" => { + "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()], + "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 @@ -190,29 +191,32 @@ 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 // suggest out-of-the-blue options. - let mut filtered = cmds.iter().map(|c| (lev_distance(&c, cmd), c)) - .filter(|&(d, _)| d < 4) - .collect::>(); + let mut filtered = cmds.iter() + .map(|c| (lev_distance(&c, cmd), c)) + .filter(|&(d, _)| d < 4) + .collect::>(); filtered.sort_by(|a, b| a.0.cmp(&b.0)); filtered.get(0).map(|slot| slot.1.clone()) } -fn execute_subcommand(config: &Config, - cmd: &str, - args: &[String]) -> CliResult<()> { +fn execute_subcommand(config: &Config, cmd: &str, args: &[String]) -> CliResult<()> { let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX); let path = search_directories(config) - .iter() - .map(|dir| dir.join(&command_exe)) - .find(|file| is_executable(file)); + .iter() + .map(|dir| dir.join(&command_exe)) + .find(|file| is_executable(file)); let command = match path { Some(command) => command, None => { return Err(human(match find_closest(config, cmd) { - Some(closest) => format!("no such subcommand: `{}`\n\n\t\ - Did you mean `{}`?\n", cmd, closest), - None => format!("no such subcommand: `{}`", cmd) - }).into()) + Some(closest) => { + format!("no such subcommand: `{}`\n\n\tDid you mean `{}`?\n", + cmd, + closest) + } + None => format!("no such subcommand: `{}`", cmd), + }) + .into()) } }; let err = match util::process(&command).args(&args[1..]).exec() { @@ -236,16 +240,16 @@ fn list_commands(config: &Config) -> BTreeSet { for dir in search_directories(config) { let entries = match fs::read_dir(dir) { Ok(entries) => entries, - _ => continue + _ => 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 + _ => continue, }; if !filename.starts_with(prefix) || !filename.ends_with(suffix) { - continue + continue; } if is_executable(entry.path()) { let end = filename.len() - suffix.len(); @@ -264,9 +268,9 @@ fn list_commands(config: &Config) -> BTreeSet { #[cfg(unix)] fn is_executable>(path: P) -> bool { use std::os::unix::prelude::*; - fs::metadata(path).map(|metadata| { - metadata.is_file() && metadata.permissions().mode() & 0o111 != 0 - }).unwrap_or(false) + fs::metadata(path) + .map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0) + .unwrap_or(false) } #[cfg(windows)] fn is_executable>(path: P) -> bool { @@ -287,7 +291,7 @@ fn init_git_transports(config: &Config) { // case. The custom transport, however, is not as well battle-tested. match cargo::ops::http_proxy_exists(config) { Ok(true) => {} - _ => return + _ => return, } let handle = match cargo::ops::http_handle(config) { diff --git a/src/bin/check.rs b/src/bin/check.rs new file mode 100644 index 00000000000..cd5705d955d --- /dev/null +++ b/src/bin/check.rs @@ -0,0 +1,92 @@ +use std::env; + +use cargo::core::Workspace; +use cargo::ops::CompileOptions; +use cargo::ops; +use cargo::util::important_paths::find_root_manifest_for_wd; +use cargo::util::{CliResult, Config}; + +#[derive(RustcDecodable)] +pub struct Options { + flag_package: Vec, + flag_jobs: Option, + flag_features: Vec, + flag_no_default_features: bool, + flag_target: Option, + flag_manifest_path: Option, + flag_verbose: u32, + flag_quiet: Option, + flag_color: Option, + flag_lib: bool, + flag_bin: Vec, + flag_example: Vec, + flag_test: Vec, + flag_bench: Vec, +} + +pub const USAGE: &'static str = " +Compile a local package to check for compilation errors without creating an artifact + +Usage: + cargo check [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 + --example NAME Build only the specified example + --test NAME Build only the specified test target + --bench NAME Build only the specified benchmark target + --features FEATURES Space-separated list of features to also build + --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 + -q, --quiet No output printed to stdout + --color WHEN Coloring: auto, always, never + +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. + +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: &Config) -> CliResult> { + debug!("executing; cmd=cargo-check; args={:?}", + env::args().collect::>()); + try!(config.configure_shell(options.flag_verbose, + options.flag_quiet, + &options.flag_color)); + + let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())); + + let opts = CompileOptions { + config: config, + jobs: options.flag_jobs, + target: options.flag_target.as_ref().map(|t| &t[..]), + features: &options.flag_features, + no_default_features: options.flag_no_default_features, + spec: &options.flag_package, + exec_engine: None, + mode: ops::CompileMode::Build, + release: false, + filter: ops::CompileFilter::new(options.flag_lib, + &options.flag_bin, + &options.flag_test, + &options.flag_example, + &options.flag_bench), + target_rustdoc_args: None, + target_rustc_args: None, + compile_check: true, + }; + + let ws = try!(Workspace::new(&root, config)); + try!(ops::compile(&ws, &opts)); + Ok(None) +} diff --git a/src/bin/doc.rs b/src/bin/doc.rs index 1c420def853..3b14c743e88 100644 --- a/src/bin/doc.rs +++ b/src/bin/doc.rs @@ -1,7 +1,7 @@ use cargo::core::Workspace; use cargo::ops; use cargo::util::{CliResult, Config}; -use cargo::util::important_paths::{find_root_manifest_for_wd}; +use cargo::util::important_paths::find_root_manifest_for_wd; #[derive(RustcDecodable)] pub struct Options { @@ -77,11 +77,10 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { &empty, &empty), release: options.flag_release, - mode: ops::CompileMode::Doc { - deps: !options.flag_no_deps, - }, + mode: ops::CompileMode::Doc { deps: !options.flag_no_deps }, target_rustc_args: None, target_rustdoc_args: None, + compile_check: false, }, }; diff --git a/src/bin/install.rs b/src/bin/install.rs index 7f9ed95195b..e67aba8ac38 100644 --- a/src/bin/install.rs +++ b/src/bin/install.rs @@ -103,10 +103,10 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { exec_engine: None, mode: ops::CompileMode::Build, release: !options.flag_debug, - filter: ops::CompileFilter::new(false, &options.flag_bin, &[], - &options.flag_example, &[]), + filter: ops::CompileFilter::new(false, &options.flag_bin, &[], &options.flag_example, &[]), target_rustc_args: None, target_rustdoc_args: None, + compile_check: false, }; let source = if let Some(url) = options.flag_git { @@ -136,7 +136,12 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { if options.flag_list { try!(ops::install_list(root, config)); } else { - try!(ops::install(root, krate, &source, vers, &compile_opts, options.flag_force)); + try!(ops::install(root, + krate, + &source, + vers, + &compile_opts, + options.flag_force)); } Ok(None) } diff --git a/src/bin/run.rs b/src/bin/run.rs index 378e3dc2400..d849e8f8c89 100644 --- a/src/bin/run.rs +++ b/src/bin/run.rs @@ -1,7 +1,7 @@ use cargo::core::Workspace; use cargo::ops; use cargo::util::{CliResult, CliError, Config, Human}; -use cargo::util::important_paths::{find_root_manifest_for_wd}; +use cargo::util::important_paths::find_root_manifest_for_wd; #[derive(RustcDecodable)] pub struct Options { @@ -78,12 +78,16 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { ops::CompileFilter::Everything } else { ops::CompileFilter::Only { - lib: false, tests: &[], benches: &[], - bins: &bins, examples: &examples, + lib: false, + tests: &[], + benches: &[], + bins: &bins, + examples: &examples, } }, target_rustdoc_args: None, target_rustc_args: None, + compile_check: false, }; let ws = try!(Workspace::new(&root, config)); diff --git a/src/bin/rustc.rs b/src/bin/rustc.rs index cc029c0a489..eb06ef12607 100644 --- a/src/bin/rustc.rs +++ b/src/bin/rustc.rs @@ -3,7 +3,7 @@ use std::env; use cargo::core::Workspace; use cargo::ops::{CompileOptions, CompileMode}; use cargo::ops; -use cargo::util::important_paths::{find_root_manifest_for_wd}; +use cargo::util::important_paths::find_root_manifest_for_wd; use cargo::util::{CliResult, CliError, Config, human}; #[derive(RustcDecodable)] @@ -73,16 +73,16 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { options.flag_quiet, &options.flag_color)); - let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, - config.cwd())); + let root = try!(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(mode) => { let err = human(format!("unknown profile: `{}`, use dev, - test, or bench", mode)); - return Err(CliError::new(err, 101)) + test, or bench", + mode)); + return Err(CliError::new(err, 101)); } }; @@ -103,10 +103,10 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { &options.flag_bench), target_rustdoc_args: None, target_rustc_args: options.arg_opts.as_ref().map(|a| &a[..]), + compile_check: false, }; let ws = try!(Workspace::new(&root, config)); try!(ops::compile(&ws, &opts)); Ok(None) } - diff --git a/src/bin/rustdoc.rs b/src/bin/rustdoc.rs index c5710a184c3..255a05bf702 100644 --- a/src/bin/rustdoc.rs +++ b/src/bin/rustdoc.rs @@ -1,7 +1,7 @@ use cargo::core::Workspace; use cargo::ops; use cargo::util::{CliResult, Config}; -use cargo::util::important_paths::{find_root_manifest_for_wd}; +use cargo::util::important_paths::find_root_manifest_for_wd; #[derive(RustcDecodable)] pub struct Options { @@ -67,8 +67,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { options.flag_quiet, &options.flag_color)); - let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, - config.cwd())); + let root = try!(find_root_manifest_for_wd(options.flag_manifest_path, config.cwd())); let doc_opts = ops::DocOptions { open_result: options.flag_open, @@ -89,6 +88,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { mode: ops::CompileMode::Doc { deps: false }, target_rustdoc_args: Some(&options.arg_opts), target_rustc_args: None, + compile_check: false, }, }; diff --git a/src/bin/test.rs b/src/bin/test.rs index f7f53bc4bfd..0827baa021f 100644 --- a/src/bin/test.rs +++ b/src/bin/test.rs @@ -1,7 +1,7 @@ use cargo::core::Workspace; use cargo::ops; use cargo::util::{CliResult, CliError, Human, human, Config}; -use cargo::util::important_paths::{find_root_manifest_for_wd}; +use cargo::util::important_paths::find_root_manifest_for_wd; #[derive(RustcDecodable)] pub struct Options { @@ -117,6 +117,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { filter: filter, target_rustdoc_args: None, target_rustc_args: None, + compile_check: false, }, }; @@ -127,7 +128,7 @@ pub fn execute(options: Options, config: &Config) -> CliResult> { Some(err) => { Err(match err.exit.as_ref().and_then(|e| e.code()) { Some(i) => CliError::new(human("test failed"), i), - None => CliError::new(Box::new(Human(err)), 101) + None => CliError::new(Box::new(Human(err)), 101), }) } } diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 8f175324aab..a12e0fe3b6f 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -1,4 +1,3 @@ -//! //! Cargo compile currently does the following steps: //! //! All configurations are already injected as environment variables via the @@ -62,6 +61,8 @@ pub struct CompileOptions<'a> { /// 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]>, + /// The compilation will stop before the generation of any artifacts: -Z no-trans + pub compile_check: bool, } #[derive(Clone, Copy, PartialEq)] @@ -69,7 +70,9 @@ pub enum CompileMode { Test, Build, Bench, - Doc { deps: bool }, + Doc { + deps: bool, + }, } pub enum CompileFilter<'a> { @@ -80,10 +83,11 @@ pub enum CompileFilter<'a> { examples: &'a [String], tests: &'a [String], benches: &'a [String], - } + }, } -pub fn compile<'a>(ws: &Workspace<'a>, options: &CompileOptions<'a>) +pub fn compile<'a>(ws: &Workspace<'a>, + options: &CompileOptions<'a>) -> CargoResult> { for key in try!(ws.current()).manifest().warnings().iter() { try!(options.config.shell().warn(key)) @@ -100,8 +104,7 @@ pub fn resolve_dependencies<'a>(ws: &Workspace<'a>, let mut registry = PackageRegistry::new(ws.config()); if let Some(source) = source { - registry.add_preloaded(try!(ws.current()).package_id().source_id(), - source); + registry.add_preloaded(try!(ws.current()).package_id().source_id(), source); } // First, resolve the root_package's *listed* dependencies, as well as @@ -115,18 +118,16 @@ pub fn resolve_dependencies<'a>(ws: &Workspace<'a>, try!(add_overrides(&mut registry, ws)); - let method = Method::Required{ + let method = Method::Required { dev_deps: true, // TODO: remove this option? features: &features, uses_default_features: !no_default_features, }; let resolved_with_overrides = - try!(ops::resolve_with_previous(&mut registry, ws, - method, Some(&resolve), None)); + try!(ops::resolve_with_previous(&mut registry, ws, method, Some(&resolve), None)); - let packages = ops::get_resolved_packages(&resolved_with_overrides, - registry); + let packages = ops::get_resolved_packages(&resolved_with_overrides, registry); Ok((packages, resolved_with_overrides)) } @@ -136,16 +137,25 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, options: &CompileOptions<'a>) -> CargoResult> { let root_package = try!(ws.current()); - let CompileOptions { config, jobs, target, spec, features, - no_default_features, release, mode, - ref filter, ref exec_engine, + let CompileOptions { config, + jobs, + target, + spec, + features, + no_default_features, + release, + mode, + ref filter, + ref exec_engine, ref target_rustdoc_args, - ref target_rustc_args } = *options; + ref target_rustc_args, + compile_check } = *options; let target = target.map(|s| s.to_string()); - let features = features.iter().flat_map(|s| { - s.split(' ') - }).map(|s| s.to_string()).collect::>(); + let features = features.iter() + .flat_map(|s| s.split(' ')) + .map(|s| s.to_string()) + .collect::>(); if jobs == Some(0) { bail!("jobs must be at least 1") @@ -169,21 +179,19 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, pkgids.push(root_package.package_id()); }; - let to_builds = try!(pkgids.iter().map(|id| { - packages.get(id) - }).collect::>>()); + let to_builds = try!(pkgids.iter() + .map(|id| packages.get(id)) + .collect::>>()); 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 => { + (Some(..), _) | (_, Some(..)) if to_builds.len() != 1 => { panic!("`rustc` and `rustdoc` should not accept multiple `-p` flags") } (Some(args), _) => { - let targets = try!(generate_targets(to_builds[0], profiles, - mode, filter, release)); + let targets = try!(generate_targets(to_builds[0], profiles, mode, filter, release)); if targets.len() == 1 { let (target, profile) = targets[0]; let mut profile = profile.clone(); @@ -196,8 +204,7 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, } } (None, Some(args)) => { - let targets = try!(generate_targets(to_builds[0], profiles, - mode, filter, release)); + let targets = try!(generate_targets(to_builds[0], profiles, mode, filter, release)); if targets.len() == 1 { let (target, profile) = targets[0]; let mut profile = profile.clone(); @@ -210,10 +217,19 @@ pub fn compile_ws<'a>(ws: &Workspace<'a>, } } (None, None) => { - for &to_build in to_builds.iter() { - let targets = try!(generate_targets(to_build, profiles, mode, - filter, release)); - package_targets.push((to_build, targets)); + // If compile_check then pass -Z no-trans to rustc to + // shorten the error reporting by not building artifacts + if compile_check { + let targets = try!(generate_targets(to_builds[0], profiles, mode, filter, release)); + let (target, profile) = targets[0]; + let mut profile = profile.clone(); + profile.rustc_args = Some(vec!["-Z".to_string(), "no-trans".to_string()]); + general_targets.push((target, profile)); + } else { + for &to_build in to_builds.iter() { + let targets = try!(generate_targets(to_build, profiles, mode, filter, release)); + package_targets.push((to_build, targets)); + } } } }; @@ -253,11 +269,15 @@ impl<'a> CompileFilter<'a> { bins: &'a [String], tests: &'a [String], examples: &'a [String], - benches: &'a [String]) -> CompileFilter<'a> { - if lib_only || !bins.is_empty() || !tests.is_empty() || - !examples.is_empty() || !benches.is_empty() { + benches: &'a [String]) + -> CompileFilter<'a> { + if lib_only || !bins.is_empty() || !tests.is_empty() || !examples.is_empty() || + !benches.is_empty() { CompileFilter::Only { - lib: lib_only, bins: bins, examples: examples, benches: benches, + lib: lib_only, + bins: bins, + examples: examples, + benches: benches, tests: tests, } } else { @@ -291,8 +311,16 @@ fn generate_targets<'a>(pkg: &'a Package, filter: &CompileFilter, release: bool) -> CargoResult> { - let build = if release {&profiles.release} else {&profiles.dev}; - let test = if release {&profiles.bench} else {&profiles.test}; + let build = if release { + &profiles.release + } else { + &profiles.dev + }; + let test = if release { + &profiles.bench + } else { + &profiles.test + }; let profile = match mode { CompileMode::Test => test, CompileMode::Bench => &profiles.bench, @@ -303,16 +331,25 @@ fn generate_targets<'a>(pkg: &'a Package, CompileFilter::Everything => { match mode { CompileMode::Bench => { - Ok(pkg.targets().iter().filter(|t| t.benched()).map(|t| { - (t, profile) - }).collect::>()) + Ok(pkg.targets() + .iter() + .filter(|t| t.benched()) + .map(|t| (t, profile)) + .collect::>()) } CompileMode::Test => { - let mut base = pkg.targets().iter().filter(|t| { - t.tested() - }).map(|t| { - (t, if t.is_example() {build} else {profile}) - }).collect::>(); + let mut base = pkg.targets() + .iter() + .filter(|t| t.tested()) + .map(|t| { + (t, + if t.is_example() { + build + } else { + profile + }) + }) + .collect::>(); // Always compile the library if we're testing everything as // it'll be needed for doctests @@ -324,13 +361,18 @@ fn generate_targets<'a>(pkg: &'a Package, Ok(base) } CompileMode::Build => { - Ok(pkg.targets().iter().filter(|t| { - t.is_bin() || t.is_lib() - }).map(|t| (t, profile)).collect()) + Ok(pkg.targets() + .iter() + .filter(|t| t.is_bin() || t.is_lib()) + .map(|t| (t, profile)) + .collect()) } CompileMode::Doc { .. } => { - Ok(pkg.targets().iter().filter(|t| t.documented()) - .map(|t| (t, profile)).collect()) + Ok(pkg.targets() + .iter() + .filter(|t| t.documented()) + .map(|t| (t, profile)) + .collect()) } } } @@ -348,9 +390,8 @@ fn generate_targets<'a>(pkg: &'a Package, { let mut find = |names: &[String], desc, kind, profile| { for name in names { - let target = pkg.targets().iter().find(|t| { - t.name() == *name && *t.kind() == kind - }); + let target = + pkg.targets().iter().find(|t| t.name() == *name && *t.kind() == kind); let t = match target { Some(t) => t, None => { @@ -359,7 +400,9 @@ fn generate_targets<'a>(pkg: &'a Package, Some(s) => { let suggested_name = s.name(); bail!("no {} target named `{}`\n\nDid you mean `{}`?", - desc, name, suggested_name) + desc, + name, + suggested_name) } None => bail!("no {} target named `{}`", desc, name), } @@ -382,30 +425,33 @@ fn generate_targets<'a>(pkg: &'a Package, /// Read the `paths` configuration variable to discover all path overrides that /// have been configured. -fn add_overrides<'a>(registry: &mut PackageRegistry<'a>, - ws: &Workspace<'a>) -> CargoResult<()> { +fn add_overrides<'a>(registry: &mut PackageRegistry<'a>, ws: &Workspace<'a>) -> CargoResult<()> { let paths = match try!(ws.config().get_list("paths")) { Some(list) => list, - None => return Ok(()) + None => return Ok(()), }; let current = try!(ws.current()); - let paths = paths.val.iter().map(|&(ref s, ref p)| { - // The path listed next to the string is the config file in which the - // key was located, so we want to pop off the `.cargo/config` component - // to get the directory containing the `.cargo` folder. - (p.parent().unwrap().parent().unwrap().join(s), p) - }).filter(|&(ref p, _)| { - // Make sure we don't override the local package, even if it's in the - // list of override paths. - current.root() != &**p - }); + let paths = paths.val + .iter() + .map(|&(ref s, ref p)| { + // The path listed next to the string is the config file in which the + // key was located, so we want to pop off the `.cargo/config` component + // to get the directory containing the `.cargo` folder. + (p.parent().unwrap().parent().unwrap().join(s), p) + }) + .filter(|&(ref p, _)| { + // Make sure we don't override the local package, even if it's in the + // list of override paths. + current.root() != &**p + }); for (path, definition) in paths { let id = try!(SourceId::for_path(&path)); let mut source = PathSource::new_recursive(&path, &id, ws.config()); try!(source.update().chain_error(|| { human(format!("failed to update path override `{}` \ - (defined in `{}`)", path.display(), + (defined in `{}`)", + path.display(), definition.display())) })); registry.add_override(&id, Box::new(source)); @@ -429,9 +475,11 @@ fn scrape_build_config(config: &Config, Some(v) => { if v.val <= 0 { bail!("build.jobs must be positive, but found {} in {}", - v.val, v.definition) + v.val, + v.definition) } else if v.val >= u32::max_value() as i64 { - bail!("build.jobs is too large: found {} in {}", v.val, + bail!("build.jobs is too large: found {} in {}", + v.val, v.definition) } else { Some(v.val as u32) @@ -455,8 +503,7 @@ fn scrape_build_config(config: &Config, Ok(base) } -fn scrape_target_config(config: &Config, triple: &str) - -> CargoResult { +fn scrape_target_config(config: &Config, triple: &str) -> CargoResult { let key = format!("target.{}", triple); let mut ret = ops::TargetConfig { @@ -470,7 +517,7 @@ fn scrape_target_config(config: &Config, triple: &str) }; for (lib_name, value) in table { if lib_name == "ar" || lib_name == "linker" || lib_name == "rustflags" { - continue + continue; } let mut output = BuildOutput { @@ -486,24 +533,19 @@ fn scrape_target_config(config: &Config, triple: &str) match &k[..] { "rustc-flags" => { let (flags, definition) = try!(value.string()); - let whence = format!("in `{}` (in {})", key, - definition.display()); - let (paths, links) = try!( - BuildOutput::parse_rustc_flags(&flags, &whence) - ); + let whence = format!("in `{}` (in {})", key, definition.display()); + let (paths, links) = try!(BuildOutput::parse_rustc_flags(&flags, &whence)); output.library_paths.extend(paths); output.library_links.extend(links); } "rustc-link-lib" => { let list = try!(value.list()); output.library_links.extend(list.iter() - .map(|v| v.0.clone())); + .map(|v| v.0.clone())); } "rustc-link-search" => { let list = try!(value.list()); - output.library_paths.extend(list.iter().map(|v| { - PathBuf::from(&v.0) - })); + output.library_paths.extend(list.iter().map(|v| PathBuf::from(&v.0))); } "rustc-cfg" => { let list = try!(value.list()); diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 461068fb407..2bee9f9e787 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -21,13 +21,10 @@ pub struct PackageOpts<'cfg> { pub verify: bool, } -pub fn package(ws: &Workspace, - opts: &PackageOpts) -> CargoResult> { +pub fn package(ws: &Workspace, opts: &PackageOpts) -> CargoResult> { let pkg = try!(ws.current()); let config = ws.config(); - let mut src = PathSource::new(pkg.root(), - pkg.package_id().source_id(), - config); + let mut src = PathSource::new(pkg.root(), pkg.package_id().source_id(), config); try!(src.update()); if opts.check_metadata { @@ -36,14 +33,15 @@ pub fn package(ws: &Workspace, if opts.list { let root = pkg.root(); - let mut list: Vec<_> = try!(src.list_files(&pkg)).iter().map(|file| { - util::without_prefix(&file, &root).unwrap().to_path_buf() - }).collect(); + let mut list: Vec<_> = try!(src.list_files(&pkg)) + .iter() + .map(|file| util::without_prefix(&file, &root).unwrap().to_path_buf()) + .collect(); list.sort(); for file in list.iter() { println!("{}", file.display()); } - return Ok(None) + return Ok(None); } if !opts.allow_dirty { @@ -63,22 +61,18 @@ pub fn package(ws: &Workspace, // it exists. try!(config.shell().status("Packaging", pkg.package_id().to_string())); try!(dst.file().set_len(0)); - try!(tar(ws, &src, dst.file(), &filename).chain_error(|| { - human("failed to prepare local package for uploading") - })); + try!(tar(ws, &src, dst.file(), &filename) + .chain_error(|| human("failed to prepare local package for uploading"))); if opts.verify { try!(dst.seek(SeekFrom::Start(0))); - try!(run_verify(ws, dst.file()).chain_error(|| { - human("failed to verify package tarball") - })) + try!(run_verify(ws, dst.file()).chain_error(|| human("failed to verify package tarball"))) } try!(dst.seek(SeekFrom::Start(0))); { let src_path = dst.path(); let dst_path = dst.parent().join(&filename); - try!(fs::rename(&src_path, &dst_path).chain_error(|| { - human("failed to move temporary tarball into final location") - })); + try!(fs::rename(&src_path, &dst_path) + .chain_error(|| human("failed to move temporary tarball into final location"))); } Ok(Some(dst)) } @@ -99,7 +93,9 @@ fn check_metadata(pkg: &Package, config: &Config) -> CargoResult<()> { )* }} } - lacking!(description, license || license_file, documentation || homepage || repository); + lacking!(description, + license || license_file, + documentation || homepage || repository); if !missing.is_empty() { let mut things = missing[..missing.len() - 1].join(", "); @@ -110,10 +106,10 @@ fn check_metadata(pkg: &Package, config: &Config) -> CargoResult<()> { } things.push_str(&missing.last().unwrap()); - try!(config.shell().warn( - &format!("manifest has no {things}. \ - See http://doc.crates.io/manifest.html#package-metadata for more info.", - things = things))) + try!(config.shell().warn(&format!("manifest has no {things}. See \ + http://doc.crates.io/manifest.html#package-metadata \ + for more info.", + things = things))) } Ok(()) } @@ -128,7 +124,7 @@ fn check_not_dirty(p: &Package, src: &PathSource) -> CargoResult<()> { if let Ok(status) = repo.status_file(path) { if (status & git2::STATUS_IGNORED).is_empty() { debug!("Cargo.toml found in repo, checking if dirty"); - return git(p, src, &repo) + return git(p, src, &repo); } } } @@ -138,39 +134,38 @@ fn check_not_dirty(p: &Package, src: &PathSource) -> CargoResult<()> { // have to assume that it's clean. return Ok(()); - fn git(p: &Package, - src: &PathSource, - repo: &git2::Repository) -> CargoResult<()> { + fn git(p: &Package, src: &PathSource, repo: &git2::Repository) -> CargoResult<()> { let workdir = repo.workdir().unwrap(); - let dirty = try!(src.list_files(p)).iter().filter(|file| { - let relative = file.strip_prefix(workdir).unwrap(); - if let Ok(status) = repo.status_file(relative) { - status != git2::STATUS_CURRENT - } else { - false - } - }).map(|path| { - path.strip_prefix(p.root()).unwrap_or(path).display().to_string() - }).collect::>(); + let dirty = try!(src.list_files(p)) + .iter() + .filter(|file| { + let relative = file.strip_prefix(workdir).unwrap(); + if let Ok(status) = repo.status_file(relative) { + status != git2::STATUS_CURRENT + } else { + false + } + }) + .map(|path| path.strip_prefix(p.root()).unwrap_or(path).display().to_string()) + .collect::>(); if dirty.is_empty() { Ok(()) } else { bail!("{} dirty files found in the working directory:\n\n{}\n\n\ to publish despite this, pass `--allow-dirty` to \ `cargo publish`", - dirty.len(), dirty.join("\n")) + dirty.len(), + dirty.join("\n")) } } } -fn tar(ws: &Workspace, - src: &PathSource, - dst: &File, - filename: &str) -> CargoResult<()> { +fn tar(ws: &Workspace, src: &PathSource, dst: &File, filename: &str) -> CargoResult<()> { // Prepare the encoder and its header let filename = Path::new(filename); - let encoder = GzBuilder::new().filename(try!(util::path2bytes(filename))) - .write(dst, Compression::Best); + let encoder = GzBuilder::new() + .filename(try!(util::path2bytes(filename))) + .write(dst, Compression::Best); // Put all package files into a compressed archive let mut ar = Builder::new(encoder); @@ -181,15 +176,15 @@ fn tar(ws: &Workspace, let relative = util::without_prefix(&file, &root).unwrap(); try!(check_filename(relative)); let relative = try!(relative.to_str().chain_error(|| { - human(format!("non-utf8 path in source directory: {}", - relative.display())) + human(format!("non-utf8 path in source directory: {}", relative.display())) })); let mut file = try!(File::open(file)); - try!(config.shell().verbose(|shell| { - shell.status("Archiving", &relative) - })); - let path = format!("{}-{}{}{}", pkg.name(), pkg.version(), - path::MAIN_SEPARATOR, relative); + try!(config.shell().verbose(|shell| shell.status("Archiving", &relative))); + let path = format!("{}-{}{}{}", + pkg.name(), + pkg.version(), + path::MAIN_SEPARATOR, + relative); // The tar::Builder type by default will build GNU archives, but // unfortunately we force it here to use UStar archives instead. The @@ -210,18 +205,15 @@ fn tar(ws: &Workspace, // unpack the selectors 0.4.0 crate on crates.io. Either that or take a // look at rust-lang/cargo#2326 let mut header = Header::new_ustar(); - let metadata = try!(file.metadata().chain_error(|| { - human(format!("could not learn metadata for: `{}`", relative)) - })); - try!(header.set_path(&path).chain_error(|| { - human(format!("failed to add to archive: `{}`", relative)) - })); + let metadata = try!(file.metadata() + .chain_error(|| human(format!("could not learn metadata for: `{}`", relative)))); + try!(header.set_path(&path) + .chain_error(|| human(format!("failed to add to archive: `{}`", relative)))); header.set_metadata(&metadata); header.set_cksum(); - try!(ar.append(&header, &mut file).chain_error(|| { - internal(format!("could not archive source file `{}`", relative)) - })); + try!(ar.append(&header, &mut file) + .chain_error(|| internal(format!("could not archive source file `{}`", relative)))); } let encoder = try!(ar.into_inner()); try!(encoder.finish()); @@ -235,8 +227,7 @@ fn run_verify(ws: &Workspace, tar: &File) -> CargoResult<()> { try!(config.shell().status("Verifying", pkg)); let f = try!(GzDecoder::new(tar)); - let dst = pkg.root().join(&format!("target/package/{}-{}", - pkg.name(), pkg.version())); + let dst = pkg.root().join(&format!("target/package/{}-{}", pkg.name(), pkg.version())); if fs::metadata(&dst).is_ok() { try!(fs::remove_dir_all(&dst)); } @@ -257,7 +248,9 @@ fn run_verify(ws: &Workspace, tar: &File) -> CargoResult<()> { let new_src = try!(SourceId::for_path(&dst)).with_precise(precise); let new_pkgid = try!(PackageId::new(pkg.name(), pkg.version(), &new_src)); let new_summary = pkg.summary().clone().map_dependencies(|d| { - if !d.source_id().is_path() { return d } + if !d.source_id().is_path() { + return d; + } d.clone_inner().set_source_id(registry.clone()).into_dependency() }); let mut new_manifest = pkg.manifest().clone(); @@ -266,20 +259,23 @@ fn run_verify(ws: &Workspace, tar: &File) -> CargoResult<()> { // Now that we've rewritten all our path dependencies, compile it! let ws = Workspace::one(new_pkg, config); - try!(ops::compile_ws(&ws, None, &ops::CompileOptions { - config: config, - jobs: None, - target: None, - features: &[], - no_default_features: false, - spec: &[], - filter: ops::CompileFilter::Everything, - exec_engine: None, - release: false, - mode: ops::CompileMode::Build, - target_rustdoc_args: None, - target_rustc_args: None, - })); + try!(ops::compile_ws(&ws, + None, + &ops::CompileOptions { + config: config, + jobs: None, + target: None, + features: &[], + no_default_features: false, + spec: &[], + filter: ops::CompileFilter::Everything, + exec_engine: None, + release: false, + mode: ops::CompileMode::Build, + target_rustdoc_args: None, + target_rustc_args: None, + compile_check: false, + })); Ok(()) } @@ -299,13 +295,15 @@ fn check_filename(file: &Path) -> CargoResult<()> { Some(name) => name, None => { bail!("path does not have a unicode filename which may not unpack \ - on all platforms: {}", file.display()) + on all platforms: {}", + file.display()) } }; let bad_chars = ['/', '\\', '<', '>', ':', '"', '|', '?', '*']; for c in bad_chars.iter().filter(|c| name.contains(**c)) { bail!("cannot package a filename with a special character `{}`: {}", - c, file.display()) + c, + file.display()) } Ok(()) }