diff --git a/packages/rstack/src/fmt/cli.ts b/packages/rstack/src/fmt/cli.ts index 7b1dd4d3..55af2173 100644 --- a/packages/rstack/src/fmt/cli.ts +++ b/packages/rstack/src/fmt/cli.ts @@ -288,6 +288,17 @@ const runFmtCLI = async (args: string[]): Promise => { } const cacheDirPath = cacheLocation ? path.resolve(cwd, cacheLocation) : undefined; + if (cacheDirPath) { + const cacheDirPrefix = cacheDirPath.endsWith(path.sep) + ? cacheDirPath + : `${cacheDirPath}${path.sep}`; + if (cwd === cacheDirPath || cwd.startsWith(cacheDirPrefix)) { + throw new Error( + 'The --cache-location directory cannot be the current working directory or an ancestor.', + ); + } + } + const config = await loadFmtConfig(cwd); const files = await discoverFmtFiles({ cwd, diff --git a/packages/rstack/tests/cli/fmt/index.test.ts b/packages/rstack/tests/cli/fmt/index.test.ts index 265b14ca..289789a7 100644 --- a/packages/rstack/tests/cli/fmt/index.test.ts +++ b/packages/rstack/tests/cli/fmt/index.test.ts @@ -230,6 +230,16 @@ test.each(['relative', 'absolute'] as const)('uses a %s custom cache location', expect(existsSync(path.join(projectPath, '.rstack'))).toBe(false); }); +test.each(['.', '..'])('rejects a custom cache location at %s', (cacheLocation) => { + const result = runFmt(['--cache-location', cacheLocation, '.']); + + expect(result.status).toBe(2); + expect(result.stdout).toBe(''); + expect(result.stderr).toContain( + 'The --cache-location directory cannot be the current working directory or an ancestor.', + ); +}); + test('excludes the custom cache directory from formatting', () => { const cacheLocation = 'custom-cache'; writeProjectFile('index.ts', 'const value = 1;\n');