From a31dec990a40987187cbe6b82678a6a057f81a83 Mon Sep 17 00:00:00 2001 From: Max Holman Date: Thu, 14 Apr 2022 22:52:55 +0800 Subject: [PATCH] chore: general watching and logging fixes --- .eslintignore | 1 + bin/index.ts | 23 ++++++++++++++--- lib/config.ts | 49 +++++++++++++++++++++++++----------- lib/watcher.ts | 30 +++++++++++----------- package.json | 4 +-- prettier.config.cjs | 2 +- yarn.lock | 61 +++++++++++++++++++++++++-------------------- 7 files changed, 107 insertions(+), 63 deletions(-) diff --git a/.eslintignore b/.eslintignore index de4d1f0..998d4d7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ dist node_modules +bazel-out diff --git a/bin/index.ts b/bin/index.ts index 1ebc13c..5702eae 100644 --- a/bin/index.ts +++ b/bin/index.ts @@ -1,6 +1,7 @@ #!/usr/bin/env node import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; +import { Level } from '@block65/logger'; import { resolveConfig, InternalConfig } from '../lib/config.js'; import { startProcess } from '../lib/process.js'; import { debounce } from '../lib/utils.js'; @@ -8,7 +9,11 @@ import { startWatcher } from '../lib/watcher.js'; import { logger } from '../lib/logger.js'; async function start(config: InternalConfig) { - logger.trace(config); + if (config.verbose) { + logger.setLevel(Level.Trace); + } else if (config.quiet) { + logger.setLevel(Level.Warn); + } let [watcher, controller] = await Promise.all([ startWatcher(config), @@ -18,7 +23,7 @@ async function start(config: InternalConfig) { watcher.on( 'all', debounce(async (eventName) => { - if (['add', 'change', 'unlink'].includes(eventName)) { + if (['add', 'change', 'delete'].includes(eventName)) { controller?.abort(); controller = await startProcess(config); } @@ -41,6 +46,16 @@ const cliArgs = yargs(hideBin(process.argv)) type: 'string', description: 'Command to run', }) + .option('verbose', { + alias: 'v', + type: 'boolean', + description: 'Verbose logging (full debug output)', + }) + .option('quiet', { + alias: 'q', + type: 'boolean', + description: 'Quiet logging (warnings and errors only)', + }) .option('watch', { alias: 'w', type: 'string', @@ -71,8 +86,8 @@ resolveConfig({ command: cliArgs.command, signal: cliArgs.signal, watch: cliArgs.watch, - // verbose: cliArgs.verbose, - // globs: argv.globs, + verbose: cliArgs.verbose, + quiet: cliArgs.quiet, }) .then((config) => start(config)) .catch((err) => logger.error(err)); diff --git a/lib/config.ts b/lib/config.ts index 35a3a61..254b577 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -15,6 +15,8 @@ export interface InternalConfig { workingDirectory: string; signal: NodeJS.Signals; delay: number; + quiet?: boolean; + verbose?: boolean; } export interface CliConfig { @@ -23,7 +25,8 @@ export interface CliConfig { signal?: NodeJS.Signals; watch?: string[]; ignore?: string[]; - // verbose?: boolean; + quiet?: boolean; + verbose?: boolean; delay?: number; } @@ -33,7 +36,8 @@ export interface Config { watch?: string[]; ignore?: (string | RegExp | ((path: string) => boolean))[]; signal?: NodeJS.Signals; - // verbose?: boolean; + quiet?: boolean; + verbose?: boolean; delay?: number; } @@ -41,10 +45,19 @@ class ConfigError extends CustomError { public code = Status.INVALID_ARGUMENT; } +function loadEsm(specifier: string) { + return import(specifier); +} + export async function resolveConfig( cliConfig: CliConfig, ): Promise { - const configResult = await lilconfig('demonade').search(); + const configResult = await lilconfig('demonade', { + loaders: { + '.js': loadEsm, + '.mjs': loadEsm, + }, + }).search(); if ( !cliConfig.command && @@ -69,16 +82,22 @@ export async function resolveConfig( : packageDir; const watch = [ - ...new Set( - configResult?.config?.watch || cliConfig?.watch || [workingDirectory], - ), + ...new Set([ + ...(configResult?.config?.watch || []), + ...(cliConfig?.watch || []), + ...(!configResult?.config?.watch && cliConfig?.watch + ? [workingDirectory] + : []), + ]), ] - .map((p) => relative(workingDirectory, p) || '.') + .map((p) => relative(workingDirectory, p)) .filter(Boolean); const configIgnore: (string | RegExp | ((path: string) => boolean))[] = [ - ...(configResult?.config?.ignore || []), - ...(cliConfig?.ignore || []), + ...new Set([ + ...(configResult?.config?.ignore || []), + ...(cliConfig?.ignore || []), + ]), ].filter(Boolean); const defaultIgnore = [/(^|[/\\])\../, '**/node_modules/**']; @@ -86,14 +105,16 @@ export async function resolveConfig( const ignore = configIgnore.length > 0 ? configIgnore : defaultIgnore; const resolved: InternalConfig = { - command: - configResult?.config?.command || cliConfig?.command || process.execPath, - args: configResult?.config?.args || cliConfig?.args || [], - signal: configResult?.config?.signal || cliConfig?.signal || 'SIGUSR2', - delay: configResult?.config?.delay || cliConfig?.delay || 200, workingDirectory, watch, ignore, + command: + cliConfig?.command || configResult?.config?.command || process.execPath, + args: cliConfig?.args || configResult?.config?.args || [], + signal: cliConfig?.signal || configResult?.config?.signal || 'SIGUSR2', + delay: cliConfig?.delay || configResult?.config?.delay || 200, + quiet: cliConfig?.quiet || configResult?.config?.quiet, + verbose: cliConfig?.verbose || configResult?.config?.verbose, }; logger.trace( diff --git a/lib/watcher.ts b/lib/watcher.ts index d516abd..3569f2a 100644 --- a/lib/watcher.ts +++ b/lib/watcher.ts @@ -3,12 +3,10 @@ import { logger } from './logger.js'; import { InternalConfig } from './config.js'; export async function startWatcher(config: InternalConfig): Promise { - const paths = config.watch; - logger.info( - { paths }, + config.watch, 'Watching %s paths from %s', - paths.length, + config.watch.length, config.workingDirectory, ); @@ -16,27 +14,29 @@ export async function startWatcher(config: InternalConfig): Promise { cwd: config.workingDirectory, ignored: config.ignore, ignorePermissionErrors: true, + ignoreInitial: true, // we dont even resolve until ready fires }); return new Promise((resolve, reject) => { watcher.on('ready', () => { const watched = watcher.getWatched(); - const dirs = Object.keys(watched); - const files = Object.values(watched).flatMap((f) => f); + const paths = Object.values(watched).flatMap((f) => f); - logger.info( - 'Watching %d files and %d directories', - files.length, - dirs.length, - ); + logger.info('Watching %d paths', paths.length); - logger.trace({ files, dirs }, 'watched'), resolve(watcher); + resolve(watcher); }); - watcher.on('raw', (event, path, details) => - logger.trace({ details }, 'watcher: %s for %s', event, path), - ); + // watcher.on('raw', (event, path, details) => + // + // ); + + watcher.on('all', (eventName, path) => { + if (['add', 'change', 'delete'].includes(eventName)) { + logger.trace('watcher: %s for %s', eventName, path); + } + }); watcher.on('error', reject); }); diff --git a/package.json b/package.json index 741f113..a2ff3d7 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "dependencies": { "@block65/custom-error": "^8.0.0", - "@block65/logger": "^12.0.0-rc.13", + "@block65/logger": "^12.0.0-rc.14", "chokidar": "^3.5.3", "find-up": "^6.3.0", "lilconfig": "^2.0.5", @@ -63,4 +63,4 @@ "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } -} +} \ No newline at end of file diff --git a/prettier.config.cjs b/prettier.config.cjs index b433e0a..b6b590f 100644 --- a/prettier.config.cjs +++ b/prettier.config.cjs @@ -1 +1 @@ -module.exports = require("@block65/eslint-config/prettier.config.js"); +module.exports = require('@block65/eslint-config/prettier.config.js'); diff --git a/yarn.lock b/yarn.lock index cc6276f..3dc51d1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -333,10 +333,10 @@ eslint-config-prettier "^8.3.0" eslint-import-resolver-node "^0.3.6" -"@block65/logger@^12.0.0-rc.13": - version "12.0.0-rc.13" - resolved "https://registry.yarnpkg.com/@block65/logger/-/logger-12.0.0-rc.13.tgz#8e414e30fddc434f2379d5763eae1816709c20ab" - integrity sha512-DyweZ1NTbba3X0PLsdhFYg2X/09kEZ9dweFbfsgbhE7U+3PEgh6sn9ZFZlR6u3M+jPt/C4sETmuvM+O1E56v0g== +"@block65/logger@^12.0.0-rc.14": + version "12.0.0-rc.14" + resolved "https://registry.yarnpkg.com/@block65/logger/-/logger-12.0.0-rc.14.tgz#80574555e34e50bd233b606c85dd969230fbbbd5" + integrity sha512-PCHg1sCFWZocXVCeba6fZRhAMruTazi9VS4t93gBBwq7ox9XSagbxb+Q8KaoE7Qu07Ds5sefv0q+c1yb+fEKTg== dependencies: "@types/aws-lambda" "^8.10.93" "@types/express" "^4.17.13" @@ -737,9 +737,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.14.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.14.2.tgz#ffcd470bbb3f8bf30481678fb5502278ca833a43" - integrity sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.17.0.tgz#7a9b80f712fe2052bc20da153ff1e552404d8e4b" + integrity sha512-r8aveDbd+rzGP+ykSdF3oPuTVRWRfbBiHl0rVDM2yNEmSMXfkObQLV46b4RnCv3Lra51OlfnZhkkFaDl2MIRaA== dependencies: "@babel/types" "^7.3.0" @@ -829,9 +829,9 @@ integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== "@types/node@*": - version "17.0.23" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.23.tgz#3b41a6e643589ac6442bdbd7a4a3ded62f33f7da" - integrity sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw== + version "17.0.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.24.tgz#20ba1bf69c1b4ab405c7a01e950c4f446b05029f" + integrity sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g== "@types/node@^10.1.0": version "10.17.60" @@ -839,9 +839,9 @@ integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== "@types/node@^16": - version "16.11.26" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.26.tgz#63d204d136c9916fb4dcd1b50f9740fe86884e47" - integrity sha512-GZ7bu5A6+4DtG7q9GsoHXy3ALcgeIHP4NnL0Vv2wu0uUB/yQex26v0tf6/na1mm0+bS9Uw+0DFex7aaKr2qawQ== + version "16.11.27" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.27.tgz#5da19383bdbeda99bc0d09cfbb88cab7297ebc51" + integrity sha512-C1pD3kgLoZ56Uuy5lhfOxie4aZlA3UMGLX9rXteq4WitEZH6Rl80mwactt9QG0w0gLFlN/kLBTFnGXtDVWvWQw== "@types/prettier@^2.1.5": version "2.6.0" @@ -1243,9 +1243,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001317: - version "1.0.30001328" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001328.tgz#0ed7a2ca65ec45872c613630201644237ba1e329" - integrity sha512-Ue55jHkR/s4r00FLNiX+hGMMuwml/QGqqzVeMQ5thUewznU2EdULFvI3JR7JJid6OrjJNfFvHY2G2dIjmRaDDQ== + version "1.0.30001332" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001332.tgz#39476d3aa8d83ea76359c70302eafdd4a1d727dd" + integrity sha512-10T30NYOEQtN6C11YGg411yebhvpnC6Z102+B95eAsN0oB6KUs01ivE8u+G6FMIRtIrVlYXhL+LUwQ3/hXwDWw== chalk@^2.0.0: version "2.4.2" @@ -1530,9 +1530,9 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.19.1, es-abstract@^1.19.2: - version "1.19.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.3.tgz#4dd9da55868192756c83c5c30c7878d04e77125d" - integrity sha512-4axXLNovnMYf0+csS5rVnS5hLmV1ek+ecx9MuCjByL1E5Nn54avf6CHQxIjgQIHBnfX9AMxTRIy0q+Yu5J/fXA== + version "1.19.5" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.5.tgz#a2cb01eb87f724e815b278b0dd0d00f36ca9a7f1" + integrity sha512-Aa2G2+Rd3b6kxEUKTF4TaW67czBLyAv3z7VOhYRU50YBx+bbsYZ9xQP4lMNazePuFlybXI0V4MruPos7qUo5fA== dependencies: call-bind "^1.0.2" es-to-primitive "^1.2.1" @@ -2909,10 +2909,12 @@ long@^4.0.0: resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== -lru-cache@^7.4.0: - version "7.8.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.8.1.tgz#68ee3f4807a57d2ba185b7fd90827d5c21ce82bb" - integrity sha512-E1v547OCgJvbvevfjgK9sNKIVXO96NnsTsFPBlg4ZxjhsJSODoH9lk8Bm0OxvHNm6Vm5Yqkl/1fErDxhYL8Skg== +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" make-dir@^3.0.0: version "3.1.0" @@ -3412,11 +3414,11 @@ semver@^6.0.0, semver@^6.3.0: integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== semver@^7.3.2, semver@^7.3.5: - version "7.3.6" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.6.tgz#5d73886fb9c0c6602e79440b97165c29581cbb2b" - integrity sha512-HZWqcgwLsjaX1HBD31msI/rXktuIhS+lWvdE4kN9z+8IVT4Itc7vqU2WvYsyD6/sjYCt4dEKH/m1M3dwI9CC5w== + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: - lru-cache "^7.4.0" + lru-cache "^6.0.0" serialize-error@^9.1.1: version "9.1.1" @@ -3915,6 +3917,11 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"