]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_dev/src/setup/vscode.rs
Merge commit 'ac0e10aa68325235069a842f47499852b2dee79e' into clippyup
[rust.git] / src / tools / clippy / clippy_dev / src / setup / vscode.rs
1 use std::fs;
2 use std::path::Path;
3
4 use super::verify_inside_clippy_dir;
5
6 const VSCODE_DIR: &str = ".vscode";
7 const TASK_SOURCE_FILE: &str = "util/etc/vscode-tasks.json";
8 const TASK_TARGET_FILE: &str = ".vscode/tasks.json";
9
10 pub fn install_tasks(force_override: bool) {
11     if !check_install_precondition(force_override) {
12         return;
13     }
14
15     match fs::copy(TASK_SOURCE_FILE, TASK_TARGET_FILE) {
16         Ok(_) => {
17             println!("info: the task file can be removed with `cargo dev remove vscode-tasks`");
18             println!("vscode tasks successfully installed");
19         },
20         Err(err) => eprintln!("error: unable to copy `{TASK_SOURCE_FILE}` to `{TASK_TARGET_FILE}` ({err})"),
21     }
22 }
23
24 fn check_install_precondition(force_override: bool) -> bool {
25     if !verify_inside_clippy_dir() {
26         return false;
27     }
28
29     let vs_dir_path = Path::new(VSCODE_DIR);
30     if vs_dir_path.exists() {
31         // verify the target will be valid
32         if !vs_dir_path.is_dir() {
33             eprintln!("error: the `.vscode` path exists but seems to be a file");
34             return false;
35         }
36
37         // make sure that we don't override any existing tasks by accident
38         let path = Path::new(TASK_TARGET_FILE);
39         if path.exists() {
40             if force_override {
41                 return delete_vs_task_file(path);
42             }
43
44             eprintln!("error: there is already a `task.json` file inside the `{VSCODE_DIR}` directory");
45             println!("info: use the `--force-override` flag to override the existing `task.json` file");
46             return false;
47         }
48     } else {
49         match fs::create_dir(vs_dir_path) {
50             Ok(_) => {
51                 println!("info: created `{VSCODE_DIR}` directory for clippy");
52             },
53             Err(err) => {
54                 eprintln!("error: the task target directory `{VSCODE_DIR}` could not be created ({err})");
55             },
56         }
57     }
58
59     true
60 }
61
62 pub fn remove_tasks() {
63     let path = Path::new(TASK_TARGET_FILE);
64     if path.exists() {
65         if delete_vs_task_file(path) {
66             try_delete_vs_directory_if_empty();
67             println!("vscode tasks successfully removed");
68         }
69     } else {
70         println!("no vscode tasks were found");
71     }
72 }
73
74 fn delete_vs_task_file(path: &Path) -> bool {
75     if let Err(err) = fs::remove_file(path) {
76         eprintln!("error: unable to delete the existing `tasks.json` file ({err})");
77         return false;
78     }
79
80     true
81 }
82
83 /// This function will try to delete the `.vscode` directory if it's empty.
84 /// It may fail silently.
85 fn try_delete_vs_directory_if_empty() {
86     let path = Path::new(VSCODE_DIR);
87     if path.read_dir().map_or(false, |mut iter| iter.next().is_none()) {
88         // The directory is empty. We just try to delete it but allow a silence
89         // fail as an empty `.vscode` directory is still valid
90         let _silence_result = fs::remove_dir(path);
91     } else {
92         // The directory is not empty or could not be read. Either way don't take
93         // any further actions
94     }
95 }