Skip to content

Commit 6619235

Browse files
committed
When mounting a file create a empty file node instead of a directory node
1 parent 1e38f50 commit 6619235

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

packages/php-wasm/node/src/lib/load-runtime.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { FileLockManager } from './file-lock-manager';
1212
import { withICUData } from './data/with-icu-data';
1313
import { withXdebug } from './xdebug/with-xdebug';
1414
import { joinPaths } from '@php-wasm/util';
15+
import { dirname } from 'path';
1516

1617
export interface PHPLoaderOptions {
1718
emscriptenOptions?: EmscriptenOptions;
@@ -108,7 +109,17 @@ export async function loadNodeRuntime(
108109
!FSHelpers.fileExists(phpRuntime.FS, symlinkPath) &&
109110
fs.existsSync(absoluteSourcePath)
110111
) {
111-
phpRuntime.FS.mkdirTree(symlinkPath);
112+
const sourceStat = fs.statSync(absoluteSourcePath);
113+
if (sourceStat.isDirectory()) {
114+
phpRuntime.FS.mkdirTree(symlinkPath);
115+
} else if (sourceStat.isFile()) {
116+
phpRuntime.FS.mkdirTree(dirname(symlinkPath));
117+
phpRuntime.FS.writeFile(symlinkPath, '');
118+
} else {
119+
throw new Error(
120+
'Unsupported file type. PHP-wasm supports only symlinks that link to files, directories, or symlinks.'
121+
);
122+
}
112123
phpRuntime.FS.mount(
113124
phpRuntime.FS.filesystems.NODEFS,
114125
{ root: absoluteSourcePath },

packages/php-wasm/node/src/lib/node-fs-mount.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,42 @@
11
import type { MountHandler } from '@php-wasm/universal';
2+
import { statSync } from 'fs';
3+
import { dirname } from 'path';
24

35
export function createNodeFsMountHandler(localPath: string): MountHandler {
46
return async function (php, FS, vfsMountPoint) {
57
/**
6-
* DON'T MERGE THIS.
7-
* This is a temporary workaround to demonstrate how mounting requires the mount point to be a directory.
8-
*
9-
* Emscripten requires the mount point to be a directory.
10-
* By creating a directory we can even mount a file over it as long as the paths match.
11-
* PHP-WASM source: https://github.com/WordPress/wordpress-playground/blob/trunk/packages/php-wasm/node/asyncify/php_8_0.js#L2679
12-
*
138
* When Emscripten attempt to mount a local path into VFS, it looks up the path
149
* and adds the local path as a mount to the VFS Node.
1510
* PHP-WASM source: https://github.com/WordPress/wordpress-playground/blob/trunk/packages/php-wasm/node/asyncify/php_8_0.js#L2700
1611
*
17-
* For mounting to work, the Node must exist in VFS and be a directory.
12+
* For mounting to work, the Node must exist in VFS.
1813
* If the Node doesn't exist, the mount fails with error 44 (MEMFS.doesNotExistError).
1914
* PHP-WASM source: https://github.com/WordPress/wordpress-playground/blob/trunk/packages/php-wasm/node/asyncify/php_8_0.js#L1201
15+
*
16+
* Emscripten requires the mount point to be a directory.
17+
* To work around this, the PHP-wasm compile removes the directory check.
18+
* PHP-WASM source: https://github.com/WordPress/wordpress-playground/blob/5821cee231f452d050fd337b99ad0b26ebda487e/packages/php-wasm/compile/php/Dockerfile#L2148
2019
*/
20+
let lookup;
2121
try {
22-
FS.lookupPath(vfsMountPoint);
22+
lookup = FS.lookupPath(vfsMountPoint);
2323
} catch (e) {
2424
// FS.lookupPath will throw an error if the path doesn't exist.
25-
FS.mkdirTree(vfsMountPoint);
25+
if (statSync(localPath).isFile()) {
26+
FS.writeFile(vfsMountPoint, '');
27+
} else if (statSync(localPath).isDirectory()) {
28+
FS.mkdirTree(dirname(vfsMountPoint));
29+
FS.mkdirTree(vfsMountPoint);
30+
} else {
31+
throw new Error(
32+
'Unsupported file type. PHP-wasm supports only symlinks that link to files, directories, or symlinks.'
33+
);
34+
}
35+
lookup = FS.lookupPath(vfsMountPoint);
36+
}
37+
if (!lookup.node) {
38+
// TODO: Improve error once I understand the limitations.
39+
throw new Error('Unable to access the mount point in VFS.');
2640
}
2741
FS.mount(FS.filesystems['NODEFS'], { root: localPath }, vfsMountPoint);
2842
return () => {

0 commit comments

Comments
 (0)