fix(mod_compiler): flush directory entries before unpack to avoid XFS delayed-log causing partial readdir results
This commit is contained in:
@@ -1,5 +1,13 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-03-05 - 4.1.11 - fix(mod_compiler)
|
||||||
|
flush directory entries before unpack to avoid XFS delayed-log causing partial readdir results
|
||||||
|
|
||||||
|
- Add fs import and call child_process.execSync('sync') before unpacking compiled output to force kernel-level sync
|
||||||
|
- Add syncDirectoryTree(dir) to recursively open and fsync directory file descriptors and traverse subdirectories
|
||||||
|
- Call syncDirectoryTree on the destination directory before performing unpack to ensure TypeScript writeFileSync entries are committed (prevents partial readdir results on XFS)
|
||||||
|
- Errors during directory sync are ignored to avoid breaking normal flow
|
||||||
|
|
||||||
## 2026-03-05 - 4.1.10 - fix(unpack)
|
## 2026-03-05 - 4.1.10 - fix(unpack)
|
||||||
use atomic renames to flatten nested output and make unpacking more reliable
|
use atomic renames to flatten nested output and make unpacking more reliable
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@git.zone/tsbuild',
|
name: '@git.zone/tsbuild',
|
||||||
version: '4.1.10',
|
version: '4.1.11',
|
||||||
description: 'A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.'
|
description: 'A tool for compiling TypeScript files using the latest nightly features, offering flexible APIs and a CLI for streamlined development.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import type { CompilerOptions, Diagnostic, Program } from 'typescript';
|
import type { CompilerOptions, Diagnostic, Program } from 'typescript';
|
||||||
import typescript from 'typescript';
|
import typescript from 'typescript';
|
||||||
|
import * as fs from 'fs';
|
||||||
import * as smartdelay from '@push.rocks/smartdelay';
|
import * as smartdelay from '@push.rocks/smartdelay';
|
||||||
import * as smartpromise from '@push.rocks/smartpromise';
|
import * as smartpromise from '@push.rocks/smartpromise';
|
||||||
import * as smartpath from '@push.rocks/smartpath';
|
import * as smartpath from '@push.rocks/smartpath';
|
||||||
@@ -367,6 +368,12 @@ export class TsCompiler {
|
|||||||
|
|
||||||
// Perform unpack if compilation succeeded
|
// Perform unpack if compilation succeeded
|
||||||
if (result.errorSummary.totalErrors === 0) {
|
if (result.errorSummary.totalErrors === 0) {
|
||||||
|
// Force XFS to commit all pending directory entries before unpacking.
|
||||||
|
// TypeScript's writeFileSync creates entries that may reside in XFS's
|
||||||
|
// delayed log. Without sync, readdir can return partial results.
|
||||||
|
require('child_process').execSync('sync');
|
||||||
|
this.syncDirectoryTree(destDir);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await performUnpack(pattern, destDir, this.cwd);
|
await performUnpack(pattern, destDir, this.cwd);
|
||||||
} catch (unpackErr: any) {
|
} catch (unpackErr: any) {
|
||||||
@@ -495,6 +502,27 @@ export class TsCompiler {
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively fsync all directories in a tree.
|
||||||
|
* Forces XFS to commit pending directory entries from its log.
|
||||||
|
*/
|
||||||
|
private syncDirectoryTree(dirPath: string): void {
|
||||||
|
try {
|
||||||
|
const fd = fs.openSync(dirPath, 'r');
|
||||||
|
fs.fsyncSync(fd);
|
||||||
|
fs.closeSync(fd);
|
||||||
|
|
||||||
|
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
this.syncDirectoryTree(require('path').join(dirPath, entry.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Ignore errors (directory may not exist)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merge multiple error summaries into one
|
* Merge multiple error summaries into one
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user