Skip to content

Commit

Permalink
Fix config guard lock for ratoml tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Veykril committed Dec 9, 2024
1 parent 4fcecbb commit 9323968
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 41 deletions.
4 changes: 2 additions & 2 deletions crates/load-cargo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ impl ProjectFolders {
pub fn new(
workspaces: &[ProjectWorkspace],
global_excludes: &[AbsPathBuf],
user_config_dir_path: Option<&'static AbsPath>,
user_config_dir_path: Option<&AbsPath>,
) -> ProjectFolders {
let mut res = ProjectFolders::default();
let mut fsc = FileSetConfig::builder();
Expand Down Expand Up @@ -302,7 +302,7 @@ impl ProjectFolders {
p
};

let file_set_roots: Vec<VfsPath> = vec![VfsPath::from(ratoml_path.to_owned())];
let file_set_roots = vec![VfsPath::from(ratoml_path.to_owned())];
let entry = vfs::loader::Entry::Files(vec![ratoml_path.to_owned()]);

res.watch.push(res.load.len());
Expand Down
25 changes: 9 additions & 16 deletions crates/rust-analyzer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@
//! Of particular interest is the `feature_flags` hash map: while other fields
//! configure the server itself, feature flags are passed into analysis, and
//! tweak things like automatic insertion of `()` in completions.
use std::{
env, fmt, iter,
ops::Not,
sync::{LazyLock, OnceLock},
};
use std::{env, fmt, iter, ops::Not, sync::OnceLock};

use cfg::{CfgAtom, CfgDiff};
use hir::Symbol;
Expand Down Expand Up @@ -805,16 +801,13 @@ impl std::ops::Deref for Config {

impl Config {
/// Path to the user configuration dir. This can be seen as a generic way to define what would be `$XDG_CONFIG_HOME/rust-analyzer` in Linux.
pub fn user_config_dir_path() -> Option<&'static AbsPath> {
static USER_CONFIG_PATH: LazyLock<Option<AbsPathBuf>> = LazyLock::new(|| {
let user_config_path = if let Some(path) = env::var_os("__TEST_RA_USER_CONFIG_DIR") {
std::path::PathBuf::from(path)
} else {
dirs::config_dir()?.join("rust-analyzer")
};
Some(AbsPathBuf::assert_utf8(user_config_path))
});
USER_CONFIG_PATH.as_deref()
pub fn user_config_dir_path() -> Option<AbsPathBuf> {
let user_config_path = if let Some(path) = env::var_os("__TEST_RA_USER_CONFIG_DIR") {
std::path::PathBuf::from(path)
} else {
dirs::config_dir()?.join("rust-analyzer")
};
Some(AbsPathBuf::assert_utf8(user_config_path))
}

pub fn same_source_root_parent_map(
Expand Down Expand Up @@ -1254,7 +1247,7 @@ pub struct NotificationsConfig {
pub cargo_toml_not_found: bool,
}

#[derive(Deserialize, Serialize, Debug, Clone)]
#[derive(Debug, Clone)]
pub enum RustfmtConfig {
Rustfmt { extra_args: Vec<String>, enable_range_formatting: bool },
CustomCommand { command: String, args: Vec<String> },
Expand Down
10 changes: 5 additions & 5 deletions crates/rust-analyzer/src/global_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -392,13 +392,13 @@ impl GlobalState {
|| !self.config.same_source_root_parent_map(&self.local_roots_parent_map)
{
let config_change = {
let user_config_path = {
let mut p = Config::user_config_dir_path().unwrap().to_path_buf();
let user_config_path = (|| {
let mut p = Config::user_config_dir_path()?;
p.push("rust-analyzer.toml");
p
};
Some(p)
})();

let user_config_abs_path = Some(user_config_path.as_path());
let user_config_abs_path = user_config_path.as_deref();

let mut change = ConfigChange::default();
let db = self.analysis_host.raw_database();
Expand Down
4 changes: 2 additions & 2 deletions crates/rust-analyzer/src/reload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ impl GlobalState {
}

watchers.extend(
iter::once(Config::user_config_dir_path())
iter::once(Config::user_config_dir_path().as_deref())
.chain(self.workspaces.iter().map(|ws| ws.manifest().map(ManifestPath::as_ref)))
.flatten()
.map(|glob_pattern| lsp_types::FileSystemWatcher {
Expand All @@ -616,7 +616,7 @@ impl GlobalState {
let project_folders = ProjectFolders::new(
&self.workspaces,
&files_config.exclude,
Config::user_config_dir_path().to_owned(),
Config::user_config_dir_path().as_deref(),
);

if (self.proc_macro_clients.is_empty() || !same_workspaces)
Expand Down
13 changes: 8 additions & 5 deletions crates/rust-analyzer/tests/slow-tests/ratoml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct RatomlTest {
urls: Vec<Url>,
server: Server,
tmp_path: Utf8PathBuf,
config_locked: bool,
}

impl RatomlTest {
Expand Down Expand Up @@ -65,13 +66,14 @@ impl RatomlTest {

let server = project.server_with_lock(prelock).wait_until_workspace_is_loaded();

let mut case = Self { urls: vec![], server, tmp_path };
let urls = fixtures.iter().map(|fixture| case.fixture_path(fixture)).collect::<Vec<_>>();
let mut case = Self { urls: vec![], server, tmp_path, config_locked: prelock };
let urls =
fixtures.iter().map(|fixture| case.fixture_path(fixture, prelock)).collect::<Vec<_>>();
case.urls = urls;
case
}

fn fixture_path(&self, fixture: &str) -> Url {
fn fixture_path(&self, fixture: &str, prelock: bool) -> Url {
let mut lines = fixture.trim().split('\n');

let mut path =
Expand All @@ -89,7 +91,8 @@ impl RatomlTest {
let mut spl = spl.into_iter();
if let Some(first) = spl.next() {
if first == "$$CONFIG_DIR$$" {
path = Config::user_config_dir_path().unwrap().to_path_buf().into();
assert!(prelock, "this test requires prelock to be set");
path = Config::user_config_dir_path().unwrap().into();
} else {
path = path.join(first);
}
Expand All @@ -109,7 +112,7 @@ impl RatomlTest {
}

fn create(&mut self, fixture_path: &str, text: String) {
let url = self.fixture_path(fixture_path);
let url = self.fixture_path(fixture_path, self.config_locked);

self.server.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams {
text_document: TextDocumentItem {
Expand Down
24 changes: 13 additions & 11 deletions crates/rust-analyzer/tests/slow-tests/support.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::{
cell::{Cell, RefCell},
env, fs,
sync::Once,
sync::{Once, OnceLock},
time::Duration,
};

Expand Down Expand Up @@ -141,12 +141,17 @@ impl Project<'_> {
/// file in the config dir after server is run, something where our naive approach comes short.
/// Using a `prelock` allows us to force a lock when we know we need it.
pub(crate) fn server_with_lock(self, prelock: bool) -> Server {
static CONFIG_DIR_LOCK: Mutex<()> = Mutex::new(());

let mut config_dir_guard = if prelock {
let v = Some(CONFIG_DIR_LOCK.lock());
env::set_var("__TEST_RA_USER_CONFIG_DIR", TestDir::new().path());
v
static CONFIG_DIR_LOCK: OnceLock<Mutex<()>> = OnceLock::new();

let config_dir_guard = if prelock {
Some(
CONFIG_DIR_LOCK
.get_or_init(|| {
env::set_var("__TEST_RA_USER_CONFIG_DIR", TestDir::new().keep().path());
Mutex::new(())
})
.lock(),
)
} else {
None
};
Expand Down Expand Up @@ -185,10 +190,7 @@ impl Project<'_> {

for entry in fixture {
if let Some(pth) = entry.path.strip_prefix("/$$CONFIG_DIR$$") {
if config_dir_guard.is_none() {
config_dir_guard = Some(CONFIG_DIR_LOCK.lock());
env::set_var("__TEST_RA_USER_CONFIG_DIR", TestDir::new().path());
}
assert!(config_dir_guard.is_some(), "this test requires prelock to be set to true");

let path = Config::user_config_dir_path().unwrap().join(&pth['/'.len_utf8()..]);
fs::create_dir_all(path.parent().unwrap()).unwrap();
Expand Down

0 comments on commit 9323968

Please sign in to comment.