From c1bea1bfd963e846e9f9df931d6f1bfb407a9cee Mon Sep 17 00:00:00 2001 From: Vladimir Sheremet Date: Sat, 2 Jul 2022 09:37:40 +0300 Subject: [PATCH] chore: add clearCache --- docs/config/index.md | 4 +-- docs/guide/cli.md | 4 +++ packages/vitest/src/node/cache/index.ts | 36 +++++++++++++++++++ .../src/node/{cache.ts => cache/results.ts} | 23 ++++++------ packages/vitest/src/node/cli.ts | 4 +++ packages/vitest/src/node/config.ts | 11 +++--- packages/vitest/src/node/state.ts | 2 +- packages/vitest/src/types/config.ts | 6 ++-- test/cache/cache/.vitest-base/results.json | 1 + test/cache/package.json | 11 ++++++ test/cache/test/clear-cache.test.ts | 26 ++++++++++++++ test/cache/vitest-custom.config.ts | 9 +++++ test/cache/vitest.config.ts | 10 ++++++ 13 files changed, 123 insertions(+), 24 deletions(-) create mode 100644 packages/vitest/src/node/cache/index.ts rename packages/vitest/src/node/{cache.ts => cache/results.ts} (64%) create mode 100644 test/cache/cache/.vitest-base/results.json create mode 100644 test/cache/package.json create mode 100644 test/cache/test/clear-cache.test.ts create mode 100644 test/cache/vitest-custom.config.ts create mode 100644 test/cache/vitest.config.ts diff --git a/docs/config/index.md b/docs/config/index.md index 1c39cd645334..e6f0ef760c36 100644 --- a/docs/config/index.md +++ b/docs/config/index.md @@ -567,11 +567,11 @@ Test above this limit will be queued to run when available slot appears. ### cache -- **Type**: `false | { path? }` +- **Type**: `false | { dir? }` Options to configure Vitest cache policy. At the moment Vitest stores cache for test results to run the longer and failed tests first. -#### cache.path +#### cache.dir - **Type**: `string` - **Default**: `node_modules/.vitest` diff --git a/docs/guide/cli.md b/docs/guide/cli.md index 0699d1535fea..c5ee86dde314 100644 --- a/docs/guide/cli.md +++ b/docs/guide/cli.md @@ -36,6 +36,10 @@ Useful to run with [`lint-staged`](https://github.com/okonet/lint-staged) or wit vitest related /src/index.ts /src/hello-world.js ``` +### `vitest clearCache` + +Clears cache folder. + ## Options | Options | | diff --git a/packages/vitest/src/node/cache/index.ts b/packages/vitest/src/node/cache/index.ts new file mode 100644 index 000000000000..c18d5612d90c --- /dev/null +++ b/packages/vitest/src/node/cache/index.ts @@ -0,0 +1,36 @@ +import fs from 'fs' +import { findUp } from 'find-up' +import { resolve } from 'pathe' +import { loadConfigFromFile } from 'vite' +import { configFiles } from '../../constants' +import type { CliOptions } from '../cli-api' +import { slash } from '../../utils' + +export class VitestCache { + static resolveCacheDir(root: string, dir: string | undefined) { + return resolve(root, slash(dir || 'node_modules/.vitest')) + } + + static async clearCache(options: CliOptions) { + const root = resolve(options.root || process.cwd()) + + const configPath = options.config + ? resolve(root, options.config) + : await findUp(configFiles, { cwd: root } as any) + + const config = await loadConfigFromFile({ command: 'serve', mode: 'test' }, configPath) + + if (!config) + throw new Error(`[vitest] Not able to load config from ${configPath}`) + + const cache = config.config.test?.cache + + if (!cache) + throw new Error('[vitest] Cache is disabled') + + const cachePath = VitestCache.resolveCacheDir(root, cache.dir) + + if (fs.existsSync(cachePath)) + fs.rmSync(cachePath, { recursive: true, force: true }) + } +} diff --git a/packages/vitest/src/node/cache.ts b/packages/vitest/src/node/cache/results.ts similarity index 64% rename from packages/vitest/src/node/cache.ts rename to packages/vitest/src/node/cache/results.ts index e5c0530a56bf..1ef0f97e521f 100644 --- a/packages/vitest/src/node/cache.ts +++ b/packages/vitest/src/node/cache/results.ts @@ -1,7 +1,7 @@ import fs from 'fs' import { dirname, resolve } from 'pathe' -import type { File, ResolvedConfig } from '../types' -import { version } from '../../package.json' +import type { File, ResolvedConfig } from '../../types' +import { version } from '../../../package.json' interface SuiteResultCache { failed: boolean @@ -10,10 +10,11 @@ interface SuiteResultCache { export class ResultsCache { private cache = new Map() - public config!: ResolvedConfig['cache'] + private cachePath: string | null = null setConfig(config: ResolvedConfig['cache']) { - this.config = config + if (config) + this.cachePath = resolve(config.dir, 'results.json') } getResults(id: string) { @@ -21,12 +22,11 @@ export class ResultsCache { } async readFromCache() { - if (this.config === false) + if (!this.cachePath) return - const resultsCachePath = resolve(this.config.path, 'results.json') - if (fs.existsSync(resultsCachePath)) { - const resultsCache = await fs.promises.readFile(resultsCachePath, 'utf8') + if (fs.existsSync(this.cachePath)) { + const resultsCache = await fs.promises.readFile(this.cachePath, 'utf8') this.cache = new Map(JSON.parse(resultsCache).results) } } @@ -49,18 +49,17 @@ export class ResultsCache { } async writeToCache() { - if (this.config === false) + if (!this.cachePath) return - const resultsCachePath = resolve(this.config.path, 'results.json') const resultsCache = Array.from(this.cache.entries()) - const cacheDirname = dirname(resultsCachePath) + const cacheDirname = dirname(this.cachePath) if (!fs.existsSync(cacheDirname)) await fs.promises.mkdir(cacheDirname, { recursive: true }) - await fs.promises.writeFile(resultsCachePath, JSON.stringify({ + await fs.promises.writeFile(this.cachePath, JSON.stringify({ version, results: resultsCache, })) diff --git a/packages/vitest/src/node/cli.ts b/packages/vitest/src/node/cli.ts index 496f4ce88f28..02cdab26363c 100644 --- a/packages/vitest/src/node/cli.ts +++ b/packages/vitest/src/node/cli.ts @@ -1,6 +1,7 @@ import cac from 'cac' import c from 'picocolors' import { version } from '../../package.json' +import { VitestCache } from './cache' import type { CliOptions } from './cli-api' import { startVitest } from './cli-api' import { divider } from './reporters/renderers/utils' @@ -57,6 +58,9 @@ cli .command('[...filters]') .action(start) +cli.command('clearCache') + .action(VitestCache.clearCache) + cli.parse() async function runRelated(relatedFiles: string[] | string, argv: CliOptions) { diff --git a/packages/vitest/src/node/config.ts b/packages/vitest/src/node/config.ts index 6caca428ff04..53b55a7afa0a 100644 --- a/packages/vitest/src/node/config.ts +++ b/packages/vitest/src/node/config.ts @@ -7,7 +7,8 @@ import type { ApiConfig, ResolvedConfig, UserConfig } from '../types' import { defaultPort } from '../constants' import { configDefaults } from '../defaults' import { resolveC8Options } from '../integrations/coverage' -import { slash, toArray } from '../utils' +import { toArray } from '../utils' +import { VitestCache } from './cache' const extraInlineDeps = [ /^(?!.*(?:node_modules)).*\.mjs$/, @@ -179,11 +180,9 @@ export function resolveConfig( if (typeof resolved.css === 'object') resolved.css.include ??= [/\.module\./] - resolved.cache ??= { path: '' } - if (resolved.cache) { - const path = slash(resolved.cache.path || 'node_modules/.vitest') - resolved.cache.path = resolve(resolved.root, path) - } + resolved.cache ??= { dir: '' } + if (resolved.cache) + resolved.cache.dir = VitestCache.resolveCacheDir(resolved.root, resolved.cache.dir) return resolved } diff --git a/packages/vitest/src/node/state.ts b/packages/vitest/src/node/state.ts index ffdd78d3cf07..e9d76275065e 100644 --- a/packages/vitest/src/node/state.ts +++ b/packages/vitest/src/node/state.ts @@ -1,5 +1,5 @@ import type { ErrorWithDiff, File, Task, TaskResultPack, UserConsoleLog } from '../types' -import { ResultsCache } from './cache' +import { ResultsCache } from './cache/results' export class StateManager { filesMap = new Map() diff --git a/packages/vitest/src/types/config.ts b/packages/vitest/src/types/config.ts index 6728668e24b5..656919ddfdf0 100644 --- a/packages/vitest/src/types/config.ts +++ b/packages/vitest/src/types/config.ts @@ -364,10 +364,10 @@ export interface InlineConfig { /** * Options for configuring cache policy. - * @default { path: 'node_modules/.vitest' } + * @default { dir: 'node_modules/.vitest' } */ cache?: false | { - path?: string + dir?: string } } @@ -437,6 +437,6 @@ export interface ResolvedConfig extends Omit, 'config' | 'f } cache: { - path: string + dir: string } | false } diff --git a/test/cache/cache/.vitest-base/results.json b/test/cache/cache/.vitest-base/results.json new file mode 100644 index 000000000000..cdf96b046df9 --- /dev/null +++ b/test/cache/cache/.vitest-base/results.json @@ -0,0 +1 @@ +{"version":"0.16.0","results":[["/Users/sheremet/local-git/vitest/test/cache/test/clear-cache.test.ts",{"duration":32,"failed":false}]]} \ No newline at end of file diff --git a/test/cache/package.json b/test/cache/package.json new file mode 100644 index 000000000000..f7632e3d4479 --- /dev/null +++ b/test/cache/package.json @@ -0,0 +1,11 @@ +{ + "name": "@vitest/test-cache", + "private": true, + "scripts": { + "test": "vitest", + "coverage": "vitest run --coverage" + }, + "devDependencies": { + "vitest": "workspace:*" + } +} diff --git a/test/cache/test/clear-cache.test.ts b/test/cache/test/clear-cache.test.ts new file mode 100644 index 000000000000..c96c1af83c5e --- /dev/null +++ b/test/cache/test/clear-cache.test.ts @@ -0,0 +1,26 @@ +import fs, { promises as fsp } from 'fs' +import { resolve } from 'pathe' +import { describe, expect, test } from 'vitest' +import { VitestCache } from '../../../packages/vitest/src/node/cache/index' + +const root = resolve(__dirname, '..') + +const pathBase = resolve(root, 'cache/.vitest-base') +const pathCustom = resolve(root, 'cache/.vitest-custom') + +describe('vitest cache', async () => { + await fsp.mkdir(pathBase, { recursive: true }) + await fsp.mkdir(pathCustom, { recursive: true }) + + test('clears cache without specifying config path', async () => { + await VitestCache.clearCache({}) + + expect(fs.existsSync(pathBase)).toBe(false) + }) + + test('clears cache with specified config path', async () => { + await VitestCache.clearCache({ config: 'vitest-custom.config.ts' }) + + expect(fs.existsSync(pathCustom)).toBe(false) + }) +}) diff --git a/test/cache/vitest-custom.config.ts b/test/cache/vitest-custom.config.ts new file mode 100644 index 000000000000..6087616010f8 --- /dev/null +++ b/test/cache/vitest-custom.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from 'vite' + +export default defineConfig({ + test: { + cache: { + dir: 'cache/.vitest-custom', + }, + }, +}) diff --git a/test/cache/vitest.config.ts b/test/cache/vitest.config.ts new file mode 100644 index 000000000000..2822c141f94f --- /dev/null +++ b/test/cache/vitest.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'vite' + +export default defineConfig({ + test: { + threads: false, + cache: { + dir: 'cache/.vitest-base', + }, + }, +})