Merge PR #6606: fix(natives): preserve newer cache versions (@wolfiesch)

This commit is contained in:
can1357
2026-07-26 15:45:31 +02:00
3 changed files with 29 additions and 3 deletions
+3
View File
@@ -8,6 +8,9 @@
### Fixed
- Fixed Linux native audio over forwarded PulseAudio servers: capture now handles 125 ms Android fragments without stalling, and playback buffers enough audio to avoid TCP underruns and stuttering ([#6628](https://github.com/can1357/oh-my-pi/pull/6628) by [@anatoli-tsinovoy](https://github.com/anatoli-tsinovoy)).
### Fixed
- Fixed older running OMP versions deleting newer native addon cache directories during cleanup, which could race a new version's first-run extraction and crash with `ENOENT`.
## [17.1.3] - 2026-07-24
+18 -1
View File
@@ -178,6 +178,23 @@ export function resolveLoaderCandidates({
// =========================================================================
function parseReleaseVersion(version) {
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
}
function isOlderReleaseVersion(candidate, current) {
const candidateParts = parseReleaseVersion(candidate);
const currentParts = parseReleaseVersion(current);
if (!candidateParts || !currentParts) return false;
for (let index = 0; index < candidateParts.length; index++) {
if (candidateParts[index] !== currentParts[index]) {
return candidateParts[index] < currentParts[index];
}
}
return false;
}
/**
* Remove version-pinned native cache directories older than the loaded package.
* Best-effort by design: permission errors and concurrent processes must not
@@ -196,7 +213,7 @@ export function cleanupStaleNativeVersions({ nativesDir, currentVersion }) {
}
for (const entry of entries) {
if (!entry.isDirectory() || entry.name === currentVersion) continue;
if (!entry.isDirectory() || !isOlderReleaseVersion(entry.name, currentVersion)) continue;
const targetPath = path.join(nativesDir, entry.name);
try {
fs.rmSync(targetPath, { recursive: true, force: true });
@@ -134,17 +134,23 @@ describe("windows native addon staging", () => {
expect(candidates).toContain(nodeModulesBaseline);
});
it("removes stale version directories after the current native version loads", async () => {
it("removes only older version directories after the current native version loads", async () => {
const nativesDir = await fs.mkdtemp(path.join(os.tmpdir(), "omp-natives-cache-"));
const currentMajor = Number.parseInt(packageJson.version, 10);
const futureVersion = `${currentMajor + 1}.0.0`;
try {
await fs.mkdir(path.join(nativesDir, "15.10.11"));
await fs.mkdir(path.join(nativesDir, packageJson.version));
await fs.mkdir(path.join(nativesDir, futureVersion));
await fs.mkdir(path.join(nativesDir, "not-a-version"));
await Bun.write(path.join(nativesDir, "README.txt"), "not a version directory");
const removed = cleanupStaleNativeVersions({ nativesDir, currentVersion: packageJson.version });
expect(removed.map(filePath => path.basename(filePath))).toEqual(["15.10.11"]);
expect((await fs.readdir(nativesDir)).sort()).toEqual(["README.txt", packageJson.version].sort());
expect((await fs.readdir(nativesDir)).sort()).toEqual(
["README.txt", packageJson.version, futureVersion, "not-a-version"].sort(),
);
} finally {
await fs.rm(nativesDir, { recursive: true, force: true });
}