-
Notifications
You must be signed in to change notification settings - Fork 542
/
watchHandler.ts
123 lines (113 loc) · 3.19 KB
/
watchHandler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import {
getOutfilePath,
logError,
logInfo,
validateDirPath,
validateFilePath,
validateOutfileName,
NpmSnapFileNames,
} from '@metamask/snaps-utils';
import chokidar from 'chokidar';
import pathUtils from 'path';
import { YargsArgs } from '../../types/yargs';
import { CONFIG_FILE, loadConfig } from '../../utils';
import { bundle } from '../build/bundle';
import { evalHandler } from '../eval/evalHandler';
import { manifestHandler } from '../manifest/manifestHandler';
import { serve } from '../serve/serveHandler';
/**
* Watch a directory and its subdirectories for changes, and build when files
* are added or changed.
*
* Ignores 'node_modules' and dotfiles.
* Creates destination directory if it doesn't exist.
*
* @param argv - Arguments as an object generated by Yargs.
* @param argv.src - The source file path.
* @param argv.dist - The output directory path.
* @param argv.'outfileName' - The output file name.
*/
export async function watch(argv: YargsArgs): Promise<void> {
const {
dist,
eval: shouldEval,
manifest,
outfileName,
src,
serve: shouldServe,
} = argv;
if (outfileName) {
validateOutfileName(outfileName);
}
await validateFilePath(src);
await validateDirPath(dist, true);
const srcDir = pathUtils.dirname(src);
const watchDirs = [srcDir, NpmSnapFileNames.Manifest, CONFIG_FILE];
const outfilePath = getOutfilePath(dist, outfileName);
const buildSnap = async (path?: string, logMessage?: string) => {
if (logMessage !== undefined) {
logInfo(logMessage);
}
try {
await bundle(src, outfilePath, argv, loadConfig().bundlerCustomizer);
if (manifest) {
await manifestHandler(argv);
}
if (shouldEval) {
await evalHandler({ ...argv, bundle: outfilePath });
}
} catch (error) {
logError(
`Error ${
path === undefined
? 'during initial build'
: `while processing "${path}"`
}.`,
error,
);
}
};
chokidar
.watch(watchDirs, {
ignoreInitial: true,
ignored: [
'**/node_modules/**',
`**/${dist}/**`,
`**/test/**`,
`**/tests/**`,
`**/*.test.js`,
`**/*.test.ts`,
/* istanbul ignore next */
(str: string) => str !== '.' && str.startsWith('.'),
],
})
.on('ready', () => {
buildSnap()
.then(async () => {
if (shouldServe) {
return serve(argv);
}
return undefined;
})
.catch((error) => {
logError('Error during initial build.', error);
});
})
.on('add', (path) => {
buildSnap(path, `File added: ${path}`).catch((error) => {
logError(`Error while processing "${path}".`, error);
});
})
.on('change', (path) => {
buildSnap(path, `File changed: ${path}`).catch((error) => {
logError(`Error while processing "${path}".`, error);
});
})
.on('unlink', (path) => logInfo(`File removed: ${path}`))
.on('error', (error: Error) => {
logError(`Watcher error: ${error.message}`, error);
});
logInfo(
`Watching ${watchDirs.map((dir) => `'${dir}'`).join(', ')} for changes...`,
);
}