mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-21 11:15:36 -05:00
use mkdirTree in emscripten FS (#1245)
* try mkdirTree * suggested changes * fix pre-commit
This commit is contained in:
@@ -193,61 +193,39 @@ export class RemoteInterpreter extends Object {
|
||||
* @param path : the path in the filesystem
|
||||
* @param fetch_path : the path to be fetched
|
||||
*
|
||||
* Given a file available at `fetch_path` URL (eg: `http://dummy.com/hi.py`),
|
||||
* the function downloads the file and saves it to the `path` (eg: `a/b/c/foo.py`)
|
||||
* on the FS.
|
||||
* Given a file available at `fetch_path` URL (eg:
|
||||
* `http://dummy.com/hi.py`), the function downloads the file and saves it
|
||||
* to the `path` (eg: `a/b/c/foo.py`) on the FS.
|
||||
*
|
||||
* Example usage:
|
||||
* await loadFromFile(`a/b/c/foo.py`, `http://dummy.com/hi.py`)
|
||||
* Example usage: await loadFromFile(`a/b/c/foo.py`,
|
||||
* `http://dummy.com/hi.py`)
|
||||
*
|
||||
* Nested paths are iteratively analysed and each part is created
|
||||
* if it doesn't exist.
|
||||
*
|
||||
* The analysis returns if the part exists and if it's parent directory exists
|
||||
* Due to the manner in which we proceed, the parent will ALWAYS exist.
|
||||
*
|
||||
* The iteration proceeds in the following manner for `a/b/c/foo.py`:
|
||||
*
|
||||
* - `a` doesn't exist but it's parent i.e. `root` exists --> create `a`
|
||||
* - `a/b` doesn't exist but it's parent i.e. `a` exists --> create `a/b`
|
||||
* - `a/b/c` doesn't exist but it's parent i.e. `a/b` exists --> create `a/b/c`
|
||||
*
|
||||
* Finally, write content of `http://dummy.com/hi.py` to `a/b/c/foo.py`
|
||||
* Write content of `http://dummy.com/hi.py` to `a/b/c/foo.py`
|
||||
*
|
||||
* NOTE: The `path` parameter expects to have the `filename` in it i.e.
|
||||
* `a/b/c/foo.py` is valid while `a/b/c` (i.e. only the folders) are incorrect.
|
||||
* `a/b/c/foo.py` is valid while `a/b/c` (i.e. only the folders) are
|
||||
* incorrect.
|
||||
*
|
||||
* The path will be resolved relative to the current working directory,
|
||||
* which is initially `/home/pyodide`. So by default `a/b.py` will be placed
|
||||
* in `/home/pyodide/a/b.py`, `../a/b.py` will be placed into `/home/a/b.py`
|
||||
* and `/a/b.py` will be placed into `/a/b.py`.
|
||||
*/
|
||||
async loadFromFile(path: string, fetch_path: string): Promise<void> {
|
||||
const pathArr = path.split('/');
|
||||
const filename = pathArr.pop();
|
||||
for (let i = 0; i < pathArr.length; i++) {
|
||||
// iteratively calculates parts of the path i.e. `a`, `a/b`, `a/b/c` for `a/b/c/foo.py`
|
||||
const eachPath = pathArr.slice(0, i + 1).join('/');
|
||||
|
||||
// analyses `eachPath` and returns if it exists along with if its parent directory exists or not
|
||||
const { exists, parentExists } = this.interface.FS.analyzePath(eachPath);
|
||||
|
||||
// due to the iterative manner in which we proceed, the parent directory should ALWAYS exist
|
||||
if (!parentExists) {
|
||||
throw new Error(`'INTERNAL ERROR! cannot create ${path}, this should never happen'`);
|
||||
}
|
||||
|
||||
// creates `eachPath` if it doesn't exist
|
||||
if (!exists) {
|
||||
this.interface.FS.mkdir(eachPath);
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
path = this.interface._module.PATH_FS.resolve(path);
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
const dir = this.interface._module.PATH.dirname(path);
|
||||
this.interface.FS.mkdirTree(dir);
|
||||
|
||||
// `robustFetch` checks for failures in getting a response
|
||||
const response = await robustFetch(fetch_path);
|
||||
const buffer = await response.arrayBuffer();
|
||||
const data = new Uint8Array(buffer);
|
||||
|
||||
pathArr.push(filename);
|
||||
// opens a file descriptor for the file at `path`
|
||||
const stream = this.interface.FS.open(pathArr.join('/'), 'w');
|
||||
this.interface.FS.write(stream, data, 0, data.length, 0);
|
||||
this.interface.FS.close(stream);
|
||||
this.interface.FS.writeFile(path, data, { canOwn: true });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user