permachine 0.5.0 → 0.5.2
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 +384 -174
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -5934,6 +5934,10 @@ function matchFilters(filename, context) {
|
|
|
5934
5934
|
function getBaseFilename(filename) {
|
|
5935
5935
|
return parseFilters(filename).baseFilename;
|
|
5936
5936
|
}
|
|
5937
|
+
function isBaseFile(filename) {
|
|
5938
|
+
const basename = filename.includes("/") || filename.includes("\\") ? filename.split(/[/\\]/).pop() || filename : filename;
|
|
5939
|
+
return basename.includes(".base.") || basename.endsWith(".base");
|
|
5940
|
+
}
|
|
5937
5941
|
function isLegacyFilename(filename, machineName) {
|
|
5938
5942
|
const middlePattern = new RegExp(`\\.${machineName}\\.`, "i");
|
|
5939
5943
|
const endPattern = new RegExp(`\\.${machineName}$`, "i");
|
|
@@ -5943,6 +5947,8 @@ function isLegacyFilename(filename, machineName) {
|
|
|
5943
5947
|
// src/core/file-scanner.ts
|
|
5944
5948
|
async function scanForMergeOperations(machineName, cwd = process.cwd()) {
|
|
5945
5949
|
const operations = [];
|
|
5950
|
+
const processedOutputs = new Set;
|
|
5951
|
+
const baseFilesWithMachineFiles = new Set;
|
|
5946
5952
|
const patterns = [
|
|
5947
5953
|
"**/*{*}*",
|
|
5948
5954
|
`**/*.${machineName}.*`,
|
|
@@ -5965,25 +5971,93 @@ async function scanForMergeOperations(machineName, cwd = process.cwd()) {
|
|
|
5965
5971
|
const context = createCustomContext({ machine: machineName });
|
|
5966
5972
|
for (const file of uniqueFiles) {
|
|
5967
5973
|
const basename = path2.basename(file);
|
|
5968
|
-
if (
|
|
5974
|
+
if (isBaseFile(basename)) {
|
|
5969
5975
|
continue;
|
|
5970
5976
|
}
|
|
5971
5977
|
let shouldProcess = false;
|
|
5972
5978
|
if (hasFilters(basename)) {
|
|
5973
5979
|
const result = matchFilters(basename, context);
|
|
5974
5980
|
shouldProcess = result.matches;
|
|
5981
|
+
const operation = createMergeOperation(file, machineName, cwd);
|
|
5982
|
+
if (operation && operation.basePath) {
|
|
5983
|
+
baseFilesWithMachineFiles.add(operation.basePath);
|
|
5984
|
+
}
|
|
5975
5985
|
} else if (isLegacyFilename(basename, machineName)) {
|
|
5976
5986
|
shouldProcess = true;
|
|
5987
|
+
const operation = createMergeOperation(file, machineName, cwd);
|
|
5988
|
+
if (operation && operation.basePath) {
|
|
5989
|
+
baseFilesWithMachineFiles.add(operation.basePath);
|
|
5990
|
+
}
|
|
5977
5991
|
}
|
|
5978
5992
|
if (shouldProcess) {
|
|
5979
5993
|
const operation = createMergeOperation(file, machineName, cwd);
|
|
5980
5994
|
if (operation) {
|
|
5981
5995
|
operations.push(operation);
|
|
5996
|
+
processedOutputs.add(operation.outputPath);
|
|
5982
5997
|
}
|
|
5983
5998
|
}
|
|
5984
5999
|
}
|
|
6000
|
+
const basePatterns = [
|
|
6001
|
+
"**/*.base.json",
|
|
6002
|
+
"**/.*.base",
|
|
6003
|
+
"**/.*.base.*"
|
|
6004
|
+
];
|
|
6005
|
+
for (const pattern of basePatterns) {
|
|
6006
|
+
try {
|
|
6007
|
+
const baseFiles = await glob(pattern, {
|
|
6008
|
+
cwd,
|
|
6009
|
+
ignore: ["node_modules/**", ".git/**", "dist/**"],
|
|
6010
|
+
dot: true,
|
|
6011
|
+
nodir: true
|
|
6012
|
+
});
|
|
6013
|
+
for (const baseFile of baseFiles) {
|
|
6014
|
+
const fullPath = path2.join(cwd, baseFile);
|
|
6015
|
+
if (baseFilesWithMachineFiles.has(fullPath)) {
|
|
6016
|
+
continue;
|
|
6017
|
+
}
|
|
6018
|
+
const operation = createBaseOnlyMergeOperation(baseFile, cwd);
|
|
6019
|
+
if (operation && !processedOutputs.has(operation.outputPath)) {
|
|
6020
|
+
operations.push(operation);
|
|
6021
|
+
processedOutputs.add(operation.outputPath);
|
|
6022
|
+
}
|
|
6023
|
+
}
|
|
6024
|
+
} catch (error) {}
|
|
6025
|
+
}
|
|
5985
6026
|
return operations;
|
|
5986
6027
|
}
|
|
6028
|
+
function createBaseOnlyMergeOperation(baseFile, cwd) {
|
|
6029
|
+
const dir = path2.dirname(baseFile);
|
|
6030
|
+
const fullBasename = path2.basename(baseFile);
|
|
6031
|
+
let type;
|
|
6032
|
+
let ext2;
|
|
6033
|
+
if (fullBasename.endsWith(".json") || fullBasename.includes(".base.json") || fullBasename.includes(".{base}.json")) {
|
|
6034
|
+
type = "json";
|
|
6035
|
+
ext2 = ".json";
|
|
6036
|
+
} else if (fullBasename.startsWith(".env")) {
|
|
6037
|
+
type = "env";
|
|
6038
|
+
ext2 = "";
|
|
6039
|
+
} else {
|
|
6040
|
+
type = "unknown";
|
|
6041
|
+
ext2 = path2.extname(baseFile);
|
|
6042
|
+
}
|
|
6043
|
+
if (type === "unknown") {
|
|
6044
|
+
return null;
|
|
6045
|
+
}
|
|
6046
|
+
let outputName;
|
|
6047
|
+
if (type === "env") {
|
|
6048
|
+
outputName = fullBasename.replace(".base", "").replace(".{base}", "");
|
|
6049
|
+
} else {
|
|
6050
|
+
outputName = fullBasename.replace(".base", "").replace(".{base}", "");
|
|
6051
|
+
}
|
|
6052
|
+
const basePath = path2.join(cwd, baseFile);
|
|
6053
|
+
const outputPath = path2.join(cwd, dir, outputName);
|
|
6054
|
+
return {
|
|
6055
|
+
basePath,
|
|
6056
|
+
machinePath: "",
|
|
6057
|
+
outputPath,
|
|
6058
|
+
type
|
|
6059
|
+
};
|
|
6060
|
+
}
|
|
5987
6061
|
function createMergeOperation(machineFile, machineName, cwd) {
|
|
5988
6062
|
const dir = path2.dirname(machineFile);
|
|
5989
6063
|
const fullBasename = path2.basename(machineFile);
|
|
@@ -6458,6 +6532,142 @@ async function isFileTrackedByGit(filePath, cwd) {
|
|
|
6458
6532
|
}
|
|
6459
6533
|
}
|
|
6460
6534
|
|
|
6535
|
+
// src/core/git-hooks.ts
|
|
6536
|
+
import fs3 from "node:fs/promises";
|
|
6537
|
+
import path6 from "node:path";
|
|
6538
|
+
import { exec as exec2 } from "node:child_process";
|
|
6539
|
+
import { promisify as promisify2 } from "node:util";
|
|
6540
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
6541
|
+
var execAsync2 = promisify2(exec2);
|
|
6542
|
+
var __filename2 = fileURLToPath3(import.meta.url);
|
|
6543
|
+
var __dirname2 = path6.dirname(__filename2);
|
|
6544
|
+
var HOOK_NAMES = ["post-checkout", "post-merge", "post-commit"];
|
|
6545
|
+
var HOOKS_DIR = ".permachine/hooks";
|
|
6546
|
+
async function installHooks(options = {}) {
|
|
6547
|
+
const warnings = [];
|
|
6548
|
+
if (!await isGitRepository()) {
|
|
6549
|
+
throw new Error('Not a git repository. Run "git init" first.');
|
|
6550
|
+
}
|
|
6551
|
+
const cwd = process.cwd();
|
|
6552
|
+
const existingHooksPath = await getGitConfig("core.hooksPath");
|
|
6553
|
+
if (existingHooksPath && existingHooksPath !== HOOKS_DIR && !options.legacy) {
|
|
6554
|
+
warnings.push(`Git core.hooksPath is already set to: ${existingHooksPath}`, "Use --legacy flag to install hooks in .git/hooks instead");
|
|
6555
|
+
}
|
|
6556
|
+
const useLegacy = options.legacy || existingHooksPath && existingHooksPath !== HOOKS_DIR;
|
|
6557
|
+
if (useLegacy) {
|
|
6558
|
+
return await installLegacyHooks(warnings);
|
|
6559
|
+
} else {
|
|
6560
|
+
return await installHooksPathMethod(warnings);
|
|
6561
|
+
}
|
|
6562
|
+
}
|
|
6563
|
+
async function installHooksPathMethod(warnings) {
|
|
6564
|
+
const cwd = process.cwd();
|
|
6565
|
+
const hooksDir = path6.join(cwd, HOOKS_DIR);
|
|
6566
|
+
await fs3.mkdir(hooksDir, { recursive: true });
|
|
6567
|
+
let templatesDir = path6.join(__dirname2, "../../templates/hooks");
|
|
6568
|
+
if (!await fileExists2(path6.join(templatesDir, "post-checkout"))) {
|
|
6569
|
+
templatesDir = path6.join(__dirname2, "../templates/hooks");
|
|
6570
|
+
}
|
|
6571
|
+
const installedHooks = [];
|
|
6572
|
+
for (const hookName of HOOK_NAMES) {
|
|
6573
|
+
const templatePath = path6.join(templatesDir, hookName);
|
|
6574
|
+
const hookPath = path6.join(hooksDir, hookName);
|
|
6575
|
+
const content = await fs3.readFile(templatePath, "utf-8");
|
|
6576
|
+
await fs3.writeFile(hookPath, content, { mode: 493 });
|
|
6577
|
+
installedHooks.push(hookName);
|
|
6578
|
+
}
|
|
6579
|
+
await setGitConfig("core.hooksPath", HOOKS_DIR);
|
|
6580
|
+
logger.success(`Installed git hooks via core.hooksPath`);
|
|
6581
|
+
return {
|
|
6582
|
+
method: "hooksPath",
|
|
6583
|
+
hooksInstalled: installedHooks,
|
|
6584
|
+
warnings
|
|
6585
|
+
};
|
|
6586
|
+
}
|
|
6587
|
+
async function installLegacyHooks(warnings) {
|
|
6588
|
+
const cwd = process.cwd();
|
|
6589
|
+
const gitHooksDir = path6.join(cwd, ".git/hooks");
|
|
6590
|
+
const installedHooks = [];
|
|
6591
|
+
for (const hookName of HOOK_NAMES) {
|
|
6592
|
+
const hookPath = path6.join(gitHooksDir, hookName);
|
|
6593
|
+
const backupPath = path6.join(gitHooksDir, `${hookName}.pre-mcs`);
|
|
6594
|
+
const hookExists = await fileExists2(hookPath);
|
|
6595
|
+
if (hookExists) {
|
|
6596
|
+
await fs3.rename(hookPath, backupPath);
|
|
6597
|
+
}
|
|
6598
|
+
const hookContent = `#!/bin/sh
|
|
6599
|
+
# Auto-generated by permachine (legacy mode)
|
|
6600
|
+
|
|
6601
|
+
permachine merge --silent
|
|
6602
|
+
|
|
6603
|
+
# Call original hook if it existed
|
|
6604
|
+
if [ -f "${backupPath}" ]; then
|
|
6605
|
+
"${backupPath}" "$@"
|
|
6606
|
+
fi
|
|
6607
|
+
|
|
6608
|
+
exit 0
|
|
6609
|
+
`;
|
|
6610
|
+
await fs3.writeFile(hookPath, hookContent, { mode: 493 });
|
|
6611
|
+
installedHooks.push(hookName);
|
|
6612
|
+
}
|
|
6613
|
+
logger.success("Installed git hooks via legacy .git/hooks wrapping");
|
|
6614
|
+
return {
|
|
6615
|
+
method: "legacy",
|
|
6616
|
+
hooksInstalled: installedHooks,
|
|
6617
|
+
warnings
|
|
6618
|
+
};
|
|
6619
|
+
}
|
|
6620
|
+
async function uninstallHooks() {
|
|
6621
|
+
const cwd = process.cwd();
|
|
6622
|
+
const hooksPath = await getGitConfig("core.hooksPath");
|
|
6623
|
+
if (hooksPath === HOOKS_DIR) {
|
|
6624
|
+
await execAsync2("git config --unset core.hooksPath");
|
|
6625
|
+
const hooksDir = path6.join(cwd, HOOKS_DIR);
|
|
6626
|
+
await fs3.rm(hooksDir, { recursive: true, force: true });
|
|
6627
|
+
logger.success("Uninstalled git hooks (removed core.hooksPath)");
|
|
6628
|
+
} else {
|
|
6629
|
+
const gitHooksDir = path6.join(cwd, ".git/hooks");
|
|
6630
|
+
for (const hookName of HOOK_NAMES) {
|
|
6631
|
+
const hookPath = path6.join(gitHooksDir, hookName);
|
|
6632
|
+
const backupPath = path6.join(gitHooksDir, `${hookName}.pre-mcs`);
|
|
6633
|
+
if (await fileExists2(hookPath)) {
|
|
6634
|
+
await fs3.unlink(hookPath);
|
|
6635
|
+
}
|
|
6636
|
+
if (await fileExists2(backupPath)) {
|
|
6637
|
+
await fs3.rename(backupPath, hookPath);
|
|
6638
|
+
}
|
|
6639
|
+
}
|
|
6640
|
+
logger.success("Uninstalled git hooks (restored original hooks)");
|
|
6641
|
+
}
|
|
6642
|
+
}
|
|
6643
|
+
async function isGitRepository() {
|
|
6644
|
+
try {
|
|
6645
|
+
await execAsync2("git rev-parse --git-dir");
|
|
6646
|
+
return true;
|
|
6647
|
+
} catch {
|
|
6648
|
+
return false;
|
|
6649
|
+
}
|
|
6650
|
+
}
|
|
6651
|
+
async function getGitConfig(key) {
|
|
6652
|
+
try {
|
|
6653
|
+
const { stdout } = await execAsync2(`git config --get ${key}`);
|
|
6654
|
+
return stdout.trim() || null;
|
|
6655
|
+
} catch {
|
|
6656
|
+
return null;
|
|
6657
|
+
}
|
|
6658
|
+
}
|
|
6659
|
+
async function setGitConfig(key, value) {
|
|
6660
|
+
await execAsync2(`git config ${key} "${value}"`);
|
|
6661
|
+
}
|
|
6662
|
+
async function fileExists2(filePath) {
|
|
6663
|
+
try {
|
|
6664
|
+
await fs3.access(filePath);
|
|
6665
|
+
return true;
|
|
6666
|
+
} catch {
|
|
6667
|
+
return false;
|
|
6668
|
+
}
|
|
6669
|
+
}
|
|
6670
|
+
|
|
6461
6671
|
// node_modules/chokidar/index.js
|
|
6462
6672
|
import { EventEmitter as EventEmitter2 } from "node:events";
|
|
6463
6673
|
import { stat as statcb, Stats } from "node:fs";
|
|
@@ -6549,7 +6759,7 @@ class ReaddirpStream extends Readable {
|
|
|
6549
6759
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
6550
6760
|
const statMethod = opts.lstat ? lstat2 : stat;
|
|
6551
6761
|
if (wantBigintFsStats) {
|
|
6552
|
-
this._stat = (
|
|
6762
|
+
this._stat = (path7) => statMethod(path7, { bigint: true });
|
|
6553
6763
|
} else {
|
|
6554
6764
|
this._stat = statMethod;
|
|
6555
6765
|
}
|
|
@@ -6574,8 +6784,8 @@ class ReaddirpStream extends Readable {
|
|
|
6574
6784
|
const par = this.parent;
|
|
6575
6785
|
const fil = par && par.files;
|
|
6576
6786
|
if (fil && fil.length > 0) {
|
|
6577
|
-
const { path:
|
|
6578
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
6787
|
+
const { path: path7, depth } = par;
|
|
6788
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path7));
|
|
6579
6789
|
const awaited = await Promise.all(slice);
|
|
6580
6790
|
for (const entry of awaited) {
|
|
6581
6791
|
if (!entry)
|
|
@@ -6615,20 +6825,20 @@ class ReaddirpStream extends Readable {
|
|
|
6615
6825
|
this.reading = false;
|
|
6616
6826
|
}
|
|
6617
6827
|
}
|
|
6618
|
-
async _exploreDir(
|
|
6828
|
+
async _exploreDir(path7, depth) {
|
|
6619
6829
|
let files;
|
|
6620
6830
|
try {
|
|
6621
|
-
files = await readdir2(
|
|
6831
|
+
files = await readdir2(path7, this._rdOptions);
|
|
6622
6832
|
} catch (error) {
|
|
6623
6833
|
this._onError(error);
|
|
6624
6834
|
}
|
|
6625
|
-
return { files, depth, path:
|
|
6835
|
+
return { files, depth, path: path7 };
|
|
6626
6836
|
}
|
|
6627
|
-
async _formatEntry(dirent,
|
|
6837
|
+
async _formatEntry(dirent, path7) {
|
|
6628
6838
|
let entry;
|
|
6629
6839
|
const basename = this._isDirent ? dirent.name : dirent;
|
|
6630
6840
|
try {
|
|
6631
|
-
const fullPath = presolve(pjoin(
|
|
6841
|
+
const fullPath = presolve(pjoin(path7, basename));
|
|
6632
6842
|
entry = { path: prelative(this._root, fullPath), fullPath, basename };
|
|
6633
6843
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
6634
6844
|
} catch (err) {
|
|
@@ -7027,16 +7237,16 @@ var delFromSet = (main, prop, item) => {
|
|
|
7027
7237
|
};
|
|
7028
7238
|
var isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val;
|
|
7029
7239
|
var FsWatchInstances = new Map;
|
|
7030
|
-
function createFsWatchInstance(
|
|
7240
|
+
function createFsWatchInstance(path7, options, listener, errHandler, emitRaw) {
|
|
7031
7241
|
const handleEvent = (rawEvent, evPath) => {
|
|
7032
|
-
listener(
|
|
7033
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
7034
|
-
if (evPath &&
|
|
7035
|
-
fsWatchBroadcast(sp.resolve(
|
|
7242
|
+
listener(path7);
|
|
7243
|
+
emitRaw(rawEvent, evPath, { watchedPath: path7 });
|
|
7244
|
+
if (evPath && path7 !== evPath) {
|
|
7245
|
+
fsWatchBroadcast(sp.resolve(path7, evPath), KEY_LISTENERS, sp.join(path7, evPath));
|
|
7036
7246
|
}
|
|
7037
7247
|
};
|
|
7038
7248
|
try {
|
|
7039
|
-
return fs_watch(
|
|
7249
|
+
return fs_watch(path7, {
|
|
7040
7250
|
persistent: options.persistent
|
|
7041
7251
|
}, handleEvent);
|
|
7042
7252
|
} catch (error) {
|
|
@@ -7052,12 +7262,12 @@ var fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
|
|
|
7052
7262
|
listener(val1, val2, val3);
|
|
7053
7263
|
});
|
|
7054
7264
|
};
|
|
7055
|
-
var setFsWatchListener = (
|
|
7265
|
+
var setFsWatchListener = (path7, fullPath, options, handlers) => {
|
|
7056
7266
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
7057
7267
|
let cont = FsWatchInstances.get(fullPath);
|
|
7058
7268
|
let watcher;
|
|
7059
7269
|
if (!options.persistent) {
|
|
7060
|
-
watcher = createFsWatchInstance(
|
|
7270
|
+
watcher = createFsWatchInstance(path7, options, listener, errHandler, rawEmitter);
|
|
7061
7271
|
if (!watcher)
|
|
7062
7272
|
return;
|
|
7063
7273
|
return watcher.close.bind(watcher);
|
|
@@ -7067,7 +7277,7 @@ var setFsWatchListener = (path6, fullPath, options, handlers) => {
|
|
|
7067
7277
|
addAndConvert(cont, KEY_ERR, errHandler);
|
|
7068
7278
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
7069
7279
|
} else {
|
|
7070
|
-
watcher = createFsWatchInstance(
|
|
7280
|
+
watcher = createFsWatchInstance(path7, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
|
|
7071
7281
|
if (!watcher)
|
|
7072
7282
|
return;
|
|
7073
7283
|
watcher.on(EV.ERROR, async (error) => {
|
|
@@ -7076,7 +7286,7 @@ var setFsWatchListener = (path6, fullPath, options, handlers) => {
|
|
|
7076
7286
|
cont.watcherUnusable = true;
|
|
7077
7287
|
if (isWindows && error.code === "EPERM") {
|
|
7078
7288
|
try {
|
|
7079
|
-
const fd = await open(
|
|
7289
|
+
const fd = await open(path7, "r");
|
|
7080
7290
|
await fd.close();
|
|
7081
7291
|
broadcastErr(error);
|
|
7082
7292
|
} catch (err) {}
|
|
@@ -7106,7 +7316,7 @@ var setFsWatchListener = (path6, fullPath, options, handlers) => {
|
|
|
7106
7316
|
};
|
|
7107
7317
|
};
|
|
7108
7318
|
var FsWatchFileInstances = new Map;
|
|
7109
|
-
var setFsWatchFileListener = (
|
|
7319
|
+
var setFsWatchFileListener = (path7, fullPath, options, handlers) => {
|
|
7110
7320
|
const { listener, rawEmitter } = handlers;
|
|
7111
7321
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
7112
7322
|
const copts = cont && cont.options;
|
|
@@ -7128,7 +7338,7 @@ var setFsWatchFileListener = (path6, fullPath, options, handlers) => {
|
|
|
7128
7338
|
});
|
|
7129
7339
|
const currmtime = curr.mtimeMs;
|
|
7130
7340
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
7131
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
7341
|
+
foreach(cont.listeners, (listener2) => listener2(path7, curr));
|
|
7132
7342
|
}
|
|
7133
7343
|
})
|
|
7134
7344
|
};
|
|
@@ -7153,13 +7363,13 @@ class NodeFsHandler {
|
|
|
7153
7363
|
this.fsw = fsW;
|
|
7154
7364
|
this._boundHandleError = (error) => fsW._handleError(error);
|
|
7155
7365
|
}
|
|
7156
|
-
_watchWithNodeFs(
|
|
7366
|
+
_watchWithNodeFs(path7, listener) {
|
|
7157
7367
|
const opts = this.fsw.options;
|
|
7158
|
-
const directory = sp.dirname(
|
|
7159
|
-
const basename2 = sp.basename(
|
|
7368
|
+
const directory = sp.dirname(path7);
|
|
7369
|
+
const basename2 = sp.basename(path7);
|
|
7160
7370
|
const parent = this.fsw._getWatchedDir(directory);
|
|
7161
7371
|
parent.add(basename2);
|
|
7162
|
-
const absolutePath = sp.resolve(
|
|
7372
|
+
const absolutePath = sp.resolve(path7);
|
|
7163
7373
|
const options = {
|
|
7164
7374
|
persistent: opts.persistent
|
|
7165
7375
|
};
|
|
@@ -7169,12 +7379,12 @@ class NodeFsHandler {
|
|
|
7169
7379
|
if (opts.usePolling) {
|
|
7170
7380
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
7171
7381
|
options.interval = enableBin && isBinaryPath(basename2) ? opts.binaryInterval : opts.interval;
|
|
7172
|
-
closer = setFsWatchFileListener(
|
|
7382
|
+
closer = setFsWatchFileListener(path7, absolutePath, options, {
|
|
7173
7383
|
listener,
|
|
7174
7384
|
rawEmitter: this.fsw._emitRaw
|
|
7175
7385
|
});
|
|
7176
7386
|
} else {
|
|
7177
|
-
closer = setFsWatchListener(
|
|
7387
|
+
closer = setFsWatchListener(path7, absolutePath, options, {
|
|
7178
7388
|
listener,
|
|
7179
7389
|
errHandler: this._boundHandleError,
|
|
7180
7390
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -7192,7 +7402,7 @@ class NodeFsHandler {
|
|
|
7192
7402
|
let prevStats = stats;
|
|
7193
7403
|
if (parent.has(basename2))
|
|
7194
7404
|
return;
|
|
7195
|
-
const listener = async (
|
|
7405
|
+
const listener = async (path7, newStats) => {
|
|
7196
7406
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
7197
7407
|
return;
|
|
7198
7408
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -7206,11 +7416,11 @@ class NodeFsHandler {
|
|
|
7206
7416
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
7207
7417
|
}
|
|
7208
7418
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
7209
|
-
this.fsw._closeFile(
|
|
7419
|
+
this.fsw._closeFile(path7);
|
|
7210
7420
|
prevStats = newStats2;
|
|
7211
7421
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
7212
7422
|
if (closer2)
|
|
7213
|
-
this.fsw._addPathCloser(
|
|
7423
|
+
this.fsw._addPathCloser(path7, closer2);
|
|
7214
7424
|
} else {
|
|
7215
7425
|
prevStats = newStats2;
|
|
7216
7426
|
}
|
|
@@ -7234,7 +7444,7 @@ class NodeFsHandler {
|
|
|
7234
7444
|
}
|
|
7235
7445
|
return closer;
|
|
7236
7446
|
}
|
|
7237
|
-
async _handleSymlink(entry, directory,
|
|
7447
|
+
async _handleSymlink(entry, directory, path7, item) {
|
|
7238
7448
|
if (this.fsw.closed) {
|
|
7239
7449
|
return;
|
|
7240
7450
|
}
|
|
@@ -7244,7 +7454,7 @@ class NodeFsHandler {
|
|
|
7244
7454
|
this.fsw._incrReadyCount();
|
|
7245
7455
|
let linkPath;
|
|
7246
7456
|
try {
|
|
7247
|
-
linkPath = await fsrealpath(
|
|
7457
|
+
linkPath = await fsrealpath(path7);
|
|
7248
7458
|
} catch (e) {
|
|
7249
7459
|
this.fsw._emitReady();
|
|
7250
7460
|
return true;
|
|
@@ -7254,12 +7464,12 @@ class NodeFsHandler {
|
|
|
7254
7464
|
if (dir.has(item)) {
|
|
7255
7465
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
7256
7466
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
7257
|
-
this.fsw._emit(EV.CHANGE,
|
|
7467
|
+
this.fsw._emit(EV.CHANGE, path7, entry.stats);
|
|
7258
7468
|
}
|
|
7259
7469
|
} else {
|
|
7260
7470
|
dir.add(item);
|
|
7261
7471
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
7262
|
-
this.fsw._emit(EV.ADD,
|
|
7472
|
+
this.fsw._emit(EV.ADD, path7, entry.stats);
|
|
7263
7473
|
}
|
|
7264
7474
|
this.fsw._emitReady();
|
|
7265
7475
|
return true;
|
|
@@ -7289,9 +7499,9 @@ class NodeFsHandler {
|
|
|
7289
7499
|
return;
|
|
7290
7500
|
}
|
|
7291
7501
|
const item = entry.path;
|
|
7292
|
-
let
|
|
7502
|
+
let path7 = sp.join(directory, item);
|
|
7293
7503
|
current.add(item);
|
|
7294
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
7504
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path7, item)) {
|
|
7295
7505
|
return;
|
|
7296
7506
|
}
|
|
7297
7507
|
if (this.fsw.closed) {
|
|
@@ -7300,8 +7510,8 @@ class NodeFsHandler {
|
|
|
7300
7510
|
}
|
|
7301
7511
|
if (item === target || !target && !previous.has(item)) {
|
|
7302
7512
|
this.fsw._incrReadyCount();
|
|
7303
|
-
|
|
7304
|
-
this._addToNodeFs(
|
|
7513
|
+
path7 = sp.join(dir, sp.relative(dir, path7));
|
|
7514
|
+
this._addToNodeFs(path7, initialAdd, wh, depth + 1);
|
|
7305
7515
|
}
|
|
7306
7516
|
}).on(EV.ERROR, this._boundHandleError);
|
|
7307
7517
|
return new Promise((resolve2, reject) => {
|
|
@@ -7350,13 +7560,13 @@ class NodeFsHandler {
|
|
|
7350
7560
|
}
|
|
7351
7561
|
return closer;
|
|
7352
7562
|
}
|
|
7353
|
-
async _addToNodeFs(
|
|
7563
|
+
async _addToNodeFs(path7, initialAdd, priorWh, depth, target) {
|
|
7354
7564
|
const ready = this.fsw._emitReady;
|
|
7355
|
-
if (this.fsw._isIgnored(
|
|
7565
|
+
if (this.fsw._isIgnored(path7) || this.fsw.closed) {
|
|
7356
7566
|
ready();
|
|
7357
7567
|
return false;
|
|
7358
7568
|
}
|
|
7359
|
-
const wh = this.fsw._getWatchHelpers(
|
|
7569
|
+
const wh = this.fsw._getWatchHelpers(path7);
|
|
7360
7570
|
if (priorWh) {
|
|
7361
7571
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
7362
7572
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -7372,8 +7582,8 @@ class NodeFsHandler {
|
|
|
7372
7582
|
const follow = this.fsw.options.followSymlinks;
|
|
7373
7583
|
let closer;
|
|
7374
7584
|
if (stats.isDirectory()) {
|
|
7375
|
-
const absPath = sp.resolve(
|
|
7376
|
-
const targetPath = follow ? await fsrealpath(
|
|
7585
|
+
const absPath = sp.resolve(path7);
|
|
7586
|
+
const targetPath = follow ? await fsrealpath(path7) : path7;
|
|
7377
7587
|
if (this.fsw.closed)
|
|
7378
7588
|
return;
|
|
7379
7589
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -7383,29 +7593,29 @@ class NodeFsHandler {
|
|
|
7383
7593
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
7384
7594
|
}
|
|
7385
7595
|
} else if (stats.isSymbolicLink()) {
|
|
7386
|
-
const targetPath = follow ? await fsrealpath(
|
|
7596
|
+
const targetPath = follow ? await fsrealpath(path7) : path7;
|
|
7387
7597
|
if (this.fsw.closed)
|
|
7388
7598
|
return;
|
|
7389
7599
|
const parent = sp.dirname(wh.watchPath);
|
|
7390
7600
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
7391
7601
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
7392
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
7602
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path7, wh, targetPath);
|
|
7393
7603
|
if (this.fsw.closed)
|
|
7394
7604
|
return;
|
|
7395
7605
|
if (targetPath !== undefined) {
|
|
7396
|
-
this.fsw._symlinkPaths.set(sp.resolve(
|
|
7606
|
+
this.fsw._symlinkPaths.set(sp.resolve(path7), targetPath);
|
|
7397
7607
|
}
|
|
7398
7608
|
} else {
|
|
7399
7609
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
7400
7610
|
}
|
|
7401
7611
|
ready();
|
|
7402
7612
|
if (closer)
|
|
7403
|
-
this.fsw._addPathCloser(
|
|
7613
|
+
this.fsw._addPathCloser(path7, closer);
|
|
7404
7614
|
return false;
|
|
7405
7615
|
} catch (error) {
|
|
7406
7616
|
if (this.fsw._handleError(error)) {
|
|
7407
7617
|
ready();
|
|
7408
|
-
return
|
|
7618
|
+
return path7;
|
|
7409
7619
|
}
|
|
7410
7620
|
}
|
|
7411
7621
|
}
|
|
@@ -7449,24 +7659,24 @@ function createPattern(matcher) {
|
|
|
7449
7659
|
}
|
|
7450
7660
|
return () => false;
|
|
7451
7661
|
}
|
|
7452
|
-
function normalizePath(
|
|
7453
|
-
if (typeof
|
|
7662
|
+
function normalizePath(path7) {
|
|
7663
|
+
if (typeof path7 !== "string")
|
|
7454
7664
|
throw new Error("string expected");
|
|
7455
|
-
|
|
7456
|
-
|
|
7665
|
+
path7 = sp2.normalize(path7);
|
|
7666
|
+
path7 = path7.replace(/\\/g, "/");
|
|
7457
7667
|
let prepend = false;
|
|
7458
|
-
if (
|
|
7668
|
+
if (path7.startsWith("//"))
|
|
7459
7669
|
prepend = true;
|
|
7460
|
-
|
|
7670
|
+
path7 = path7.replace(DOUBLE_SLASH_RE, "/");
|
|
7461
7671
|
if (prepend)
|
|
7462
|
-
|
|
7463
|
-
return
|
|
7672
|
+
path7 = "/" + path7;
|
|
7673
|
+
return path7;
|
|
7464
7674
|
}
|
|
7465
7675
|
function matchPatterns(patterns, testString, stats) {
|
|
7466
|
-
const
|
|
7676
|
+
const path7 = normalizePath(testString);
|
|
7467
7677
|
for (let index = 0;index < patterns.length; index++) {
|
|
7468
7678
|
const pattern = patterns[index];
|
|
7469
|
-
if (pattern(
|
|
7679
|
+
if (pattern(path7, stats)) {
|
|
7470
7680
|
return true;
|
|
7471
7681
|
}
|
|
7472
7682
|
}
|
|
@@ -7504,19 +7714,19 @@ var toUnix = (string) => {
|
|
|
7504
7714
|
}
|
|
7505
7715
|
return str;
|
|
7506
7716
|
};
|
|
7507
|
-
var normalizePathToUnix = (
|
|
7508
|
-
var normalizeIgnored = (cwd = "") => (
|
|
7509
|
-
if (typeof
|
|
7510
|
-
return normalizePathToUnix(sp2.isAbsolute(
|
|
7717
|
+
var normalizePathToUnix = (path7) => toUnix(sp2.normalize(toUnix(path7)));
|
|
7718
|
+
var normalizeIgnored = (cwd = "") => (path7) => {
|
|
7719
|
+
if (typeof path7 === "string") {
|
|
7720
|
+
return normalizePathToUnix(sp2.isAbsolute(path7) ? path7 : sp2.join(cwd, path7));
|
|
7511
7721
|
} else {
|
|
7512
|
-
return
|
|
7722
|
+
return path7;
|
|
7513
7723
|
}
|
|
7514
7724
|
};
|
|
7515
|
-
var getAbsolutePath = (
|
|
7516
|
-
if (sp2.isAbsolute(
|
|
7517
|
-
return
|
|
7725
|
+
var getAbsolutePath = (path7, cwd) => {
|
|
7726
|
+
if (sp2.isAbsolute(path7)) {
|
|
7727
|
+
return path7;
|
|
7518
7728
|
}
|
|
7519
|
-
return sp2.join(cwd,
|
|
7729
|
+
return sp2.join(cwd, path7);
|
|
7520
7730
|
};
|
|
7521
7731
|
var EMPTY_SET = Object.freeze(new Set);
|
|
7522
7732
|
|
|
@@ -7583,10 +7793,10 @@ class WatchHelper {
|
|
|
7583
7793
|
dirParts;
|
|
7584
7794
|
followSymlinks;
|
|
7585
7795
|
statMethod;
|
|
7586
|
-
constructor(
|
|
7796
|
+
constructor(path7, follow, fsw) {
|
|
7587
7797
|
this.fsw = fsw;
|
|
7588
|
-
const watchPath =
|
|
7589
|
-
this.path =
|
|
7798
|
+
const watchPath = path7;
|
|
7799
|
+
this.path = path7 = path7.replace(REPLACER_RE, "");
|
|
7590
7800
|
this.watchPath = watchPath;
|
|
7591
7801
|
this.fullWatchPath = sp2.resolve(watchPath);
|
|
7592
7802
|
this.dirParts = [];
|
|
@@ -7717,20 +7927,20 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7717
7927
|
this._closePromise = undefined;
|
|
7718
7928
|
let paths = unifyPaths(paths_);
|
|
7719
7929
|
if (cwd) {
|
|
7720
|
-
paths = paths.map((
|
|
7721
|
-
const absPath = getAbsolutePath(
|
|
7930
|
+
paths = paths.map((path7) => {
|
|
7931
|
+
const absPath = getAbsolutePath(path7, cwd);
|
|
7722
7932
|
return absPath;
|
|
7723
7933
|
});
|
|
7724
7934
|
}
|
|
7725
|
-
paths.forEach((
|
|
7726
|
-
this._removeIgnoredPath(
|
|
7935
|
+
paths.forEach((path7) => {
|
|
7936
|
+
this._removeIgnoredPath(path7);
|
|
7727
7937
|
});
|
|
7728
7938
|
this._userIgnored = undefined;
|
|
7729
7939
|
if (!this._readyCount)
|
|
7730
7940
|
this._readyCount = 0;
|
|
7731
7941
|
this._readyCount += paths.length;
|
|
7732
|
-
Promise.all(paths.map(async (
|
|
7733
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
7942
|
+
Promise.all(paths.map(async (path7) => {
|
|
7943
|
+
const res = await this._nodeFsHandler._addToNodeFs(path7, !_internal, undefined, 0, _origAdd);
|
|
7734
7944
|
if (res)
|
|
7735
7945
|
this._emitReady();
|
|
7736
7946
|
return res;
|
|
@@ -7749,17 +7959,17 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7749
7959
|
return this;
|
|
7750
7960
|
const paths = unifyPaths(paths_);
|
|
7751
7961
|
const { cwd } = this.options;
|
|
7752
|
-
paths.forEach((
|
|
7753
|
-
if (!sp2.isAbsolute(
|
|
7962
|
+
paths.forEach((path7) => {
|
|
7963
|
+
if (!sp2.isAbsolute(path7) && !this._closers.has(path7)) {
|
|
7754
7964
|
if (cwd)
|
|
7755
|
-
|
|
7756
|
-
|
|
7965
|
+
path7 = sp2.join(cwd, path7);
|
|
7966
|
+
path7 = sp2.resolve(path7);
|
|
7757
7967
|
}
|
|
7758
|
-
this._closePath(
|
|
7759
|
-
this._addIgnoredPath(
|
|
7760
|
-
if (this._watched.has(
|
|
7968
|
+
this._closePath(path7);
|
|
7969
|
+
this._addIgnoredPath(path7);
|
|
7970
|
+
if (this._watched.has(path7)) {
|
|
7761
7971
|
this._addIgnoredPath({
|
|
7762
|
-
path:
|
|
7972
|
+
path: path7,
|
|
7763
7973
|
recursive: true
|
|
7764
7974
|
});
|
|
7765
7975
|
}
|
|
@@ -7808,38 +8018,38 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7808
8018
|
if (event !== EVENTS.ERROR)
|
|
7809
8019
|
this.emit(EVENTS.ALL, event, ...args);
|
|
7810
8020
|
}
|
|
7811
|
-
async _emit(event,
|
|
8021
|
+
async _emit(event, path7, stats) {
|
|
7812
8022
|
if (this.closed)
|
|
7813
8023
|
return;
|
|
7814
8024
|
const opts = this.options;
|
|
7815
8025
|
if (isWindows)
|
|
7816
|
-
|
|
8026
|
+
path7 = sp2.normalize(path7);
|
|
7817
8027
|
if (opts.cwd)
|
|
7818
|
-
|
|
7819
|
-
const args = [
|
|
8028
|
+
path7 = sp2.relative(opts.cwd, path7);
|
|
8029
|
+
const args = [path7];
|
|
7820
8030
|
if (stats != null)
|
|
7821
8031
|
args.push(stats);
|
|
7822
8032
|
const awf = opts.awaitWriteFinish;
|
|
7823
8033
|
let pw;
|
|
7824
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
8034
|
+
if (awf && (pw = this._pendingWrites.get(path7))) {
|
|
7825
8035
|
pw.lastChange = new Date;
|
|
7826
8036
|
return this;
|
|
7827
8037
|
}
|
|
7828
8038
|
if (opts.atomic) {
|
|
7829
8039
|
if (event === EVENTS.UNLINK) {
|
|
7830
|
-
this._pendingUnlinks.set(
|
|
8040
|
+
this._pendingUnlinks.set(path7, [event, ...args]);
|
|
7831
8041
|
setTimeout(() => {
|
|
7832
|
-
this._pendingUnlinks.forEach((entry,
|
|
8042
|
+
this._pendingUnlinks.forEach((entry, path8) => {
|
|
7833
8043
|
this.emit(...entry);
|
|
7834
8044
|
this.emit(EVENTS.ALL, ...entry);
|
|
7835
|
-
this._pendingUnlinks.delete(
|
|
8045
|
+
this._pendingUnlinks.delete(path8);
|
|
7836
8046
|
});
|
|
7837
8047
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
7838
8048
|
return this;
|
|
7839
8049
|
}
|
|
7840
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
8050
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path7)) {
|
|
7841
8051
|
event = EVENTS.CHANGE;
|
|
7842
|
-
this._pendingUnlinks.delete(
|
|
8052
|
+
this._pendingUnlinks.delete(path7);
|
|
7843
8053
|
}
|
|
7844
8054
|
}
|
|
7845
8055
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -7857,16 +8067,16 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7857
8067
|
this.emitWithAll(event, args);
|
|
7858
8068
|
}
|
|
7859
8069
|
};
|
|
7860
|
-
this._awaitWriteFinish(
|
|
8070
|
+
this._awaitWriteFinish(path7, awf.stabilityThreshold, event, awfEmit);
|
|
7861
8071
|
return this;
|
|
7862
8072
|
}
|
|
7863
8073
|
if (event === EVENTS.CHANGE) {
|
|
7864
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
8074
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path7, 50);
|
|
7865
8075
|
if (isThrottled)
|
|
7866
8076
|
return this;
|
|
7867
8077
|
}
|
|
7868
8078
|
if (opts.alwaysStat && stats === undefined && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
7869
|
-
const fullPath = opts.cwd ? sp2.join(opts.cwd,
|
|
8079
|
+
const fullPath = opts.cwd ? sp2.join(opts.cwd, path7) : path7;
|
|
7870
8080
|
let stats2;
|
|
7871
8081
|
try {
|
|
7872
8082
|
stats2 = await stat3(fullPath);
|
|
@@ -7885,23 +8095,23 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7885
8095
|
}
|
|
7886
8096
|
return error || this.closed;
|
|
7887
8097
|
}
|
|
7888
|
-
_throttle(actionType,
|
|
8098
|
+
_throttle(actionType, path7, timeout) {
|
|
7889
8099
|
if (!this._throttled.has(actionType)) {
|
|
7890
8100
|
this._throttled.set(actionType, new Map);
|
|
7891
8101
|
}
|
|
7892
8102
|
const action = this._throttled.get(actionType);
|
|
7893
8103
|
if (!action)
|
|
7894
8104
|
throw new Error("invalid throttle");
|
|
7895
|
-
const actionPath = action.get(
|
|
8105
|
+
const actionPath = action.get(path7);
|
|
7896
8106
|
if (actionPath) {
|
|
7897
8107
|
actionPath.count++;
|
|
7898
8108
|
return false;
|
|
7899
8109
|
}
|
|
7900
8110
|
let timeoutObject;
|
|
7901
8111
|
const clear = () => {
|
|
7902
|
-
const item = action.get(
|
|
8112
|
+
const item = action.get(path7);
|
|
7903
8113
|
const count = item ? item.count : 0;
|
|
7904
|
-
action.delete(
|
|
8114
|
+
action.delete(path7);
|
|
7905
8115
|
clearTimeout(timeoutObject);
|
|
7906
8116
|
if (item)
|
|
7907
8117
|
clearTimeout(item.timeoutObject);
|
|
@@ -7909,50 +8119,50 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7909
8119
|
};
|
|
7910
8120
|
timeoutObject = setTimeout(clear, timeout);
|
|
7911
8121
|
const thr = { timeoutObject, clear, count: 0 };
|
|
7912
|
-
action.set(
|
|
8122
|
+
action.set(path7, thr);
|
|
7913
8123
|
return thr;
|
|
7914
8124
|
}
|
|
7915
8125
|
_incrReadyCount() {
|
|
7916
8126
|
return this._readyCount++;
|
|
7917
8127
|
}
|
|
7918
|
-
_awaitWriteFinish(
|
|
8128
|
+
_awaitWriteFinish(path7, threshold, event, awfEmit) {
|
|
7919
8129
|
const awf = this.options.awaitWriteFinish;
|
|
7920
8130
|
if (typeof awf !== "object")
|
|
7921
8131
|
return;
|
|
7922
8132
|
const pollInterval = awf.pollInterval;
|
|
7923
8133
|
let timeoutHandler;
|
|
7924
|
-
let fullPath =
|
|
7925
|
-
if (this.options.cwd && !sp2.isAbsolute(
|
|
7926
|
-
fullPath = sp2.join(this.options.cwd,
|
|
8134
|
+
let fullPath = path7;
|
|
8135
|
+
if (this.options.cwd && !sp2.isAbsolute(path7)) {
|
|
8136
|
+
fullPath = sp2.join(this.options.cwd, path7);
|
|
7927
8137
|
}
|
|
7928
8138
|
const now = new Date;
|
|
7929
8139
|
const writes = this._pendingWrites;
|
|
7930
8140
|
function awaitWriteFinishFn(prevStat) {
|
|
7931
8141
|
statcb(fullPath, (err, curStat) => {
|
|
7932
|
-
if (err || !writes.has(
|
|
8142
|
+
if (err || !writes.has(path7)) {
|
|
7933
8143
|
if (err && err.code !== "ENOENT")
|
|
7934
8144
|
awfEmit(err);
|
|
7935
8145
|
return;
|
|
7936
8146
|
}
|
|
7937
8147
|
const now2 = Number(new Date);
|
|
7938
8148
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
7939
|
-
writes.get(
|
|
8149
|
+
writes.get(path7).lastChange = now2;
|
|
7940
8150
|
}
|
|
7941
|
-
const pw = writes.get(
|
|
8151
|
+
const pw = writes.get(path7);
|
|
7942
8152
|
const df = now2 - pw.lastChange;
|
|
7943
8153
|
if (df >= threshold) {
|
|
7944
|
-
writes.delete(
|
|
8154
|
+
writes.delete(path7);
|
|
7945
8155
|
awfEmit(undefined, curStat);
|
|
7946
8156
|
} else {
|
|
7947
8157
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
7948
8158
|
}
|
|
7949
8159
|
});
|
|
7950
8160
|
}
|
|
7951
|
-
if (!writes.has(
|
|
7952
|
-
writes.set(
|
|
8161
|
+
if (!writes.has(path7)) {
|
|
8162
|
+
writes.set(path7, {
|
|
7953
8163
|
lastChange: now,
|
|
7954
8164
|
cancelWait: () => {
|
|
7955
|
-
writes.delete(
|
|
8165
|
+
writes.delete(path7);
|
|
7956
8166
|
clearTimeout(timeoutHandler);
|
|
7957
8167
|
return event;
|
|
7958
8168
|
}
|
|
@@ -7960,8 +8170,8 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7960
8170
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval);
|
|
7961
8171
|
}
|
|
7962
8172
|
}
|
|
7963
|
-
_isIgnored(
|
|
7964
|
-
if (this.options.atomic && DOT_RE.test(
|
|
8173
|
+
_isIgnored(path7, stats) {
|
|
8174
|
+
if (this.options.atomic && DOT_RE.test(path7))
|
|
7965
8175
|
return true;
|
|
7966
8176
|
if (!this._userIgnored) {
|
|
7967
8177
|
const { cwd } = this.options;
|
|
@@ -7971,13 +8181,13 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7971
8181
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
7972
8182
|
this._userIgnored = anymatch(list, undefined);
|
|
7973
8183
|
}
|
|
7974
|
-
return this._userIgnored(
|
|
8184
|
+
return this._userIgnored(path7, stats);
|
|
7975
8185
|
}
|
|
7976
|
-
_isntIgnored(
|
|
7977
|
-
return !this._isIgnored(
|
|
8186
|
+
_isntIgnored(path7, stat4) {
|
|
8187
|
+
return !this._isIgnored(path7, stat4);
|
|
7978
8188
|
}
|
|
7979
|
-
_getWatchHelpers(
|
|
7980
|
-
return new WatchHelper(
|
|
8189
|
+
_getWatchHelpers(path7) {
|
|
8190
|
+
return new WatchHelper(path7, this.options.followSymlinks, this);
|
|
7981
8191
|
}
|
|
7982
8192
|
_getWatchedDir(directory) {
|
|
7983
8193
|
const dir = sp2.resolve(directory);
|
|
@@ -7991,57 +8201,57 @@ class FSWatcher extends EventEmitter2 {
|
|
|
7991
8201
|
return Boolean(Number(stats.mode) & 256);
|
|
7992
8202
|
}
|
|
7993
8203
|
_remove(directory, item, isDirectory) {
|
|
7994
|
-
const
|
|
7995
|
-
const fullPath = sp2.resolve(
|
|
7996
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
7997
|
-
if (!this._throttle("remove",
|
|
8204
|
+
const path7 = sp2.join(directory, item);
|
|
8205
|
+
const fullPath = sp2.resolve(path7);
|
|
8206
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path7) || this._watched.has(fullPath);
|
|
8207
|
+
if (!this._throttle("remove", path7, 100))
|
|
7998
8208
|
return;
|
|
7999
8209
|
if (!isDirectory && this._watched.size === 1) {
|
|
8000
8210
|
this.add(directory, item, true);
|
|
8001
8211
|
}
|
|
8002
|
-
const wp = this._getWatchedDir(
|
|
8212
|
+
const wp = this._getWatchedDir(path7);
|
|
8003
8213
|
const nestedDirectoryChildren = wp.getChildren();
|
|
8004
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
8214
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path7, nested));
|
|
8005
8215
|
const parent = this._getWatchedDir(directory);
|
|
8006
8216
|
const wasTracked = parent.has(item);
|
|
8007
8217
|
parent.remove(item);
|
|
8008
8218
|
if (this._symlinkPaths.has(fullPath)) {
|
|
8009
8219
|
this._symlinkPaths.delete(fullPath);
|
|
8010
8220
|
}
|
|
8011
|
-
let relPath =
|
|
8221
|
+
let relPath = path7;
|
|
8012
8222
|
if (this.options.cwd)
|
|
8013
|
-
relPath = sp2.relative(this.options.cwd,
|
|
8223
|
+
relPath = sp2.relative(this.options.cwd, path7);
|
|
8014
8224
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
8015
8225
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
8016
8226
|
if (event === EVENTS.ADD)
|
|
8017
8227
|
return;
|
|
8018
8228
|
}
|
|
8019
|
-
this._watched.delete(
|
|
8229
|
+
this._watched.delete(path7);
|
|
8020
8230
|
this._watched.delete(fullPath);
|
|
8021
8231
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
8022
|
-
if (wasTracked && !this._isIgnored(
|
|
8023
|
-
this._emit(eventName,
|
|
8024
|
-
this._closePath(
|
|
8232
|
+
if (wasTracked && !this._isIgnored(path7))
|
|
8233
|
+
this._emit(eventName, path7);
|
|
8234
|
+
this._closePath(path7);
|
|
8025
8235
|
}
|
|
8026
|
-
_closePath(
|
|
8027
|
-
this._closeFile(
|
|
8028
|
-
const dir = sp2.dirname(
|
|
8029
|
-
this._getWatchedDir(dir).remove(sp2.basename(
|
|
8236
|
+
_closePath(path7) {
|
|
8237
|
+
this._closeFile(path7);
|
|
8238
|
+
const dir = sp2.dirname(path7);
|
|
8239
|
+
this._getWatchedDir(dir).remove(sp2.basename(path7));
|
|
8030
8240
|
}
|
|
8031
|
-
_closeFile(
|
|
8032
|
-
const closers = this._closers.get(
|
|
8241
|
+
_closeFile(path7) {
|
|
8242
|
+
const closers = this._closers.get(path7);
|
|
8033
8243
|
if (!closers)
|
|
8034
8244
|
return;
|
|
8035
8245
|
closers.forEach((closer) => closer());
|
|
8036
|
-
this._closers.delete(
|
|
8246
|
+
this._closers.delete(path7);
|
|
8037
8247
|
}
|
|
8038
|
-
_addPathCloser(
|
|
8248
|
+
_addPathCloser(path7, closer) {
|
|
8039
8249
|
if (!closer)
|
|
8040
8250
|
return;
|
|
8041
|
-
let list = this._closers.get(
|
|
8251
|
+
let list = this._closers.get(path7);
|
|
8042
8252
|
if (!list) {
|
|
8043
8253
|
list = [];
|
|
8044
|
-
this._closers.set(
|
|
8254
|
+
this._closers.set(path7, list);
|
|
8045
8255
|
}
|
|
8046
8256
|
list.push(closer);
|
|
8047
8257
|
}
|
|
@@ -8071,7 +8281,7 @@ function watch(paths, options = {}) {
|
|
|
8071
8281
|
var chokidar_default = { watch, FSWatcher };
|
|
8072
8282
|
|
|
8073
8283
|
// src/core/watcher.ts
|
|
8074
|
-
import
|
|
8284
|
+
import path7 from "node:path";
|
|
8075
8285
|
function formatTime() {
|
|
8076
8286
|
const now = new Date;
|
|
8077
8287
|
const hours = String(now.getHours()).padStart(2, "0");
|
|
@@ -8104,7 +8314,7 @@ function getWatchPaths(operations) {
|
|
|
8104
8314
|
return Array.from(paths);
|
|
8105
8315
|
}
|
|
8106
8316
|
async function handleFileChange(changedPath, state, options) {
|
|
8107
|
-
const relPath =
|
|
8317
|
+
const relPath = path7.relative(options.cwd || process.cwd(), changedPath);
|
|
8108
8318
|
if (!logger.isSilent() && !options.verbose) {
|
|
8109
8319
|
console.log(`[${formatTime()}] Changed: ${relPath}`);
|
|
8110
8320
|
}
|
|
@@ -8118,9 +8328,9 @@ async function handleFileChange(changedPath, state, options) {
|
|
|
8118
8328
|
for (const op of affectedOps) {
|
|
8119
8329
|
const result = await performMerge(op);
|
|
8120
8330
|
if (result.success && result.changed) {
|
|
8121
|
-
const baseFile = op.basePath ?
|
|
8122
|
-
const machineFile =
|
|
8123
|
-
const outputFile =
|
|
8331
|
+
const baseFile = op.basePath ? path7.basename(op.basePath) : "";
|
|
8332
|
+
const machineFile = path7.basename(op.machinePath);
|
|
8333
|
+
const outputFile = path7.basename(op.outputPath);
|
|
8124
8334
|
if (!logger.isSilent()) {
|
|
8125
8335
|
if (baseFile) {
|
|
8126
8336
|
console.log(`[${formatTime()}] Merged ${baseFile} + ${machineFile} → ${outputFile}`);
|
|
@@ -8131,7 +8341,7 @@ async function handleFileChange(changedPath, state, options) {
|
|
|
8131
8341
|
} else if (!result.success && result.error) {
|
|
8132
8342
|
logger.error(`Failed to merge: ${result.error.message}`);
|
|
8133
8343
|
} else if (options.verbose && !result.changed) {
|
|
8134
|
-
logger.info(`No changes needed for ${
|
|
8344
|
+
logger.info(`No changes needed for ${path7.basename(op.outputPath)}`);
|
|
8135
8345
|
}
|
|
8136
8346
|
}
|
|
8137
8347
|
if (!logger.isSilent() && !options.verbose) {
|
|
@@ -8162,7 +8372,7 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8162
8372
|
if (!logger.isSilent()) {
|
|
8163
8373
|
console.log(`✓ Watching ${watchPaths.length} file(s) for changes...`);
|
|
8164
8374
|
for (const watchPath of watchPaths) {
|
|
8165
|
-
console.log(` - ${
|
|
8375
|
+
console.log(` - ${path7.relative(cwd, watchPath)}`);
|
|
8166
8376
|
}
|
|
8167
8377
|
console.log("");
|
|
8168
8378
|
}
|
|
@@ -8175,9 +8385,9 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8175
8385
|
}
|
|
8176
8386
|
});
|
|
8177
8387
|
watcher.on("change", (changedPath) => {
|
|
8178
|
-
const absolutePath =
|
|
8388
|
+
const absolutePath = path7.resolve(cwd, changedPath);
|
|
8179
8389
|
if (options.verbose) {
|
|
8180
|
-
logger.info(`File changed: ${
|
|
8390
|
+
logger.info(`File changed: ${path7.relative(cwd, absolutePath)}`);
|
|
8181
8391
|
}
|
|
8182
8392
|
const existingTimer = state.debounceTimers.get(absolutePath);
|
|
8183
8393
|
if (existingTimer) {
|
|
@@ -8190,9 +8400,9 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8190
8400
|
state.debounceTimers.set(absolutePath, timer);
|
|
8191
8401
|
});
|
|
8192
8402
|
watcher.on("add", async (addedPath) => {
|
|
8193
|
-
const absolutePath =
|
|
8403
|
+
const absolutePath = path7.resolve(cwd, addedPath);
|
|
8194
8404
|
if (options.verbose) {
|
|
8195
|
-
logger.info(`File added: ${
|
|
8405
|
+
logger.info(`File added: ${path7.relative(cwd, absolutePath)}`);
|
|
8196
8406
|
}
|
|
8197
8407
|
const newOperations = await scanForMergeOperations(machineName, cwd);
|
|
8198
8408
|
state.operations = newOperations;
|
|
@@ -8201,7 +8411,7 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8201
8411
|
});
|
|
8202
8412
|
watcher.on("unlink", (deletedPath) => {
|
|
8203
8413
|
if (options.verbose) {
|
|
8204
|
-
const relPath =
|
|
8414
|
+
const relPath = path7.relative(cwd, deletedPath);
|
|
8205
8415
|
logger.warn(`File deleted: ${relPath}`);
|
|
8206
8416
|
logger.info("Run merge manually or restart watch to update operations");
|
|
8207
8417
|
}
|
|
@@ -8222,17 +8432,17 @@ async function startWatcher(machineName, options = {}) {
|
|
|
8222
8432
|
}
|
|
8223
8433
|
|
|
8224
8434
|
// src/cli.ts
|
|
8225
|
-
import
|
|
8226
|
-
import
|
|
8227
|
-
import { fileURLToPath as
|
|
8435
|
+
import fs4 from "node:fs/promises";
|
|
8436
|
+
import path8 from "node:path";
|
|
8437
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
8228
8438
|
import { createInterface } from "node:readline";
|
|
8229
|
-
var
|
|
8230
|
-
var
|
|
8439
|
+
var __filename3 = fileURLToPath4(import.meta.url);
|
|
8440
|
+
var __dirname3 = path8.dirname(__filename3);
|
|
8231
8441
|
async function checkExistingOutputFiles(operations) {
|
|
8232
8442
|
const existing = [];
|
|
8233
8443
|
for (const op of operations) {
|
|
8234
8444
|
try {
|
|
8235
|
-
await
|
|
8445
|
+
await fs4.access(op.outputPath);
|
|
8236
8446
|
existing.push(op.outputPath);
|
|
8237
8447
|
} catch {}
|
|
8238
8448
|
}
|
|
@@ -8243,8 +8453,8 @@ async function checkTrackedOutputFiles(operations) {
|
|
|
8243
8453
|
const cwd = process.cwd();
|
|
8244
8454
|
for (const op of operations) {
|
|
8245
8455
|
try {
|
|
8246
|
-
await
|
|
8247
|
-
const relativePath =
|
|
8456
|
+
await fs4.access(op.outputPath);
|
|
8457
|
+
const relativePath = path8.relative(cwd, op.outputPath);
|
|
8248
8458
|
const isTracked = await isFileTrackedByGit(relativePath, cwd);
|
|
8249
8459
|
if (isTracked) {
|
|
8250
8460
|
tracked.push(op.outputPath);
|
|
@@ -8324,7 +8534,7 @@ async function handleInit(argv) {
|
|
|
8324
8534
|
if (trackedFiles.length > 0 && !argv["no-gitignore"]) {
|
|
8325
8535
|
logger.warn("⚠️ Warning: The following files will be overwritten and untracked from git:");
|
|
8326
8536
|
for (const file of trackedFiles) {
|
|
8327
|
-
logger.warn(` - ${
|
|
8537
|
+
logger.warn(` - ${path8.relative(process.cwd(), file)}`);
|
|
8328
8538
|
}
|
|
8329
8539
|
logger.info("");
|
|
8330
8540
|
const confirmed = argv.yes || await promptConfirmation("Do you want to continue?");
|
|
@@ -8392,7 +8602,7 @@ async function handleMerge(argv) {
|
|
|
8392
8602
|
if (trackedFiles.length > 0) {
|
|
8393
8603
|
logger.warn("⚠️ Warning: The following files will be overwritten and untracked from git:");
|
|
8394
8604
|
for (const file of trackedFiles) {
|
|
8395
|
-
logger.warn(` - ${
|
|
8605
|
+
logger.warn(` - ${path8.relative(process.cwd(), file)}`);
|
|
8396
8606
|
}
|
|
8397
8607
|
logger.info("");
|
|
8398
8608
|
const confirmed = argv.yes || await promptConfirmation("Do you want to continue?");
|
|
@@ -8430,11 +8640,11 @@ async function handleInfo(argv) {
|
|
|
8430
8640
|
const operations = await scanForMergeOperations(machineName);
|
|
8431
8641
|
console.log(`Machine name: ${machineName}`);
|
|
8432
8642
|
console.log(`Repository: ${process.cwd()}`);
|
|
8433
|
-
const { exec:
|
|
8434
|
-
const { promisify:
|
|
8435
|
-
const
|
|
8643
|
+
const { exec: exec3 } = await import("node:child_process");
|
|
8644
|
+
const { promisify: promisify3 } = await import("node:util");
|
|
8645
|
+
const execAsync3 = promisify3(exec3);
|
|
8436
8646
|
try {
|
|
8437
|
-
const { stdout } = await
|
|
8647
|
+
const { stdout } = await execAsync3("git config --get core.hooksPath");
|
|
8438
8648
|
const hooksPath = stdout.trim();
|
|
8439
8649
|
if (hooksPath) {
|
|
8440
8650
|
console.log(`Hooks method: core.hooksPath`);
|
|
@@ -8447,9 +8657,9 @@ async function handleInfo(argv) {
|
|
|
8447
8657
|
}
|
|
8448
8658
|
console.log(`Tracked patterns: ${operations.length}`);
|
|
8449
8659
|
for (const op of operations) {
|
|
8450
|
-
const baseName = op.basePath ?
|
|
8451
|
-
const machineName2 =
|
|
8452
|
-
const outputName =
|
|
8660
|
+
const baseName = op.basePath ? path8.basename(op.basePath) : "(none)";
|
|
8661
|
+
const machineName2 = path8.basename(op.machinePath);
|
|
8662
|
+
const outputName = path8.basename(op.outputPath);
|
|
8453
8663
|
console.log(` - ${baseName} + ${machineName2} → ${outputName}`);
|
|
8454
8664
|
}
|
|
8455
8665
|
if (operations.length > 0) {
|
|
@@ -8459,7 +8669,7 @@ async function handleInfo(argv) {
|
|
|
8459
8669
|
if (existingFiles.length > 0) {
|
|
8460
8670
|
console.log("Existing output files:");
|
|
8461
8671
|
for (const file of existingFiles) {
|
|
8462
|
-
console.log(` - ${
|
|
8672
|
+
console.log(` - ${path8.relative(process.cwd(), file)}`);
|
|
8463
8673
|
}
|
|
8464
8674
|
}
|
|
8465
8675
|
}
|
|
@@ -8542,8 +8752,8 @@ DOCUMENTATION:
|
|
|
8542
8752
|
}
|
|
8543
8753
|
async function showVersion() {
|
|
8544
8754
|
try {
|
|
8545
|
-
const packageJsonPath =
|
|
8546
|
-
const packageJson = JSON.parse(await
|
|
8755
|
+
const packageJsonPath = path8.join(__dirname3, "../package.json");
|
|
8756
|
+
const packageJson = JSON.parse(await fs4.readFile(packageJsonPath, "utf-8"));
|
|
8547
8757
|
console.log(packageJson.version);
|
|
8548
8758
|
} catch {
|
|
8549
8759
|
console.log("unknown");
|