Skip to content

Commit e88c29c

Browse files
authored
Merge pull request #1860 from Vurich/master
Allow cargo-clippy to work in subdirectories
2 parents 1788f7b + 01bb0f9 commit e88c29c

File tree

1 file changed

+43
-15
lines changed

1 file changed

+43
-15
lines changed

src/main.rs

+43-15
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,12 @@ fn show_version() {
158158
println!("{}", env!("CARGO_PKG_VERSION"));
159159
}
160160

161+
// FIXME: false positive for needless_lifetimes
162+
#[allow(needless_lifetimes)]
163+
fn has_prefix<'a, T: PartialEq, I: Iterator<Item = &'a T>>(v: &'a [T], itr: I) -> bool {
164+
v.iter().zip(itr).all(|(a, b)| a == b)
165+
}
166+
161167
pub fn main() {
162168
use std::env;
163169

@@ -192,26 +198,48 @@ pub fn main() {
192198

193199
let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));
194200

195-
let current_dir = std::env::current_dir();
201+
let package_index = {
202+
let mut iterator = metadata.packages.iter();
196203

197-
let package_index = metadata
198-
.packages
199-
.iter()
200-
.position(|package| {
201-
let package_manifest_path = Path::new(&package.manifest_path);
202204
if let Some(ref manifest_path) = manifest_path {
203-
package_manifest_path == manifest_path
205+
iterator.position(|package| {
206+
let package_manifest_path = Path::new(&package.manifest_path);
207+
package_manifest_path == manifest_path
208+
})
204209
} else {
205-
let current_dir = current_dir
206-
.as_ref()
207-
.expect("could not read current directory");
208-
let package_manifest_directory = package_manifest_path
209-
.parent()
210-
.expect("could not find parent directory of package manifest");
211-
package_manifest_directory == current_dir
210+
let current_dir = std::env::current_dir()
211+
.expect("could not read current directory")
212+
.canonicalize()
213+
.expect("current directory cannot be canonicalized");
214+
let current_dir_components = current_dir.components().collect::<Vec<_>>();
215+
216+
// This gets the most-recent parent (the one that takes the fewest `cd ..`s to
217+
// reach).
218+
iterator
219+
.enumerate()
220+
.filter_map(|(i, package)| {
221+
let package_manifest_path = Path::new(&package.manifest_path);
222+
let canonical_path = package_manifest_path
223+
.parent()
224+
.expect("could not find parent directory of package manifest")
225+
.canonicalize()
226+
.expect("package directory cannot be canonicalized");
227+
228+
// TODO: We can do this in `O(1)` by combining the `len` and the
229+
// iteration.
230+
let components = canonical_path.components().collect::<Vec<_>>();
231+
if has_prefix(&current_dir_components, components.iter()) {
232+
Some((i, components.len()))
233+
} else {
234+
None
235+
}
236+
})
237+
.max_by_key(|&(_, length)| length)
238+
.map(|(i, _)| i)
212239
}
213-
})
240+
}
214241
.expect("could not find matching package");
242+
215243
let package = metadata.packages.remove(package_index);
216244
for target in package.targets {
217245
let args = std::env::args().skip(2);

0 commit comments

Comments
 (0)