From 69f9d6805a84cdd69cf0fd107ca3acb8e757118c Mon Sep 17 00:00:00 2001 From: Pookie717 Date: Thu, 1 Jun 2023 09:14:16 +0200 Subject: [PATCH] PHP: Add `prependPath` option to `listFiles` method (#462) ## What? Add `prependPath` option to `PHP.listFiles` method, which will prepend given folder path to every file found in it. ## Why? It's a common need to iterate over a list of files with each file path being an accessible path instead of only the file name. Idea mentioned in: - https://github.com/WordPress/wordpress-playground/pull/427#discussion_r1207443739 For example, this is a common pattern: ```ts const files = await playground.listFiles( folderPath ) for (const file of files) { const filePath = `${folderPath}/${file}`; ... } ``` Also expressed as: ```ts const filePaths = (await playground.listFiles( folderPath )).map( (name: string) => `${folderPath}/${name}`) ) ``` With the new option, the above can be simplified as: ```ts const filePaths = await playground.listFiles(folderPath, { prependPath: true }) ``` ## How? - [x] Add `prependPath` option to `BasePHP.listFiles` method - [x] Document the option and what it does - [x] Add test ## Testing Instructions 1. Check out the branch. 2. Run `nx test playground-blueprints` --- packages/php-wasm/node/src/test/php.spec.ts | 10 ++++++++++ packages/php-wasm/universal/src/lib/base-php.ts | 13 +++++++++++-- .../php-wasm/universal/src/lib/universal-php.ts | 8 ++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/packages/php-wasm/node/src/test/php.spec.ts b/packages/php-wasm/node/src/test/php.spec.ts index 9e74c87b..dbf7fa1c 100644 --- a/packages/php-wasm/node/src/test/php.spec.ts +++ b/packages/php-wasm/node/src/test/php.spec.ts @@ -152,6 +152,16 @@ describe.each(SupportedPHPVersions)('PHP %s', (phpVersion) => { 'test2.txt', ]); }); + + it('listFiles() option prependPath should prepend given path to all files returned', () => { + php.mkdir(testDirPath); + php.writeFile(testDirPath + '/test.txt', 'Hello World!'); + php.writeFile(testDirPath + '/test2.txt', 'Hello World!'); + expect(php.listFiles(testDirPath, { prependPath: true })).toEqual([ + testDirPath + '/test.txt', + testDirPath + '/test2.txt', + ]); + }); }); describe('Stdio', () => { diff --git a/packages/php-wasm/universal/src/lib/base-php.ts b/packages/php-wasm/universal/src/lib/base-php.ts index 19e35d2f..706cd4ec 100644 --- a/packages/php-wasm/universal/src/lib/base-php.ts +++ b/packages/php-wasm/universal/src/lib/base-php.ts @@ -14,6 +14,7 @@ import { PHPRequestHeaders, PHPRunOptions, RmDirOptions, + ListFilesOptions, } from './universal-php'; import { getFunctionsMaybeMissingFromAsyncify, @@ -507,14 +508,22 @@ export abstract class BasePHP implements IsomorphicLocalPHP { /** @inheritDoc */ @rethrowFileSystemError('Could not list files in "{path}"') - listFiles(path: string): string[] { + listFiles( + path: string, + options: ListFilesOptions = { prependPath: false } + ): string[] { if (!this.fileExists(path)) { return []; } try { - return this[__private__dont__use].FS.readdir(path).filter( + const files = this[__private__dont__use].FS.readdir(path).filter( (name: string) => name !== '.' && name !== '..' ); + if (options.prependPath) { + const prepend = path.replace(/\/$/, ''); + return files.map((name: string) => `${prepend}/${name}`); + } + return files; } catch (e) { console.error(e, { path }); return []; diff --git a/packages/php-wasm/universal/src/lib/universal-php.ts b/packages/php-wasm/universal/src/lib/universal-php.ts index 4a598a7c..5be4f29d 100644 --- a/packages/php-wasm/universal/src/lib/universal-php.ts +++ b/packages/php-wasm/universal/src/lib/universal-php.ts @@ -439,3 +439,11 @@ export interface RmDirOptions { */ recursive?: boolean; } + +export interface ListFilesOptions { + /** + * If true, prepend given folder path to all file names. + * Default: false. + */ + prependPath: boolean; +}