diff options
| author | xFrednet <xFrednet@gmail.com> | 2021-06-27 16:59:17 +0200 |
|---|---|---|
| committer | xFrednet <xFrednet@gmail.com> | 2021-06-27 22:36:41 +0200 |
| commit | 2098b27a200152f949bf08946c639d632146fb9b (patch) | |
| tree | 715b6100dd450ec0cb74e20d1e5faaf9c5dee30b /clippy_dev/src/setup | |
| parent | 8d427b624f15a5c782c97021c3717451d86b8576 (diff) | |
Added `cargo dev setup vscode-tasks` for simplicity
Diffstat (limited to 'clippy_dev/src/setup')
| -rw-r--r-- | clippy_dev/src/setup/git_hook.rs | 6 | ||||
| -rw-r--r-- | clippy_dev/src/setup/mod.rs | 21 | ||||
| -rw-r--r-- | clippy_dev/src/setup/vscode.rs | 104 |
3 files changed, 131 insertions, 0 deletions
diff --git a/clippy_dev/src/setup/git_hook.rs b/clippy_dev/src/setup/git_hook.rs index f27b69a195b..3fbb77d5923 100644 --- a/clippy_dev/src/setup/git_hook.rs +++ b/clippy_dev/src/setup/git_hook.rs @@ -1,6 +1,8 @@ use std::fs; use std::path::Path; +use super::verify_inside_clippy_dir; + /// Rusts setup uses `git rev-parse --git-common-dir` to get the root directory of the repo. /// I've decided against this for the sake of simplicity and to make sure that it doesn't install /// the hook if `clippy_dev` would be used in the rust tree. The hook also references this tool @@ -36,6 +38,10 @@ pub fn install_hook(force_override: bool) { } fn check_precondition(force_override: bool) -> bool { + if !verify_inside_clippy_dir() { + return false; + } + // Make sure that we can find the git repository let git_path = Path::new(REPO_GIT_DIR); if !git_path.exists() || !git_path.is_dir() { diff --git a/clippy_dev/src/setup/mod.rs b/clippy_dev/src/setup/mod.rs index 3834f5a1842..a1e4dd103b8 100644 --- a/clippy_dev/src/setup/mod.rs +++ b/clippy_dev/src/setup/mod.rs @@ -1,2 +1,23 @@ pub mod git_hook; pub mod intellij; +pub mod vscode; + +use std::path::Path; + +const CLIPPY_DEV_DIR: &str = "clippy_dev"; + +/// This function verifies that the tool is being executed in the clippy directory. +/// This is useful to ensure that setups only modify Clippys resources. The verification +/// is done by checking that `clippy_dev` is a sub directory of the current directory. +/// +/// It will print an error message and return `false` if the directory could not be +/// verified. +fn verify_inside_clippy_dir() -> bool { + let path = Path::new(CLIPPY_DEV_DIR); + if path.exists() && path.is_dir() { + true + } else { + eprintln!("error: unable to verify that the working directory is clippys directory"); + false + } +} diff --git a/clippy_dev/src/setup/vscode.rs b/clippy_dev/src/setup/vscode.rs new file mode 100644 index 00000000000..d59001b2c66 --- /dev/null +++ b/clippy_dev/src/setup/vscode.rs @@ -0,0 +1,104 @@ +use std::fs; +use std::path::Path; + +use super::verify_inside_clippy_dir; + +const VSCODE_DIR: &str = ".vscode"; +const TASK_SOURCE_FILE: &str = "util/etc/vscode-tasks.json"; +const TASK_TARGET_FILE: &str = ".vscode/tasks.json"; + +pub fn install_tasks(force_override: bool) { + if !check_install_precondition(force_override) { + return; + } + + match fs::copy(TASK_SOURCE_FILE, TASK_TARGET_FILE) { + Ok(_) => { + println!("info: the task file can be removed with `cargo dev remove vscode-tasks`"); + println!("vscode tasks successfully installed"); + }, + Err(err) => eprintln!( + "error: unable to copy `{}` to `{}` ({})", + TASK_SOURCE_FILE, TASK_TARGET_FILE, err + ), + } +} + +fn check_install_precondition(force_override: bool) -> bool { + if !verify_inside_clippy_dir() { + return false; + } + + let vs_dir_path = Path::new(VSCODE_DIR); + if vs_dir_path.exists() { + // verify the target will be valid + if !vs_dir_path.is_dir() { + eprintln!("error: the `.vscode` path exists but seems to be a file"); + return false; + } + + // make sure that we don't override any existing tasks by accident + let path = Path::new(TASK_TARGET_FILE); + if path.exists() { + if force_override { + return delete_vs_task_file(path); + } + + eprintln!( + "error: there is already a `task.json` file inside the `{}` directory", + VSCODE_DIR + ); + println!("info: use the `--force-override` flag to override the existing `task.json` file"); + return false; + } + } else { + match fs::create_dir(vs_dir_path) { + Ok(_) => { + println!("info: created `{}` directory for clippy", VSCODE_DIR); + }, + Err(err) => { + eprintln!( + "error: the task target directory `{}` could not be created ({})", + VSCODE_DIR, err + ); + }, + } + } + + true +} + +pub fn remove_tasks() { + let path = Path::new(TASK_TARGET_FILE); + if path.exists() { + if delete_vs_task_file(path) { + try_delete_vs_directory_if_empty(); + println!("vscode tasks successfully removed"); + } + } else { + println!("no vscode tasks were found"); + } +} + +fn delete_vs_task_file(path: &Path) -> bool { + if let Err(err) = fs::remove_file(path) { + eprintln!("error: unable to delete the existing `tasks.json` file ({})", err); + return false; + } + + true +} + +/// This function will try to delete the `.vscode` directory if it's empty. +/// It may fail silently. +fn try_delete_vs_directory_if_empty() { + let path = Path::new(VSCODE_DIR); + if path.read_dir().map_or(false, |mut iter| iter.next().is_none()) { + // The directory is empty. We just try to delete it but allow a silence + // fail as an empty `.vscode` directory is still valid + let _silence_result = fs::remove_dir(path); + } else { + // The directory is not empty or could not be read. Either way don't take + // any further actions + } +} |
