fix(dev): consolidate generated cache directories
This commit is contained in:
@@ -268,7 +268,7 @@
|
|||||||
},
|
},
|
||||||
"packages/cli": {
|
"packages/cli": {
|
||||||
"name": "@wrnexus/cli",
|
"name": "@wrnexus/cli",
|
||||||
"version": "0.8.30",
|
"version": "0.8.31",
|
||||||
"bin": {
|
"bin": {
|
||||||
"wrnexus": "src/index.ts",
|
"wrnexus": "src/index.ts",
|
||||||
},
|
},
|
||||||
@@ -332,7 +332,7 @@
|
|||||||
},
|
},
|
||||||
"packages/dev-server": {
|
"packages/dev-server": {
|
||||||
"name": "@wrnexus/dev-server",
|
"name": "@wrnexus/dev-server",
|
||||||
"version": "0.8.28",
|
"version": "0.8.29",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@wrnexus/authz": "workspace:*",
|
"@wrnexus/authz": "workspace:*",
|
||||||
"@wrnexus/cache": "workspace:*",
|
"@wrnexus/cache": "workspace:*",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/cli",
|
"name": "@wrnexus/cli",
|
||||||
"version": "0.8.30",
|
"version": "0.8.31",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -540,6 +540,7 @@ export async function runGateway(root: string, args: string[]): Promise<void> {
|
|||||||
|
|
||||||
const hostname = hostArg?.split("=")[1] ?? environmentConfig.hostname;
|
const hostname = hostArg?.split("=")[1] ?? environmentConfig.hostname;
|
||||||
|
|
||||||
|
// The published CLI bundle carries the matching gateway/cache lifecycle.
|
||||||
const { startGateway } = await import("@wrnexus/dev-server");
|
const { startGateway } = await import("@wrnexus/dev-server");
|
||||||
|
|
||||||
await startGateway({
|
await startGateway({
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@wrnexus/dev-server",
|
"name": "@wrnexus/dev-server",
|
||||||
"version": "0.8.28",
|
"version": "0.8.29",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"exports": {
|
"exports": {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { existsSync, rmSync } from "node:fs";
|
import { existsSync, readdirSync, rmSync } from "node:fs";
|
||||||
import { resolve } from "node:path";
|
import { join, resolve } from "node:path";
|
||||||
|
|
||||||
export interface ResetDevCacheOptions {
|
export interface ResetDevCacheOptions {
|
||||||
rootDir?: string;
|
rootDir?: string;
|
||||||
@@ -7,6 +7,19 @@ export interface ResetDevCacheOptions {
|
|||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeLegacyProcessCaches(rootDir: string): void {
|
||||||
|
if (!existsSync(rootDir)) return;
|
||||||
|
for (const entry of readdirSync(rootDir, { withFileTypes: true })) {
|
||||||
|
if (!entry.isDirectory() || !/^\.wrnexus-\d+$/.test(entry.name)) continue;
|
||||||
|
rmSync(join(rootDir, entry.name), {
|
||||||
|
recursive: true,
|
||||||
|
force: true,
|
||||||
|
maxRetries: 3,
|
||||||
|
retryDelay: 100,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function resetDevCache(options: ResetDevCacheOptions = {}): string {
|
export function resetDevCache(options: ResetDevCacheOptions = {}): string {
|
||||||
const rootDir = resolve(options.rootDir ?? process.cwd());
|
const rootDir = resolve(options.rootDir ?? process.cwd());
|
||||||
|
|
||||||
@@ -16,6 +29,8 @@ export function resetDevCache(options: ResetDevCacheOptions = {}): string {
|
|||||||
return cacheDir;
|
return cacheDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeLegacyProcessCaches(rootDir);
|
||||||
|
|
||||||
// Safety: never allow deleting the project root.
|
// Safety: never allow deleting the project root.
|
||||||
if (cacheDir === rootDir) {
|
if (cacheDir === rootDir) {
|
||||||
throw new Error("Refusing to remove the project root as the WRNexus cache directory.");
|
throw new Error("Refusing to remove the project root as the WRNexus cache directory.");
|
||||||
|
|||||||
@@ -288,10 +288,9 @@ export async function startServer(opts: ServeOptions): Promise<RunningServer> {
|
|||||||
|
|
||||||
const pluginContributions = await pluginRunner.contributions();
|
const pluginContributions = await pluginRunner.contributions();
|
||||||
const virtualModules = new Map<string, string>();
|
const virtualModules = new Map<string, string>();
|
||||||
// A live dev server and a test process can share an app root. Keeping the
|
// Keep generated artifacts under the single framework state directory.
|
||||||
// generated artifacts in a process-specific directory prevents a test boot
|
// Startup clears this cache and removes legacy PID-suffixed cache folders.
|
||||||
// from deleting the running server's client modules.
|
const cacheDir = join(appRoot, ".wrnexus", "cache");
|
||||||
const cacheDir = join(appRoot, `.wrnexus-${process.pid}`);
|
|
||||||
const virtualDir = join(cacheDir, "virtual");
|
const virtualDir = join(cacheDir, "virtual");
|
||||||
mkdirSync(virtualDir, { recursive: true });
|
mkdirSync(virtualDir, { recursive: true });
|
||||||
for (const [index, module] of pluginContributions.virtualModules.entries()) {
|
for (const [index, module] of pluginContributions.virtualModules.entries()) {
|
||||||
|
|||||||
@@ -63,14 +63,14 @@ export default defineAuthz({ permissions: { "post:read": { title: "View posts" }
|
|||||||
try {
|
try {
|
||||||
expect(hasAuthzCatalog()).toBe(true);
|
expect(hasAuthzCatalog()).toBe(true);
|
||||||
expect(getAuthzCatalog().permissions.has("post:read")).toBe(true);
|
expect(getAuthzCatalog().permissions.has("post:read")).toBe(true);
|
||||||
const cacheDir = join(appDir, "..", `.wrnexus-${process.pid}`);
|
const cacheDir = join(appDir, "..", ".wrnexus", "cache");
|
||||||
mkdirSync(cacheDir, { recursive: true });
|
mkdirSync(cacheDir, { recursive: true });
|
||||||
writeFileSync(join(cacheDir, "generated.js"), "generated", "utf8");
|
writeFileSync(join(cacheDir, "generated.js"), "generated", "utf8");
|
||||||
expect(existsSync(cacheDir)).toBe(true);
|
expect(existsSync(cacheDir)).toBe(true);
|
||||||
} finally {
|
} finally {
|
||||||
server.stop();
|
server.stop();
|
||||||
}
|
}
|
||||||
expect(existsSync(join(appDir, "..", `.wrnexus-${process.pid}`))).toBe(false);
|
expect(existsSync(join(appDir, "..", ".wrnexus", "cache"))).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("an app with no app/authz declarations boots without throwing", async () => {
|
test("an app with no app/authz declarations boots without throwing", async () => {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ test("per-process dev caches are excluded from root and example project tools",
|
|||||||
const projects = ["basic-app", "inter-app-api-showcase"].map((name) =>
|
const projects = ["basic-app", "inter-app-api-showcase"].map((name) =>
|
||||||
join(root, "examples", name),
|
join(root, "examples", name),
|
||||||
);
|
);
|
||||||
const caches = projects.map((project) => join(project, ".wrnexus-123"));
|
const caches = projects.map((project) => join(project, ".wrnexus", "cache"));
|
||||||
|
|
||||||
for (const project of projects) {
|
for (const project of projects) {
|
||||||
const projectEslint = readFileSync(join(project, "eslint.config.js"), "utf8");
|
const projectEslint = readFileSync(join(project, "eslint.config.js"), "utf8");
|
||||||
|
|||||||
Reference in New Issue
Block a user