blob: 204f4af2cf1beaed308347e3eca0787e1f49c126 [file] [log] [blame]
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 `{TASK_SOURCE_FILE}` to `{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 `{VSCODE_DIR}` directory");
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 `{VSCODE_DIR}` directory for clippy");
},
Err(err) => {
eprintln!("error: the task target directory `{VSCODE_DIR}` could not be created ({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
}
}