diff --git a/src/bin/watch.ts b/src/bin/watch.ts index 66af43c..56d87d6 100644 --- a/src/bin/watch.ts +++ b/src/bin/watch.ts @@ -1,7 +1,18 @@ import { Task } from '../definitions'; -import { series, raises, print, log, combine, watch, context } from '../tasks'; +import { run } from '../utils'; +import { + series, + raises, + print, + log, + combine, + watch, + context, + clear +} from '../tasks'; import { stripIndent as indent } from 'common-tags'; import { flags, safePairs, splitBy } from 'cli-belt'; +import { into } from 'pipettes'; import chalk from 'chalk'; import arg from 'arg'; @@ -26,7 +37,9 @@ export default async function bin( Options: -p, --path Paths to watch + -e, --exclude File or path to exclude -g, --glob Parse globs in paths + -c, --clear Clear stdout before tasks execution -i, --initial Run tasks on start, before changes -s, --symlinks Follow symlinks --parallel Don't cancel running tasks @@ -42,7 +55,9 @@ export default async function bin( const types = { '--path': [String] as [StringConstructor], + '--exclude': String, '--glob': Boolean, + '--clear': Boolean, '--initial': Boolean, '--parallel': Boolean, '--symlinks': Boolean, @@ -65,29 +80,57 @@ export default async function bin( const [names, args] = splitBy(cmd._, '--'); return names.length - ? series( - log('debug', 'Working directory:', process.cwd()), - log( - 'info', - chalk.bold(opts.bin), - chalk.bold.blue(':watch'), - names.join(' ') - ), - print(), - watch( - cmd['--path'] || './', - { - glob: cmd['--glob'], - initial: cmd['--initial'], - parallel: cmd['--parallel'], - debounce: cmd['--debounce'], - depth: cmd['--depth'], - poll: cmd['--poll'], - symlinks: cmd['--symlinks'] - }, - context({ args }, combine(params.record, names)) - ) - ) + ? async (ctx) => { + let first = true; + return into( + series( + log('debug', 'Working directory:', process.cwd()), + log( + 'info', + chalk.bold(opts.bin), + chalk.bold.blue(':watch'), + names.join(' ') + ), + print(), + watch( + cmd['--path'] || './', + { + glob: cmd['--glob'], + initial: cmd['--initial'], + exclude: cmd['--exclude'] || 'node_modules', + parallel: cmd['--parallel'], + debounce: cmd['--debounce'], + depth: cmd['--depth'], + poll: cmd['--poll'], + symlinks: cmd['--symlinks'] + }, + async (ctx) => { + return first + ? into(combine(params.record, names), (task) => { + first = false; + return run(task, ctx); + }) + : into( + series( + cmd['--clear'] ? clear() : null, + log( + 'info', + chalk.bold(opts.bin), + chalk.bold.blue(':watch'), + names.join(' ') + ), + print(), + combine(params.record, names) + ), + (task) => run(task, ctx) + ); + } + ) + ), + context.bind(null, { args }), + (task) => run(task, ctx) + ); + } : series( print(help + '\n'), raises(Error(`A command or task is required`)) diff --git a/src/tasks/filesystem/watch.ts b/src/tasks/filesystem/watch.ts index 185d62a..e44626d 100644 --- a/src/tasks/filesystem/watch.ts +++ b/src/tasks/filesystem/watch.ts @@ -11,6 +11,8 @@ export interface WatchOptions { glob?: boolean; /** Runs the task on start instead of waiting for changes */ initial?: boolean; + /** Files and paths to exclude */ + exclude?: string | RegExp; /** Doesn't cancel tasks in execution when a new task runs */ parallel?: boolean; /** Avoids rapid task restarts by debouncing by a set number of ms */ @@ -40,6 +42,7 @@ export function watch( { glob: false, initial: false, + exclude: undefined, parallel: false, debounce: -1, depth: -1, @@ -51,6 +54,7 @@ export function watch( const watcher = chokidar.watch(paths, { persistent: true, + ignored: opts.exclude, ignorePermissionErrors: false, ignoreInitial: true, cwd: ctx.cwd,