about summary refs log tree commit diff
path: root/clippy_dev/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'clippy_dev/src/lib.rs')
-rw-r--r--clippy_dev/src/lib.rs31
1 files changed, 27 insertions, 4 deletions
diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
index 3aae3e53317..c58b80e4318 100644
--- a/clippy_dev/src/lib.rs
+++ b/clippy_dev/src/lib.rs
@@ -7,6 +7,7 @@ use std::collections::HashMap;
 use std::ffi::OsStr;
 use std::fs;
 use std::io::prelude::*;
+use std::path::{Path, PathBuf};
 use walkdir::WalkDir;
 
 lazy_static! {
@@ -205,7 +206,8 @@ fn parse_contents(content: &str, filename: &str) -> impl Iterator<Item = Lint> {
 fn lint_files() -> impl Iterator<Item = walkdir::DirEntry> {
     // We use `WalkDir` instead of `fs::read_dir` here in order to recurse into subdirectories.
     // Otherwise we would not collect all the lints, for example in `clippy_lints/src/methods/`.
-    WalkDir::new("../clippy_lints/src")
+    let path = clippy_project_root().join("clippy_lints/src");
+    WalkDir::new(path)
         .into_iter()
         .filter_map(std::result::Result::ok)
         .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
@@ -225,7 +227,7 @@ pub struct FileChange {
 /// See `replace_region_in_text` for documentation of the other options.
 #[allow(clippy::expect_fun_call)]
 pub fn replace_region_in_file<F>(
-    path: &str,
+    path: &Path,
     start: &str,
     end: &str,
     replace_start: bool,
@@ -235,14 +237,15 @@ pub fn replace_region_in_file<F>(
 where
     F: Fn() -> Vec<String>,
 {
-    let mut f = fs::File::open(path).expect(&format!("File not found: {}", path));
+    let path = clippy_project_root().join(path);
+    let mut f = fs::File::open(&path).expect(&format!("File not found: {}", path.to_string_lossy()));
     let mut contents = String::new();
     f.read_to_string(&mut contents)
         .expect("Something went wrong reading the file");
     let file_change = replace_region_in_text(&contents, start, end, replace_start, replacements);
 
     if write_back {
-        let mut f = fs::File::create(path).expect(&format!("File not found: {}", path));
+        let mut f = fs::File::create(&path).expect(&format!("File not found: {}", path.to_string_lossy()));
         f.write_all(file_change.new_lines.as_bytes())
             .expect("Unable to write file");
         // Ensure we write the changes with a trailing newline so that
@@ -318,6 +321,26 @@ where
     }
 }
 
+/// Returns the path to the Clippy project directory
+#[must_use]
+pub fn clippy_project_root() -> PathBuf {
+    let current_dir = std::env::current_dir().unwrap();
+    for path in current_dir.ancestors() {
+        let result = std::fs::read_to_string(path.join("Cargo.toml"));
+        if let Err(err) = &result {
+            if err.kind() == std::io::ErrorKind::NotFound {
+                continue;
+            }
+        }
+
+        let content = result.unwrap();
+        if content.contains("[package]\nname = \"clippy\"") {
+            return path.to_path_buf();
+        }
+    }
+    panic!("error: Can't determine root of project. Please run inside a Clippy working dir.");
+}
+
 #[test]
 fn test_parse_contents() {
     let result: Vec<Lint> = parse_contents(