diff --git a/src/cmd/run.js b/src/cmd/run.js index b2790bd28f..6a820dc26e 100644 --- a/src/cmd/run.js +++ b/src/cmd/run.js @@ -38,7 +38,7 @@ export type CmdRunParams = {| noReload: boolean, preInstall: boolean, sourceDir: string, - watchFile?: string, + watchFile?: Array, watchIgnored?: Array, startUrl?: Array, target?: Array, diff --git a/src/extension-runners/index.js b/src/extension-runners/index.js index 2b10183d05..cafa7e04d5 100644 --- a/src/extension-runners/index.js +++ b/src/extension-runners/index.js @@ -239,7 +239,7 @@ export class MultiExtensionRunner { export type WatcherCreatorParams = {| reloadExtension: (string) => void, sourceDir: string, - watchFile?: string, + watchFile?: Array, watchIgnored?: Array, artifactsDir: string, onSourceChange?: OnSourceChangeFn, @@ -276,7 +276,7 @@ export function defaultWatcherCreator( export type ReloadStrategyParams = {| extensionRunner: IExtensionRunner, sourceDir: string, - watchFile?: string, + watchFile?: Array, watchIgnored?: Array, artifactsDir: string, ignoreFiles?: Array, diff --git a/src/program.js b/src/program.js index dc0b3fb460..5aac4f7820 100644 --- a/src/program.js +++ b/src/program.js @@ -619,7 +619,7 @@ Example: $0 --help run. ' file changes. This is useful if you use a custom' + ' build process for your extension', demandOption: false, - type: 'string', + type: 'array', }, 'watch-ignored': { describe: 'Paths and globs patterns that should not be ' + diff --git a/src/watcher.js b/src/watcher.js index 4aa7021aaf..58bb211db6 100644 --- a/src/watcher.js +++ b/src/watcher.js @@ -18,7 +18,7 @@ export type OnChangeFn = () => any; export type OnSourceChangeParams = {| sourceDir: string, - watchFile?: string, + watchFile?: Array, watchIgnored?: Array, artifactsDir: string, onChange: OnChangeFn, @@ -57,18 +57,22 @@ export default function onSourceChange( proxyFileChanges({artifactsDir, onChange, filePath, shouldWatchFile}); }); - log.debug(`Watching for file changes in ${watchFile || sourceDir}`); + log.debug( + `Watching ${watchFile ? watchFile.join(',') : sourceDir} for changes` + ); const watchedDirs = []; const watchedFiles = []; if (watchFile) { - if (fs.existsSync(watchFile) && !fs.lstatSync(watchFile).isFile()) { - throw new UsageError('Invalid --watch-file value: ' + - `"${watchFile}" is not a file.`); - } + for (const path of watchFile) { + if (fs.existsSync(path) && !fs.lstatSync(path).isFile()) { + throw new UsageError('Invalid --watch-file value: ' + + `"${path}" is not a file.`); + } - watchedFiles.push(watchFile); + watchedFiles.push(path); + } } else { watchedDirs.push(sourceDir); } diff --git a/tests/unit/test.program.js b/tests/unit/test.program.js index 1a89b958ef..1a7ca21e45 100644 --- a/tests/unit/test.program.js +++ b/tests/unit/test.program.js @@ -543,15 +543,13 @@ describe('program.main', () => { }); }); - it('calls run with a watched file', () => { - const watchFile = 'path/to/fake/file.txt'; - + async function testWatchFileOption(watchFile) { const fakeCommands = fake(commands, { run: () => Promise.resolve(), }); return execProgram( - ['run', '--watch-file', watchFile], + ['run', '--watch-file', ...watchFile], {commands: fakeCommands}) .then(() => { sinon.assert.calledWithMatch( @@ -559,6 +557,16 @@ describe('program.main', () => { {watchFile} ); }); + } + + it('calls run with a watched file', () => { + testWatchFileOption(['path/to/fake/file.txt']); + }); + + it('calls run with multiple watched files', () => { + testWatchFileOption( + ['path/to/fake/file.txt', 'path/to/fake/file2.txt'] + ); }); async function testWatchIgnoredOption(watchIgnored) { diff --git a/tests/unit/test.watcher.js b/tests/unit/test.watcher.js index 5e0016ff74..2b4a5c3530 100644 --- a/tests/unit/test.watcher.js +++ b/tests/unit/test.watcher.js @@ -13,7 +13,7 @@ import {withTempDir} from '../../src/util/temp-dir'; import { makeSureItFails } from './helpers'; type AssertWatchedParams = { - watchFile?: string, + watchFile?: Array, touchedFile: string, } @@ -28,7 +28,7 @@ describe('watcher', () => { const someFile = path.join(tmpDir.path(), touchedFile); if (watchFile) { - watchFile = path.join(tmpDir.path(), watchFile); + watchFile = watchFile.map((f) => path.join(tmpDir.path(), f)); } var resolveChange; @@ -116,7 +116,7 @@ describe('watcher', () => { watchedDirPath, tmpDirPath, } = await watchChange({ - watchFile: 'foo.txt', + watchFile: ['foo.txt'], touchedFile: 'foo.txt', }); @@ -132,7 +132,7 @@ describe('watcher', () => { watchedDirPath, tmpDirPath, } = await watchChange({ - watchFile: 'bar.txt', + watchFile: ['bar.txt'], touchedFile: 'foo.txt', }); @@ -143,7 +143,7 @@ describe('watcher', () => { it('throws error if a non-file is passed into --watch-file', () => { return watchChange({ - watchFile: '/', + watchFile: ['/'], touchedFile: 'foo.txt', }).then(makeSureItFails()).catch((error) => { assert.match(