From 5899c265158ebb450bd457f9d258a0fd89bcc12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Fri, 22 Dec 2023 12:18:47 +0100 Subject: [PATCH 1/2] =?UTF-8?q?Blueprints=20internals=20=E2=80=93=20split?= =?UTF-8?q?=20the=20`common.ts`=20file=20into=20smaller=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This small commit brings a part of #851 into trunk for easier review. ## Testing instructions Confirm the CI tests pass --- packages/playground/blueprints/src/index.ts | 2 + .../steps/apply-wordpress-patches/index.ts | 2 +- .../blueprints/src/lib/steps/common.ts | 74 ------------------- .../src/lib/steps/import-wp-content.ts | 2 +- .../blueprints/src/lib/steps/index.ts | 2 - .../src/lib/steps/install-plugin.ts | 2 +- .../blueprints/src/lib/steps/install-theme.ts | 2 +- .../blueprints/src/lib/steps/unzip.ts | 2 +- .../blueprints/src/lib/steps/write-file.ts | 3 +- .../src/lib/steps/zip-wp-content.ts | 4 +- .../src/lib/utils/flatten-directory.ts | 36 +++++++++ .../lib/utils/run-php-with-zip-functions.ts | 18 +++++ .../blueprints/src/lib/utils/update-file.ts | 23 ++++++ .../wp-content-files-excluded-from-exports.ts | 28 +++++++ .../lib/{steps => utils}/zip-functions.php | 0 .../src/lib/utils/zip-name-to-human-name.ts | 15 ++++ 16 files changed, 130 insertions(+), 85 deletions(-) delete mode 100644 packages/playground/blueprints/src/lib/steps/common.ts create mode 100644 packages/playground/blueprints/src/lib/utils/flatten-directory.ts create mode 100644 packages/playground/blueprints/src/lib/utils/run-php-with-zip-functions.ts create mode 100644 packages/playground/blueprints/src/lib/utils/update-file.ts create mode 100644 packages/playground/blueprints/src/lib/utils/wp-content-files-excluded-from-exports.ts rename packages/playground/blueprints/src/lib/{steps => utils}/zip-functions.php (100%) create mode 100644 packages/playground/blueprints/src/lib/utils/zip-name-to-human-name.ts diff --git a/packages/playground/blueprints/src/index.ts b/packages/playground/blueprints/src/index.ts index 9302e411658..48623ec67cf 100644 --- a/packages/playground/blueprints/src/index.ts +++ b/packages/playground/blueprints/src/index.ts @@ -32,6 +32,8 @@ export type { VFSResource, } from './lib/resources'; +export { wpContentFilesExcludedFromExport } from './lib/utils/wp-content-files-excluded-from-exports'; + /** * @deprecated This function is a no-op. Playground no longer uses a proxy to download plugins and themes. * To be removed in v0.3.0 diff --git a/packages/playground/blueprints/src/lib/steps/apply-wordpress-patches/index.ts b/packages/playground/blueprints/src/lib/steps/apply-wordpress-patches/index.ts index 54f31548edf..e8ca0731d5d 100644 --- a/packages/playground/blueprints/src/lib/steps/apply-wordpress-patches/index.ts +++ b/packages/playground/blueprints/src/lib/steps/apply-wordpress-patches/index.ts @@ -1,6 +1,5 @@ import { UniversalPHP } from '@php-wasm/universal'; import { StepHandler } from '..'; -import { updateFile } from '../common'; import { defineWpConfigConsts } from '../define-wp-config-consts'; /** @ts-ignore */ @@ -9,6 +8,7 @@ import transportFetch from './wp-content/mu-plugins/playground-includes/wp_http_ import transportDummy from './wp-content/mu-plugins/playground-includes/requests_transport_dummy.php?raw'; /** @ts-ignore */ import playgroundMuPlugin from './wp-content/mu-plugins/0-playground.php?raw'; +import { updateFile } from '../../utils/update-file'; /** * @private diff --git a/packages/playground/blueprints/src/lib/steps/common.ts b/packages/playground/blueprints/src/lib/steps/common.ts deleted file mode 100644 index 3421a1c36fb..00000000000 --- a/packages/playground/blueprints/src/lib/steps/common.ts +++ /dev/null @@ -1,74 +0,0 @@ -import type { UniversalPHP } from '@php-wasm/universal'; - -/** - * Used by the export step to exclude the Playground-specific files - * from the zip file. Keep it in sync with the list of files created - * by WordPressPatcher. - */ -export const wpContentFilesExcludedFromExport = [ - 'db.php', - 'plugins/akismet', - 'plugins/hello.php', - 'plugins/wordpress-importer', - 'plugins/sqlite-database-integration', - 'mu-plugins/playground-includes', - 'mu-plugins/export-wxz.php', - 'mu-plugins/0-playground.php', - - /* - * Listing core themes like that here isn't ideal, especially since - * developers may actually want to use one of them. - * @TODO Let's give the user a choice whether or not to include them. - */ - 'themes/twentytwenty', - 'themes/twentytwentyone', - 'themes/twentytwentytwo', - 'themes/twentytwentythree', - 'themes/twentytwentyfour', - 'themes/twentytwentyfive', - 'themes/twentytwentysix', -]; - -// @ts-ignore -import zipFunctions from './zip-functions.php?raw'; - -export function zipNameToHumanName(zipName: string) { - const mixedCaseName = zipName.split('.').shift()!.replace(/-/g, ' '); - return ( - mixedCaseName.charAt(0).toUpperCase() + - mixedCaseName.slice(1).toLowerCase() - ); -} - -type PatchFileCallback = (contents: string) => string | Uint8Array; -export async function updateFile( - php: UniversalPHP, - path: string, - callback: PatchFileCallback -) { - let contents = ''; - if (await php.fileExists(path)) { - contents = await php.readFileAsText(path); - } - await php.writeFile(path, callback(contents)); -} - -export async function fileToUint8Array(file: File) { - return new Uint8Array(await file.arrayBuffer()); -} - -export async function runPhpWithZipFunctions( - playground: UniversalPHP, - code: string -) { - const result = await playground.run({ - code: zipFunctions + code, - }); - if (result.exitCode !== 0) { - console.log(zipFunctions + code); - console.log(code + ''); - console.log(result.errors); - throw result.errors; - } - return result; -} diff --git a/packages/playground/blueprints/src/lib/steps/import-wp-content.ts b/packages/playground/blueprints/src/lib/steps/import-wp-content.ts index 9900a202fa1..42ac7b8f69b 100644 --- a/packages/playground/blueprints/src/lib/steps/import-wp-content.ts +++ b/packages/playground/blueprints/src/lib/steps/import-wp-content.ts @@ -1,8 +1,8 @@ import { StepHandler } from '.'; import { unzip } from './unzip'; import { dirname, joinPaths, phpVar } from '@php-wasm/util'; -import { wpContentFilesExcludedFromExport } from './common'; import { UniversalPHP } from '@php-wasm/universal'; +import { wpContentFilesExcludedFromExport } from '../utils/wp-content-files-excluded-from-exports'; /** * @inheritDoc importWordPressFiles diff --git a/packages/playground/blueprints/src/lib/steps/index.ts b/packages/playground/blueprints/src/lib/steps/index.ts index ad6a25a7fd3..2db8593045f 100644 --- a/packages/playground/blueprints/src/lib/steps/index.ts +++ b/packages/playground/blueprints/src/lib/steps/index.ts @@ -37,8 +37,6 @@ export type StepDefinition = Step & { }; }; -export { wpContentFilesExcludedFromExport } from './common'; - /** * If you add a step here, make sure to also * add it to the exports below. diff --git a/packages/playground/blueprints/src/lib/steps/install-plugin.ts b/packages/playground/blueprints/src/lib/steps/install-plugin.ts index 96ce736ee99..cd51ed763fe 100644 --- a/packages/playground/blueprints/src/lib/steps/install-plugin.ts +++ b/packages/playground/blueprints/src/lib/steps/install-plugin.ts @@ -1,9 +1,9 @@ import { UniversalPHP } from '@php-wasm/universal'; import { StepHandler } from '.'; -import { zipNameToHumanName } from './common'; import { installAsset } from './install-asset'; import { activatePlugin } from './activate-plugin'; import { makeEditorFrameControlled } from './apply-wordpress-patches'; +import { zipNameToHumanName } from '../utils/zip-name-to-human-name'; /** * @inheritDoc installPlugin diff --git a/packages/playground/blueprints/src/lib/steps/install-theme.ts b/packages/playground/blueprints/src/lib/steps/install-theme.ts index 6316c9559d4..d6d8995d050 100644 --- a/packages/playground/blueprints/src/lib/steps/install-theme.ts +++ b/packages/playground/blueprints/src/lib/steps/install-theme.ts @@ -1,7 +1,7 @@ import { StepHandler } from '.'; -import { zipNameToHumanName } from './common'; import { installAsset } from './install-asset'; import { activateTheme } from './activate-theme'; +import { zipNameToHumanName } from '../utils/zip-name-to-human-name'; /** * @inheritDoc installTheme diff --git a/packages/playground/blueprints/src/lib/steps/unzip.ts b/packages/playground/blueprints/src/lib/steps/unzip.ts index 90dbb60df7b..dd55e1616be 100644 --- a/packages/playground/blueprints/src/lib/steps/unzip.ts +++ b/packages/playground/blueprints/src/lib/steps/unzip.ts @@ -1,6 +1,6 @@ import { phpVars } from '@php-wasm/util'; import { StepHandler } from '.'; -import { runPhpWithZipFunctions } from './common'; +import { runPhpWithZipFunctions } from '../utils/run-php-with-zip-functions'; /** * @inheritDoc unzip diff --git a/packages/playground/blueprints/src/lib/steps/write-file.ts b/packages/playground/blueprints/src/lib/steps/write-file.ts index 19bd58f80e3..244b3a01058 100644 --- a/packages/playground/blueprints/src/lib/steps/write-file.ts +++ b/packages/playground/blueprints/src/lib/steps/write-file.ts @@ -1,5 +1,4 @@ import { StepHandler } from '.'; -import { fileToUint8Array } from './common'; /** * @inheritDoc writeFile @@ -31,7 +30,7 @@ export const writeFile: StepHandler> = async ( { path, data } ) => { if (data instanceof File) { - data = await fileToUint8Array(data); + data = new Uint8Array(await data.arrayBuffer()); } await playground.writeFile(path, data); }; diff --git a/packages/playground/blueprints/src/lib/steps/zip-wp-content.ts b/packages/playground/blueprints/src/lib/steps/zip-wp-content.ts index 1f0d420315a..5f49d08dc5f 100644 --- a/packages/playground/blueprints/src/lib/steps/zip-wp-content.ts +++ b/packages/playground/blueprints/src/lib/steps/zip-wp-content.ts @@ -1,7 +1,7 @@ import { joinPaths, phpVars } from '@php-wasm/util'; -import { runPhpWithZipFunctions } from './common'; -import { wpContentFilesExcludedFromExport } from './common'; import { UniversalPHP } from '@php-wasm/universal'; +import { wpContentFilesExcludedFromExport } from '../utils/wp-content-files-excluded-from-exports'; +import { runPhpWithZipFunctions } from '../utils/run-php-with-zip-functions'; interface ZipWpContentOptions { /** diff --git a/packages/playground/blueprints/src/lib/utils/flatten-directory.ts b/packages/playground/blueprints/src/lib/utils/flatten-directory.ts new file mode 100644 index 00000000000..8dda36ade14 --- /dev/null +++ b/packages/playground/blueprints/src/lib/utils/flatten-directory.ts @@ -0,0 +1,36 @@ +import type { UniversalPHP } from '@php-wasm/universal'; +import { dirname, joinPaths } from '@php-wasm/util'; + +/** + * Flattens a directory. + * If the directory contains only one file, it will be moved to the parent directory. + * Otherwise, the directory will be renamed to the default name. + * + * @param php Playground client. + * @param directoryPath The directory to flatten. + * @param defaultName The name to use if the directory contains only one file. + * @returns The final path of the directory. + */ +export async function flattenDirectory( + php: UniversalPHP, + directoryPath: string, + defaultName: string +) { + const parentPath = dirname(directoryPath); + + const filesInside = await php.listFiles(directoryPath); + if (filesInside.length === 1) { + const onlyFilePath = joinPaths(directoryPath, filesInside[0]); + const isDir = await php.isDir(onlyFilePath); + if (isDir) { + const finalPath = joinPaths(parentPath, filesInside[0]); + await php.mv(onlyFilePath, finalPath); + await php.rmdir(directoryPath, { recursive: true }); + return finalPath; + } + } + + const finalPath = joinPaths(parentPath, defaultName); + await php.mv(directoryPath, finalPath); + return finalPath; +} diff --git a/packages/playground/blueprints/src/lib/utils/run-php-with-zip-functions.ts b/packages/playground/blueprints/src/lib/utils/run-php-with-zip-functions.ts new file mode 100644 index 00000000000..4568523dbda --- /dev/null +++ b/packages/playground/blueprints/src/lib/utils/run-php-with-zip-functions.ts @@ -0,0 +1,18 @@ +import { UniversalPHP } from '@php-wasm/universal'; +// @ts-ignore +import zipFunctions from './zip-functions.php?raw'; +export async function runPhpWithZipFunctions( + playground: UniversalPHP, + code: string +) { + const result = await playground.run({ + code: zipFunctions + code, + }); + if (result.exitCode !== 0) { + console.log(zipFunctions + code); + console.log(code + ''); + console.log(result.errors); + throw result.errors; + } + return result; +} diff --git a/packages/playground/blueprints/src/lib/utils/update-file.ts b/packages/playground/blueprints/src/lib/utils/update-file.ts new file mode 100644 index 00000000000..c7242b8e096 --- /dev/null +++ b/packages/playground/blueprints/src/lib/utils/update-file.ts @@ -0,0 +1,23 @@ +import type { UniversalPHP } from '@php-wasm/universal'; + +type PatchFileCallback = (contents: string) => string | Uint8Array; + +/** + * Updates a file in the PHP filesystem. + * If the file does not exist, it will be created. + * + * @param php The PHP instance. + * @param path The path to the file. + * @param callback A function that maps the old file contents to the new file contents. + */ +export async function updateFile( + php: UniversalPHP, + path: string, + callback: PatchFileCallback +) { + let contents = ''; + if (await php.fileExists(path)) { + contents = await php.readFileAsText(path); + } + await php.writeFile(path, callback(contents)); +} diff --git a/packages/playground/blueprints/src/lib/utils/wp-content-files-excluded-from-exports.ts b/packages/playground/blueprints/src/lib/utils/wp-content-files-excluded-from-exports.ts new file mode 100644 index 00000000000..a7a9c33c8f2 --- /dev/null +++ b/packages/playground/blueprints/src/lib/utils/wp-content-files-excluded-from-exports.ts @@ -0,0 +1,28 @@ +/** + * Used by the export step to exclude the Playground-specific files + * from the zip file. Keep it in sync with the list of files created + * by WordPressPatcher. + */ +export const wpContentFilesExcludedFromExport = [ + 'db.php', + 'plugins/akismet', + 'plugins/hello.php', + 'plugins/wordpress-importer', + 'plugins/sqlite-database-integration', + 'mu-plugins/playground-includes', + 'mu-plugins/export-wxz.php', + 'mu-plugins/0-playground.php', + + /* + * Listing core themes like that here isn't ideal, especially since + * developers may actually want to use one of them. + * @TODO Let's give the user a choice whether or not to include them. + */ + 'themes/twentytwenty', + 'themes/twentytwentyone', + 'themes/twentytwentytwo', + 'themes/twentytwentythree', + 'themes/twentytwentyfour', + 'themes/twentytwentyfive', + 'themes/twentytwentysix', +]; diff --git a/packages/playground/blueprints/src/lib/steps/zip-functions.php b/packages/playground/blueprints/src/lib/utils/zip-functions.php similarity index 100% rename from packages/playground/blueprints/src/lib/steps/zip-functions.php rename to packages/playground/blueprints/src/lib/utils/zip-functions.php diff --git a/packages/playground/blueprints/src/lib/utils/zip-name-to-human-name.ts b/packages/playground/blueprints/src/lib/utils/zip-name-to-human-name.ts new file mode 100644 index 00000000000..dce30317722 --- /dev/null +++ b/packages/playground/blueprints/src/lib/utils/zip-name-to-human-name.ts @@ -0,0 +1,15 @@ +/** + * Converts a zip file name to a nice, human-readable name. + * + * @example `hello-dolly.zip` -> `Hello dolly` + * + * @param zipName A zip filename. + * @returns A nice, human-readable name. + */ +export function zipNameToHumanName(zipName: string) { + const mixedCaseName = zipName.split('.').shift()!.replace(/-/g, ' '); + return ( + mixedCaseName.charAt(0).toUpperCase() + + mixedCaseName.slice(1).toLowerCase() + ); +} From b53de0e8411f53d97ca635f9ce24bcad2193b178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Zieli=C5=84ski?= Date: Fri, 22 Dec 2023 12:25:09 +0100 Subject: [PATCH 2/2] Fix import in resources.ts --- packages/playground/blueprints/src/lib/resources.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/playground/blueprints/src/lib/resources.ts b/packages/playground/blueprints/src/lib/resources.ts index 982dc278cd1..5d4ac62fe8a 100644 --- a/packages/playground/blueprints/src/lib/resources.ts +++ b/packages/playground/blueprints/src/lib/resources.ts @@ -4,7 +4,7 @@ import { } from '@php-wasm/progress'; import { UniversalPHP } from '@php-wasm/universal'; import { Semaphore } from '@php-wasm/util'; -import { zipNameToHumanName } from './steps/common'; +import { zipNameToHumanName } from './utils/zip-name-to-human-name'; export const ResourceTypes = [ 'vfs',