diff --git a/crates/rust-analyzer/tests/heavy_tests/main.rs b/crates/rust-analyzer/tests/rust-analyzer/main.rs similarity index 97% rename from crates/rust-analyzer/tests/heavy_tests/main.rs rename to crates/rust-analyzer/tests/rust-analyzer/main.rs index 7370505f8b..fa315ff8ee 100644 --- a/crates/rust-analyzer/tests/heavy_tests/main.rs +++ b/crates/rust-analyzer/tests/rust-analyzer/main.rs @@ -1,3 +1,13 @@ +//! The most high-level integrated tests for rust-analyzer. +//! +//! This tests run a full LSP event loop, spawn cargo and process stdlib from +//! sysroot. For this reason, the tests here are very slow, and should be +//! avoided unless absolutely necessary. +//! +//! In particular, it's fine *not* to test that client & server agree on +//! specific JSON shapes here -- there's little value in such tests, as we can't +//! be sure without a real client anyway. + mod testdir; mod support; diff --git a/crates/rust-analyzer/tests/heavy_tests/support.rs b/crates/rust-analyzer/tests/rust-analyzer/support.rs similarity index 100% rename from crates/rust-analyzer/tests/heavy_tests/support.rs rename to crates/rust-analyzer/tests/rust-analyzer/support.rs diff --git a/crates/rust-analyzer/tests/heavy_tests/testdir.rs b/crates/rust-analyzer/tests/rust-analyzer/testdir.rs similarity index 100% rename from crates/rust-analyzer/tests/heavy_tests/testdir.rs rename to crates/rust-analyzer/tests/rust-analyzer/testdir.rs diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs index f3ad81ba72..e790d995fb 100644 --- a/xtask/src/lib.rs +++ b/xtask/src/lib.rs @@ -3,14 +3,15 @@ //! See https://github.com/matklad/cargo-xtask/ pub mod not_bash; +pub mod codegen; +mod ast_src; + pub mod install; pub mod release; pub mod dist; pub mod pre_commit; pub mod metrics; - -pub mod codegen; -mod ast_src; +pub mod pre_cache; use std::{ env, @@ -21,7 +22,7 @@ use walkdir::{DirEntry, WalkDir}; use crate::{ codegen::Mode, - not_bash::{fs2, pushd, pushenv, rm_rf}, + not_bash::{pushd, pushenv}, }; pub use anyhow::{bail, Context as _, Result}; @@ -108,42 +109,6 @@ pub fn run_fuzzer() -> Result<()> { Ok(()) } -/// Cleans the `./target` dir after the build such that only -/// dependencies are cached on CI. -pub fn run_pre_cache() -> Result<()> { - let slow_tests_cookie = Path::new("./target/.slow_tests_cookie"); - if !slow_tests_cookie.exists() { - panic!("slow tests were skipped on CI!") - } - rm_rf(slow_tests_cookie)?; - - for entry in Path::new("./target/debug").read_dir()? { - let entry = entry?; - if entry.file_type().map(|it| it.is_file()).ok() == Some(true) { - // Can't delete yourself on windows :-( - if !entry.path().ends_with("xtask.exe") { - rm_rf(&entry.path())? - } - } - } - - fs2::remove_file("./target/.rustc_info.json")?; - let to_delete = ["hir", "heavy_test", "xtask", "ide", "rust-analyzer"]; - for &dir in ["./target/debug/deps", "target/debug/.fingerprint"].iter() { - for entry in Path::new(dir).read_dir()? { - let entry = entry?; - if to_delete.iter().any(|&it| entry.path().display().to_string().contains(it)) { - // Can't delete yourself on windows :-( - if !entry.path().ends_with("xtask.exe") { - rm_rf(&entry.path())? - } - } - } - } - - Ok(()) -} - fn is_release_tag(tag: &str) -> bool { tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit()) } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index b69b884e54..fb38fdc92f 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -17,9 +17,10 @@ use xtask::{ install::{ClientOpt, InstallCmd, Malloc, ServerOpt}, metrics::MetricsCmd, not_bash::pushd, + pre_cache::PreCacheCmd, pre_commit, project_root, release::{PromoteCmd, ReleaseCmd}, - run_clippy, run_fuzzer, run_pre_cache, run_rustfmt, Result, + run_clippy, run_fuzzer, run_rustfmt, Result, }; fn main() -> Result<()> { @@ -100,7 +101,7 @@ FLAGS: } "pre-cache" => { args.finish()?; - run_pre_cache() + PreCacheCmd.run() } "release" => { let dry_run = args.contains("--dry-run"); diff --git a/xtask/src/pre_cache.rs b/xtask/src/pre_cache.rs new file mode 100644 index 0000000000..47ba6ba246 --- /dev/null +++ b/xtask/src/pre_cache.rs @@ -0,0 +1,80 @@ +use std::{ + fs::FileType, + path::{Path, PathBuf}, +}; + +use anyhow::Result; + +use crate::not_bash::{fs2, rm_rf}; + +pub struct PreCacheCmd; + +impl PreCacheCmd { + /// Cleans the `./target` dir after the build such that only + /// dependencies are cached on CI. + pub fn run(self) -> Result<()> { + let slow_tests_cookie = Path::new("./target/.slow_tests_cookie"); + if !slow_tests_cookie.exists() { + panic!("slow tests were skipped on CI!") + } + rm_rf(slow_tests_cookie)?; + + for path in read_dir("./target/debug", FileType::is_file)? { + // Can't delete yourself on windows :-( + if !path.ends_with("xtask.exe") { + rm_rf(&path)? + } + } + + fs2::remove_file("./target/.rustc_info.json")?; + + let to_delete = read_dir("./crates", FileType::is_dir)? + .into_iter() + .map(|path| path.file_name().unwrap().to_string_lossy().replace('-', "_")) + .collect::>(); + + for &dir in ["./target/debug/deps", "target/debug/.fingerprint"].iter() { + for path in read_dir(dir, |_file_type| true)? { + if path.ends_with("xtask.exe") { + continue; + } + let file_name = path.file_name().unwrap().to_string_lossy(); + let (stem, _) = match rsplit_once(&file_name, '-') { + Some(it) => it, + None => { + rm_rf(path)?; + continue; + } + }; + let stem = stem.replace('-', "_"); + if to_delete.contains(&stem) { + rm_rf(path)?; + } + } + } + + Ok(()) + } +} +fn read_dir(path: impl AsRef, cond: impl Fn(&FileType) -> bool) -> Result> { + read_dir_impl(path.as_ref(), &cond) +} + +fn read_dir_impl(path: &Path, cond: &dyn Fn(&FileType) -> bool) -> Result> { + let mut res = Vec::new(); + for entry in path.read_dir()? { + let entry = entry?; + let file_type = entry.file_type()?; + if cond(&file_type) { + res.push(entry.path()) + } + } + Ok(res) +} + +fn rsplit_once(haystack: &str, delim: char) -> Option<(&str, &str)> { + let mut split = haystack.rsplitn(2, delim); + let suffix = split.next()?; + let prefix = split.next()?; + Some((prefix, suffix)) +}