дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 03:05:40 +02:00
fix(run): write Gradle init scripts on the host that runs the build (#1377)
The test-events and delegated-run init scripts were written to a path built from the desktop's temporary directory, which doesn't exist on a remote host. A new `run_gradle_init_script` command writes a script under the host's own temporary directory, named by its content, and returns the path Gradle reads it from.
Цей коміт міститься в:
1 джерело
8021a8ccca
коміт
e17e59ce7d
6 files changed
+56
-10
No files matched your search
@@ -142,6 +142,21 @@ pub async fn run_gradle_jvm_args_script(_host: &Host, _window: &str, jvm_args: V
|
||||
.map_err(|e| IdeError::internal(e.to_string()))?
|
||||
}
|
||||
|
||||
/// Writes one of the IDE's Gradle init scripts (`text`; the file is named `<name>-<hash>`) on
|
||||
/// the machine that runs the build, for `--init-script`, and returns its path.
|
||||
pub async fn run_gradle_init_script(_host: &Host, _window: &str, name: String, text: String) -> IdeResult<String> {
|
||||
if name.is_empty() || !name.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'-') {
|
||||
return Err(IdeError::invalid(format!("invalid init script name {name:?}")));
|
||||
}
|
||||
tokio::task::spawn_blocking(move || {
|
||||
ide_run::gradle_jvm::write_script(&ide_run::gradle_jvm::default_dir(), &name, &text)
|
||||
.map(|p| p.to_string_lossy().into_owned())
|
||||
.map_err(|e| IdeError::internal(format!("cannot write the Gradle init script: {e}")))
|
||||
})
|
||||
.await
|
||||
.map_err(|e| IdeError::internal(e.to_string()))?
|
||||
}
|
||||
|
||||
/// Results from the JUnit XML reports (Surefire, Failsafe, Gradle) of the module at
|
||||
/// `module` (relative to the project root) written since `since_ms` (Unix epoch, ms).
|
||||
pub async fn run_test_reports(
|
||||
@@ -308,6 +323,9 @@ pub(crate) fn register(d: &mut Dispatcher) {
|
||||
d.add("run_gradle_jvm_args_script", |c| async move {
|
||||
run_gradle_jvm_args_script(&c.host, &c.window, c.arg("jvmArgs")?).await
|
||||
});
|
||||
d.add("run_gradle_init_script", |c| async move {
|
||||
run_gradle_init_script(&c.host, &c.window, c.arg("name")?, c.arg("text")?).await
|
||||
});
|
||||
d.add("run_test_reports", |c| async move {
|
||||
run_test_reports(&c.host, &c.window, c.arg("module")?, c.arg("sinceMs")?).await
|
||||
});
|
||||
|
||||
@@ -141,3 +141,19 @@ async fn workspace_cmake_before_launch_tasks_resolve_in_the_member() {
|
||||
assert!(configs.iter().any(|c| c.id == task.target && c.cwd == build.cwd));
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn gradle_init_scripts_are_written_by_the_host_that_runs_the_build() {
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let host = host(tmp.path());
|
||||
let text = "allprojects { }\n".to_string();
|
||||
let path =
|
||||
ops::run::run_gradle_init_script(&host, "main", "openidea-gradle-tests".into(), text.clone()).await.unwrap();
|
||||
assert!(path.contains("openidea-gradle-tests-"), "{path}");
|
||||
assert_eq!(std::fs::read_to_string(&path).unwrap(), text);
|
||||
let again = ops::run::run_gradle_init_script(&host, "main", "openidea-gradle-tests".into(), text).await.unwrap();
|
||||
assert_eq!(again, path);
|
||||
// A name is not a path.
|
||||
let escaped = ops::run::run_gradle_init_script(&host, "main", "../escape".into(), String::new()).await;
|
||||
assert!(escaped.is_err(), "{escaped:?}");
|
||||
}
|
||||
@@ -343,6 +343,7 @@ pub fn builder() -> tauri_specta::Builder<tauri::Wry> {
|
||||
run::run_close_stdin,
|
||||
run::run_resize,
|
||||
run::run_gradle_jvm_args_script,
|
||||
run::run_gradle_init_script,
|
||||
run::run_tomcat_home,
|
||||
run::run_tomcat_artifacts,
|
||||
run::run_tomcat_build,
|
||||
|
||||
@@ -189,6 +189,18 @@ pub async fn run_gradle_jvm_args_script(
|
||||
ide_host::ops::run::run_gradle_jvm_args_script(&state.host, window.label(), jvm_args).await
|
||||
}
|
||||
|
||||
/// Writes one of the IDE's Gradle init scripts where the build runs; returns its path.
|
||||
#[tauri::command]
|
||||
#[specta::specta]
|
||||
pub async fn run_gradle_init_script(
|
||||
window: Window,
|
||||
state: State<'_, AppState>,
|
||||
name: String,
|
||||
text: String,
|
||||
) -> IdeResult<String> {
|
||||
ide_host::ops::run::run_gradle_init_script(&state.host, window.label(), name, text).await
|
||||
}
|
||||
|
||||
/// Results from the JUnit XML reports (Surefire, Failsafe, Gradle) of the module at
|
||||
/// `module` (relative to the project root) written since `since_ms` (Unix epoch, ms).
|
||||
#[tauri::command]
|
||||
|
||||
@@ -630,6 +630,8 @@ export const commands = {
|
||||
runResize: (id: RunId, cols: number, rows: number) => typedError<null, IdeError>(__TAURI_INVOKE("run_resize", { id, cols, rows })),
|
||||
/** Writes the Gradle init script adding `jvm_args` to the JVMs the build forks; returns its path. */
|
||||
runGradleJvmArgsScript: (jvmArgs: string[]) => typedError<string, IdeError>(__TAURI_INVOKE("run_gradle_jvm_args_script", { jvmArgs })),
|
||||
/** Writes one of the IDE's Gradle init scripts where the build runs; returns its path. */
|
||||
runGradleInitScript: (name: string, text: string) => typedError<string, IdeError>(__TAURI_INVOKE("run_gradle_init_script", { name, text })),
|
||||
runTomcatHome: (home: string) => typedError<TomcatHome, IdeError>(__TAURI_INVOKE("run_tomcat_home", { home })),
|
||||
runTomcatArtifacts: () => typedError<WebArtifact[], IdeError>(__TAURI_INVOKE("run_tomcat_artifacts")),
|
||||
runTomcatBuild: (config: RunConfig_Deserialize) => typedError<({
|
||||
|
||||
@@ -85,18 +85,15 @@ export function delegatedGradleConfig(config: RunConfig, module: string, ctx: De
|
||||
};
|
||||
}
|
||||
|
||||
/** Writes an init script where Gradle can read it; it never changes, so once per session. */
|
||||
/**
|
||||
* Writes an init script where Gradle reads it: on the machine that runs the build (the
|
||||
* remote host in remote development). It never changes, so once per session.
|
||||
*/
|
||||
const scriptPaths = new Map<string, Promise<string>>();
|
||||
function writeScript(name: string, text: string): Promise<string> {
|
||||
let written = scriptPaths.get(name);
|
||||
if (!written) {
|
||||
written = (async () => {
|
||||
const { tempDir, join } = await import("@tauri-apps/api/path");
|
||||
const path = await join(await tempDir(), name);
|
||||
await call(commands.fsDelete(path)).catch(() => {});
|
||||
await call(commands.fsCreateFileBytes(path, Array.from(new TextEncoder().encode(text))));
|
||||
return path;
|
||||
})().catch((e) => {
|
||||
written = call(commands.runGradleInitScript(name, text)).catch((e) => {
|
||||
scriptPaths.delete(name);
|
||||
throw e;
|
||||
});
|
||||
@@ -121,7 +118,7 @@ export function withTestEvents<T extends Pick<RunConfig, "kind" | "command" | "a
|
||||
export async function gradleTestLaunch<T extends RunConfig>(config: T): Promise<T> {
|
||||
if (!isTauri() || !config.isTest || !isGradleCommand(config)) return config;
|
||||
try {
|
||||
return withTestEvents(config, await writeScript("openidea-gradle-tests.gradle", TESTS_SCRIPT));
|
||||
return withTestEvents(config, await writeScript("openidea-gradle-tests", TESTS_SCRIPT));
|
||||
} catch (e) {
|
||||
console.warn("Gradle test init script not written", e);
|
||||
return config;
|
||||
@@ -150,7 +147,7 @@ export async function gradleDelegation(config: RunConfig): Promise<RunConfig | n
|
||||
};
|
||||
if (!delegatedGradleConfig(config, module, ctx)) return null;
|
||||
const [script, configurationCache] = await Promise.all([
|
||||
writeScript("openidea-gradle-run.gradle", RUN_SCRIPT),
|
||||
writeScript("openidea-gradle-run", RUN_SCRIPT),
|
||||
supportsConfigurationCache(ctx),
|
||||
]);
|
||||
return delegatedGradleConfig(config, module, { ...ctx, script, configurationCache });
|
||||
|
||||
Reference in new issue
Заблокувати користувача