дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 11:15:40 +02:00
CI / Changes (push) Successful in 1s
Language smoke / Language smoke (go) (push) Failing after 6s
Language smoke / Language smoke (java) (push) Failing after 5s
Language smoke / Language smoke (kotlin) (push) Failing after 5s
Language smoke / Language smoke (python) (push) Failing after 4s
Language smoke / Language smoke (typescript) (push) Failing after 4s
Language smoke / Language smoke (rust) (push) Failing after 5s
CI / Rust (ubuntu-22.04) (push) Failing after 43s
CI / Plugins (SDK, official, fixtures) (push) Failing after 1m19s
CI / Remote server (linux musl) (push) Failing after 1m32s
CI / Cargo deny (push) Successful in 54s
CI / E2E (push) Successful in 15m57s
CI / Frontend (push) Successful in 24m49s
CI / Rust (macos-latest) (push) Canceled after 0s
CI / Rust (windows-latest) (push) Canceled after 0s
* fix(build): scope Kotlin bridge to linked Maven modules * fix(run): resolve nested Go modules for context runs * fix(gradle): discover nested builds and select compatible JVMs * fix(workspace): share project discovery and module ownership * fix(run): keep root toolchains for nested modules and resolve them once per module - Python run configurations of a nested module without its own virtualenv use the closest one up to the project root. - Gradle builds and runs fall back to the JDK matching the project's Java version when the Gradle version is unknown. - Module-local interpreters and toolchains are resolved lazily, once per owning module. - Tests build expected paths per segment so they hold on Windows.
126 рядки
5.5 KiB
Rust
126 рядки
5.5 KiB
Rust
//! A configuration's module and relative paths move together when projects are nested.
|
|
|
|
use crate::RunConfig;
|
|
use ide_core::{ipc_path::to_ipc, project_roots};
|
|
use std::path::{Path, PathBuf};
|
|
|
|
pub fn owner(root: &Path, config: &RunConfig) -> PathBuf {
|
|
if matches!(config.kind.as_str(), "dotnet" | "dotnet-test")
|
|
&& let Some(project) = config.extras.params.get("project").filter(|p| !p.is_empty())
|
|
{
|
|
return project_roots::resolve(root, Path::new(project)).parent().unwrap_or(root).to_path_buf();
|
|
}
|
|
let module = (config.kind == "go")
|
|
.then(|| config.extras.params.get("module"))
|
|
.flatten()
|
|
.map(String::as_str)
|
|
.or(config.extras.module.as_deref())
|
|
.map(Path::new)
|
|
.or(config.cwd.as_deref())
|
|
.unwrap_or(Path::new(""));
|
|
project_roots::resolve(root, module)
|
|
}
|
|
|
|
pub fn rebase(config: &mut RunConfig, from: &Path, relative_to: Option<&Path>) {
|
|
let path = |value: &str| {
|
|
let absolute = project_roots::resolve(from, Path::new(value));
|
|
to_ipc(&relative_to.map_or(absolute.clone(), |root| project_roots::relative(root, &absolute)))
|
|
};
|
|
let cwd = config.cwd.as_deref().unwrap_or(Path::new("")).to_path_buf();
|
|
config.cwd = Some(path(&to_ipc(&cwd)).into());
|
|
if config.extras.module.is_some() || !matches!(config.kind.as_str(), "application" | "spring-boot") {
|
|
config.extras.module = Some(path(config.extras.module.as_deref().unwrap_or("")));
|
|
}
|
|
if config.kind == "go" && config.extras.params.contains_key("goKind") {
|
|
config.extras.params.entry("module".into()).or_default();
|
|
}
|
|
for file in &mut config.extras.env_files {
|
|
*file = path(file);
|
|
}
|
|
for file in [&mut config.extras.stdin_file, &mut config.extras.output_file].into_iter().flatten() {
|
|
*file = path(file);
|
|
}
|
|
let keys: &[&str] = match config.kind.as_str() {
|
|
"go" => &["module", "outputDir"],
|
|
"dotnet" | "dotnet-test" => &["project", "targetPath"],
|
|
_ => &[],
|
|
};
|
|
for key in keys {
|
|
if let Some(value) = config.extras.params.get_mut(*key)
|
|
&& (*key == "module" || !value.is_empty())
|
|
{
|
|
*value = path(value);
|
|
}
|
|
}
|
|
if !matches!(config.kind.as_str(), "shell" | "compound") && Path::new(&config.command).components().count() > 1 {
|
|
// Executables are relative to the old cwd, unlike env/input/output files.
|
|
let cwd = project_roots::resolve(from, &cwd);
|
|
config.command = to_ipc(&project_roots::resolve(&cwd, Path::new(&config.command)));
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use std::collections::BTreeMap;
|
|
|
|
#[test]
|
|
fn default_go_module_moves_with_member_but_unknown_jvm_module_stays_inferred() {
|
|
let temp = tempfile::tempdir().unwrap();
|
|
for (kind, params) in
|
|
[("go", serde_json::json!({"goKind":"build", "target":"."})), ("application", serde_json::json!({}))]
|
|
{
|
|
let mut config: RunConfig = serde_json::from_value(serde_json::json!({
|
|
"id":"run", "name":"run", "kind":kind, "command":"tool", "args":[], "cwd":null,
|
|
"env":{}, "detected":false, "isTest":false, "debugAdapter":null, "params":params
|
|
}))
|
|
.unwrap();
|
|
rebase(&mut config, temp.path(), None);
|
|
if kind == "go" {
|
|
assert_eq!(config.extras.params["module"], to_ipc(temp.path()));
|
|
} else {
|
|
assert_eq!(config.extras.module, None);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn workspace_members_rebase_every_typed_root_without_changing_targets() {
|
|
let temp = tempfile::tempdir().unwrap();
|
|
let member = temp.path().join("member with spaces");
|
|
for (kind, params) in [
|
|
("application", BTreeMap::<String, String>::new()),
|
|
(
|
|
"go",
|
|
BTreeMap::from([
|
|
("module".into(), "api".into()),
|
|
("target".into(), "./cmd/server".into()),
|
|
("outputDir".into(), "bin".into()),
|
|
]),
|
|
),
|
|
("dotnet", BTreeMap::from([("project".into(), "src/App.csproj".into())])),
|
|
] {
|
|
let mut config: RunConfig = serde_json::from_value(serde_json::json!({
|
|
"id":"run", "name":"run", "kind":kind, "command":"tool", "args":["unchanged"], "cwd":null,
|
|
"env":{}, "detected":true, "isTest":false, "debugAdapter":null,
|
|
"module":"app", "params":params, "envFiles":[".env"], "stdinFile":"input.txt", "outputFile":"out/result.txt"
|
|
})).unwrap();
|
|
rebase(&mut config, &member, None);
|
|
assert_eq!(config.cwd.as_deref(), Some(member.as_path()));
|
|
assert_eq!(config.extras.module.as_deref(), Some(to_ipc(&member.join("app")).as_str()));
|
|
assert_eq!(config.extras.env_files, [to_ipc(&member.join(".env"))]);
|
|
assert_eq!(config.extras.stdin_file, Some(to_ipc(&member.join("input.txt"))));
|
|
assert_eq!(config.extras.output_file, Some(to_ipc(&member.join("out/result.txt"))));
|
|
assert_eq!(config.args, ["unchanged"]);
|
|
if kind == "go" {
|
|
assert_eq!(config.extras.params["module"], to_ipc(&member.join("api")));
|
|
assert_eq!(config.extras.params["outputDir"], to_ipc(&member.join("bin")));
|
|
assert_eq!(config.extras.params["target"], "./cmd/server");
|
|
}
|
|
if kind == "dotnet" {
|
|
assert_eq!(config.extras.params["project"], to_ipc(&member.join("src/App.csproj")));
|
|
}
|
|
}
|
|
}
|
|
}
|