Skip to content
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

Add terminal to playground site #161

Closed
wants to merge 47 commits into from
Closed

Conversation

swissspidy
Copy link
Member

@swissspidy swissspidy commented Mar 18, 2023

Screenshot 2023-03-18 at 18 37 35

@adamziel
Copy link
Collaborator

Thank you @swissspidy ! GitHub is going through some outage and mostly not accepting my comments so I'll review it tomorrow

@@ -200,7 +200,7 @@ const char WASM_HARDCODED_INI[] =
"always_populate_raw_post_data = -1\n"
"upload_max_filesize = 2000M\n"
"post_max_size = 2000M\n"
"disable_functions = proc_open,popen,curl_exec,curl_multi_exec\n"
"disable_functions = proc_open,popen,curl_exec,curl_multi_exec,shell_exec,proc_close\n"
Copy link
Collaborator

@adamziel adamziel Mar 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"disable_functions = proc_open,popen,curl_exec,curl_multi_exec,shell_exec,proc_close\n"
"disable_functions = proc_open,popen,curl_exec,curl_multi_exec,proc_close\n"

It's possible to provide a custom JavaScript handler for shell_exec so let's only soft-disable it in php.ini. This way it's possible to re-enable it in runtime.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the same possible also for proc_open? Overriding that one would be needed for making Behat tests work.

Copy link
Collaborator

@adamziel adamziel Mar 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not at the moment. shell_exec was easier to handle because it returns the output as a string. proc_open returns a resource and exposes low-level process calls and will require more effort. Definitely possible to support, though.

Comment on lines +99 to +100
WITH_LIBXML: 'yes',
WITH_MBSTRING: 'yes',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building with libxml adds 1MB to the bundle size, but I realize it's critical for this PR to be useful 🤔

I need to think a bit more about this. Emscripten seems to support runtime dynamic linking, but it's a small project in itself I don't want to block this PR on it. Maybe an additional MB wouldn't be that bad for now.

@adamziel
Copy link
Collaborator

Only got so far today. I'll continue reviewing tomorrow.

@@ -22,6 +22,32 @@ RUN wget -O wp.zip $WP_ZIP_URL && \
unzip -q wp.zip && \
rm wp.zip

# Run extra steps for the develop branch
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more these Dockerfiles grow the more I want to migrate to a Makefile down the road. Nothing blocking here, just sharing.

@@ -37,40 +63,57 @@ RUN git clone https://github.com/WordPress/sqlite-database-integration.git \
# Required by the SQLite integration plugin:
cp wordpress/wp-config-sample.php wordpress/wp-config.php

# Enable the SQLite support for the src folder in wordpress-develop:

RUN if [[ -d wordpress-develop-trunk ]] ; then \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This RUN is mostly the same as the one above, perhaps merging them and exporting a PATH_PREFIX inside of an if/else would make it shorter? I'm happy to fiddle with that if you invite me to your fork.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should already have access according to the "Allow edits by maintainers" checkbox, so feel free to make any edits

@@ -129,15 +174,44 @@ RUN ls -la && \
exit 'WordPress installation failed'; \
fi

# === Run WordPress Installer for the src install ===
#RUN if [[ -d wordpress-develop-trunk ]] ; then \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this code path used in wordpress-develop build? If so, https://github.com/WordPress/wordpress-playground/pull/161/files#r1152126565 it could likely be merged with the RUN above into a single RUN. Again, I'm happy to play with it.

@@ -3,6 +3,11 @@ import { spawn } from 'child_process';
import yargs from 'yargs';

