const path = require('path'); const fs = require('fs-extra'); const chokidar = require('chokidar'); const multimatch = require('multimatch'); const { exec } = require('child_process'); const { dirs, jsFiles, scssFiles, ignoreMask, copyDirs, symlinkFiles } = require('./config'); const { envCheckTrue, onSuccess, onError, getSignatures, writeSignatures, cleanUp, formatDirsForMatcher } = require('./utils'); const getJS = require('./js'); const getSass = require('./sass'); const getCopy = require('./copy'); const getSymlinks = require('./symlinks'); const ROOT = path.resolve(__dirname, '..'); const addOmniExecPath = path.join(ROOT, '..', 'zotero-standalone-build', 'scripts', 'add_omni_file'); let shouldAddOmni = false; const source = [ 'chrome', 'components', 'defaults', 'resource', 'scss', 'test', 'styles', 'translators', 'scss', 'chrome/**', 'components/**', 'defaults/**', 'resource/**', 'scss/**', 'test/**', 'styles/**', 'translators/**', 'scss/**' ]; const symlinks = symlinkFiles .concat(dirs.map(d => `${d}/**`)) .concat([`!${formatDirsForMatcher(dirs)}/**/*.js`]) .concat([`!${formatDirsForMatcher(dirs)}/**/*.jsx`]) .concat([`!${formatDirsForMatcher(dirs)}/**/*.scss`]) .concat([`!${formatDirsForMatcher(copyDirs)}/**`]); var signatures; process.on('SIGINT', () => { writeSignatures(signatures); process.exit(); }); async function addOmniFiles(relPaths) { const t1 = Date.now(); const buildDirPath = path.join(ROOT, 'build'); const wrappedPaths = relPaths.map(relPath => `"${path.relative(buildDirPath, relPath)}"`); await new Promise((resolve, reject) => { const cmd = `"${addOmniExecPath}" ${wrappedPaths.join(' ')}`; exec(cmd, { cwd: buildDirPath }, (error, output) => { if (error) { reject(error); } else { process.env.NODE_ENV === 'debug' && console.log(`Executed:\n${cmd};\nOutput:\n${output}\n`); resolve(output); } }); }); const t2 = Date.now(); return { action: 'add-omni-files', count: relPaths.length, totalCount: relPaths.length, processingTime: t2 - t1 }; } async function getWatch() { try { await fs.access(addOmniExecPath, fs.constants.F_OK); shouldAddOmni = !envCheckTrue(process.env.SKIP_OMNI); } catch (_) {} let watcher = chokidar.watch(source, { cwd: ROOT }) .on('change', async (path) => { try { var result = false; if (multimatch(path, jsFiles).length && !multimatch(path, ignoreMask).length) { result = await getJS(path, { ignore: ignoreMask }, signatures); onSuccess(await cleanUp(signatures)); } if (!result) { for (var i = 0; i < scssFiles.length; i++) { if (multimatch(path, scssFiles[i]).length) { result = await getSass(scssFiles[i], { ignore: ignoreMask }); // eslint-disable-line no-await-in-loop break; } } } if (!result && multimatch(path, copyDirs.map(d => `${d}/**`)).length) { result = await getCopy(path, {}, signatures); } if (!result && multimatch(path, symlinks).length) { result = await getSymlinks(path, { nodir: true }, signatures); } onSuccess(result); onSuccess(await cleanUp(signatures)); if (shouldAddOmni && result.outFiles?.length) { onSuccess(await addOmniFiles(result.outFiles)); } } catch (err) { onError(err); } }) .on('unlink', async () => { const signatures = await getSignatures(); onSuccess(await cleanUp(signatures)); }); watcher.add(source); console.log(`Watching files for changes (omni updates ${shouldAddOmni ? 'enabled' : 'disabled'})...`); } module.exports = getWatch; if (require.main === module) { (async () => { signatures = await getSignatures(); getWatch(); })(); }