mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-22 20:53:21 +00:00
Fix logic that determines closest parent crate when invoked from a subdirectory.
The previous logic incorrectly matches the deepest child of the current directory that is a crate.
This commit is contained in:
parent
38680e8411
commit
db7a5c69f1
6 changed files with 46 additions and 32 deletions
|
@ -34,6 +34,10 @@ script:
|
||||||
- cp clippy_tests/target/debug/cargo-clippy ~/rust/cargo/bin/cargo-clippy
|
- cp clippy_tests/target/debug/cargo-clippy ~/rust/cargo/bin/cargo-clippy
|
||||||
- PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy
|
- PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy
|
||||||
- cd clippy_lints && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy && cd ..
|
- cd clippy_lints && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy && cd ..
|
||||||
|
- cd clippy_workspace_tests && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy && cd ..
|
||||||
|
- cd clippy_workspace_tests/src && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy && cd ../..
|
||||||
|
- cd clippy_workspace_tests/subcrate && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy && cd ../..
|
||||||
|
- cd clippy_workspace_tests/subcrate/src && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy && cd ../../..
|
||||||
- set +e
|
- set +e
|
||||||
|
|
||||||
after_success: |
|
after_success: |
|
||||||
|
|
6
clippy_workspace_tests/Cargo.toml
Normal file
6
clippy_workspace_tests/Cargo.toml
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "clippy_workspace_tests"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[workspace]
|
||||||
|
members = ["subcrate"]
|
2
clippy_workspace_tests/src/main.rs
Normal file
2
clippy_workspace_tests/src/main.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
fn main() {
|
||||||
|
}
|
3
clippy_workspace_tests/subcrate/Cargo.toml
Normal file
3
clippy_workspace_tests/subcrate/Cargo.toml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[package]
|
||||||
|
name = "subcrate"
|
||||||
|
version = "0.1.0"
|
0
clippy_workspace_tests/subcrate/src/lib.rs
Normal file
0
clippy_workspace_tests/subcrate/src/lib.rs
Normal file
63
src/main.rs
63
src/main.rs
|
@ -15,6 +15,7 @@ extern crate syntax;
|
||||||
use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
|
use rustc_driver::{driver, CompilerCalls, RustcDefaultCalls, Compilation};
|
||||||
use rustc::session::{config, Session, CompileIncomplete};
|
use rustc::session::{config, Session, CompileIncomplete};
|
||||||
use rustc::session::config::{Input, ErrorOutputType};
|
use rustc::session::config::{Input, ErrorOutputType};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::{self, Command};
|
use std::process::{self, Command};
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
@ -158,12 +159,6 @@ fn show_version() {
|
||||||
println!("{}", env!("CARGO_PKG_VERSION"));
|
println!("{}", env!("CARGO_PKG_VERSION"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: false positive for needless_lifetimes
|
|
||||||
#[allow(needless_lifetimes)]
|
|
||||||
fn has_prefix<'a, T: PartialEq, I: Iterator<Item = &'a T>>(v: &'a [T], itr: I) -> bool {
|
|
||||||
v.iter().zip(itr).all(|(a, b)| a == b)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
|
@ -199,43 +194,47 @@ pub fn main() {
|
||||||
let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));
|
let manifest_path = manifest_path_arg.map(|arg| PathBuf::from(Path::new(&arg["--manifest-path=".len()..])));
|
||||||
|
|
||||||
let package_index = {
|
let package_index = {
|
||||||
let mut iterator = metadata.packages.iter();
|
|
||||||
|
|
||||||
if let Some(ref manifest_path) = manifest_path {
|
if let Some(ref manifest_path) = manifest_path {
|
||||||
iterator.position(|package| {
|
metadata.packages.iter().position(|package| {
|
||||||
let package_manifest_path = Path::new(&package.manifest_path);
|
let package_manifest_path = Path::new(&package.manifest_path);
|
||||||
package_manifest_path == manifest_path
|
package_manifest_path == manifest_path
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let current_dir = std::env::current_dir()
|
let package_manifest_paths: HashMap<_, _> =
|
||||||
.expect("could not read current directory")
|
metadata.packages.iter()
|
||||||
.canonicalize()
|
|
||||||
.expect("current directory cannot be canonicalized");
|
|
||||||
let current_dir_components = current_dir.components().collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// This gets the most-recent parent (the one that takes the fewest `cd ..`s to
|
|
||||||
// reach).
|
|
||||||
iterator
|
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(i, package)| {
|
.map(|(i, package)| {
|
||||||
let package_manifest_path = Path::new(&package.manifest_path);
|
let package_manifest_path = Path::new(&package.manifest_path)
|
||||||
let canonical_path = package_manifest_path
|
|
||||||
.parent()
|
.parent()
|
||||||
.expect("could not find parent directory of package manifest")
|
.expect("could not find parent directory of package manifest")
|
||||||
.canonicalize()
|
.canonicalize()
|
||||||
.expect("package directory cannot be canonicalized");
|
.expect("package directory cannot be canonicalized");
|
||||||
|
(package_manifest_path, i)
|
||||||
// TODO: We can do this in `O(1)` by combining the `len` and the
|
|
||||||
// iteration.
|
|
||||||
let components = canonical_path.components().collect::<Vec<_>>();
|
|
||||||
if has_prefix(¤t_dir_components, components.iter()) {
|
|
||||||
Some((i, components.len()))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.max_by_key(|&(_, length)| length)
|
.collect();
|
||||||
.map(|(i, _)| i)
|
|
||||||
|
let current_dir = std::env::current_dir()
|
||||||
|
.expect("could not read current directory")
|
||||||
|
.canonicalize()
|
||||||
|
.expect("current directory cannot be canonicalized");
|
||||||
|
|
||||||
|
let mut current_path: &Path = ¤t_dir;
|
||||||
|
|
||||||
|
// This gets the most-recent parent (the one that takes the fewest `cd ..`s to
|
||||||
|
// reach).
|
||||||
|
loop {
|
||||||
|
if let Some(&package_index) = package_manifest_paths.get(current_path) {
|
||||||
|
break Some(package_index);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// We'll never reach the filesystem root, because to get to this point in the code
|
||||||
|
// the call to `cargo_metadata::metadata` must have succeeded. So it's okay to
|
||||||
|
// unwrap the current path's parent.
|
||||||
|
current_path = current_path
|
||||||
|
.parent()
|
||||||
|
.unwrap_or_else(|| panic!("could not find parent of path {}", current_path.display()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.expect("could not find matching package");
|
.expect("could not find matching package");
|
||||||
|
|
Loading…
Reference in a new issue