const presets = {
develop: {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: formatting. Running nx format and npm run lint should fix it automatically.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will keep coming up in other PRs so I should just add a pre-commit hook. I really dislike lint-staged because of how many times it put me in a detached HEAD state, but Husky alone should suffice since nx is smart enough to ignore unchanged files.

@@ -3,6 +3,11 @@ import { spawn } from 'child_process';
import yargs from 'yargs';

const presets = {
develop: {
KEEP_THEME: 'twentytwentythree',
WP_ZIP_URL: 'https://github.com/WordPress/wordpress-develop/archive/refs/heads/trunk.zip',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smart!

return null;
}

const extensions = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For posterity: Later on this and #168 may converge into a single CodeMirror. For now, let's ship both.


function proc_open( $command, $descriptor_spec, $pipes ) { return false; }

define('STDIN', fopen('php://stdin', 'rb'));
Copy link
Collaborator

@adamziel adamziel Mar 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Future idea: provide php.define( name, value ) and php.defineStdio()

scriptPath: '/wordpress/run-tests.php'
});

const decodedOutput = new TextDecoder().decode(output.body);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next iteration idea: Stream the output live. This will require a function like php.outputMode( 'file' | 'callback' )

import React, {useCallback, useEffect, useRef, useState} from 'react';
import css from './style.module.css';
import {PlaygroundClient} from '@wp-playground/playground-remote';
import {Terminal} from 'xterm';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

64kb uncompressed, maybe import asynchronously? Vite will handle code splitting when it finds import('xterm')

contentLabel='This is a dialog window which overlays the main content of the page.'
onRequestClose={closeModal}
style={{
content: {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: Extract a generic PlaygroundModal component to avoid duplicating these styles.

@@ -0,0 +1,22 @@
.btn {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: Extract a generic Button component to avoid copying and pasting the same CSS

@@ -37,15 +37,11 @@ interface UsePlaygroundOptions {
onConnected?: (playground: PlaygroundClient) => Promise<void>;
onConnectionTimeout?: () => void;
timeout?: number;
php?: string;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch

@adamziel
Copy link
Collaborator

It reads well, thank you @swissspidy! I left some notes for now and some future ideas. I'm happy to tackle any of these, too. I tried running the PR locally but Vite complained about the missing wp-develop.js. I commented the import and then it gave me an FS Error 44 – must be something with paths. Perhaps I just need to rebuild WordPress.

Not sure what exactly you had in mind with editor.html, but I did some cleanup now at least to make the PR more reviewable.

From reading the code, that's exactly what I had in mind. Thank you! Having a separate entrypoint keeps the code editor in the repo, enables using it on demand, and helps incubate it over time.

@swissspidy
Copy link
Member Author

Thanks for your thorough review!

I'm happy to tackle any of these, too.

I'll be on vacation soon, so I'll take any help I can get with this :)

I commented the import and then it gave me an FS Error 44 – must be something with paths.

Docroot is right now hardcoded to /wordpress/build, so this would need reverting. And yeah maybe a rebuild too 🤷

@adamziel
Copy link
Collaborator

adamziel commented Mar 30, 2023

I'll be on vacation soon, so I'll take any help I can get with this :)

Oh yay, have fun! Would you please invite me to your fork? Otherwise I'll have to start a new PR to be able to make changes.

Docroot is right now hardcoded to /wordpress/build, so this would need reverting. And yeah maybe a rebuild too 🤷

Oh that's right, thank you

@swissspidy
Copy link
Member Author

Would you please invite me to your fork?

Done!

@adamziel adamziel mentioned this pull request Nov 24, 2023
1 task
adamziel added a commit that referenced this pull request Jan 22, 2024
Adds `wp-cli` support in the browser!

![CleanShot 2024-01-22 at 15 13
38@2x](https://github.com/WordPress/wordpress-playground/assets/205419/4f0a352f-8e2f-4961-b0c4-a9e88804931e)

This PR brings parts of
#161 by
@swissspidy into `trunk` to enable using `wp-cli` in the browser.

## Codebase changes

* `setSapiName` method for PHP. `wp-cli` expects to see the exact string
`"cli"` as the SAPI name.
*  All PHP versions are now built with phar support.
* `js_open_process` is asynchronous via Asyncify. This is to enable
calling `setSpawnHandler(handler)` from the parent site to set a handler
in an asynchronous web worker. Unfortunately, using the Comlink
messaging library is challenging with complex objects like spawn
handlers so this PR ships a workaround where spawn handlers are passed
as strings and `eval()`-ed in the worker. This shouldn't have any
security implications as Playground enables evaluating arbitrary code by
definition.
* `proc_open` waits for the process to spawn, and `proc_close` waits for
the process to die. This is necessary to support the `wp-cli` behavior
of piping its output through a pager program (like `cat` or `less -S`).

## Follow-up work

* Remove `eval()` from `setSpawnHandler(handler)`. Setting spawn handler
works in Node.js where PHP runs synchronously in the same process, but
these spawn handlers are challenging to transfer over `postMessage` as
they're essentially composite EventEmitters that need to accept input
inside the Worker process, handle it in the client process, and transmit
it back to the worker process. Intuitively, it would be pretty easy if
we used `MessagePort` directly. It seems like `Comlink` as an
abstraction layer makes things much easier to a point, since we can
magically call functions on objects living in another thread, but
there's a boundary beyond which Comlink makes these API interactions
more difficult.


cc @danielbachhuber @schlessera
@swissspidy
Copy link
Member Author

Superseded by ae8ec6a

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants