diff options
| author | xFrednet <xFrednet@gmail.com> | 2021-06-22 00:25:10 +0200 |
|---|---|---|
| committer | flip1995 <philipp.krones@embecosm.com> | 2021-06-25 11:17:00 +0200 |
| commit | 8fdf2897da4ba476018090f3fb8f637a0de00c73 (patch) | |
| tree | db7c2a781b2cc15442a5dfeac445d63cdc67a400 /clippy_dev/src/setup | |
| parent | b48f041befdca6ad14acfda2db68c280ee3fbc85 (diff) | |
| download | rust-8fdf2897da4ba476018090f3fb8f637a0de00c73.tar.gz rust-8fdf2897da4ba476018090f3fb8f637a0de00c73.zip | |
Updated `cargo dev setup intellij` for cleaner user messages
Diffstat (limited to 'clippy_dev/src/setup')
| -rw-r--r-- | clippy_dev/src/setup/intellij.rs | 147 |
1 files changed, 109 insertions, 38 deletions
diff --git a/clippy_dev/src/setup/intellij.rs b/clippy_dev/src/setup/intellij.rs index 9b084f52466..3685e1b6def 100644 --- a/clippy_dev/src/setup/intellij.rs +++ b/clippy_dev/src/setup/intellij.rs @@ -8,42 +8,113 @@ use std::path::{Path, PathBuf}; // This allows rust analyzer to analyze rustc internals and show proper information inside clippy // code. See https://github.com/rust-analyzer/rust-analyzer/issues/3517 and https://github.com/rust-lang/rust-clippy/issues/5514 for details -/// # Panics -/// -/// Panics if `rustc_path` does not lead to a rustc repo or the files could not be read -pub fn run(rustc_path: Option<&str>) { - // we can unwrap here because the arg is required by clap - let rustc_path = PathBuf::from(rustc_path.unwrap()) - .canonicalize() - .expect("failed to get the absolute repo path"); - assert!(rustc_path.is_dir(), "path is not a directory"); - let rustc_source_basedir = rustc_path.join("compiler"); - assert!( - rustc_source_basedir.is_dir(), - "are you sure the path leads to a rustc repo?" - ); - - let clippy_root_manifest = fs::read_to_string("Cargo.toml").expect("failed to read ./Cargo.toml"); - let clippy_root_lib_rs = fs::read_to_string("src/driver.rs").expect("failed to read ./src/driver.rs"); - inject_deps_into_manifest( - &rustc_source_basedir, - "Cargo.toml", - &clippy_root_manifest, - &clippy_root_lib_rs, - ) - .expect("Failed to inject deps into ./Cargo.toml"); - - let clippy_lints_manifest = - fs::read_to_string("clippy_lints/Cargo.toml").expect("failed to read ./clippy_lints/Cargo.toml"); - let clippy_lints_lib_rs = - fs::read_to_string("clippy_lints/src/lib.rs").expect("failed to read ./clippy_lints/src/lib.rs"); - inject_deps_into_manifest( - &rustc_source_basedir, - "clippy_lints/Cargo.toml", - &clippy_lints_manifest, - &clippy_lints_lib_rs, - ) - .expect("Failed to inject deps into ./clippy_lints/Cargo.toml"); +const CLIPPY_PROJECTS: &[ClippyProjectInfo] = &[ + ClippyProjectInfo::new("root", "Cargo.toml", "src/driver.rs"), + ClippyProjectInfo::new("clippy_lints", "clippy_lints/Cargo.toml", "clippy_lints/src/lib.rs"), + ClippyProjectInfo::new("clippy_utils", "clippy_utils/Cargo.toml", "clippy_utils/src/lib.rs"), +]; + +/// Used to store clippy project information to later inject the dependency into. +struct ClippyProjectInfo { + /// Only used to display information to the user + name: &'static str, + cargo_file: &'static str, + lib_rs_file: &'static str, +} + +impl ClippyProjectInfo { + const fn new(name: &'static str, cargo_file: &'static str, lib_rs_file: &'static str) -> Self { + Self { + name, + cargo_file, + lib_rs_file, + } + } +} + +pub fn setup_rustc_src(rustc_path: &str) { + let rustc_source_dir = match check_and_get_rustc_dir(rustc_path) { + Ok(path) => path, + Err(_) => return, + }; + + for project in CLIPPY_PROJECTS { + if inject_deps_into_project(&rustc_source_dir, project).is_err() { + return; + } + } +} + +fn check_and_get_rustc_dir(rustc_path: &str) -> Result<PathBuf, ()> { + let mut path = PathBuf::from(rustc_path); + + if path.is_relative() { + match path.canonicalize() { + Ok(absolute_path) => { + println!("note: the rustc path was resolved to: `{}`", absolute_path.display()); + path = absolute_path; + }, + Err(err) => { + println!("error: unable to get the absolute path of rustc ({})", err); + return Err(()); + }, + }; + } + + let path = path.join("compiler"); + println!("note: looking for compiler sources at: {}", path.display()); + + if !path.exists() { + println!("error: the given path does not exist"); + return Err(()); + } + + if !path.is_dir() { + println!("error: the given path is a file and not a directory"); + return Err(()); + } + + Ok(path) +} + +fn inject_deps_into_project(rustc_source_dir: &Path, project: &ClippyProjectInfo) -> Result<(), ()> { + let cargo_content = read_project_file(project.cargo_file, "Cargo.toml", project.name)?; + let lib_content = read_project_file(project.lib_rs_file, "lib.rs", project.name)?; + + if inject_deps_into_manifest(rustc_source_dir, project.cargo_file, &cargo_content, &lib_content).is_err() { + println!( + "error: unable to inject dependencies into {} with the Cargo file {}", + project.name, project.cargo_file + ); + Err(()) + } else { + Ok(()) + } +} + +/// `clippy_dev` expects to be executed in the root directory of Clippy. This function +/// loads the given file or returns an error. Having it in this extra function ensures +/// that the error message looks nice. +fn read_project_file(file_path: &str, file_name: &str, project: &str) -> Result<String, ()> { + let path = Path::new(file_path); + if !path.exists() { + println!( + "error: unable to find the `{}` file for the project {}", + file_name, project + ); + return Err(()); + } + + match fs::read_to_string(path) { + Ok(content) => Ok(content), + Err(err) => { + println!( + "error: the `{}` file for the project {} could not be read ({})", + file_name, project, err + ); + Err(()) + }, + } } fn inject_deps_into_manifest( @@ -55,7 +126,7 @@ fn inject_deps_into_manifest( // do not inject deps if we have aleady done so if cargo_toml.contains("[target.'cfg(NOT_A_PLATFORM)'.dependencies]") { eprintln!( - "cargo dev setup intellij: warning: deps already found inside {}, doing nothing.", + "warn: dependencies are already setup inside {}, skipping file.", manifest_path ); return Ok(()); @@ -97,7 +168,7 @@ fn inject_deps_into_manifest( let mut file = File::create(manifest_path)?; file.write_all(new_manifest.as_bytes())?; - println!("Dependency paths injected: {}", manifest_path); + println!("note: successfully setup dependencies inside {}", manifest_path); Ok(()) } |
