git-watchtower 1.14.15 → 1.14.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -104,6 +104,7 @@ const { WebDashboardServer } = require('../src/server/web');
104
104
  const { Coordinator, Worker, generateProjectId, getActiveCoordinator, tryAcquireLock, finalizeLock, removeLock, removeSocket, isProcessAlive } = require('../src/server/coordinator');
105
105
  const monitorLock = require('../src/utils/monitor-lock');
106
106
  const { createPipeErrorHandler } = require('../src/utils/pipe-error');
107
+ const { getRecursiveWatchSupport } = require('../src/utils/fs-watch');
107
108
 
108
109
  const PROJECT_ROOT = process.cwd();
109
110
 
@@ -2290,6 +2291,21 @@ function setupFileWatcher() {
2290
2291
  addLog(`Loaded ${ignorePatterns.length} ignore patterns from .gitignore`, 'info');
2291
2292
  }
2292
2293
 
2294
+ // Before calling fs.watch, surface any known incompatibility explicitly —
2295
+ // the generic catch below would otherwise report a confusing
2296
+ // "Could not set up file watcher: ..." for the well-known case of a
2297
+ // forced install on Node <20 Linux, where recursive watching is
2298
+ // unreliable. A clear message points the user at the real fix
2299
+ // (upgrade Node) instead of making them debug a live-reload that
2300
+ // appears to work but silently ignores subdirectory edits.
2301
+ const support = getRecursiveWatchSupport();
2302
+ if (!support.supported) {
2303
+ addLog(
2304
+ `Live reload may miss nested file changes: ${support.reason}`,
2305
+ 'error',
2306
+ );
2307
+ }
2308
+
2293
2309
  try {
2294
2310
  fileWatcher = fs.watch(STATIC_DIR, { recursive: true }, (eventType, filename) => {
2295
2311
  if (!filename) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "git-watchtower",
3
- "version": "1.14.15",
3
+ "version": "1.14.16",
4
4
  "description": "Terminal-based Git branch monitor with activity sparklines and optional dev server with live reload",
5
5
  "main": "bin/git-watchtower.js",
6
6
  "bin": {
@@ -0,0 +1,84 @@
1
+ /**
2
+ * fs.watch recursive-option support detection.
3
+ *
4
+ * `fs.watch(..., { recursive: true })` was not reliable on Linux before
5
+ * Node 20 — depending on the point release it either threw
6
+ * ERR_FEATURE_UNAVAILABLE_ON_PLATFORM or silently ignored the flag and
7
+ * watched only the top-level directory, leaving subdirectory changes
8
+ * undetected. macOS and Windows have supported recursive watching for
9
+ * much longer.
10
+ *
11
+ * git-watchtower declares engines.node >=20 in package.json, but users
12
+ * can bypass that with `npm install --force`. When they do, the static-
13
+ * server live-reload watcher needs to warn clearly rather than appear
14
+ * to work but silently miss edits in nested directories.
15
+ *
16
+ * @module utils/fs-watch
17
+ */
18
+
19
+ 'use strict';
20
+
21
+ /**
22
+ * Parse `process.version` ("v20.11.1") into a numeric major version.
23
+ * Exported so tests can drive edge cases (malformed strings, pre-releases).
24
+ *
25
+ * @param {string} versionString
26
+ * @returns {number} major version, or NaN if unparseable
27
+ */
28
+ function parseMajor(versionString) {
29
+ if (typeof versionString !== 'string') return NaN;
30
+ const match = /^v?(\d+)\./.exec(versionString);
31
+ if (!match) return NaN;
32
+ return parseInt(match[1], 10);
33
+ }
34
+
35
+ /**
36
+ * Decide whether fs.watch recursive mode is reliably supported on the
37
+ * current Node/platform combination.
38
+ *
39
+ * @param {Object} [env] - Injected for tests.
40
+ * @param {string} [env.version] - e.g. process.version
41
+ * @param {string} [env.platform] - e.g. process.platform
42
+ * @returns {{ supported: boolean, reason: string | null }}
43
+ * reason is a short, user-facing explanation when !supported.
44
+ */
45
+ function getRecursiveWatchSupport(env = {}) {
46
+ const version = env.version !== undefined ? env.version : process.version;
47
+ const platform = env.platform !== undefined ? env.platform : process.platform;
48
+
49
+ // macOS and Windows have supported recursive watching since well before
50
+ // any Node version we care about.
51
+ if (platform === 'darwin' || platform === 'win32') {
52
+ return { supported: true, reason: null };
53
+ }
54
+
55
+ if (platform === 'linux') {
56
+ const major = parseMajor(version);
57
+ if (Number.isNaN(major)) {
58
+ return {
59
+ supported: false,
60
+ reason: `could not parse Node version "${version}"`,
61
+ };
62
+ }
63
+ if (major < 20) {
64
+ return {
65
+ supported: false,
66
+ reason:
67
+ `Node ${version} on Linux does not reliably support fs.watch({ recursive: true }); ` +
68
+ 'upgrade to Node >=20 (see package.json engines).',
69
+ };
70
+ }
71
+ return { supported: true, reason: null };
72
+ }
73
+
74
+ // Unknown platform (AIX, FreeBSD, etc.). Don't claim support we can't verify.
75
+ return {
76
+ supported: false,
77
+ reason: `recursive fs.watch support is not verified on platform "${platform}"`,
78
+ };
79
+ }
80
+
81
+ module.exports = {
82
+ parseMajor,
83
+ getRecursiveWatchSupport,
84
+ };