Skip to content

Commit

Permalink
Auto merge of rust-lang#7409 - xFrednet:5394-vs-code-tasks, r=giraffa…
Browse files Browse the repository at this point in the history
…te,flip1995

Added `cargo dev setup vscode-tasks` for simplicity

This PR adds a setup command to `clippy dev` that installs tasks into the Clippy vscode workspace. These might be useful as they be used via shortcuts and are accessible over the GUI. The available tasks are:
* `cargo check` (standard Linux shortcut `[ctrl] + [shift] + b`)
* `cargo dev fmt`
* `cargo uitest` (with a comment how to add the `TESTNAME` environment value)
* `cargo test`
* `cargo dev bless`

---

changelog: none

only internal changes again. cc rust-lang#5394

r? `@flip1995` This should be pretty much the same as the other `cargo dev setup` commands. Would you mind reviewing this? 🙃
  • Loading branch information
bors committed Jun 29, 2021
2 parents e405c68 + e400191 commit f4bc9cf
Show file tree
Hide file tree
Showing 5 changed files with 202 additions and 0 deletions.
14 changes: 14 additions & 0 deletions clippy_dev/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ fn main() {
.expect("this field is mandatory and therefore always valid"),
),
("git-hook", Some(matches)) => setup::git_hook::install_hook(matches.is_present("force-override")),
("vscode-tasks", Some(matches)) => setup::vscode::install_tasks(matches.is_present("force-override")),
_ => {},
},
("remove", Some(sub_command)) => match sub_command.subcommand() {
("git-hook", Some(_)) => setup::git_hook::remove_hook(),
("intellij", Some(_)) => setup::intellij::remove_rustc_src(),
("vscode-tasks", Some(_)) => setup::vscode::remove_tasks(),
_ => {},
},
("serve", Some(matches)) => {
Expand Down Expand Up @@ -181,13 +183,25 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
.help("Forces the override of an existing git pre-commit hook")
.required(false),
),
)
.subcommand(
SubCommand::with_name("vscode-tasks")
.about("Add several tasks to vscode for formatting, validation and testing")
.arg(
Arg::with_name("force-override")
.long("force-override")
.short("f")
.help("Forces the override of existing vscode tasks")
.required(false),
),
),
)
.subcommand(
SubCommand::with_name("remove")
.about("Support for undoing changes done by the setup command")
.setting(AppSettings::ArgRequiredElseHelp)
.subcommand(SubCommand::with_name("git-hook").about("Remove any existing pre-commit git hook"))
.subcommand(SubCommand::with_name("vscode-tasks").about("Remove any existing vscode tasks"))
.subcommand(
SubCommand::with_name("intellij")
.about("Removes rustc source paths added via `cargo dev setup intellij`"),
Expand Down
6 changes: 6 additions & 0 deletions clippy_dev/src/setup/git_hook.rs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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() {
Expand Down
21 changes: 21 additions & 0 deletions clippy_dev/src/setup/mod.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
104 changes: 104 additions & 0 deletions clippy_dev/src/setup/vscode.rs
Original file line number Diff line number Diff line change
@@ -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
}
}
57 changes: 57 additions & 0 deletions util/etc/vscode-tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "cargo check",
"type": "shell",
"command": "cargo check",
"problemMatcher": [],
"group": {
"kind": "build",
"isDefault": true,
},
},
{
"label": "cargo dev fmt",
"type": "shell",
"command": "cargo dev fmt",
"problemMatcher": [],
"group": "none",
},
{
"label": "cargo uitest",
"type": "shell",
"command": "cargo uitest",
"options": {
"env": {
"RUST_BACKTRACE": "1",
// This task will usually execute all UI tests inside `tests/ui` you can
// optionally uncomment the line below and only run a specific test.
//
// See: https://github.com/rust-lang/rust-clippy/blob/master/doc/adding_lints.md#testing
//
// "TESTNAME": "<TODO>",
},
},
"problemMatcher": [],
"group": {
"kind": "test",
"isDefault": true,
}
},
{
"label": "cargo test",
"type": "shell",
"command": "cargo test",
"problemMatcher": [],
"group": "test",
},
{
"label": "cargo dev bless",
"type": "shell",
"command": "cargo dev bless",
"problemMatcher": [],
"group": "none",
},
],
}

0 comments on commit f4bc9cf

Please sign in to comment.