diff --git a/scripts/stryker-diff.mjs b/scripts/stryker-diff.mjs index c0e8a6cd1a..32211ebbd6 100644 --- a/scripts/stryker-diff.mjs +++ b/scripts/stryker-diff.mjs @@ -313,6 +313,10 @@ export function resolveVitestBinary(repoRoot, packageEntry) { return candidates.find((candidate) => fs.existsSync(candidate)) ?? candidates.at(-1) } +export function resolveStrykerTempDir(repoRoot, runRoot) { + return path.relative(runRoot, path.join(repoRoot, ".stryker-tmp")) || ".stryker-tmp" +} + export function discoverRelatedTestFiles(repoRoot, packageEntry, reportDirectory) { const packageRoot = path.join(repoRoot, packageEntry.root) const runRoot = path.join(repoRoot, packageEntry.runRoot ?? packageEntry.root) @@ -378,6 +382,7 @@ function runStryker(repoRoot, packageEntry, reportRoot, dryRunOnly) { .relative(runRoot, path.join(packageRoot, packageEntry.vitestConfig)) .replaceAll("\\", "/"), STRYKER_REPORT_DIR: reportDirectory, + STRYKER_TEMP_DIR: resolveStrykerTempDir(repoRoot, runRoot), STRYKER_IN_PLACE: "false", STRYKER_VITEST_RELATED: packageEntry.vitestRelated === false ? "false" : "true", STRYKER_TEST_FILES: JSON.stringify(packageEntry.testFiles ?? []), diff --git a/scripts/stryker-diff.test.mjs b/scripts/stryker-diff.test.mjs index 0f39dc507f..80b04e2a51 100644 --- a/scripts/stryker-diff.test.mjs +++ b/scripts/stryker-diff.test.mjs @@ -4,7 +4,7 @@ import fs from "node:fs" import os from "node:os" import path from "node:path" import { describe, it } from "node:test" -import { fileURLToPath } from "node:url" +import { fileURLToPath, pathToFileURL } from "node:url" import { MAX_CHANGED_LINES, @@ -23,6 +23,7 @@ import { parseNameStatus, parseVitestTestFiles, preferDirectTestFiles, + resolveStrykerTempDir, resolveVitestBinary, packageForPath, runManifest, @@ -211,6 +212,11 @@ describe("preferDirectTestFiles", () => { }) describe("related-test discovery", () => { + it("keeps Stryker's temp directory relative to each run root", () => { + assert.equal(resolveStrykerTempDir("/repo", "/repo"), ".stryker-tmp") + assert.equal(resolveStrykerTempDir("/repo", "/repo/src"), path.join("..", ".stryker-tmp")) + }) + it("resolves Vitest from each package before falling back to the repository", () => { const repo = fs.mkdtempSync(path.join(os.tmpdir(), "stryker-vitest-")) const extension = PACKAGE_CONFIGS.find(({ id }) => id === "extension") @@ -259,6 +265,26 @@ describe("related-test discovery", () => { }) }) +describe("Stryker configuration", () => { + it("uses the default or configured temp directory", async () => { + const originalTempDir = process.env.STRYKER_TEMP_DIR + const configUrl = pathToFileURL(path.join(repositoryRoot, "stryker.config.mjs")) + + try { + delete process.env.STRYKER_TEMP_DIR + const defaultConfig = (await import(`${configUrl.href}?temp-dir=default`)).default + assert.equal(defaultConfig.tempDirName, ".stryker-tmp") + + process.env.STRYKER_TEMP_DIR = path.join("..", ".stryker-tmp") + const configuredConfig = (await import(`${configUrl.href}?temp-dir=configured`)).default + assert.equal(configuredConfig.tempDirName, path.join("..", ".stryker-tmp")) + } finally { + if (originalTempDir === undefined) delete process.env.STRYKER_TEMP_DIR + else process.env.STRYKER_TEMP_DIR = originalTempDir + } + }) +}) + describe("selectFromGit", () => { it("derives changed executable ranges from the base/head merge base", () => { const repo = fs.mkdtempSync(path.join(os.tmpdir(), "stryker-diff-")) diff --git a/src/eslint.config.mjs b/src/eslint.config.mjs index bd41ff807b..7120f2e875 100644 --- a/src/eslint.config.mjs +++ b/src/eslint.config.mjs @@ -58,6 +58,6 @@ export default [ }, }, { - ignores: ["webview-ui", "out"], + ignores: [".stryker-tmp", "webview-ui", "out"], }, ] diff --git a/src/tsconfig.json b/src/tsconfig.json index 255fa2b8a4..c62520e8ae 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -21,12 +21,12 @@ "useUnknownInCatchVariables": false }, "include": ["."], - "exclude": ["node_modules"], + "exclude": ["**/.stryker-tmp", "node_modules"], "watchOptions": { "watchFile": "useFsEvents", "watchDirectory": "useFsEvents", "fallbackPolling": "dynamicPriority", "synchronousWatchDirectory": true, - "excludeDirectories": ["**/node_modules", "**/dist", "**/.turbo"] + "excludeDirectories": ["**/node_modules", "**/dist", "**/.stryker-tmp", "**/.turbo"] } } diff --git a/stryker.config.mjs b/stryker.config.mjs index c1a652e7c1..7d85640377 100644 --- a/stryker.config.mjs +++ b/stryker.config.mjs @@ -1,5 +1,6 @@ const vitestConfig = process.env.STRYKER_VITEST_CONFIG ?? "vitest.config.ts" const reportDirectory = process.env.STRYKER_REPORT_DIR ?? "reports/mutation" +const tempDirName = process.env.STRYKER_TEMP_DIR ?? ".stryker-tmp" const testFiles = JSON.parse(process.env.STRYKER_TEST_FILES ?? "[]") export default { @@ -12,6 +13,7 @@ export default { testFiles, incremental: false, inPlace: process.env.STRYKER_IN_PLACE === "true", + tempDirName, concurrency: 2, timeoutMS: 5_000, timeoutFactor: 1.5,