-
Notifications
You must be signed in to change notification settings - Fork 369
wp now: load virtually config constants to allow running multiple projects at the same time #343
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wp now: load virtually config constants to allow running multiple projects at the same time #343
Conversation
…_file to define php constants
…tant instead of given path
…to update/wp-now-load-virtually-config-constants
danielbachhuber
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works as expected 👍
I was able to run wp-now start in a gutenberg plugin directory and wp-now start in a twentytwenty theme directory. Both sites worked fine side by side.
wp-config.php still seems to define constants, though:
$ cat ~/.wp-now/wordpress-versions/latest/wp-config.php
<?php
// ** Database settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'database_name_here' );
Would it make sense to remove some of the constants to prevent them from being defined twice?
Also (outside the scope of this PR): how should we let users define their own wp-config.php constants?
packages/playground/blueprints/src/lib/steps/define-virtual-wp-config-consts.ts
Outdated
Show resolved
Hide resolved
packages/playground/blueprints/src/lib/steps/define-virtual-wp-config-consts.ts
Outdated
Show resolved
Hide resolved
|
I like |
| defineWpConfigConsts, | ||
| login, | ||
| } from '@wp-playground/blueprints'; | ||
| import { defineVirtualWpConfigConsts, login } from '@wp-playground/blueprints'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need defineWpConfigConsts, or can we remove the old one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wojtekn , I was not sure if it's used by other apps that import this library.
I would leave this as expected behavior - that way, wp-now won't modify the developer's environment at all and will define the constants it needs to run.
If we are worried about someone breaking their wp-now local environment, we can document that in the readme and say that for smooth work with wp-now, user shouldn't have
We are not replacing the In the future, if we add support for the |
@adamziel I think it's the intention as we are defining run-time constants here, not constants that are part of the user's configuration. If users want to define their own constants and have them preserved, they can use Also, if we decide to add support for environment-specific configuration files like
Could we just remove the previous step? |
wojtekn
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great and works as expected.
katinthehatsite
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It worked as expected for me. I tried with Gutenberg and Twenty Twenty One theme and both projects launched well.
One thing that I came across is that the server failed to start because it could not read /var/www/html/wp-config-sample.php. I also got a similar error with Sqlite plugin (I will paste the error below). I had to delete both wordpress-versions and sqlite-database-integration-main folders in ~/.wp-now/ directory before I could run both of these projects at the same time. I understand that this perhaps is not related directly to this issue but should we create a different issue to prevent this from happening?
This was an error:
Starting the server......
directory: /Users/katerynakodonenko/Documents/A8C-Projects/twentytwentyone
mode: theme
php: 8.0
wp: latest
WordPress latest folder already exists. Skipping download.
Sqlite folder already exists. Skipping download.
Error: Could not read "/var/www/html/wp-config-sample.php": There is no such file or directory OR the parent directory does not exist.
at _NodePHP.descriptor.value (/Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/php-wasm/node/index.cjs:67319:17)
at _NodePHP.readFileAsText (/Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/php-wasm/node/index.cjs:67760:42)
at _NodePHP.descriptor.value (/Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/php-wasm/node/index.cjs:67312:23)
at initWordPress (file:///Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/wp-now/main.js:464:9)
at runPluginOrThemeMode (file:///Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/wp-now/main.js:445:9)
at startWPNow (file:///Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/wp-now/main.js:382:13)
at async startServer (file:///Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/wp-now/main.js:562:42)
at async Object.handler (file:///Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/wp-now/main.js:668:25) {
[cause]: ErrnoError
at Object.ensureErrnoError (/Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/php-wasm/node/index.cjs:20233:33)
at Object.staticInit (/Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/php-wasm/node/index.cjs:20241:10)
at Object.init3 (/Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/php-wasm/node/index.cjs:24083:6)
at loadPHPRuntime (/Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/php-wasm/node/index.cjs:67338:38)
at doLoad (/Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/php-wasm/node/index.cjs:68228:31)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Function.load (/Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/php-wasm/node/index.cjs:68200:12)
at async startWPNow (file:///Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/wp-now/main.js:339:15)
at async startServer (file:///Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/wp-now/main.js:562:42)
at async Object.handler (file:///Users/katerynakodonenko/Documents/A8C-Projects/wordpress-playground/dist/packages/wp-now/main.js:668:25) {
node: undefined,
setErrno: [Function (anonymous)],
errno: 44,
message: 'FS error'
}
}
Failed to start the server: Could not read "/var/www/html/wp-config-sample.php": There is no such file or directory OR the parent directory does not exist.
@adamziel , Option 1.
|
|
It turns out that we already have the |
…to update/wp-now-load-virtually-config-constants
|
@adamziel , I've refactored the code to make |
Oh I see, that makes sense 👍 Still, let's reuse as much code as possible between the two steps, they accomplish mostly the same task after all. Right now this PR appends await updateFile(
playground,
VFS_JSON_FILE_PATH,
(contents) =>
JSON.stringify({
...JSON.parse(contents || '{}'),
...consts,
})
); |
| const requiredFiles = [ | ||
| 'wp-content/db.php', | ||
| 'wp-content/mu-plugins/0-allow-wp-org.php', | ||
| 'playground-consts.json', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wojtekn , I'm removing this .json constants from our tests since they are not needed anymore.
| let contents = `<?php `; | ||
| for (const [key, value] of Object.entries(consts)) { | ||
| contents += `if (!defined('${key}')) { | ||
| define("${key}", ${JSON.stringify(value)}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a phpVars utility for bringing data into PHP code:
import { phpVars } from '@php-wasm/util';
const js = phpVars({
host,
port,
httpUrl,
});
js.host // "127.0.0.1"Right now it boils down to JSON.stringify, but it will get more powerful escaping at one point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @adamziel , I followed the pattern to load a virtual json file.
Now, this step can be called multiple times, and the latest calls will merge previous values and overwrite conflicting values.
I can see that we could refactor defineWpConfigConsts and defineVirtualWpConfigConsts and accept a VFS path in case the user want's to virtualize .json and wp-config.php files. If you like the idea, I can create an issue as a follow-up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like that @sejas, thank you for proposing. Let's refactor that! To make sure I follow – they would become the same step, only with a virtualize: true/false option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think the virtualize: true/false option is the best approach.
Another option would be using the given directory and if it's empty, then use documentRoot.
What approach would you like the most?
I'll create the follow-up PR tomorrow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s use the virtualize option, the directory requires more careful choice from the API consumer when ultimately it’s about a boolean choice
…to update/wp-now-load-virtually-config-constants
danielbachhuber
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to successfully start two sites side by side!
| export const defineVirtualWpConfigConsts: StepHandler< | ||
| DefineVirtualWpConfigConstsStep | ||
| > = async (playground, { consts }) => { | ||
| playground.mkdir(VFS_CONFIG_FILE_BASENAME); | ||
| const jsonPath = `${VFS_CONFIG_FILE_BASENAME}/playground-consts.json`; | ||
| await updateFile(playground, jsonPath, (contents) => | ||
| JSON.stringify({ | ||
| ...JSON.parse(contents || '{}'), | ||
| ...consts, | ||
| }) | ||
| ); | ||
| await updateFile(playground, VFS_CONFIG_FILE_PATH, (contents) => { | ||
| if (!contents.includes('playground-consts.json')) { | ||
| return `<?php | ||
| $consts = json_decode(file_get_contents('${jsonPath}'), true); | ||
| foreach ($consts as $const => $value) { | ||
| if (!defined($const)) { | ||
| define($const, $value); | ||
| } | ||
| } | ||
| ?>${contents}`; | ||
| } | ||
| return contents; | ||
| }); | ||
| return VFS_CONFIG_FILE_PATH; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sejas I understand the follow-up you proposed would reduce the duplication, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, let's make sure any new steps are reflected in pages/blueprints-reference.md
…`defineWpConfigConsts` (#415) Remove `defineVirtualWpConfigConsts` in favor of `defineWpConfigConsts`, adding a `virtualize` option. Asee #343 (comment)
…`defineWpConfigConsts` (#415) Remove `defineVirtualWpConfigConsts` in favor of `defineWpConfigConsts`, adding a `virtualize` option. Asee WordPress/wordpress-playground#343 (comment)
…ineWpConfigConsts step PR #343 added a "virtualize" option so Playground can define new PHP constants without changing the WordPress files in the filesystem. This is incredibly useful. At the same time, mixing defineWpConfigConst calls with and without the "virtualize" option may lead to a situation where some constants are lost or when Playground tries to load a non-existing playground-consts.json file – see #735. Since I can't think of a good rationale to keep the non-virtualized version around, let's reduce complexity and always virtualize the constants. The "virtualize" option will now be noop and is only kept to avoid breaking Blueprint schema validation for existing apps. Closes #735
…ineWpConfigConsts step (#738) ## Description PR #343 added a "virtualize" option so Playground can define new PHP constants without changing the WordPress files in the filesystem. This is incredibly useful. At the same time, mixing defineWpConfigConst calls with and without the "virtualize" option may lead to a situation where some constants are lost or when Playground tries to load a non-existing playground-consts.json file – see #735. Since I can't think of a good rationale to keep the non-virtualized version around, let's reduce complexity and always virtualize the constants. The "virtualize" option will now be noop and is only kept to avoid breaking Blueprint schema validation for existing apps. ## Testing instructions * Confirm unit tests pass * Confirm the [WordPress PR previewer](http://localhost:5400/website-server/wordpress.html) loads Pull Requests without triggering any warnings ## Follow-up work * Adjust Blueprint schema validation to tolerate the `virtualize` option so we can remove it from the type * Call this step `definePHPConsts` as there is nothing specific to `wp-config.php` in it Closes #735
What?
auto_prepend_filewp-nowprojects at the same timeWhy?
The current blueprint
defineSiteUrlcreates ajsonfile that is re-used in every wp-now instance. Creating conflicts between site redirections. See #324How?
defineVirtualWpConfigConstsan alternative ofdefineWpConfigConsts.Testing Instructions
npx nx preview wp-now start --path=/path/to/theme-plugin-1npx nx preview wp-now start --path=/path/to/theme-plugin-2wp-config.phpwas not modified and you don't have any newplayground-consts.json.jsonfile in the root of your folder. (For a clean test, remove your files inside~/.wp-now)