From 11fcaaab9ce20168b5840c3174232bffd2b6ac5c Mon Sep 17 00:00:00 2001 From: Remy Sharp Date: Thu, 19 Sep 2024 11:42:24 +0100 Subject: [PATCH] fix: watch nested paths Fixes #2216 The file change is mostly prettier moving things about, slightly more debug but a `break` has been removed to resolve the issue. --- lib/monitor/match.js | 109 ++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/lib/monitor/match.js b/lib/monitor/match.js index 2ac3b291..11691d7d 100644 --- a/lib/monitor/match.js +++ b/lib/monitor/match.js @@ -31,9 +31,12 @@ function rulesToMonitor(watch, ignore, config) { } if (ignore) { - [].push.apply(monitor, (ignore || []).map(function (rule) { - return '!' + rule; - })); + [].push.apply( + monitor, + (ignore || []).map(function (rule) { + return '!' + rule; + }) + ); } var cwd = process.cwd(); @@ -87,16 +90,16 @@ function rulesToMonitor(watch, ignore, config) { // if the url ends with * but not **/* and not *.* // then convert to **/* - somehow it was missed :-\ - if (rule.slice(-4) !== '**/*' && + if ( + rule.slice(-4) !== '**/*' && rule.slice(-1) === '*' && - rule.indexOf('*.') === -1) { - + rule.indexOf('*.') === -1 + ) { if (rule.slice(-2) !== '**') { rule += '*/*'; } } - return (not ? '!' : '') + rule; }); @@ -105,7 +108,8 @@ function rulesToMonitor(watch, ignore, config) { function tryBaseDir(dir) { var stat; - if (/[?*\{\[]+/.test(dir)) { // if this is pattern, then try to find the base + if (/[?*\{\[]+/.test(dir)) { + // if this is pattern, then try to find the base try { var base = path.dirname(dir.replace(/([?*\{\[]+.*$)/, 'foo')); stat = fs.statSync(base); @@ -123,7 +127,7 @@ function tryBaseDir(dir) { if (stat.isFile() || stat.isDirectory()) { return dir; } - } catch (e) { } + } catch (e) {} } return false; @@ -133,50 +137,52 @@ function match(files, monitor, ext) { // sort the rules by highest specificity (based on number of slashes) // ignore rules (!) get sorted highest as they take precedent const cwd = process.cwd(); - var rules = monitor.sort(function (a, b) { - var r = b.split(path.sep).length - a.split(path.sep).length; - var aIsIgnore = a.slice(0, 1) === '!'; - var bIsIgnore = b.slice(0, 1) === '!'; - - if (aIsIgnore || bIsIgnore) { - if (aIsIgnore) { - return -1; + var rules = monitor + .sort(function (a, b) { + var r = b.split(path.sep).length - a.split(path.sep).length; + var aIsIgnore = a.slice(0, 1) === '!'; + var bIsIgnore = b.slice(0, 1) === '!'; + + if (aIsIgnore || bIsIgnore) { + if (aIsIgnore) { + return -1; + } + + return 1; } - return 1; - } + if (r === 0) { + return b.length - a.length; + } + return r; + }) + .map(function (s) { + var prefix = s.slice(0, 1); + + if (prefix === '!') { + if (s.indexOf('!' + cwd) === 0) { + return s; + } - if (r === 0) { - return b.length - a.length; - } - return r; - }).map(function (s) { - var prefix = s.slice(0, 1); + // if it starts with a period, then let's get the relative path + if (s.indexOf('!.') === 0) { + return '!' + path.resolve(cwd, s.substring(1)); + } - if (prefix === '!') { - if (s.indexOf('!' + cwd) === 0) { - return s; + return '!**' + (prefix !== path.sep ? path.sep : '') + s.slice(1); } // if it starts with a period, then let's get the relative path - if (s.indexOf('!.') === 0) { - return '!' + path.resolve(cwd, s.substring(1)); + if (s.indexOf('.') === 0) { + return path.resolve(cwd, s); } - return '!**' + (prefix !== path.sep ? path.sep : '') + s.slice(1); - } - - // if it starts with a period, then let's get the relative path - if (s.indexOf('.') === 0) { - return path.resolve(cwd, s); - } - - if (s.indexOf(cwd) === 0) { - return s; - } + if (s.indexOf(cwd) === 0) { + return s; + } - return '**' + (prefix !== path.sep ? path.sep : '') + s; - }); + return '**' + (prefix !== path.sep ? path.sep : '') + s; + }); debug('rules', rules); @@ -221,8 +227,10 @@ function match(files, monitor, ext) { // but *does* match a rule that ends with *.*, then // white list it - in that we don't run it through // the extension check too. - if (rules[i] !== '**' + path.sep + '*.*' && - rules[i].slice(-3) === '*.*') { + if ( + rules[i] !== '**' + path.sep + '*.*' && + rules[i].slice(-3) === '*.*' + ) { whitelist.push(file); } else if (path.basename(file) === path.basename(rules[i])) { // if the file matches the actual rule, then it's put on whitelist @@ -231,7 +239,6 @@ function match(files, monitor, ext) { good.push(file); } matched = true; - break; } else { // utils.log.detail('no match: ' + rules[i], file); } @@ -242,8 +249,6 @@ function match(files, monitor, ext) { } }); - debug('good', good) - // finally check the good files against the extensions that we're monitoring if (ext) { if (ext.indexOf(',') === -1) { @@ -256,7 +261,13 @@ function match(files, monitor, ext) { // only compare the filename to the extension test return minimatch(path.basename(file), ext, minimatchOpts); }); - } // else assume *.* + debug('good (filtered by ext)', good); + } else { + // else assume *.* + debug('good', good); + } + + if (whitelist.length) debug('whitelist', whitelist); var result = good.concat(whitelist);