Skip to content

Commit 1265b46

Browse files
committed
Basic implementation of cargo clippy --all
This implements workspace support for `cargo clippy` by running clippy over all packages in the workspace (in serial). This should probably be parallelised in future (as `cargo build --all`).
1 parent 7cdaeae commit 1265b46

File tree

1 file changed

+75
-63
lines changed

1 file changed

+75
-63
lines changed

src/main.rs

Lines changed: 75 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ Common options:
152152
-h, --help Print this message
153153
--features Features to compile for the package
154154
-V, --version Print version info and exit
155+
--all @@@ something sensible here (copy from cargo-edit?)
155156
156157
Other options are the same as `cargo rustc`.
157158
@@ -217,74 +218,85 @@ pub fn main() {
217218
.expect("manifest path could not be canonicalized")
218219
});
219220

220-
let package_index = {
221-
if let Some(manifest_path) = manifest_path {
222-
metadata.packages.iter().position(|package| {
223-
let package_manifest_path = Path::new(&package.manifest_path).canonicalize().expect(
224-
"package manifest path could not be canonicalized",
225-
);
226-
package_manifest_path == manifest_path
227-
})
228-
} else {
229-
let package_manifest_paths: HashMap<_, _> = metadata
230-
.packages
231-
.iter()
232-
.enumerate()
233-
.map(|(i, package)| {
234-
let package_manifest_path = Path::new(&package.manifest_path)
235-
.parent()
236-
.expect("could not find parent directory of package manifest")
237-
.canonicalize()
238-
.expect("package directory cannot be canonicalized");
239-
(package_manifest_path, i)
221+
let packages = if std::env::args().any(|a| a == "--all" ) {
222+
metadata.packages
223+
} else {
224+
let package_index = {
225+
if let Some(manifest_path) = manifest_path {
226+
metadata.packages.iter().position(|package| {
227+
let package_manifest_path = Path::new(&package.manifest_path).canonicalize().expect(
228+
"package manifest path could not be canonicalized",
229+
);
230+
package_manifest_path == manifest_path
240231
})
241-
.collect();
242-
243-
let current_dir = std::env::current_dir()
244-
.expect("could not read current directory")
245-
.canonicalize()
246-
.expect("current directory cannot be canonicalized");
247-
248-
let mut current_path: &Path = &current_dir;
249-
250-
// This gets the most-recent parent (the one that takes the fewest `cd ..`s to
251-
// reach).
252-
loop {
253-
if let Some(&package_index) = package_manifest_paths.get(current_path) {
254-
break Some(package_index);
255-
} else {
256-
// We'll never reach the filesystem root, because to get to this point in the
257-
// code
258-
// the call to `cargo_metadata::metadata` must have succeeded. So it's okay to
259-
// unwrap the current path's parent.
260-
current_path = current_path.parent().unwrap_or_else(|| {
261-
panic!("could not find parent of path {}", current_path.display())
262-
});
232+
} else {
233+
let package_manifest_paths: HashMap<_, _> = metadata
234+
.packages
235+
.iter()
236+
.enumerate()
237+
.map(|(i, package)| {
238+
let package_manifest_path = Path::new(&package.manifest_path)
239+
.parent()
240+
.expect("could not find parent directory of package manifest")
241+
.canonicalize()
242+
.expect("package directory cannot be canonicalized");
243+
(package_manifest_path, i)
244+
})
245+
.collect();
246+
247+
let current_dir = std::env::current_dir()
248+
.expect("could not read current directory")
249+
.canonicalize()
250+
.expect("current directory cannot be canonicalized");
251+
252+
let mut current_path: &Path = &current_dir;
253+
254+
// This gets the most-recent parent (the one that takes the fewest `cd ..`s to
255+
// reach).
256+
loop {
257+
if let Some(&package_index) = package_manifest_paths.get(current_path) {
258+
break Some(package_index);
259+
} else {
260+
// We'll never reach the filesystem root, because to get to this point in the
261+
// code
262+
// the call to `cargo_metadata::metadata` must have succeeded. So it's okay to
263+
// unwrap the current path's parent.
264+
current_path = current_path.parent().unwrap_or_else(|| {
265+
panic!("could not find parent of path {}", current_path.display())
266+
});
267+
}
263268
}
264269
}
265-
}
266-
}.expect("could not find matching package");
267-
268-
let package = metadata.packages.remove(package_index);
269-
for target in package.targets {
270-
let args = std::env::args().skip(2);
271-
if let Some(first) = target.kind.get(0) {
272-
if target.kind.len() > 1 || first.ends_with("lib") {
273-
if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args)) {
274-
std::process::exit(code);
275-
}
276-
} else if ["bin", "example", "test", "bench"].contains(&&**first) {
277-
if let Err(code) = process(
278-
vec![format!("--{}", first), target.name]
279-
.into_iter()
280-
.chain(args),
281-
)
282-
{
283-
std::process::exit(code);
270+
}.expect("could not find matching package");
271+
272+
vec![metadata.packages.remove(package_index)]
273+
};
274+
275+
for package in packages {
276+
let manifest_path = package.manifest_path;
277+
278+
for target in package.targets {
279+
let args = std::env::args().skip(2).filter(|a| a != "--all" && !a.starts_with("--manifest-path="));
280+
281+
let args = std::iter::once(format!("--manifest-path={}", manifest_path)).chain(args);
282+
if let Some(first) = target.kind.get(0) {
283+
if target.kind.len() > 1 || first.ends_with("lib") {
284+
if let Err(code) = process(std::iter::once("--lib".to_owned()).chain(args)) {
285+
std::process::exit(code);
286+
}
287+
} else if ["bin", "example", "test", "bench"].contains(&&**first) {
288+
if let Err(code) = process(
289+
vec![format!("--{}", first), target.name]
290+
.into_iter()
291+
.chain(args),
292+
)
293+
{
294+
std::process::exit(code);
295+
}
284296
}
297+
} else {
298+
panic!("badly formatted cargo metadata: target::kind is an empty array");
285299
}
286-
} else {
287-
panic!("badly formatted cargo metadata: target::kind is an empty array");
288300
}
289301
}
290302
} else {

0 commit comments

Comments
 (0)