fix(run): enable Spring console colours with manual classpaths (#888)

Spring Boot runs with a manual classpath (or no classpath placeholder) skip Java classpath resolution and so also skipped the console colour VM option. The shared console VM options are now applied on that launch path too; explicit spring.output.ansi.enabled settings are kept and resolved classpaths get the option once.
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-11-02 23:37:52 +08:00
1 джерело 51988985c5
коміт c0c56dac8a
2 files changed
+46 -2

No files matched your search

+38
Переглянути файл
@@ -87,6 +87,44 @@ it("finds the source module for an old saved configuration without a module", as
expect(ipc.runStart).toHaveBeenCalledWith(expect.objectContaining({ cwd: "/outside/modules" }), expect.anything());
});
it.each([["-cp", "lib/*"], []])("colours Spring Boot runs without classpath resolution (%j)", async (...classpath) => {
const args = ["-Xmx256m", ...classpath, "a.Main", "--spring.profiles.active=dev"];
const boot = { ...config, kind: "spring-boot", args };
const session = await startRun(boot);
expect(session?.status).toBe("running");
expect(ipc.runStart).toHaveBeenCalledWith(
expect.objectContaining({ args: ["-Dspring.output.ansi.enabled=always", ...args] }),
expect.anything(),
);
expect(ipc.javaResolveLaunch).not.toHaveBeenCalled();
expect(boot.args).toBe(args);
expect(args).not.toContain("-Dspring.output.ansi.enabled=always");
});
it.each(["never", "detect", "always"])("preserves an explicit Spring Boot console setting (%s)", async (value) => {
const args = [`-Dspring.output.ansi.enabled=${value}`, "-cp", "lib/*", "a.Main"];
await startRun({ ...config, kind: "spring-boot", args });
expect(ipc.runStart).toHaveBeenCalledWith(expect.objectContaining({ args }), expect.anything());
expect(ipc.javaResolveLaunch).not.toHaveBeenCalled();
});
it("keeps plain Java runs with an explicit classpath free of Spring Boot options", async () => {
const args = ["-cp", "lib/*", "a.Main"];
await startRun({ ...config, args });
expect(ipc.runStart).toHaveBeenCalledWith(expect.objectContaining({ args }), expect.anything());
expect(ipc.javaResolveLaunch).not.toHaveBeenCalled();
});
it("adds the Spring Boot console option once when resolving the module classpath", async () => {
await startRun({ ...config, kind: "spring-boot", module: "app" });
expect(ipc.runStart).toHaveBeenCalledWith(
expect.objectContaining({
args: ["-Dspring.output.ansi.enabled=always", "-cp", "/p/app/target/classes", "a.Main"],
}),
expect.anything(),
);
});
it("keeps an explicitly stored root module", async () => {
expect(await findJavaModule({ ...config, module: "", cwd: "sibling" })).toBe("");
expect(ipc.findFiles).not.toHaveBeenCalled();
+8 -2
Переглянути файл
@@ -17,7 +17,13 @@ import {
type RunId,
type TestCaseReport,
} from "@/platform/ipc";
import { findJavaModule, isJvmApplication, parseJavaArgs, prepareJavaLaunch } from "@/platform/javaLaunch";
import {
consoleVmArgs,
findJavaModule,
isJvmApplication,
parseJavaArgs,
prepareJavaLaunch,
} from "@/platform/javaLaunch";
import { downloadJdkActions } from "@/platform/jdk";
import { useProject } from "@/platform/project";
import { executeAction } from "@/platform/actions";
@@ -721,7 +727,7 @@ async function resolveJvmApplication(sessionId: string, config: RunConfig): Prom
say(`No main class in '${config.name}': expected java [options] -cp \${classpath} <main class> [args]\n`, "stderr");
return null;
}
if (!parsed.classpath) return config;
if (!parsed.classpath) return { ...config, args: [...consoleVmArgs(config), ...config.args] };
const rt = runtime(sessionId)!;
const request = { id: nextRequestId(), controller: new AbortController() };
rt.resolveRequest = request;