diff --git a/src/participation/cloning.service.ts b/src/participation/cloning.service.ts index 33fd386..7b15b7c 100644 --- a/src/participation/cloning.service.ts +++ b/src/participation/cloning.service.ts @@ -8,6 +8,8 @@ import * as path from "path"; import { retrieveVcsAccessToken } from "../artemis/authentication.client"; import { getWorkspaceFolder, theiaEnv } from "../theia/theia"; import { addVcsTokenToUrl } from "@shared/models/participation.model"; +import { ProgrammingExercise, ProgrammingLanguage } from "@shared/models/exercise.model"; +import { warmupGradleDaemon } from "./gradle.service"; export async function cloneUserRepo(repoUrl: string, username: string) { // get folder to clone repo into @@ -48,6 +50,12 @@ export async function cloneUserRepo(repoUrl: string, username: string) { const cloneUrlWithToken = new URL(addVcsTokenToUrl(repoUrl, username, vcsToken)); const clonePath = await cloneByGivenURL(cloneUrlWithToken, destinationPath); + // Pre-warm Gradle daemon in background to avoid ~3s init on first build + const exercise = getState().displayedExercise; + if ((exercise as ProgrammingExercise)?.programmingLanguage === ProgrammingLanguage.JAVA) { + warmupGradleDaemon(clonePath); + } + if (!theiaEnv.THEIA_FLAG) { // Prompt the user to open the cloned folder in a new workspace const openIn = await vscode.window.showInformationMessage( diff --git a/src/participation/gradle.service.ts b/src/participation/gradle.service.ts new file mode 100644 index 0000000..bbcb913 --- /dev/null +++ b/src/participation/gradle.service.ts @@ -0,0 +1,35 @@ +import { spawn } from "child_process"; +import * as fs from "fs"; +import * as path from "path"; + +/** + * Pre-warms the Gradle daemon in the background after cloning a repository. + * This avoids the ~3s daemon initialization overhead on the first build. + * + * Silently skips if: + * - Running on Windows (not a supported environment) + * - The project does not contain a `gradlew` file (not a Gradle project) + */ +export function warmupGradleDaemon(projectPath: string): void { + if (process.platform === "win32") { + return; + } + + const gradlewPath = path.join(projectPath, "gradlew"); + if (!fs.existsSync(gradlewPath)) { + return; + } + + try { + fs.chmodSync(gradlewPath, 0o755); + + const child = spawn("./gradlew", ["--daemon"], { + cwd: projectPath, + detached: true, + stdio: "ignore", + }); + child.unref(); + } catch (error: any) { + console.warn(`Gradle daemon warmup failed: ${error.message}`); + } +}