diff --git a/src/watch/index.ts b/src/watch/index.ts index b798ad1ae..826bce1c3 100644 --- a/src/watch/index.ts +++ b/src/watch/index.ts @@ -32,14 +32,19 @@ const flags = { description: 'Clearing the screen on rerun', default: true, }, + // Deprecated ignore: { type: [String], - description: 'Paths & globs to exclude from being watched', + description: 'Paths & globs to exclude from being watched (Deprecated: use --exclude)', }, include: { type: [String], description: 'Additional paths & globs to watch', }, + exclude: { + type: [String], + description: 'Paths & globs to exclude from being watched', + }, } as const; export const watchCommand = command({ @@ -63,8 +68,11 @@ export const watchCommand = command({ noCache: argv.flags.noCache, tsconfigPath: argv.flags.tsconfig, clearScreen: argv.flags.clearScreen, - ignore: argv.flags.ignore, include: argv.flags.include, + exclude: [ + ...argv.flags.ignore, + ...argv.flags.exclude, + ], ipc: true, }; @@ -217,7 +225,7 @@ export const watchCommand = command({ // 3rd party packages '**/{node_modules,bower_components,vendor}/**', - ...options.ignore, + ...options.exclude, ], ignorePermissionErrors: true, }, diff --git a/tests/specs/watch.ts b/tests/specs/watch.ts index 47d562b85..35bd4f7e8 100644 --- a/tests/specs/watch.ts +++ b/tests/specs/watch.ts @@ -1,4 +1,3 @@ -import path from 'node:path'; import { setTimeout } from 'node:timers/promises'; import { testSuite, expect } from 'manten'; import { createFixture } from 'fs-fixture'; @@ -222,14 +221,73 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => { }, 10_000); }); - describe('ignore', ({ test }) => { - test('file path & glob', async ({ onTestFinish, onTestFail }) => { + describe('include', ({ test }) => { + test('file path & glob', async () => { + const entryFile = 'index.js'; + const fileA = 'file-a'; + const fileB = 'directory/file-b'; + await using fixture = await createFixture({ + [entryFile]: ` + import fs from 'fs/promises'; + Promise.all([ + fs.readFile('./${fileA}', 'utf8'), + fs.readFile('./${fileB}', 'utf8') + ]).then(console.log, console.error); + `.trim(), + [fileA]: 'content-a', + [fileB]: 'content-b', + }); + + const tsxProcess = tsx( + [ + 'watch', + '--clear-screen=false', + `--include=${fileA}`, + '--include=directory/*', + entryFile, + ], + fixture.path, + ); + + await processInteract( + tsxProcess.stdout!, + [ + (data) => { + if (data.includes("'content-a', 'content-b'")) { + fixture.writeFile(fileA, 'update-a'); + return true; + } + }, + (data) => { + if (data.includes("'update-a', 'content-b'")) { + fixture.writeFile(fileB, 'update-b'); + return true; + } + }, + (data) => { + if (data.includes("'update-a', 'update-b'")) { + return true; + } + }, + ], + 9000, + ); + + tsxProcess.kill(); + + const tsxProcessResolved = await tsxProcess; + expect(tsxProcessResolved.stderr).toBe(''); + }, 10_000); + }); + + describe('exclude (ignore)', ({ test }) => { + test('file path & glob', async ({ onTestFail }) => { const entryFile = 'index.js'; const fileA = 'file-a.js'; const fileB = 'directory/file-b.js'; const depA = 'node_modules/a/index.js'; - const fixtureGlob = await createFixture({ + await using fixtureGlob = await createFixture({ [fileA]: 'export default "logA"', [fileB]: 'export default "logB"', [depA]: 'export default "logC"', @@ -241,14 +299,12 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => { `.trim(), }); - onTestFinish(async () => await fixtureGlob.rm()); - const tsxProcess = tsx( [ 'watch', '--clear-screen=false', `--ignore=${fileA}`, - `--ignore=${path.join(fixtureGlob.path, 'directory/*')}`, + '--exclude=directory/*', entryFile, ], fixtureGlob.path, @@ -300,64 +356,5 @@ export default testSuite(async ({ describe }, { tsx }: NodeApis) => { expect(p.stderr).toBe(''); }, 10_000); }); - - describe('watch additional files', ({ test }) => { - test('file path & glob', async () => { - const entryFile = 'index.js'; - const fileA = 'file-a'; - const fileB = 'directory/file-b'; - await using fixture = await createFixture({ - [entryFile]: ` - import fs from 'fs/promises'; - Promise.all([ - fs.readFile('./${fileA}', 'utf8'), - fs.readFile('./${fileB}', 'utf8') - ]).then(console.log, console.error); - `.trim(), - [fileA]: 'content-a', - [fileB]: 'content-b', - }); - - const tsxProcess = tsx( - [ - 'watch', - '--clear-screen=false', - `--include=${fileA}`, - '--include=directory/*', - entryFile, - ], - fixture.path, - ); - - await processInteract( - tsxProcess.stdout!, - [ - (data) => { - if (data.includes("'content-a', 'content-b'")) { - fixture.writeFile(fileA, 'update-a'); - return true; - } - }, - (data) => { - if (data.includes("'update-a', 'content-b'")) { - fixture.writeFile(fileB, 'update-b'); - return true; - } - }, - (data) => { - if (data.includes("'update-a', 'update-b'")) { - return true; - } - }, - ], - 9000, - ); - - tsxProcess.kill(); - - const tsxProcessResolved = await tsxProcess; - expect(tsxProcessResolved.stderr).toBe(''); - }, 10_000); - }); }); });