permachine 0.4.0 → 0.4.1
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.
- package/dist/cli.js +199 -320
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -6376,148 +6376,12 @@ async function performAllMerges(operations) {
|
|
|
6376
6376
|
return results;
|
|
6377
6377
|
}
|
|
6378
6378
|
|
|
6379
|
-
// src/core/
|
|
6379
|
+
// src/core/gitignore-manager.ts
|
|
6380
6380
|
import fs2 from "node:fs/promises";
|
|
6381
6381
|
import path5 from "node:path";
|
|
6382
6382
|
import { exec } from "node:child_process";
|
|
6383
6383
|
import { promisify } from "node:util";
|
|
6384
|
-
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
6385
6384
|
var execAsync = promisify(exec);
|
|
6386
|
-
var __filename2 = fileURLToPath3(import.meta.url);
|
|
6387
|
-
var __dirname2 = path5.dirname(__filename2);
|
|
6388
|
-
var HOOK_NAMES = ["post-checkout", "post-merge", "post-commit"];
|
|
6389
|
-
var HOOKS_DIR = ".permachine/hooks";
|
|
6390
|
-
async function installHooks(options = {}) {
|
|
6391
|
-
const warnings = [];
|
|
6392
|
-
if (!await isGitRepository()) {
|
|
6393
|
-
throw new Error('Not a git repository. Run "git init" first.');
|
|
6394
|
-
}
|
|
6395
|
-
const cwd = process.cwd();
|
|
6396
|
-
const existingHooksPath = await getGitConfig("core.hooksPath");
|
|
6397
|
-
if (existingHooksPath && existingHooksPath !== HOOKS_DIR && !options.legacy) {
|
|
6398
|
-
warnings.push(`Git core.hooksPath is already set to: ${existingHooksPath}`, "Use --legacy flag to install hooks in .git/hooks instead");
|
|
6399
|
-
}
|
|
6400
|
-
const useLegacy = options.legacy || existingHooksPath && existingHooksPath !== HOOKS_DIR;
|
|
6401
|
-
if (useLegacy) {
|
|
6402
|
-
return await installLegacyHooks(warnings);
|
|
6403
|
-
} else {
|
|
6404
|
-
return await installHooksPathMethod(warnings);
|
|
6405
|
-
}
|
|
6406
|
-
}
|
|
6407
|
-
async function installHooksPathMethod(warnings) {
|
|
6408
|
-
const cwd = process.cwd();
|
|
6409
|
-
const hooksDir = path5.join(cwd, HOOKS_DIR);
|
|
6410
|
-
await fs2.mkdir(hooksDir, { recursive: true });
|
|
6411
|
-
let templatesDir = path5.join(__dirname2, "../../templates/hooks");
|
|
6412
|
-
if (!await fileExists2(path5.join(templatesDir, "post-checkout"))) {
|
|
6413
|
-
templatesDir = path5.join(__dirname2, "../templates/hooks");
|
|
6414
|
-
}
|
|
6415
|
-
const installedHooks = [];
|
|
6416
|
-
for (const hookName of HOOK_NAMES) {
|
|
6417
|
-
const templatePath = path5.join(templatesDir, hookName);
|
|
6418
|
-
const hookPath = path5.join(hooksDir, hookName);
|
|
6419
|
-
const content = await fs2.readFile(templatePath, "utf-8");
|
|
6420
|
-
await fs2.writeFile(hookPath, content, { mode: 493 });
|
|
6421
|
-
installedHooks.push(hookName);
|
|
6422
|
-
}
|
|
6423
|
-
await setGitConfig("core.hooksPath", HOOKS_DIR);
|
|
6424
|
-
logger.success(`Installed git hooks via core.hooksPath`);
|
|
6425
|
-
return {
|
|
6426
|
-
method: "hooksPath",
|
|
6427
|
-
hooksInstalled: installedHooks,
|
|
6428
|
-
warnings
|
|
6429
|
-
};
|
|
6430
|
-
}
|
|
6431
|
-
async function installLegacyHooks(warnings) {
|
|
6432
|
-
const cwd = process.cwd();
|
|
6433
|
-
const gitHooksDir = path5.join(cwd, ".git/hooks");
|
|
6434
|
-
const installedHooks = [];
|
|
6435
|
-
for (const hookName of HOOK_NAMES) {
|
|
6436
|
-
const hookPath = path5.join(gitHooksDir, hookName);
|
|
6437
|
-
const backupPath = path5.join(gitHooksDir, `${hookName}.pre-mcs`);
|
|
6438
|
-
const hookExists = await fileExists2(hookPath);
|
|
6439
|
-
if (hookExists) {
|
|
6440
|
-
await fs2.rename(hookPath, backupPath);
|
|
6441
|
-
}
|
|
6442
|
-
const hookContent = `#!/bin/sh
|
|
6443
|
-
# Auto-generated by permachine (legacy mode)
|
|
6444
|
-
|
|
6445
|
-
permachine merge --silent
|
|
6446
|
-
|
|
6447
|
-
# Call original hook if it existed
|
|
6448
|
-
if [ -f "${backupPath}" ]; then
|
|
6449
|
-
"${backupPath}" "$@"
|
|
6450
|
-
fi
|
|
6451
|
-
|
|
6452
|
-
exit 0
|
|
6453
|
-
`;
|
|
6454
|
-
await fs2.writeFile(hookPath, hookContent, { mode: 493 });
|
|
6455
|
-
installedHooks.push(hookName);
|
|
6456
|
-
}
|
|
6457
|
-
logger.success("Installed git hooks via legacy .git/hooks wrapping");
|
|
6458
|
-
return {
|
|
6459
|
-
method: "legacy",
|
|
6460
|
-
hooksInstalled: installedHooks,
|
|
6461
|
-
warnings
|
|
6462
|
-
};
|
|
6463
|
-
}
|
|
6464
|
-
async function uninstallHooks() {
|
|
6465
|
-
const cwd = process.cwd();
|
|
6466
|
-
const hooksPath = await getGitConfig("core.hooksPath");
|
|
6467
|
-
if (hooksPath === HOOKS_DIR) {
|
|
6468
|
-
await execAsync("git config --unset core.hooksPath");
|
|
6469
|
-
const hooksDir = path5.join(cwd, HOOKS_DIR);
|
|
6470
|
-
await fs2.rm(hooksDir, { recursive: true, force: true });
|
|
6471
|
-
logger.success("Uninstalled git hooks (removed core.hooksPath)");
|
|
6472
|
-
} else {
|
|
6473
|
-
const gitHooksDir = path5.join(cwd, ".git/hooks");
|
|
6474
|
-
for (const hookName of HOOK_NAMES) {
|
|
6475
|
-
const hookPath = path5.join(gitHooksDir, hookName);
|
|
6476
|
-
const backupPath = path5.join(gitHooksDir, `${hookName}.pre-mcs`);
|
|
6477
|
-
if (await fileExists2(hookPath)) {
|
|
6478
|
-
await fs2.unlink(hookPath);
|
|
6479
|
-
}
|
|
6480
|
-
if (await fileExists2(backupPath)) {
|
|
6481
|
-
await fs2.rename(backupPath, hookPath);
|
|
6482
|
-
}
|
|
6483
|
-
}
|
|
6484
|
-
logger.success("Uninstalled git hooks (restored original hooks)");
|
|
6485
|
-
}
|
|
6486
|
-
}
|
|
6487
|
-
async function isGitRepository() {
|
|
6488
|
-
try {
|
|
6489
|
-
await execAsync("git rev-parse --git-dir");
|
|
6490
|
-
return true;
|
|
6491
|
-
} catch {
|
|
6492
|
-
return false;
|
|
6493
|
-
}
|
|
6494
|
-
}
|
|
6495
|
-
async function getGitConfig(key) {
|
|
6496
|
-
try {
|
|
6497
|
-
const { stdout } = await execAsync(`git config --get ${key}`);
|
|
6498
|
-
return stdout.trim() || null;
|
|
6499
|
-
} catch {
|
|
6500
|
-
return null;
|
|
6501
|
-
}
|
|
6502
|
-
}
|
|
6503
|
-
async function setGitConfig(key, value) {
|
|
6504
|
-
await execAsync(`git config ${key} "${value}"`);
|
|
6505
|
-
}
|
|
6506
|
-
async function fileExists2(filePath) {
|
|
6507
|
-
try {
|
|
6508
|
-
await fs2.access(filePath);
|
|
6509
|
-
return true;
|
|
6510
|
-
} catch {
|
|
6511
|
-
return false;
|
|
6512
|
-
}
|
|
6513
|
-
}
|
|
6514
|
-
|
|
6515
|
-
// src/core/gitignore-manager.ts
|
|
6516
|
-
import fs3 from "node:fs/promises";
|
|
6517
|
-
import path6 from "node:path";
|
|
6518
|
-
import { exec as exec2 } from "node:child_process";
|
|
6519
|
-
import { promisify as promisify2 } from "node:util";
|
|
6520
|
-
var execAsync2 = promisify2(exec2);
|
|
6521
6385
|
async function manageGitignore(outputPaths, options = {}) {
|
|
6522
6386
|
const result = {
|
|
6523
6387
|
added: [],
|
|
@@ -6528,13 +6392,13 @@ async function manageGitignore(outputPaths, options = {}) {
|
|
|
6528
6392
|
return result;
|
|
6529
6393
|
}
|
|
6530
6394
|
const cwd = options.cwd || process.cwd();
|
|
6531
|
-
const gitignorePath =
|
|
6395
|
+
const gitignorePath = path5.join(cwd, ".gitignore");
|
|
6532
6396
|
try {
|
|
6533
|
-
const relativePaths = outputPaths.map((p) =>
|
|
6397
|
+
const relativePaths = outputPaths.map((p) => path5.relative(cwd, p).replace(/\\/g, "/"));
|
|
6534
6398
|
let gitignoreContent = "";
|
|
6535
6399
|
let gitignoreExists = false;
|
|
6536
6400
|
try {
|
|
6537
|
-
gitignoreContent = await
|
|
6401
|
+
gitignoreContent = await fs2.readFile(gitignorePath, "utf-8");
|
|
6538
6402
|
gitignoreExists = true;
|
|
6539
6403
|
} catch (error) {
|
|
6540
6404
|
if (error.code !== "ENOENT") {
|
|
@@ -6561,7 +6425,7 @@ async function manageGitignore(outputPaths, options = {}) {
|
|
|
6561
6425
|
` : newEntries.join(`
|
|
6562
6426
|
`) + `
|
|
6563
6427
|
`;
|
|
6564
|
-
await
|
|
6428
|
+
await fs2.writeFile(gitignorePath, updatedContent, "utf-8");
|
|
6565
6429
|
if (!gitignoreExists) {
|
|
6566
6430
|
logger.info("Created .gitignore");
|
|
6567
6431
|
}
|
|
@@ -6570,7 +6434,7 @@ async function manageGitignore(outputPaths, options = {}) {
|
|
|
6570
6434
|
try {
|
|
6571
6435
|
const isTracked = await isFileTrackedByGit(relPath, cwd);
|
|
6572
6436
|
if (isTracked) {
|
|
6573
|
-
await
|
|
6437
|
+
await execAsync(`git rm --cached "${relPath}"`, { cwd });
|
|
6574
6438
|
result.removed.push(relPath);
|
|
6575
6439
|
logger.info(`Removed ${relPath} from git tracking`);
|
|
6576
6440
|
}
|
|
@@ -6587,7 +6451,7 @@ async function manageGitignore(outputPaths, options = {}) {
|
|
|
6587
6451
|
}
|
|
6588
6452
|
async function isFileTrackedByGit(filePath, cwd) {
|
|
6589
6453
|
try {
|
|
6590
|
-
await
|
|
6454
|
+
await execAsync(`git ls-files --error-unmatch "${filePath}"`, { cwd });
|
|
6591
6455
|
return true;
|
|
6592
6456
|
} catch {
|
|
6593
6457
|
return false;
|
|
@@ -6685,7 +6549,7 @@ class ReaddirpStream extends Readable {
|
|
|
6685
6549
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
6686
6550
|
const statMethod = opts.lstat ? lstat2 : stat;
|
|
6687
6551
|
if (wantBigintFsStats) {
|
|
6688
|
-
this._stat = (
|
|
6552
|
+
this._stat = (path6) => statMethod(path6, { bigint: true });
|
|
6689
6553
|
} else {
|
|
6690
6554
|
this._stat = statMethod;
|
|
6691
6555
|
}
|
|
@@ -6710,8 +6574,8 @@ class ReaddirpStream extends Readable {
|
|
|
6710
6574
|
const par = this.parent;
|
|
6711
6575
|
const fil = par && par.files;
|
|
6712
6576
|
if (fil && fil.length > 0) {
|
|
6713
|
-
const { path:
|
|
6714
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
6577
|
+
const { path: path6, depth } = par;
|
|
6578
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path6));
|
|
6715
6579
|
const awaited = await Promise.all(slice);
|
|
6716
6580
|
for (const entry of awaited) {
|
|
6717
6581
|
if (!entry)
|
|
@@ -6751,20 +6615,20 @@ class ReaddirpStream extends Readable {
|
|
|
6751
6615
|
this.reading = false;
|
|
6752
6616
|
}
|
|
6753
6617
|
}
|
|
6754
|
-
async _exploreDir(
|
|
6618
|
+
async _exploreDir(path6, depth) {
|
|
6755
6619
|
let files;
|
|
6756
6620
|
try {
|
|
6757
|
-
files = await readdir2(
|
|
6621
|
+
files = await readdir2(path6, this._rdOptions);
|
|
6758
6622
|
} catch (error) {
|
|
6759
6623
|
this._onError(error);
|
|
6760
6624
|
}
|
|
6761
|
-
return { files, depth, path:
|
|
6625
|
+
return { files, depth, path: path6 };
|
|
6762
6626
|
}
|
|
6763
|
-
async _formatEntry(dirent,
|
|
6627
|
+
async _formatEntry(dirent, path6) {
|
|
6764
6628
|
let entry;
|
|
6765
6629
|
const basename = this._isDirent ? dirent.name : dirent;
|
|
6766
6630
|
try {
|
|
6767
|
-
const fullPath = presolve(pjoin(
|
|
6631
|
+
const fullPath = presolve(pjoin(path6, basename));
|
|
6768
6632
|
entry = { path: prelative(this._root, fullPath), fullPath, basename };
|
|
6769
6633
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
6770
6634
|
} catch (err) {
|
|
@@ -7163,16 +7027,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
7163
7027
|
};
|
|
7164
7028
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
7165
7029
|
var FsWatchInstances = new Map;
|
|
7166
|
-
function createFsWatchInstance(
|
|
7030
|
+
function createFsWatchInstance(path6, options, listener, errHandler, emitRaw) {
|
|
7167
7031
|
const handleEvent = (rawEvent, evPath) => {
|
|
7168
|
-
listener(
|
|
7169
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
7170
|
-
if (evPath &&
|
|
7171
|
-
fsWatchBroadcast(sp.resolve(
|
|
7032
|
+
listener(path6);
|
|
7033
|
+
emitRaw(rawEvent, evPath, { watchedPath: path6 });
|
|
7034
|
+
if (evPath && path6 !== evPath) {
|
|
7035
|
+
fsWatchBroadcast(sp.resolve(path6, evPath), KEY_LISTENERS, sp.join(path6, evPath));
|
|
7172
7036
|
}
|
|
7173
7037
|
};
|
|
7174
7038
|
try {
|
|
7175
|
-
return fs_watch(
|
|
7039
|
+
return fs_watch(path6, {
|
|
7176
7040
|
persistent: options.persistent
|
|
7177
7041
|
}, handleEvent);
|
|
7178
7042
|
} catch (error) {
|
|
@@ -7188,12 +7052,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
7188
7052
|
listener(val1, val2, val3);
|
|
7189
7053
|
});
|
|
7190
7054
|
};
|
|
7191
|
-
var setFsWatchListener = (
|
|
7055
|
+
var setFsWatchListener = (path6, fullPath, options, handlers) => {
|
|
7192
7056
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
7193
7057
|
let cont = FsWatchInstances.get(fullPath);
|
|
7194
7058
|
let watcher;
|
|
7195
7059
|
if (!options.persistent) {
|
|
7196
|
-
watcher = createFsWatchInstance(
|
|
7060
|
+
watcher = createFsWatchInstance(path6, options, listener, errHandler, rawEmitter);
|
|
7197
7061
|
if (!watcher)
|
|
7198
7062
|
return;
|
|
7199
7063
|
return watcher.close.bind(watcher);
|
|
@@ -7203,7 +7067,7 @@ var setFsWatchListener = (path7, fullPath, options, handlers) => {
|
|
|
7203
7067
|
addAndConvert(cont, KEY_ERR, errHandler);
|
|
7204
7068
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
7205
7069
|
} else {
|
|
7206
|
-
watcher = createFsWatchInstance(
|
|
7070
|
+
watcher = createFsWatchInstance(path6, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
|
|
7207
7071
|
if (!watcher)
|
|
7208
7072
|
return;
|
|
7209
7073
|
watcher.on(EV.ERROR, async (error) => {
|
|
@@ -7212,7 +7076,7 @@ var setFsWatchListener = (path7, fullPath, options, handlers) => {
|
|
|
7212
7076
|
cont.watcherUnusable = true;
|
|
7213
7077
|
if (isWindows && error.code === "EPERM") {
|
|
7214
7078
|
try {
|
|
7215
|
-
const fd = await open(
|
|
7079
|
+
const fd = await open(path6, "r");
|
|
7216
7080
|
await fd.close();
|
|
7217
7081
|
broadcastErr(error);
|
|
7218
7082
|
} catch (err) {}
|
|
@@ -7242,7 +7106,7 @@ var setFsWatchListener = (path7, fullPath, options, handlers) => {
|
|
|
7242
7106
|
};
|
|
7243
7107
|
};
|
|
7244
7108
|
var FsWatchFileInstances = new Map;
|
|
7245
|
-
var setFsWatchFileListener = (
|
|
7109
|
+
var setFsWatchFileListener = (path6, fullPath, options, handlers) => {
|
|
7246
7110
|
const { listener, rawEmitter } = handlers;
|
|
7247
7111
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
7248
7112
|
const copts = cont && cont.options;
|
|
@@ -7264,7 +7128,7 @@ var setFsWatchFileListener = (path7, fullPath, options, handlers) => {
|
|
|
7264
7128
|
});
|
|
7265
7129
|
const currmtime = curr.mtimeMs;
|
|
7266
7130
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
7267
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
7131
|
+
foreach(cont.listeners, (listener2) => listener2(path6, curr));
|
|
7268
7132
|
}
|
|
7269
7133
|
})
|
|
7270
7134
|
};
|
|
@@ -7289,13 +7153,13 @@ class NodeFsHandler {
|
|
|
7289
7153
|
this.fsw = fsW;
|
|
7290
7154
|
this._boundHandleError = (error) => fsW._handleError(error);
|
|
7291
7155
|
}
|
|
7292
|
-
_watchWithNodeFs(
|
|
7156
|
+
_watchWithNodeFs(path6, listener) {
|
|
7293
7157
|
const opts = this.fsw.options;
|
|
7294
|
-
const directory = sp.dirname(
|
|
7295
|
-
const basename2 = sp.basename(
|
|
7158
|
+
const directory = sp.dirname(path6);
|
|
7159
|
+
const basename2 = sp.basename(path6);
|
|
7296
7160
|
const parent = this.fsw._getWatchedDir(directory);
|
|
7297
7161
|
parent.add(basename2);
|
|
7298
|
-
const absolutePath = sp.resolve(
|
|
7162
|
+
const absolutePath = sp.resolve(path6);
|
|
7299
7163
|
const options = {
|
|
7300
7164
|
persistent: opts.persistent
|
|
7301
7165
|
};
|
|
@@ -7305,12 +7169,12 @@ class NodeFsHandler {
|
|
|
7305
7169
|
if (opts.usePolling) {
|
|
7306
7170
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
7307
7171
|
options.interval = enableBin && isBinaryPath(basename2) ? opts.binaryInterval : opts.interval;
|
|
7308
|
-
closer = setFsWatchFileListener(
|
|
7172
|
+
closer = setFsWatchFileListener(path6, absolutePath, options, {
|
|
7309
7173
|
listener,
|
|
7310
7174
|
rawEmitter: this.fsw._emitRaw
|
|
7311
7175
|
});
|
|
7312
7176
|
} else {
|
|
7313
|
-
closer = setFsWatchListener(
|
|
7177
|
+
closer = setFsWatchListener(path6, absolutePath, options, {
|
|
7314
7178
|
listener,
|
|
7315
7179
|
errHandler: this._boundHandleError,
|
|
7316
7180
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -7328,7 +7192,7 @@ class NodeFsHandler {
|
|
|
7328
7192
|
let prevStats = stats;
|
|
7329
7193
|
if (parent.has(basename2))
|
|
7330
7194
|
return;
|
|
7331
|
-
const listener = async (
|
|
7195
|
+
const listener = async (path6, newStats) => {
|
|
7332
7196
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
7333
7197
|
return;
|
|
7334
7198
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -7342,11 +7206,11 @@ class NodeFsHandler {
|
|
|
7342
7206
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
7343
7207
|
}
|
|
7344
7208
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
7345
|
-
this.fsw._closeFile(
|
|
7209
|
+
this.fsw._closeFile(path6);
|
|
7346
7210
|
prevStats = newStats2;
|
|
7347
7211
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
7348
7212
|
if (closer2)
|
|
7349
|
-
this.fsw._addPathCloser(
|
|
7213
|
+
this.fsw._addPathCloser(path6, closer2);
|
|
7350
7214
|
} else {
|
|
7351
7215
|
prevStats = newStats2;
|
|
7352
7216
|
}
|
|
@@ -7370,7 +7234,7 @@ class NodeFsHandler {
|
|
|
7370
7234
|
}
|
|
7371
7235
|
return closer;
|
|
7372
7236
|
}
|
|
7373
|
-
async _handleSymlink(entry, directory,
|
|
7237
|
+
async _handleSymlink(entry, directory, path6, item) {
|
|
7374
7238
|
if (this.fsw.closed) {
|
|
7375
7239
|
return;
|
|
7376
7240
|
}
|
|
@@ -7380,7 +7244,7 @@ class NodeFsHandler {
|
|
|
7380
7244
|
this.fsw._incrReadyCount();
|
|
7381
7245
|
let linkPath;
|
|
7382
7246
|
try {
|
|
7383
|
-
linkPath = await fsrealpath(
|
|
7247
|
+
linkPath = await fsrealpath(path6);
|
|
7384
7248
|
} catch (e) {
|
|
7385
7249
|
this.fsw._emitReady();
|
|
7386
7250
|
return true;
|
|
@@ -7390,12 +7254,12 @@ class NodeFsHandler {
|
|
|
7390
7254
|
if (dir.has(item)) {
|
|
7391
7255
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
7392
7256
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
7393
|
-
this.fsw._emit(EV.CHANGE,
|
|
7257
|
+
this.fsw._emit(EV.CHANGE, path6, entry.stats);
|
|
7394
7258
|
}
|
|
7395
7259
|
} else {
|
|
7396
7260
|
dir.add(item);
|
|
7397
7261
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
7398
|
-
this.fsw._emit(EV.ADD,
|
|
7262
|
+
this.fsw._emit(EV.ADD, path6, entry.stats);
|
|
7399
7263
|
}
|
|
7400
7264
|
this.fsw._emitReady();
|
|
7401
7265
|
return true;
|
|
@@ -7425,9 +7289,9 @@ class NodeFsHandler {
|
|
|
7425
7289
|
return;
|
|
7426
7290
|
}
|
|
7427
7291
|
const item = entry.path;
|
|
7428
|
-
let
|
|
7292
|
+
let path6 = sp.join(directory, item);
|
|
7429
7293
|
current.add(item);
|
|
7430
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
7294
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path6, item)) {
|
|
7431
7295
|
return;
|
|
7432
7296
|
}
|
|
7433
7297
|
if (this.fsw.closed) {
|
|
@@ -7436,8 +7300,8 @@ class NodeFsHandler {
|
|
|
7436
7300
|
}
|
|
7437
7301
|
if (item === target || !target && !previous.has(item)) {
|
|
7438
7302
|
this.fsw._incrReadyCount();
|
|
7439
|
-
|
|
7440
|
-
this._addToNodeFs(
|
|
7303
|
+
path6 = sp.join(dir, sp.relative(dir, path6));
|
|
7304
|
+
this._addToNodeFs(path6, initialAdd, wh, depth + 1);
|
|
7441
7305
|
}
|
|
7442
7306
|
}).on(EV.ERROR, this._boundHandleError);
|
|
7443
7307
|
return new Promise((resolve2, reject) => {
|
|
@@ -7486,13 +7350,13 @@ class NodeFsHandler {
|
|
|
7486
7350
|
}
|
|
7487
7351
|
return closer;
|
|
7488
7352
|
}
|
|
7489
|
-
async _addToNodeFs(
|
|
7353
|
+
async _addToNodeFs(path6, initialAdd, priorWh, depth, target) {
|
|
7490
7354
|
const ready = this.fsw._emitReady;
|
|
7491
|
-
if (this.fsw._isIgnored(
|
|
7355
|
+
if (this.fsw._isIgnored(path6) || this.fsw.closed) {
|
|
7492
7356
|
ready();
|
|
7493
7357
|
return false;
|
|
7494
7358
|
}
|
|
7495
|
-
const wh = this.fsw._getWatchHelpers(
|
|
7359
|
+
const wh = this.fsw._getWatchHelpers(path6);
|
|
7496
7360
|
if (priorWh) {
|
|
7497
7361
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
7498
7362
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -7508,8 +7372,8 @@ class NodeFsHandler {
|
|
|
7508
7372
|
const follow = this.fsw.options.followSymlinks;
|
|
7509
7373
|
let closer;
|
|
7510
7374
|
if (stats.isDirectory()) {
|
|
7511
|
-
const absPath = sp.resolve(
|
|
7512
|
-
const targetPath = follow ? await fsrealpath(
|
|
7375
|
+
const absPath = sp.resolve(path6);
|
|
7376
|
+
const targetPath = follow ? await fsrealpath(path6) : path6;
|
|
7513
7377
|
if (this.fsw.closed)
|
|
7514
7378
|
return;
|
|
7515
7379
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -7519,29 +7383,29 @@ class NodeFsHandler {
|
|
|
7519
7383
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
7520
7384
|
}
|
|
7521
7385
|
} else if (stats.isSymbolicLink()) {
|
|
7522
|
-
const targetPath = follow ? await fsrealpath(
|
|
7386
|
+
const targetPath = follow ? await fsrealpath(path6) : path6;
|
|
7523
7387
|
if (this.fsw.closed)
|
|
7524
7388
|
return;
|
|
7525
7389
|
const parent = sp.dirname(wh.watchPath);
|
|
7526
7390
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
7527
7391
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
7528
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
7392
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path6, wh, targetPath);
|
|
7529
7393
|
if (this.fsw.closed)
|
|
7530
7394
|
return;
|
|
7531
7395
|
if (targetPath !== undefined) {
|
|
7532
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
7396
|
+
this.fsw._symlinkPaths.set(sp.resolve(path6), targetPath);
|
|
7533
7397
|
}
|
|
7534
7398
|
} else {
|
|
7535
7399
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
7536
7400
|
}
|
|
7537
7401
|
ready();
|
|
7538
7402
|
if (closer)
|
|
7539
|
-
this.fsw._addPathCloser(
|
|
7403
|
+
this.fsw._addPathCloser(path6, closer);
|
|
7540
7404
|
return false;
|
|
7541
7405
|
} catch (error) {
|
|
7542
7406
|
if (this.fsw._handleError(error)) {
|
|
7543
7407
|
ready();
|
|
7544
|
-
return
|
|
7408
|
+
return path6;
|
|
7545
7409
|
}
|
|
7546
7410
|
}
|
|
7547
7411
|
}
|
|
@@ -7585,24 +7449,24 @@ function createPattern(matcher) {
|
|
|
7585
7449
|
}
|
|
7586
7450
|
return () => false;
|
|
7587
7451
|
}
|
|
7588
|
-
function normalizePath(
|
|
7589
|
-
if (typeof
|
|
7452
|
+
function normalizePath(path6) {
|
|
7453
|
+
if (typeof path6 !== "string")
|
|
7590
7454
|
throw new Error("string expected");
|
|
7591
|
-
|
|
7592
|
-
|
|
7455
|
+
path6 = sp2.normalize(path6);
|
|
7456
|
+
path6 = path6.replace(/\\/g, "/");
|
|
7593
7457
|
let prepend = false;
|
|
7594
|
-
if (
|
|
7458
|
+
if (path6.startsWith("//"))
|
|
7595
7459
|
prepend = true;
|
|
7596
|
-
|
|
7460
|
+
path6 = path6.replace(DOUBLE_SLASH_RE, "/");
|
|
7597
7461
|
if (prepend)
|
|
7598
|
-
|
|
7599
|
-
return
|
|
7462
|
+
path6 = "/" + path6;
|
|
7463
|
+
return path6;
|
|
7600
7464
|
}
|
|
7601
7465
|
function matchPatterns(patterns, testString, stats) {
|
|
7602
|
-
const
|
|
7466
|
+
const path6 = normalizePath(testString);
|
|
7603
7467
|
for (let index = 0;index < patterns.length; index++) {
|
|
7604
7468
|
const pattern = patterns[index];
|
|
7605
|
-
if (pattern(
|
|
7469
|
+
if (pattern(path6, stats)) {
|
|
7606
7470
|
return true;
|
|
7607
7471
|
}
|
|
7608
7472
|
}
|
|
@@ -7640,19 +7504,19 @@ var toUnix = (string) => {
|
|
|
7640
7504
|
}
|
|
7641
7505
|
return str;
|
|
7642
7506
|
};
|
|
7643
|
-
var normalizePathToUnix = (
|
|
7644
|
-
var normalizeIgnored = (cwd = "") => (
|
|
7645
|
-
if (typeof
|
|
7646
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
7507
|
+
var normalizePathToUnix = (path6) => toUnix(sp2.normalize(toUnix(path6)));
|
|
7508
|
+
var normalizeIgnored = (cwd = "") => (path6) => {
|
|
7509
|
+
if (typeof path6 === "string") {
|
|
7510
|
+
return normalizePathToUnix(sp2.isAbsolute(path6) ? path6 : sp2.join(cwd, path6));
|
|
7647
7511
|
} else {
|
|
7648
|
-
return
|
|
7512
|
+
return path6;
|
|
7649
7513
|
}
|
|
7650
7514
|
};
|
|
7651
|
-
var getAbsolutePath = (
|
|
7652
|
-
if (sp2.isAbsolute(
|
|
7653
|
-
return
|
|
7515
|
+
var getAbsolutePath = (path6, cwd) => {
|
|
7516
|
+
if (sp2.isAbsolute(path6)) {
|
|
7517
|
+
return path6;
|
|
7654
7518
|
}
|
|
7655
|
-
return sp2.join(cwd,
|
|
7519
|
+
return sp2.join(cwd, path6);
|
|
7656
7520
|
};
|
|
7657
7521
|
var EMPTY_SET = Object.freeze(new Set);
|
|
7658
7522
|
|
|
@@ -7719,10 +7583,10 @@ class WatchHelper {
|
|
|
7719
7583
|
dirParts;
|
|
7720
7584
|
followSymlinks;
|
|
7721
7585
|
statMethod;
|
|
7722
|
-
constructor(
|
|
7586
|
+
constructor(path6, follow, fsw) {
|
|
7723
7587
|
this.fsw = fsw;
|
|
7724
|
-
const watchPath =
|
|
7725
|
-
this.path =
|
|
7588
|
+
const watchPath = path6;
|
|
7589
|
+
this.path = path6 = path6.replace(REPLACER_RE, "");
|
|
7726
7590
|
this.watchPath = watchPath;
|
|
7727
7591
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
7728
7592
|
this.dirParts = [];
|
|
@@ -7853,20 +7717,20 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7853
7717
|
this._closePromise = undefined;
|
|
7854
7718
|
let paths = unifyPaths(paths_);
|
|
7855
7719
|
if (cwd) {
|
|
7856
|
-
paths = paths.map((
|
|
7857
|
-
const absPath = getAbsolutePath(
|
|
7720
|
+
paths = paths.map((path6) => {
|
|
7721
|
+
const absPath = getAbsolutePath(path6, cwd);
|
|
7858
7722
|
return absPath;
|
|
7859
7723
|
});
|
|
7860
7724
|
}
|
|
7861
|
-
paths.forEach((
|
|
7862
|
-
this._removeIgnoredPath(
|
|
7725
|
+
paths.forEach((path6) => {
|
|
7726
|
+
this._removeIgnoredPath(path6);
|
|
7863
7727
|
});
|
|
7864
7728
|
this._userIgnored = undefined;
|
|
7865
7729
|
if (!this._readyCount)
|
|
7866
7730
|
this._readyCount = 0;
|
|
7867
7731
|
this._readyCount += paths.length;
|
|
7868
|
-
Promise.all(paths.map(async (
|
|
7869
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
7732
|
+
Promise.all(paths.map(async (path6) => {
|
|
7733
|
+
const res = await this._nodeFsHandler._addToNodeFs(path6, !_internal, undefined, 0, _origAdd);
|
|
7870
7734
|
if (res)
|
|
7871
7735
|
this._emitReady();
|
|
7872
7736
|
return res;
|
|
@@ -7885,17 +7749,17 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7885
7749
|
return this;
|
|
7886
7750
|
const paths = unifyPaths(paths_);
|
|
7887
7751
|
const { cwd } = this.options;
|
|
7888
|
-
paths.forEach((
|
|
7889
|
-
if (!sp2.isAbsolute(
|
|
7752
|
+
paths.forEach((path6) => {
|
|
7753
|
+
if (!sp2.isAbsolute(path6) && !this._closers.has(path6)) {
|
|
7890
7754
|
if (cwd)
|
|
7891
|
-
|
|
7892
|
-
|
|
7755
|
+
path6 = sp2.join(cwd, path6);
|
|
7756
|
+
path6 = sp2.resolve(path6);
|
|
7893
7757
|
}
|
|
7894
|
-
this._closePath(
|
|
7895
|
-
this._addIgnoredPath(
|
|
7896
|
-
if (this._watched.has(
|
|
7758
|
+
this._closePath(path6);
|
|
7759
|
+
this._addIgnoredPath(path6);
|
|
7760
|
+
if (this._watched.has(path6)) {
|
|
7897
7761
|
this._addIgnoredPath({
|
|
7898
|
-
path:
|
|
7762
|
+
path: path6,
|
|
7899
7763
|
recursive: true
|
|
7900
7764
|
});
|
|
7901
7765
|
}
|
|
@@ -7944,38 +7808,38 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7944
7808
|
if (event !== EVENTS.ERROR)
|
|
7945
7809
|
this.emit(EVENTS.ALL, event, ...args);
|
|
7946
7810
|
}
|
|
7947
|
-
async _emit(event,
|
|
7811
|
+
async _emit(event, path6, stats) {
|
|
7948
7812
|
if (this.closed)
|
|
7949
7813
|
return;
|
|
7950
7814
|
const opts = this.options;
|
|
7951
7815
|
if (isWindows)
|
|
7952
|
-
|
|
7816
|
+
path6 = sp2.normalize(path6);
|
|
7953
7817
|
if (opts.cwd)
|
|
7954
|
-
|
|
7955
|
-
const args = [
|
|
7818
|
+
path6 = sp2.relative(opts.cwd, path6);
|
|
7819
|
+
const args = [path6];
|
|
7956
7820
|
if (stats != null)
|
|
7957
7821
|
args.push(stats);
|
|
7958
7822
|
const awf = opts.awaitWriteFinish;
|
|
7959
7823
|
let pw;
|
|
7960
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
7824
|
+
if (awf && (pw = this._pendingWrites.get(path6))) {
|
|
7961
7825
|
pw.lastChange = new Date;
|
|
7962
7826
|
return this;
|
|
7963
7827
|
}
|
|
7964
7828
|
if (opts.atomic) {
|
|
7965
7829
|
if (event === EVENTS.UNLINK) {
|
|
7966
|
-
this._pendingUnlinks.set(
|
|
7830
|
+
this._pendingUnlinks.set(path6, [event, ...args]);
|
|
7967
7831
|
setTimeout(() => {
|
|
7968
|
-
this._pendingUnlinks.forEach((entry,
|
|
7832
|
+
this._pendingUnlinks.forEach((entry, path7) => {
|
|
7969
7833
|
this.emit(...entry);
|
|
7970
7834
|
this.emit(EVENTS.ALL, ...entry);
|
|
7971
|
-
this._pendingUnlinks.delete(
|
|
7835
|
+
this._pendingUnlinks.delete(path7);
|
|
7972
7836
|
});
|
|
7973
7837
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
7974
7838
|
return this;
|
|
7975
7839
|
}
|
|
7976
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
7840
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path6)) {
|
|
7977
7841
|
event = EVENTS.CHANGE;
|
|
7978
|
-
this._pendingUnlinks.delete(
|
|
7842
|
+
this._pendingUnlinks.delete(path6);
|
|
7979
7843
|
}
|
|
7980
7844
|
}
|
|
7981
7845
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -7993,16 +7857,16 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7993
7857
|
this.emitWithAll(event, args);
|
|
7994
7858
|
}
|
|
7995
7859
|
};
|
|
7996
|
-
this._awaitWriteFinish(
|
|
7860
|
+
this._awaitWriteFinish(path6, awf.stabilityThreshold, event, awfEmit);
|
|
7997
7861
|
return this;
|
|
7998
7862
|
}
|
|
7999
7863
|
if (event === EVENTS.CHANGE) {
|
|
8000
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
7864
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path6, 50);
|
|
8001
7865
|
if (isThrottled)
|
|
8002
7866
|
return this;
|
|
8003
7867
|
}
|
|
8004
7868
|
if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
8005
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
7869
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path6) : path6;
|
|
8006
7870
|
let stats2;
|
|
8007
7871
|
try {
|
|
8008
7872
|
stats2 = await stat3(fullPath);
|
|
@@ -8021,23 +7885,23 @@ class FSWatcher extends EventEmitter2 {
|
|
|
8021
7885
|
}
|
|
8022
7886
|
return error || this.closed;
|
|
8023
7887
|
}
|
|
8024
|
-
_throttle(actionType,
|
|
7888
|
+
_throttle(actionType, path6, timeout) {
|
|
8025
7889
|
if (!this._throttled.has(actionType)) {
|
|
8026
7890
|
this._throttled.set(actionType, new Map);
|
|
8027
7891
|
}
|
|
8028
7892
|
const action = this._throttled.get(actionType);
|
|
8029
7893
|
if (!action)
|
|
8030
7894
|
throw new Error("invalid throttle");
|
|
8031
|
-
const actionPath = action.get(
|
|
7895
|
+
const actionPath = action.get(path6);
|
|
8032
7896
|
if (actionPath) {
|
|
8033
7897
|
actionPath.count++;
|
|
8034
7898
|
return false;
|
|
8035
7899
|
}
|
|
8036
7900
|
let timeoutObject;
|
|
8037
7901
|
const clear = () => {
|
|
8038
|
-
const item = action.get(
|
|
7902
|
+
const item = action.get(path6);
|
|
8039
7903
|
const count = item ? item.count : 0;
|
|
8040
|
-
action.delete(
|
|
7904
|
+
action.delete(path6);
|
|
8041
7905
|
clearTimeout(timeoutObject);
|
|
8042
7906
|
if (item)
|
|
8043
7907
|
clearTimeout(item.timeoutObject);
|
|
@@ -8045,50 +7909,50 @@ class FSWatcher extends EventEmitter2 {
|
|
|
8045
7909
|
};
|
|
8046
7910
|
timeoutObject = setTimeout(clear, timeout);
|
|
8047
7911
|
const thr = { timeoutObject, clear, count: 0 };
|
|
8048
|
-
action.set(
|
|
7912
|
+
action.set(path6, thr);
|
|
8049
7913
|
return thr;
|
|
8050
7914
|
}
|
|
8051
7915
|
_incrReadyCount() {
|
|
8052
7916
|
return this._readyCount++;
|
|
8053
7917
|
}
|
|
8054
|
-
_awaitWriteFinish(
|
|
7918
|
+
_awaitWriteFinish(path6, threshold, event, awfEmit) {
|
|
8055
7919
|
const awf = this.options.awaitWriteFinish;
|
|
8056
7920
|
if (typeof awf !== "object")
|
|
8057
7921
|
return;
|
|
8058
7922
|
const pollInterval = awf.pollInterval;
|
|
8059
7923
|
let timeoutHandler;
|
|
8060
|
-
let fullPath =
|
|
8061
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
8062
|
-
fullPath = sp2.join(this.options.cwd,
|
|
7924
|
+
let fullPath = path6;
|
|
7925
|
+
if (this.options.cwd && !sp2.isAbsolute(path6)) {
|
|
7926
|
+
fullPath = sp2.join(this.options.cwd, path6);
|
|
8063
7927
|
}
|
|
8064
7928
|
const now = new Date;
|
|
8065
7929
|
const writes = this._pendingWrites;
|
|
8066
7930
|
function awaitWriteFinishFn(prevStat) {
|
|
8067
7931
|
statcb(fullPath, (err, curStat) => {
|
|
8068
|
-
if (err || !writes.has(
|
|
7932
|
+
if (err || !writes.has(path6)) {
|
|
8069
7933
|
if (err && err.code !== "ENOENT")
|
|
8070
7934
|
awfEmit(err);
|
|
8071
7935
|
return;
|
|
8072
7936
|
}
|
|
8073
7937
|
const now2 = Number(new Date);
|
|
8074
7938
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
8075
|
-
writes.get(
|
|
7939
|
+
writes.get(path6).lastChange = now2;
|
|
8076
7940
|
}
|
|
8077
|
-
const pw = writes.get(
|
|
7941
|
+
const pw = writes.get(path6);
|
|
8078
7942
|
const df = now2 - pw.lastChange;
|
|
8079
7943
|
if (df >= threshold) {
|
|
8080
|
-
writes.delete(
|
|
7944
|
+
writes.delete(path6);
|
|
8081
7945
|
awfEmit(undefined, curStat);
|
|
8082
7946
|
} else {
|
|
8083
7947
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
8084
7948
|
}
|
|
8085
7949
|
});
|
|
8086
7950
|
}
|
|
8087
|
-
if (!writes.has(
|
|
8088
|
-
writes.set(
|
|
7951
|
+
if (!writes.has(path6)) {
|
|
7952
|
+
writes.set(path6, {
|
|
8089
7953
|
lastChange: now,
|
|
8090
7954
|
cancelWait: () => {
|
|
8091
|
-
writes.delete(
|
|
7955
|
+
writes.delete(path6);
|
|
8092
7956
|
clearTimeout(timeoutHandler);
|
|
8093
7957
|
return event;
|
|
8094
7958
|
}
|
|
@@ -8096,8 +7960,8 @@ class FSWatcher extends EventEmitter2 {
|
|
|
8096
7960
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
|
|
8097
7961
|
}
|
|
8098
7962
|
}
|
|
8099
|
-
_isIgnored(
|
|
8100
|
-
if (this.options.atomic && DOT_RE.test(
|
|
7963
|
+
_isIgnored(path6, stats) {
|
|
7964
|
+
if (this.options.atomic && DOT_RE.test(path6))
|
|
8101
7965
|
return true;
|
|
8102
7966
|
if (!this._userIgnored) {
|
|
8103
7967
|
const { cwd } = this.options;
|
|
@@ -8107,13 +7971,13 @@ class FSWatcher extends EventEmitter2 {
|
|
|
8107
7971
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
8108
7972
|
this._userIgnored = anymatch(list, undefined);
|
|
8109
7973
|
}
|
|
8110
|
-
return this._userIgnored(
|
|
7974
|
+
return this._userIgnored(path6, stats);
|
|
8111
7975
|
}
|
|
8112
|
-
_isntIgnored(
|
|
8113
|
-
return !this._isIgnored(
|
|
7976
|
+
_isntIgnored(path6, stat4) {
|
|
7977
|
+
return !this._isIgnored(path6, stat4);
|
|
8114
7978
|
}
|
|
8115
|
-
_getWatchHelpers(
|
|
8116
|
-
return new WatchHelper(
|
|
7979
|
+
_getWatchHelpers(path6) {
|
|
7980
|
+
return new WatchHelper(path6, this.options.followSymlinks, this);
|
|
8117
7981
|
}
|
|
8118
7982
|
_getWatchedDir(directory) {
|
|
8119
7983
|
const dir = sp2.resolve(directory);
|
|
@@ -8127,57 +7991,57 @@ class FSWatcher extends EventEmitter2 {
|
|
|
8127
7991
|
return Boolean(Number(stats.mode) & 256);
|
|
8128
7992
|
}
|
|
8129
7993
|
_remove(directory, item, isDirectory) {
|
|
8130
|
-
const
|
|
8131
|
-
const fullPath = sp2.resolve(
|
|
8132
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
8133
|
-
if (!this._throttle("remove",
|
|
7994
|
+
const path6 = sp2.join(directory, item);
|
|
7995
|
+
const fullPath = sp2.resolve(path6);
|
|
7996
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path6) || this._watched.has(fullPath);
|
|
7997
|
+
if (!this._throttle("remove", path6, 100))
|
|
8134
7998
|
return;
|
|
8135
7999
|
if (!isDirectory && this._watched.size === 1) {
|
|
8136
8000
|
this.add(directory, item, true);
|
|
8137
8001
|
}
|
|
8138
|
-
const wp = this._getWatchedDir(
|
|
8002
|
+
const wp = this._getWatchedDir(path6);
|
|
8139
8003
|
const nestedDirectoryChildren = wp.getChildren();
|
|
8140
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
8004
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path6, nested));
|
|
8141
8005
|
const parent = this._getWatchedDir(directory);
|
|
8142
8006
|
const wasTracked = parent.has(item);
|
|
8143
8007
|
parent.remove(item);
|
|
8144
8008
|
if (this._symlinkPaths.has(fullPath)) {
|
|
8145
8009
|
this._symlinkPaths.delete(fullPath);
|
|
8146
8010
|
}
|
|
8147
|
-
let relPath =
|
|
8011
|
+
let relPath = path6;
|
|
8148
8012
|
if (this.options.cwd)
|
|
8149
|
-
relPath = sp2.relative(this.options.cwd,
|
|
8013
|
+
relPath = sp2.relative(this.options.cwd, path6);
|
|
8150
8014
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
8151
8015
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
8152
8016
|
if (event === EVENTS.ADD)
|
|
8153
8017
|
return;
|
|
8154
8018
|
}
|
|
8155
|
-
this._watched.delete(
|
|
8019
|
+
this._watched.delete(path6);
|
|
8156
8020
|
this._watched.delete(fullPath);
|
|
8157
8021
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
8158
|
-
if (wasTracked && !this._isIgnored(
|
|
8159
|
-
this._emit(eventName,
|
|
8160
|
-
this._closePath(
|
|
8022
|
+
if (wasTracked && !this._isIgnored(path6))
|
|
8023
|
+
this._emit(eventName, path6);
|
|
8024
|
+
this._closePath(path6);
|
|
8161
8025
|
}
|
|
8162
|
-
_closePath(
|
|
8163
|
-
this._closeFile(
|
|
8164
|
-
const dir = sp2.dirname(
|
|
8165
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
8026
|
+
_closePath(path6) {
|
|
8027
|
+
this._closeFile(path6);
|
|
8028
|
+
const dir = sp2.dirname(path6);
|
|
8029
|
+
this._getWatchedDir(dir).remove(sp2.basename(path6));
|
|
8166
8030
|
}
|
|
8167
|
-
_closeFile(
|
|
8168
|
-
const closers = this._closers.get(
|
|
8031
|
+
_closeFile(path6) {
|
|
8032
|
+
const closers = this._closers.get(path6);
|
|
8169
8033
|
if (!closers)
|
|
8170
8034
|
return;
|
|
8171
8035
|
closers.forEach((closer) => closer());
|
|
8172
|
-
this._closers.delete(
|
|
8036
|
+
this._closers.delete(path6);
|
|
8173
8037
|
}
|
|
8174
|
-
_addPathCloser(
|
|
8038
|
+
_addPathCloser(path6, closer) {
|
|
8175
8039
|
if (!closer)
|
|
8176
8040
|
return;
|
|
8177
|
-
let list = this._closers.get(
|
|
8041
|
+
let list = this._closers.get(path6);
|
|
8178
8042
|
if (!list) {
|
|
8179
8043
|
list = [];
|
|
8180
|
-
this._closers.set(
|
|
8044
|
+
this._closers.set(path6, list);
|
|
8181
8045
|
}
|
|
8182
8046
|
list.push(closer);
|
|
8183
8047
|
}
|
|
@@ -8207,7 +8071,7 @@ function watch(paths, options = {}) {
|
|
|
8207
8071
|
var chokidar_default = { watch, FSWatcher };
|
|
8208
8072
|
|
|
8209
8073
|
// src/core/watcher.ts
|
|
8210
|
-
import
|
|
8074
|
+
import path6 from "node:path";
|
|
8211
8075
|
function formatTime() {
|
|
8212
8076
|
const now = new Date;
|
|
8213
8077
|
const hours = String(now.getHours()).padStart(2, "0");
|
|
@@ -8240,7 +8104,7 @@ function getWatchPaths(operations) {
|
|
|
8240
8104
|
return Array.from(paths);
|
|
8241
8105
|
}
|
|
8242
8106
|
async function handleFileChange(changedPath, state, options) {
|
|
8243
|
-
const relPath =
|
|
8107
|
+
const relPath = path6.relative(options.cwd || process.cwd(), changedPath);
|
|
8244
8108
|
if (!logger.isSilent() && !options.verbose) {
|
|
8245
8109
|
console.log(`[${formatTime()}] Changed: ${relPath}`);
|
|
8246
8110
|
}
|
|
@@ -8254,9 +8118,9 @@ async function handleFileChange(changedPath, state, options) {
|
|
|
8254
8118
|
for (const op of affectedOps) {
|
|
8255
8119
|
const result = await performMerge(op);
|
|
8256
8120
|
if (result.success && result.changed) {
|
|
8257
|
-
const baseFile = op.basePath ?
|
|
8258
|
-
const machineFile =
|
|
8259
|
-
const outputFile =
|
|
8121
|
+
const baseFile = op.basePath ? path6.basename(op.basePath) : "";
|
|
8122
|
+
const machineFile = path6.basename(op.machinePath);
|
|
8123
|
+
const outputFile = path6.basename(op.outputPath);
|
|
8260
8124
|
if (!logger.isSilent()) {
|
|
8261
8125
|
if (baseFile) {
|
|
8262
8126
|
console.log(`[${formatTime()}] Merged ${baseFile} + ${machineFile} → ${outputFile}`);
|
|
@@ -8267,7 +8131,7 @@ async function handleFileChange(changedPath, state, options) {
|
|
|
8267
8131
|
} else if (!result.success && result.error) {
|
|
8268
8132
|
logger.error(`Failed to merge: ${result.error.message}`);
|
|
8269
8133
|
} else if (options.verbose && !result.changed) {
|
|
8270
|
-
logger.info(`No changes needed for ${
|
|
8134
|
+
logger.info(`No changes needed for ${path6.basename(op.outputPath)}`);
|
|
8271
8135
|
}
|
|
8272
8136
|
}
|
|
8273
8137
|
if (!logger.isSilent() && !options.verbose) {
|
|
@@ -8298,7 +8162,7 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8298
8162
|
if (!logger.isSilent()) {
|
|
8299
8163
|
console.log(`✓ Watching ${watchPaths.length} file(s) for changes...`);
|
|
8300
8164
|
for (const watchPath of watchPaths) {
|
|
8301
|
-
console.log(` - ${
|
|
8165
|
+
console.log(` - ${path6.relative(cwd, watchPath)}`);
|
|
8302
8166
|
}
|
|
8303
8167
|
console.log("");
|
|
8304
8168
|
}
|
|
@@ -8311,9 +8175,9 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8311
8175
|
}
|
|
8312
8176
|
});
|
|
8313
8177
|
watcher.on("change", (changedPath) => {
|
|
8314
|
-
const absolutePath =
|
|
8178
|
+
const absolutePath = path6.resolve(cwd, changedPath);
|
|
8315
8179
|
if (options.verbose) {
|
|
8316
|
-
logger.info(`File changed: ${
|
|
8180
|
+
logger.info(`File changed: ${path6.relative(cwd, absolutePath)}`);
|
|
8317
8181
|
}
|
|
8318
8182
|
const existingTimer = state.debounceTimers.get(absolutePath);
|
|
8319
8183
|
if (existingTimer) {
|
|
@@ -8326,9 +8190,9 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8326
8190
|
state.debounceTimers.set(absolutePath, timer);
|
|
8327
8191
|
});
|
|
8328
8192
|
watcher.on("add", async (addedPath) => {
|
|
8329
|
-
const absolutePath =
|
|
8193
|
+
const absolutePath = path6.resolve(cwd, addedPath);
|
|
8330
8194
|
if (options.verbose) {
|
|
8331
|
-
logger.info(`File added: ${
|
|
8195
|
+
logger.info(`File added: ${path6.relative(cwd, absolutePath)}`);
|
|
8332
8196
|
}
|
|
8333
8197
|
const newOperations = await scanForMergeOperations(machineName, cwd);
|
|
8334
8198
|
state.operations = newOperations;
|
|
@@ -8337,7 +8201,7 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8337
8201
|
});
|
|
8338
8202
|
watcher.on("unlink", (deletedPath) => {
|
|
8339
8203
|
if (options.verbose) {
|
|
8340
|
-
const relPath =
|
|
8204
|
+
const relPath = path6.relative(cwd, deletedPath);
|
|
8341
8205
|
logger.warn(`File deleted: ${relPath}`);
|
|
8342
8206
|
logger.info("Run merge manually or restart watch to update operations");
|
|
8343
8207
|
}
|
|
@@ -8358,22 +8222,37 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8358
8222
|
}
|
|
8359
8223
|
|
|
8360
8224
|
// src/cli.ts
|
|
8361
|
-
import
|
|
8362
|
-
import
|
|
8363
|
-
import { fileURLToPath as
|
|
8225
|
+
import fs3 from "node:fs/promises";
|
|
8226
|
+
import path7 from "node:path";
|
|
8227
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
8364
8228
|
import { createInterface } from "node:readline";
|
|
8365
|
-
var
|
|
8366
|
-
var
|
|
8229
|
+
var __filename2 = fileURLToPath3(import.meta.url);
|
|
8230
|
+
var __dirname2 = path7.dirname(__filename2);
|
|
8367
8231
|
async function checkExistingOutputFiles(operations) {
|
|
8368
8232
|
const existing = [];
|
|
8369
8233
|
for (const op of operations) {
|
|
8370
8234
|
try {
|
|
8371
|
-
await
|
|
8235
|
+
await fs3.access(op.outputPath);
|
|
8372
8236
|
existing.push(op.outputPath);
|
|
8373
8237
|
} catch {}
|
|
8374
8238
|
}
|
|
8375
8239
|
return existing;
|
|
8376
8240
|
}
|
|
8241
|
+
async function checkTrackedOutputFiles(operations) {
|
|
8242
|
+
const tracked = [];
|
|
8243
|
+
const cwd = process.cwd();
|
|
8244
|
+
for (const op of operations) {
|
|
8245
|
+
try {
|
|
8246
|
+
await fs3.access(op.outputPath);
|
|
8247
|
+
const relativePath = path7.relative(cwd, op.outputPath);
|
|
8248
|
+
const isTracked = await isFileTrackedByGit(relativePath, cwd);
|
|
8249
|
+
if (isTracked) {
|
|
8250
|
+
tracked.push(op.outputPath);
|
|
8251
|
+
}
|
|
8252
|
+
} catch {}
|
|
8253
|
+
}
|
|
8254
|
+
return tracked;
|
|
8255
|
+
}
|
|
8377
8256
|
async function promptConfirmation(message) {
|
|
8378
8257
|
const rl = createInterface({
|
|
8379
8258
|
input: process.stdin,
|
|
@@ -8440,11 +8319,11 @@ async function handleInit(argv) {
|
|
|
8440
8319
|
const operations = await scanForMergeOperations(machineName);
|
|
8441
8320
|
if (operations.length > 0) {
|
|
8442
8321
|
logger.info(`Found ${operations.length} machine-specific file(s)`);
|
|
8443
|
-
const
|
|
8444
|
-
if (
|
|
8322
|
+
const trackedFiles = await checkTrackedOutputFiles(operations);
|
|
8323
|
+
if (trackedFiles.length > 0 && !argv["no-gitignore"]) {
|
|
8445
8324
|
logger.warn("⚠️ Warning: The following files will be overwritten and untracked from git:");
|
|
8446
|
-
for (const file of
|
|
8447
|
-
logger.warn(` - ${
|
|
8325
|
+
for (const file of trackedFiles) {
|
|
8326
|
+
logger.warn(` - ${path7.relative(process.cwd(), file)}`);
|
|
8448
8327
|
}
|
|
8449
8328
|
logger.info("");
|
|
8450
8329
|
const confirmed = await promptConfirmation("Do you want to continue?");
|
|
@@ -8508,11 +8387,11 @@ async function handleMerge(argv) {
|
|
|
8508
8387
|
return;
|
|
8509
8388
|
}
|
|
8510
8389
|
if (!argv.silent && !argv["no-gitignore"]) {
|
|
8511
|
-
const
|
|
8512
|
-
if (
|
|
8390
|
+
const trackedFiles = await checkTrackedOutputFiles(operations);
|
|
8391
|
+
if (trackedFiles.length > 0) {
|
|
8513
8392
|
logger.warn("⚠️ Warning: The following files will be overwritten and untracked from git:");
|
|
8514
|
-
for (const file of
|
|
8515
|
-
logger.warn(` - ${
|
|
8393
|
+
for (const file of trackedFiles) {
|
|
8394
|
+
logger.warn(` - ${path7.relative(process.cwd(), file)}`);
|
|
8516
8395
|
}
|
|
8517
8396
|
logger.info("");
|
|
8518
8397
|
const confirmed = await promptConfirmation("Do you want to continue?");
|
|
@@ -8550,11 +8429,11 @@ async function handleInfo(argv) {
|
|
|
8550
8429
|
const operations = await scanForMergeOperations(machineName);
|
|
8551
8430
|
console.log(`Machine name: ${machineName}`);
|
|
8552
8431
|
console.log(`Repository: ${process.cwd()}`);
|
|
8553
|
-
const { exec:
|
|
8554
|
-
const { promisify:
|
|
8555
|
-
const
|
|
8432
|
+
const { exec: exec2 } = await import("node:child_process");
|
|
8433
|
+
const { promisify: promisify2 } = await import("node:util");
|
|
8434
|
+
const execAsync2 = promisify2(exec2);
|
|
8556
8435
|
try {
|
|
8557
|
-
const { stdout } = await
|
|
8436
|
+
const { stdout } = await execAsync2("git config --get core.hooksPath");
|
|
8558
8437
|
const hooksPath = stdout.trim();
|
|
8559
8438
|
if (hooksPath) {
|
|
8560
8439
|
console.log(`Hooks method: core.hooksPath`);
|
|
@@ -8567,9 +8446,9 @@ async function handleInfo(argv) {
|
|
|
8567
8446
|
}
|
|
8568
8447
|
console.log(`Tracked patterns: ${operations.length}`);
|
|
8569
8448
|
for (const op of operations) {
|
|
8570
|
-
const baseName = op.basePath ?
|
|
8571
|
-
const machineName2 =
|
|
8572
|
-
const outputName =
|
|
8449
|
+
const baseName = op.basePath ? path7.basename(op.basePath) : "(none)";
|
|
8450
|
+
const machineName2 = path7.basename(op.machinePath);
|
|
8451
|
+
const outputName = path7.basename(op.outputPath);
|
|
8573
8452
|
console.log(` - ${baseName} + ${machineName2} → ${outputName}`);
|
|
8574
8453
|
}
|
|
8575
8454
|
if (operations.length > 0) {
|
|
@@ -8579,7 +8458,7 @@ async function handleInfo(argv) {
|
|
|
8579
8458
|
if (existingFiles.length > 0) {
|
|
8580
8459
|
console.log("Existing output files:");
|
|
8581
8460
|
for (const file of existingFiles) {
|
|
8582
|
-
console.log(` - ${
|
|
8461
|
+
console.log(` - ${path7.relative(process.cwd(), file)}`);
|
|
8583
8462
|
}
|
|
8584
8463
|
}
|
|
8585
8464
|
}
|
|
@@ -8660,8 +8539,8 @@ DOCUMENTATION:
|
|
|
8660
8539
|
}
|
|
8661
8540
|
async function showVersion() {
|
|
8662
8541
|
try {
|
|
8663
|
-
const packageJsonPath =
|
|
8664
|
-
const packageJson = JSON.parse(await
|
|
8542
|
+
const packageJsonPath = path7.join(__dirname2, "../package.json");
|
|
8543
|
+
const packageJson = JSON.parse(await fs3.readFile(packageJsonPath, "utf-8"));
|
|
8665
8544
|
console.log(packageJson.version);
|
|
8666
8545
|
} catch {
|
|
8667
8546
|
console.log("unknown");
|