Skip to content

Commit 17cbbd8

Browse files
feat: add --manifest-path support to cargo fmt
1 parent 679c8d5 commit 17cbbd8

File tree

1 file changed

+55
-12
lines changed

1 file changed

+55
-12
lines changed

src/cargo-fmt/main.rs

+55-12
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ pub struct Opts {
4141
#[structopt(short = "p", long = "package", value_name = "package")]
4242
packages: Vec<String>,
4343

44+
/// Specify path to Cargo.toml
45+
#[structopt(long = "manifest-path", value_name = "manifest-path")]
46+
manifest_path: Option<String>,
47+
4448
/// Options passed to rustfmt
4549
// 'raw = true' to make `--` explicit.
4650
#[structopt(name = "rustfmt_options", raw(raw = "true"))]
@@ -90,7 +94,27 @@ fn execute() -> i32 {
9094

9195
let strategy = CargoFmtStrategy::from_opts(&opts);
9296

93-
handle_command_status(format_crate(verbosity, &strategy, opts.rustfmt_options))
97+
if opts.manifest_path.is_some() {
98+
let specified_manifest_path = opts.manifest_path.unwrap();
99+
if !specified_manifest_path.ends_with("Cargo.toml") {
100+
print_usage_to_stderr("the manifest-path must be a path to a Cargo.toml file");
101+
return FAILURE;
102+
}
103+
let manifest_path = PathBuf::from(specified_manifest_path);
104+
handle_command_status(format_crate(
105+
verbosity,
106+
&strategy,
107+
opts.rustfmt_options,
108+
Some(&manifest_path),
109+
))
110+
} else {
111+
handle_command_status(format_crate(
112+
verbosity,
113+
&strategy,
114+
opts.rustfmt_options,
115+
None,
116+
))
117+
}
94118
}
95119

96120
fn print_usage_to_stderr(reason: &str) {
@@ -142,14 +166,15 @@ fn format_crate(
142166
verbosity: Verbosity,
143167
strategy: &CargoFmtStrategy,
144168
rustfmt_args: Vec<String>,
169+
manifest_path: Option<&Path>,
145170
) -> Result<i32, io::Error> {
146171
let targets = if rustfmt_args
147172
.iter()
148173
.any(|s| ["--print-config", "-h", "--help", "-V", "--version"].contains(&s.as_str()))
149174
{
150175
BTreeSet::new()
151176
} else {
152-
get_targets(strategy)?
177+
get_targets(strategy, manifest_path)?
153178
};
154179

155180
// Currently only bin and lib files get formatted.
@@ -227,13 +252,20 @@ impl CargoFmtStrategy {
227252
}
228253

229254
/// Based on the specified `CargoFmtStrategy`, returns a set of main source files.
230-
fn get_targets(strategy: &CargoFmtStrategy) -> Result<BTreeSet<Target>, io::Error> {
255+
fn get_targets(
256+
strategy: &CargoFmtStrategy,
257+
manifest_path: Option<&Path>,
258+
) -> Result<BTreeSet<Target>, io::Error> {
231259
let mut targets = BTreeSet::new();
232260

233261
match *strategy {
234-
CargoFmtStrategy::Root => get_targets_root_only(&mut targets)?,
235-
CargoFmtStrategy::All => get_targets_recursive(None, &mut targets, &mut BTreeSet::new())?,
236-
CargoFmtStrategy::Some(ref hitlist) => get_targets_with_hitlist(hitlist, &mut targets)?,
262+
CargoFmtStrategy::Root => get_targets_root_only(manifest_path, &mut targets)?,
263+
CargoFmtStrategy::All => {
264+
get_targets_recursive(manifest_path, &mut targets, &mut BTreeSet::new())?
265+
}
266+
CargoFmtStrategy::Some(ref hitlist) => {
267+
get_targets_with_hitlist(manifest_path, hitlist, &mut targets)?
268+
}
237269
}
238270

239271
if targets.is_empty() {
@@ -246,12 +278,22 @@ fn get_targets(strategy: &CargoFmtStrategy) -> Result<BTreeSet<Target>, io::Erro
246278
}
247279
}
248280

249-
fn get_targets_root_only(targets: &mut BTreeSet<Target>) -> Result<(), io::Error> {
250-
let metadata = get_cargo_metadata(None, false)?;
251-
let current_dir = env::current_dir()?.canonicalize()?;
252-
let current_dir_manifest = current_dir.join("Cargo.toml");
281+
fn get_targets_root_only(
282+
manifest_path: Option<&Path>,
283+
targets: &mut BTreeSet<Target>,
284+
) -> Result<(), io::Error> {
285+
let metadata = get_cargo_metadata(manifest_path, false)?;
253286
let workspace_root_path = PathBuf::from(&metadata.workspace_root).canonicalize()?;
254-
let in_workspace_root = workspace_root_path == current_dir;
287+
let (in_workspace_root, current_dir_manifest) = if manifest_path.is_some() {
288+
let target_manifest = manifest_path.unwrap().canonicalize()?;
289+
(workspace_root_path == target_manifest, target_manifest)
290+
} else {
291+
let current_dir = env::current_dir()?.canonicalize()?;
292+
(
293+
workspace_root_path == current_dir,
294+
current_dir.join("Cargo.toml"),
295+
)
296+
};
255297

256298
let package_targets = match metadata.packages.len() {
257299
1 => metadata.packages.into_iter().next().unwrap().targets,
@@ -319,10 +361,11 @@ fn get_targets_recursive(
319361
}
320362

321363
fn get_targets_with_hitlist(
364+
manifest_path: Option<&Path>,
322365
hitlist: &[String],
323366
targets: &mut BTreeSet<Target>,
324367
) -> Result<(), io::Error> {
325-
let metadata = get_cargo_metadata(None, false)?;
368+
let metadata = get_cargo_metadata(manifest_path, false)?;
326369

327370
let mut workspace_hitlist: BTreeSet<&String> = BTreeSet::from_iter(hitlist);
328371

0 commit comments

Comments
 (0)