wuphf 0.216.1 → 0.217.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/bin/wuphf.js +4 -2
- package/package.json +1 -1
- package/scripts/version-check.js +51 -4
package/bin/wuphf.js
CHANGED
|
@@ -27,7 +27,7 @@ const path = require("node:path");
|
|
|
27
27
|
const os = require("node:os");
|
|
28
28
|
const { spawn } = require("node:child_process");
|
|
29
29
|
const { downloadBinary, packageVersion } = require("../scripts/download-binary");
|
|
30
|
-
const { getLatestVersion, compareVersions } = require("../scripts/version-check");
|
|
30
|
+
const { getLatestVersion, compareVersions, ensureCacheDir } = require("../scripts/version-check");
|
|
31
31
|
|
|
32
32
|
const binaryName = process.platform === "win32" ? "wuphf.exe" : "wuphf";
|
|
33
33
|
const installedBinary = path.join(__dirname, binaryName);
|
|
@@ -35,8 +35,9 @@ const installedBinary = path.join(__dirname, binaryName);
|
|
|
35
35
|
function cachedBinaryPath(version) {
|
|
36
36
|
// Windows requires the .exe suffix or CreateProcess refuses to launch.
|
|
37
37
|
const suffix = process.platform === "win32" ? ".exe" : "";
|
|
38
|
+
const runtimeHome = process.env.WUPHF_RUNTIME_HOME?.trim() || os.homedir();
|
|
38
39
|
return path.join(
|
|
39
|
-
|
|
40
|
+
runtimeHome,
|
|
40
41
|
".wuphf",
|
|
41
42
|
"cache",
|
|
42
43
|
"binaries",
|
|
@@ -70,6 +71,7 @@ async function ensureBinary() {
|
|
|
70
71
|
const cachedPath = cachedBinaryPath(latestVersion);
|
|
71
72
|
if (!fs.existsSync(cachedPath)) {
|
|
72
73
|
try {
|
|
74
|
+
await ensureCacheDir();
|
|
73
75
|
await downloadBinary({
|
|
74
76
|
version: latestVersion,
|
|
75
77
|
targetPath: cachedPath,
|
package/package.json
CHANGED
package/scripts/version-check.js
CHANGED
|
@@ -24,6 +24,7 @@ const fs = require("node:fs");
|
|
|
24
24
|
const fsp = require("node:fs/promises");
|
|
25
25
|
const path = require("node:path");
|
|
26
26
|
const os = require("node:os");
|
|
27
|
+
const { execFile } = require("node:child_process");
|
|
27
28
|
|
|
28
29
|
const REGISTRY_URL = "https://registry.npmjs.org/wuphf/latest";
|
|
29
30
|
// Generous enough to survive a cold TLS handshake on a slow network but
|
|
@@ -31,17 +32,57 @@ const REGISTRY_URL = "https://registry.npmjs.org/wuphf/latest";
|
|
|
31
32
|
// per user because the result is cached on disk.
|
|
32
33
|
const FETCH_TIMEOUT_MS = 3000;
|
|
33
34
|
const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
35
|
+
const backupExcludedCacheDirs = new Set();
|
|
36
|
+
let backupExclusionRunner = (target) =>
|
|
37
|
+
new Promise((resolve, reject) => {
|
|
38
|
+
execFile(
|
|
39
|
+
"/usr/bin/tmutil",
|
|
40
|
+
["addexclusion", target],
|
|
41
|
+
{ timeout: 2000 },
|
|
42
|
+
(err) => {
|
|
43
|
+
if (err) reject(err);
|
|
44
|
+
else resolve();
|
|
45
|
+
},
|
|
46
|
+
);
|
|
47
|
+
});
|
|
34
48
|
|
|
35
49
|
function cacheDir() {
|
|
36
|
-
// Sits under
|
|
37
|
-
//
|
|
38
|
-
|
|
50
|
+
// Sits under the active WUPHF runtime home so workspace/dev overrides get
|
|
51
|
+
// separate caches from prod.
|
|
52
|
+
const runtimeHome = process.env.WUPHF_RUNTIME_HOME?.trim() || os.homedir();
|
|
53
|
+
return path.join(runtimeHome, ".wuphf", "cache");
|
|
39
54
|
}
|
|
40
55
|
|
|
41
56
|
function latestVersionCachePath() {
|
|
42
57
|
return path.join(cacheDir(), "latest-version.json");
|
|
43
58
|
}
|
|
44
59
|
|
|
60
|
+
async function markCacheDirExcludedFromBackup(dir = cacheDir()) {
|
|
61
|
+
if (process.platform !== "darwin") return;
|
|
62
|
+
const candidates = new Set([dir]);
|
|
63
|
+
try {
|
|
64
|
+
candidates.add(await fsp.realpath(dir));
|
|
65
|
+
} catch {
|
|
66
|
+
// The cache write path is best-effort; backup metadata is too.
|
|
67
|
+
}
|
|
68
|
+
for (const candidate of candidates) {
|
|
69
|
+
if (backupExcludedCacheDirs.has(candidate)) continue;
|
|
70
|
+
backupExcludedCacheDirs.add(candidate);
|
|
71
|
+
try {
|
|
72
|
+
await backupExclusionRunner(candidate);
|
|
73
|
+
} catch {
|
|
74
|
+
backupExcludedCacheDirs.delete(candidate);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function ensureCacheDir() {
|
|
80
|
+
const dir = cacheDir();
|
|
81
|
+
await fsp.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
82
|
+
await markCacheDirExcludedFromBackup(dir);
|
|
83
|
+
return dir;
|
|
84
|
+
}
|
|
85
|
+
|
|
45
86
|
async function readCache() {
|
|
46
87
|
try {
|
|
47
88
|
const raw = await fsp.readFile(latestVersionCachePath(), "utf8");
|
|
@@ -59,7 +100,7 @@ async function readCache() {
|
|
|
59
100
|
|
|
60
101
|
async function writeCache(version) {
|
|
61
102
|
try {
|
|
62
|
-
await
|
|
103
|
+
await ensureCacheDir();
|
|
63
104
|
const target = latestVersionCachePath();
|
|
64
105
|
const tmp = `${target}.tmp`;
|
|
65
106
|
await fsp.writeFile(tmp, JSON.stringify({ version, checkedAt: Date.now() }));
|
|
@@ -119,9 +160,15 @@ module.exports = {
|
|
|
119
160
|
getLatestVersion,
|
|
120
161
|
compareVersions,
|
|
121
162
|
cacheDir,
|
|
163
|
+
ensureCacheDir,
|
|
122
164
|
latestVersionCachePath,
|
|
123
165
|
// Exported for tests.
|
|
166
|
+
markCacheDirExcludedFromBackup,
|
|
124
167
|
fetchLatestFromRegistry,
|
|
125
168
|
readCache,
|
|
126
169
|
writeCache,
|
|
170
|
+
setBackupExclusionRunnerForTest(runner) {
|
|
171
|
+
backupExcludedCacheDirs.clear();
|
|
172
|
+
backupExclusionRunner = runner;
|
|
173
|
+
},
|
|
127
174
|
};
|