дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
* fix(sdk): keep the drive letter of a Maven home found on a mapped drive Maven discovery canonicalized mvn on PATH and each Maven home to resolve symlinks (Homebrew's bin/mvn). On Windows, a home on a mapped network drive or a subst drive then became \\?\UNC\server\share\… (or another drive), the Maven home setting picked from the list stored that path, and cmd.exe can't start mvn.cmd from it: every Maven run failed with "The system cannot find the path specified". Discovery now keeps the path as found when canonicalizing would change its drive letter. Refs #822 * fix(sdk): keep the drive letter of a JDK home on a mapped drive A JDK on a mapped network drive was canonicalized to \\?\UNC\server\share\… too, so Maven ran with that JAVA_HOME and mvn.cmd failed with "The system cannot find the path specified" even with a local Maven home. JDK homes (configured, JAVA_HOME, the java on PATH) now keep their drive letter like Maven homes do. * fix(maven): resolve current toolchain settings for each run * fix(sdk): distinguish mapped roots from external launcher links * test(run): preserve explicit Maven choices across save and reload * fix(maven): keep edited nested test launchers when refreshing defaults
144 рядки
6.8 KiB
Rust
144 рядки
6.8 KiB
Rust
use ide_core::NullSink;
|
|
use ide_host::{Host, HostConfig, ops};
|
|
use std::sync::Arc;
|
|
|
|
fn host(base: &std::path::Path) -> Arc<Host> {
|
|
Arc::new(Host::new(HostConfig {
|
|
config_dir: base.join("config"),
|
|
data_dir: base.join("data"),
|
|
local_data_dir: base.join("data"),
|
|
languages: Arc::new(ide_language::LanguageRegistry::load(None).unwrap()),
|
|
syntax: Arc::default(),
|
|
sink_for: Box::new(|_| Arc::new(NullSink)),
|
|
owner: |w| w,
|
|
runtime: tokio::runtime::Handle::current(),
|
|
project_environment: false,
|
|
}))
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn removed_detections_stay_removed_and_overrides_restore() {
|
|
let tmp = tempfile::tempdir().unwrap();
|
|
let root = dunce::canonicalize(tmp.path()).unwrap();
|
|
std::fs::write(root.join("package.json"), r#"{"scripts":{"dev":"node app.js","test":"node test.js"}}"#).unwrap();
|
|
let host = host(&root.join("app"));
|
|
host.trust.decide(&root, true, false).unwrap();
|
|
host.open_project("main", &root).unwrap();
|
|
let detected = ops::run::configs(&host, "main").unwrap();
|
|
assert!(detected.len() >= 2);
|
|
assert!(detected.iter().all(|c| c.detected));
|
|
let id = detected[0].id.clone();
|
|
ops::run::save_configs(&host, "main", &[], std::slice::from_ref(&id)).unwrap();
|
|
let remaining = ops::run::configs(&host, "main").unwrap();
|
|
assert!(!remaining.iter().any(|c| c.id == id));
|
|
assert_eq!(remaining.len(), detected.len() - 1);
|
|
// Reopening a project reads suppression from disk.
|
|
host.open_project("again", &root).unwrap();
|
|
assert!(!ops::run::configs(&host, "again").unwrap().iter().any(|c| c.id == id));
|
|
let mut saved = detected[0].clone();
|
|
saved.detected = false;
|
|
ops::run::save_configs(&host, "main", &[saved], &[]).unwrap();
|
|
assert!(ide_run::load_suppressed_config_ids(&root).unwrap().is_empty());
|
|
assert!(!ops::run::configs(&host, "main").unwrap().iter().find(|c| c.id == id).unwrap().detected);
|
|
ops::run::save_configs(&host, "main", &[], &[]).unwrap();
|
|
assert!(ops::run::configs(&host, "main").unwrap().iter().find(|c| c.id == id).unwrap().detected);
|
|
// An override may coexist with suppression (e.g. a shared file added elsewhere).
|
|
ops::run::save_configs(&host, "main", &[], std::slice::from_ref(&id)).unwrap();
|
|
std::fs::write(
|
|
ide_run::user_configs_path(&root),
|
|
format!("[[configurations]]\nid = {id:?}\nname = \"Override\"\ncommand = \"node\"\n"),
|
|
)
|
|
.unwrap();
|
|
assert!(ops::run::configs(&host, "main").unwrap().iter().any(|c| c.id == id && !c.detected));
|
|
ops::run::save_configs(&host, "main", &[], &[]).unwrap();
|
|
assert!(!ops::run::configs(&host, "main").unwrap().iter().any(|c| c.id == id));
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn gradle_defaults_are_not_saved_as_explicit_run_choices() {
|
|
let tmp = tempfile::tempdir().unwrap();
|
|
let root = dunce::canonicalize(tmp.path()).unwrap();
|
|
std::fs::write(root.join("build.gradle"), "plugins { id 'java' }").unwrap();
|
|
let host = host(&root.join("app"));
|
|
host.trust.decide(&root, true, false).unwrap();
|
|
host.open_project("main", &root).unwrap();
|
|
ops::project::set_settings(
|
|
&host,
|
|
"main",
|
|
ide_workspace::settings::SettingsScope::Project,
|
|
"languages.java.gradle.jvm",
|
|
"\"/configured-jdk\"",
|
|
)
|
|
.unwrap();
|
|
let configs = ops::run::configs(&host, "main").unwrap();
|
|
let mut gradle = configs.into_iter().find(|c| c.kind == "gradle").unwrap();
|
|
assert!(!gradle.env.contains_key("JAVA_HOME"));
|
|
gradle.detected = false;
|
|
gradle.env.insert("JAVA_HOME".into(), "/explicit-jdk".into());
|
|
ops::run::save_configs(&host, "main", &[gradle.clone()], &[]).unwrap();
|
|
let saved = ops::run::configs(&host, "main").unwrap().into_iter().find(|c| c.id == gradle.id).unwrap();
|
|
assert_eq!(saved.env["JAVA_HOME"], "/explicit-jdk");
|
|
assert_eq!(saved.command, gradle.command);
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn maven_defaults_are_resolved_at_launch_and_explicit_choices_survive_reload() {
|
|
let tmp = tempfile::tempdir().unwrap();
|
|
let root = dunce::canonicalize(tmp.path()).unwrap();
|
|
std::fs::write(root.join("pom.xml"), "<project/>").unwrap();
|
|
let home = root.join("maven");
|
|
std::fs::create_dir_all(home.join("bin")).unwrap();
|
|
let launcher = home.join("bin").join(if cfg!(windows) { "mvn.cmd" } else { "mvn" });
|
|
std::fs::write(&launcher, "").unwrap();
|
|
let host = host(&root.join("app"));
|
|
host.trust.decide(&root, true, false).unwrap();
|
|
host.open_project("main", &root).unwrap();
|
|
for (key, value) in [
|
|
("languages.java.maven.home", home.to_string_lossy().into_owned()),
|
|
("languages.java.maven.userSettings", "settings.xml".into()),
|
|
] {
|
|
ops::project::set_settings(
|
|
&host,
|
|
"main",
|
|
ide_workspace::settings::SettingsScope::Project,
|
|
key,
|
|
&serde_json::to_string(&value).unwrap(),
|
|
)
|
|
.unwrap();
|
|
}
|
|
let mut config = ops::run::configs(&host, "main").unwrap().into_iter().find(|c| c.id == "maven:test").unwrap();
|
|
assert_eq!(config.command, "mvn");
|
|
assert_eq!(config.args, ["test"]);
|
|
assert!(config.env.is_empty());
|
|
config.command = launcher.to_string_lossy().into_owned();
|
|
config.args = vec!["-s".into(), "own-settings.xml".into(), "test".into()];
|
|
config.env.insert("JAVA_HOME".into(), "own-jdk".into());
|
|
config.detected = false;
|
|
ops::run::save_configs(&host, "main", &[config.clone()], &[]).unwrap();
|
|
let saved = ops::run::configs(&host, "main").unwrap().into_iter().find(|c| c.id == config.id).unwrap();
|
|
assert_eq!(saved.command, config.command);
|
|
assert_eq!(saved.args, config.args);
|
|
assert_eq!(saved.env, config.env);
|
|
}
|
|
|
|
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
|
async fn workspace_cmake_before_launch_tasks_resolve_in_the_member() {
|
|
let tmp = tempfile::tempdir().unwrap();
|
|
let root = dunce::canonicalize(tmp.path()).unwrap();
|
|
let member = root.join("native");
|
|
std::fs::create_dir(&member).unwrap();
|
|
std::fs::write(member.join("CMakeLists.txt"), "project(demo)").unwrap();
|
|
let workspace = root.join("workspace");
|
|
ide_workspace::workspace::Workspace::save(&workspace, "Native", vec![member.clone()], true).unwrap();
|
|
let host = host(&root.join("app"));
|
|
host.trust.decide(&workspace, true, false).unwrap();
|
|
host.trust.decide(&member, true, false).unwrap();
|
|
host.open_project("main", &workspace).unwrap();
|
|
let configs = ops::run::configs(&host, "main").unwrap();
|
|
let build = configs.iter().find(|c| c.kind == "cmake" && c.args.first().is_some_and(|a| a == "--build")).unwrap();
|
|
assert_eq!(build.cwd.as_deref(), Some(member.as_path()));
|
|
for task in &build.extras.before_launch {
|
|
assert!(configs.iter().any(|c| c.id == task.target && c.cwd == build.cwd));
|
|
}
|
|
}
|