参考所有分组,完成尽量多的内容。禁止顺手扩功能 smoke
结论:按 align-linuxcnc 约束收窄 OPFS removeFile 和 LinuxCNC 参数 .new/.bak 清理为文件专用语义,避免把同名目录递归删除。依据 ../linuxcnc/src/emc/rs274ngc/rs274ngc_pre.cc save_parameters() 的 fopen(filename.new)、unlink(filename.bak)、link、rename 行为。 验证:./test-native.sh 通过;./test-linuxcnc-source-link.sh 通过。
This commit is contained in:
@@ -366,7 +366,10 @@ if grep -R -n -E 'localStorage|sessionStorage|indexedDB|showOpenFilePicker|showS
|
|||||||
fi
|
fi
|
||||||
grep -F 'LinuxCNC source basis: rs274ngc_pre.cc restore_parameters() reads the' web/src/wasm-core.js >/dev/null
|
grep -F 'LinuxCNC source basis: rs274ngc_pre.cc restore_parameters() reads the' web/src/wasm-core.js >/dev/null
|
||||||
grep -F 'before replacing the main file and managing filename + ".bak".' web/src/wasm-core.js >/dev/null
|
grep -F 'before replacing the main file and managing filename + ".bak".' web/src/wasm-core.js >/dev/null
|
||||||
grep -F 'await removeOpfsEntry(workspacePath, `${path}.new`, false);' web/src/wasm-core.js >/dev/null
|
grep -F 'async function removeOpfsFileEntry(workspacePath, relativePath)' web/src/wasm-core.js >/dev/null
|
||||||
|
grep -F 'await removeOpfsFileEntry(workspacePath, `${path}.new`);' web/src/wasm-core.js >/dev/null
|
||||||
|
grep -F 'removeWasmFilePath(module, `${LINUXCNC_DEFAULT_PARAMETER_FILE}.new`);' web/src/wasm-core.js >/dev/null
|
||||||
|
grep -F 'OPFS removeFile removed a directory instead of preserving file-only semantics' web/test-browser-wasm-smoke-opfs-directory-sections.js >/dev/null
|
||||||
grep -F 'OPFS workspace is required for browser program parsing' web/src/app.js >/dev/null
|
grep -F 'OPFS workspace is required for browser program parsing' web/src/app.js >/dev/null
|
||||||
grep -F 'const events = await simulator.parseFileWithParameterFile(programPath, parameterPath, "linuxcnc", parseOptions);' web/src/app.js >/dev/null
|
grep -F 'const events = await simulator.parseFileWithParameterFile(programPath, parameterPath, "linuxcnc", parseOptions);' web/src/app.js >/dev/null
|
||||||
grep -F 'default browser simulator did not create an OPFS workspace' web/test-browser-wasm-smoke-opfs-policy-sections.js >/dev/null
|
grep -F 'default browser simulator did not create an OPFS workspace' web/test-browser-wasm-smoke-opfs-policy-sections.js >/dev/null
|
||||||
|
|||||||
@@ -318,6 +318,21 @@ function removeWasmPath(module, path, recursive) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeWasmFilePath(module, path) {
|
||||||
|
let mode;
|
||||||
|
try {
|
||||||
|
mode = module.FS.stat(path).mode;
|
||||||
|
} catch (error) {
|
||||||
|
if (error?.errno !== 44) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (module.FS.isFile(mode)) {
|
||||||
|
module.FS.unlink(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function wasmPathExists(module, path) {
|
function wasmPathExists(module, path) {
|
||||||
try {
|
try {
|
||||||
module.FS.stat(path);
|
module.FS.stat(path);
|
||||||
@@ -505,9 +520,12 @@ function installOpfsWorkspace(module, options) {
|
|||||||
throw new Error("LinuxCNC parameter file was not produced by the interpreter");
|
throw new Error("LinuxCNC parameter file was not produced by the interpreter");
|
||||||
}
|
}
|
||||||
await writeOpfsFile(workspacePath, path, data);
|
await writeOpfsFile(workspacePath, path, data);
|
||||||
await removeOpfsEntry(workspacePath, `${path}.new`, false);
|
// LinuxCNC source basis: rs274ngc_pre.cc save_parameters()
|
||||||
removeWasmPath(module, `${LINUXCNC_DEFAULT_PARAMETER_FILE}.new`, false);
|
// creates filename + ".new" with fopen() and later renames that
|
||||||
removeWasmPath(module, `/${LINUXCNC_DEFAULT_PARAMETER_FILE}.new`, false);
|
// file; OPFS cleanup must not remove a directory at that path.
|
||||||
|
await removeOpfsFileEntry(workspacePath, `${path}.new`);
|
||||||
|
removeWasmFilePath(module, `${LINUXCNC_DEFAULT_PARAMETER_FILE}.new`);
|
||||||
|
removeWasmFilePath(module, `/${LINUXCNC_DEFAULT_PARAMETER_FILE}.new`);
|
||||||
const backupPath = `${LINUXCNC_DEFAULT_PARAMETER_FILE}.bak`;
|
const backupPath = `${LINUXCNC_DEFAULT_PARAMETER_FILE}.bak`;
|
||||||
const backupData = readFirstExistingWasmFile(module, [backupPath, `/${backupPath}`]);
|
const backupData = readFirstExistingWasmFile(module, [backupPath, `/${backupPath}`]);
|
||||||
if (backupData !== null) {
|
if (backupData !== null) {
|
||||||
@@ -518,8 +536,11 @@ function installOpfsWorkspace(module, options) {
|
|||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
async removeFile(path) {
|
async removeFile(path) {
|
||||||
await removeOpfsEntry(workspacePath, path, false);
|
// LinuxCNC source basis: rs274ngc_pre.cc save_parameters() uses
|
||||||
removeWasmPath(module, this.resolvePath(path), false);
|
// unlink() for backup files, so the browser bridge keeps file-only
|
||||||
|
// removal separate from recursive directory cleanup.
|
||||||
|
await removeOpfsFileEntry(workspacePath, path);
|
||||||
|
removeWasmFilePath(module, this.resolvePath(path));
|
||||||
},
|
},
|
||||||
async removeDirectory(path) {
|
async removeDirectory(path) {
|
||||||
await removeOpfsEntry(workspacePath, path, true);
|
await removeOpfsEntry(workspacePath, path, true);
|
||||||
|
|||||||
@@ -171,4 +171,20 @@ export async function runBrowserOpfsDirectorySections(context, simulator) {
|
|||||||
"OPFS removeDirectory did not remove the WASM mirror",
|
"OPFS removeDirectory did not remove the WASM mirror",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await runSection("opfs file removal preserves directories", async () => {
|
||||||
|
await simulator.fs.opfs.writeFile("parameters/remove-file-keeps-directory.var.new/stale.ngc", "G21 G90\n");
|
||||||
|
const staleDirectoryPath = simulator.fs.opfs.resolvePath("parameters/remove-file-keeps-directory.var.new");
|
||||||
|
await simulator.fs.opfs.readDirectory("parameters/remove-file-keeps-directory.var.new");
|
||||||
|
await simulator.fs.opfs.removeFile("parameters/remove-file-keeps-directory.var.new");
|
||||||
|
const staleDirectoryStat = await simulator.fs.opfs.stat("parameters/remove-file-keeps-directory.var.new");
|
||||||
|
if (staleDirectoryStat.kind !== "directory" || staleDirectoryStat.size !== null) {
|
||||||
|
throw new Error("OPFS removeFile removed a directory instead of preserving file-only semantics");
|
||||||
|
}
|
||||||
|
const staleDirectoryMode = simulator.fs.module.FS.stat(staleDirectoryPath).mode;
|
||||||
|
if (!simulator.fs.module.FS.isDir(staleDirectoryMode)) {
|
||||||
|
throw new Error("OPFS removeFile removed a WASM mirror directory instead of preserving file-only semantics");
|
||||||
|
}
|
||||||
|
await simulator.fs.opfs.removeDirectory("parameters/remove-file-keeps-directory.var.new");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user