From b9e461b144bf28510b96f9f0258ee3b9ec5ec0cb Mon Sep 17 00:00:00 2001 From: creatixchu Date: Sat, 26 Sep 2026 12:11:56 +0800 Subject: [PATCH] fix(build): make desktop keyboard output safe to clean --- scripts/clean.spec.ts | 24 ++++++++++++++++++++++++ scripts/clean.ts | 1 + tsconfig.desktop-keyboard-tests.json | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/scripts/clean.spec.ts b/scripts/clean.spec.ts index 11a8c880b0..8bbd3a4eed 100644 --- a/scripts/clean.spec.ts +++ b/scripts/clean.spec.ts @@ -1,7 +1,9 @@ import { existsSync, mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from 'node:fs' import { tmpdir } from 'node:os' import { dirname, join } from 'node:path' +import { fileURLToPath } from 'node:url' import { afterEach, describe, expect, it } from 'vitest' +import ts from 'typescript' import { RepositoryCleaner } from './clean.ts' @@ -32,6 +34,28 @@ afterEach(() => { }) describe('RepositoryCleaner', () => { + it('cleans the Desktop keyboard compiler output and its retired directory without deleting sibling files', async () => { + const root = fixture() + const configPath = fileURLToPath(new URL('../tsconfig.desktop-keyboard-tests.json', import.meta.url)) + const config = ts.readConfigFile(configPath, ts.sys.readFile).config as { compilerOptions: { outDir: string } } + write(join(root, 'tsconfig.json'), JSON.stringify({ files: [], references: [{ path: './tsconfig.desktop-keyboard-tests.json' }] })) + write(join(root, 'tsconfig.desktop-keyboard-tests.json'), JSON.stringify({ + compilerOptions: { composite: true, emitDeclarationOnly: true, outDir: config.compilerOptions.outDir }, + files: ['keyboard.ts'], + })) + write(join(root, 'keyboard.ts'), 'export {}\n') + write(join(root, config.compilerOptions.outDir, 'keyboard.d.ts')) + write(join(root, 'lib/desktop-keyboard-test-types/keyboard.d.ts')) + write(join(root, 'lib/retained.txt'), 'unrelated sibling') + + await new RepositoryCleaner(root).clean() + + expect(existsSync(join(root, 'lib/desktop-keyboard-tests'))).toBe(false) + expect(existsSync(join(root, 'lib/desktop-keyboard-test-types'))).toBe(false) + expect(existsSync(join(root, 'lib/retained.txt'))).toBe(true) + expect(existsSync(join(root, 'keyboard.ts'))).toBe(true) + }) + it('derives live build outputs from project references and removes safe stale package residue', async () => { const root = fixture() addProject(root, 'products/shell') diff --git a/scripts/clean.ts b/scripts/clean.ts index bb789f298c..3aed82079a 100644 --- a/scripts/clean.ts +++ b/scripts/clean.ts @@ -72,6 +72,7 @@ export class RepositoryCleaner { // These checks cover legacy root-level incremental state emitted by older configs. await this.addIfPresent(targets, join(this.root, '.typecheck'), canonicalRoot) + await this.addIfPresent(targets, join(this.root, 'lib/desktop-keyboard-test-types'), canonicalRoot) for (const entry of await readdir(this.root, { withFileTypes: true })) { if (entry.isFile() && entry.name.endsWith('.tsbuildinfo')) targets.add(join(this.root, entry.name)) } diff --git a/tsconfig.desktop-keyboard-tests.json b/tsconfig.desktop-keyboard-tests.json index 28cdd1bf9c..ae5cfe0639 100644 --- a/tsconfig.desktop-keyboard-tests.json +++ b/tsconfig.desktop-keyboard-tests.json @@ -3,7 +3,7 @@ "extends": "./tsconfig.base.client.json", "compilerOptions": { "rootDir": ".", - "outDir": "lib/desktop-keyboard-test-types", + "outDir": "lib/desktop-keyboard-tests/types", "emitDeclarationOnly": true, "types": ["node"] },