diff --git a/src/cargo-fmt/main.rs b/src/cargo-fmt/main.rs index acaf81e0665..3f6b3cd32fa 100644 --- a/src/cargo-fmt/main.rs +++ b/src/cargo-fmt/main.rs @@ -56,6 +56,10 @@ pub struct Opts { /// Format all packages (only usable in workspaces) #[structopt(long = "all")] format_all: bool, + + /// Run without accessing the network + #[structopt(long = "offline")] + offline: bool, } fn main() { @@ -112,6 +116,12 @@ fn execute() -> i32 { } } + let mut cargo_metadata_other_opts: Vec = vec![]; + + if opts.offline { + cargo_metadata_other_opts.push(String::from("--offline")); + } + if let Some(specified_manifest_path) = opts.manifest_path { if !specified_manifest_path.ends_with("Cargo.toml") { print_usage_to_stderr("the manifest-path must be a path to a Cargo.toml file"); @@ -123,9 +133,16 @@ fn execute() -> i32 { &strategy, rustfmt_args, Some(&manifest_path), + &cargo_metadata_other_opts, )) } else { - handle_command_status(format_crate(verbosity, &strategy, rustfmt_args, None)) + handle_command_status(format_crate( + verbosity, + &strategy, + rustfmt_args, + None, + &cargo_metadata_other_opts, + )) } } @@ -229,8 +246,9 @@ fn format_crate( strategy: &CargoFmtStrategy, rustfmt_args: Vec, manifest_path: Option<&Path>, + cargo_metadata_other_opts: &[String], ) -> Result { - let targets = get_targets(strategy, manifest_path)?; + let targets = get_targets(strategy, manifest_path, cargo_metadata_other_opts)?; // Currently only bin and lib files get formatted. run_rustfmt(&targets, &rustfmt_args, verbosity) @@ -310,17 +328,26 @@ impl CargoFmtStrategy { fn get_targets( strategy: &CargoFmtStrategy, manifest_path: Option<&Path>, + cargo_metadata_other_opts: &[String], ) -> Result, io::Error> { let mut targets = BTreeSet::new(); match *strategy { - CargoFmtStrategy::Root => get_targets_root_only(manifest_path, &mut targets)?, - CargoFmtStrategy::All => { - get_targets_recursive(manifest_path, &mut targets, &mut BTreeSet::new())? - } - CargoFmtStrategy::Some(ref hitlist) => { - get_targets_with_hitlist(manifest_path, hitlist, &mut targets)? + CargoFmtStrategy::Root => { + get_targets_root_only(manifest_path, &mut targets, cargo_metadata_other_opts)? } + CargoFmtStrategy::All => get_targets_recursive( + manifest_path, + &mut targets, + &mut BTreeSet::new(), + cargo_metadata_other_opts, + )?, + CargoFmtStrategy::Some(ref hitlist) => get_targets_with_hitlist( + manifest_path, + hitlist, + &mut targets, + cargo_metadata_other_opts, + )?, } if targets.is_empty() { @@ -336,8 +363,9 @@ fn get_targets( fn get_targets_root_only( manifest_path: Option<&Path>, targets: &mut BTreeSet, + cargo_metadata_other_opts: &[String], ) -> Result<(), io::Error> { - let metadata = get_cargo_metadata(manifest_path, false)?; + let metadata = get_cargo_metadata(manifest_path, false, cargo_metadata_other_opts)?; let workspace_root_path = PathBuf::from(&metadata.workspace_root).canonicalize()?; let (in_workspace_root, current_dir_manifest) = if let Some(target_manifest) = manifest_path { ( @@ -380,9 +408,10 @@ fn get_targets_recursive( manifest_path: Option<&Path>, mut targets: &mut BTreeSet, visited: &mut BTreeSet, + cargo_metadata_other_opts: &[String], ) -> Result<(), io::Error> { - let metadata = get_cargo_metadata(manifest_path, false)?; - let metadata_with_deps = get_cargo_metadata(manifest_path, true)?; + let metadata = get_cargo_metadata(manifest_path, false, cargo_metadata_other_opts)?; + let metadata_with_deps = get_cargo_metadata(manifest_path, true, cargo_metadata_other_opts)?; for package in metadata.packages { add_targets(&package.targets, &mut targets); @@ -409,7 +438,12 @@ fn get_targets_recursive( if manifest_path.exists() { visited.insert(dependency.name); - get_targets_recursive(Some(&manifest_path), &mut targets, visited)?; + get_targets_recursive( + Some(&manifest_path), + &mut targets, + visited, + cargo_metadata_other_opts, + )?; } } } @@ -421,8 +455,9 @@ fn get_targets_with_hitlist( manifest_path: Option<&Path>, hitlist: &[String], targets: &mut BTreeSet, + cargo_metadata_other_opts: &[String], ) -> Result<(), io::Error> { - let metadata = get_cargo_metadata(manifest_path, false)?; + let metadata = get_cargo_metadata(manifest_path, false, cargo_metadata_other_opts)?; let mut workspace_hitlist: BTreeSet<&String> = BTreeSet::from_iter(hitlist); @@ -511,6 +546,7 @@ fn run_rustfmt( fn get_cargo_metadata( manifest_path: Option<&Path>, include_deps: bool, + other_opts: &[String], ) -> Result { let mut cmd = cargo_metadata::MetadataCommand::new(); if !include_deps { @@ -519,16 +555,11 @@ fn get_cargo_metadata( if let Some(manifest_path) = manifest_path { cmd.manifest_path(manifest_path); } + cmd.other_options(other_opts); match cmd.exec() { Ok(metadata) => Ok(metadata), - Err(_) => { - cmd.other_options(&[String::from("--offline")]); - match cmd.exec() { - Ok(metadata) => Ok(metadata), - Err(error) => Err(io::Error::new(io::ErrorKind::Other, error.to_string())), - } - } + Err(error) => Err(io::Error::new(io::ErrorKind::Other, error.to_string())), } } @@ -543,6 +574,7 @@ mod cargo_fmt_tests { assert_eq!(false, o.quiet); assert_eq!(false, o.verbose); assert_eq!(false, o.version); + assert_eq!(false, o.offline); assert_eq!(empty, o.packages); assert_eq!(empty, o.rustfmt_options); assert_eq!(false, o.format_all); @@ -561,6 +593,7 @@ mod cargo_fmt_tests { "p2", "--message-format", "short", + "--offline", "--", "--edition", "2018", @@ -568,6 +601,7 @@ mod cargo_fmt_tests { assert_eq!(true, o.quiet); assert_eq!(false, o.verbose); assert_eq!(false, o.version); + assert_eq!(true, o.offline); assert_eq!(vec!["p1", "p2"], o.packages); assert_eq!(vec!["--edition", "2018"], o.rustfmt_options); assert_eq!(false, o.format_all);