Skip to content

Commit 46d4448

Browse files
committed
Improve error logging in plugin installer
1 parent afeb3b1 commit 46d4448

27 files changed

+103
-77
lines changed

components/Blueprints/Runner.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ private function executePlan( Tracker $progress, array $steps, Runtime $runtime
10311031
// as in – was the step created because of "installPlugin" or not?
10321032
// Which entry of it? etc.
10331033
throw new BlueprintExecutionException(
1034-
sprintf( "Error when executing step #d %s (#%d in the execution plan)",
1034+
sprintf( "Error when executing step %s (#%d in the execution plan)",
10351035
get_class( $step ),
10361036
$i + 1
10371037
),

components/Blueprints/Runtime.php

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
namespace WordPress\Blueprints;
44

5+
use Exception;
56
use Psr\Log\LoggerInterface;
7+
use RuntimeException;
68
use Symfony\Component\Process\Process;
79
use WordPress\Blueprints\DataReference\DataReference;
810
use WordPress\Blueprints\DataReference\DataReferenceResolver;
@@ -212,46 +214,74 @@ public function createTemporaryFile( ?string $suffix = null ): string {
212214
* @param mixed[]|null $env
213215
* @param float $timeout
214216
*/
215-
public function evalPhpInSubProcess(
217+
public function evalPhpCodeInSubProcess(
216218
$code,
217219
$env = null,
218220
$input = null,
219221
$timeout = 60
220222
) {
221-
return $this->withTemporaryFile( function ( $tempFile ) use ( $code, $env, $input, $timeout ) {
222-
return $this->withTemporaryFile( function ( $outputFile ) use ( $tempFile, $code, $env, $input, $timeout ) {
223-
file_put_contents(
224-
$tempFile,
225-
'<?php
226-
function append_output( $output ) {
227-
file_put_contents( getenv("OUTPUT_FILE"), $output, FILE_APPEND );
228-
}
229-
$_SERVER["HTTP_HOST"] = "localhost";
230-
?>' . $code
231-
);
223+
return $this->withTemporaryFile( function ( $script_path ) use ( $code, $env, $input, $timeout ) {
224+
file_put_contents( $script_path, $code );
225+
return $this->evalPhpFileInSubProcess( $script_path, $env, $input, $timeout );
226+
} );
227+
}
232228

229+
public function evalPhpFileInSubProcess(
230+
$script_path,
231+
$env = null,
232+
$input = null,
233+
$timeout = 60
234+
) {
235+
return $this->withTemporaryDirectory( function ( $tempDir ) use ( $script_path, $env, $input, $timeout ) {
236+
$prepend_path = wp_join_paths( $tempDir, 'prepend.php' );
237+
file_put_contents(
238+
$prepend_path,
239+
'<?php
240+
function append_output( $output ) {
241+
file_put_contents( getenv("OUTPUT_FILE"), $output, FILE_APPEND );
242+
}
243+
$_SERVER["HTTP_HOST"] = "localhost";
244+
?>'
245+
);
246+
247+
// Still put the script in a temporary file as the path may be refering
248+
// to a file inside the currently executed .phar archive.
249+
$actual_script_path = wp_join_paths( $tempDir, 'script.php' );
250+
$code = file_get_contents( $script_path );
251+
file_put_contents( $actual_script_path, $code );
252+
253+
$output_path = wp_join_paths( $tempDir, 'output.txt' );
254+
touch( $output_path );
255+
256+
try {
233257
$process = $this->runShellCommand(
234258
array(
235259
'php',
236-
$tempFile,
260+
'-d auto_prepend_file=' . $prepend_path,
261+
$actual_script_path,
237262
),
238263
$this->configuration->getTargetSiteRoot(),
239264
array_merge(
240265
array(
241266
'DOCROOT' => $this->configuration->getTargetSiteRoot(),
242-
'OUTPUT_FILE' => $outputFile,
267+
'OUTPUT_FILE' => $output_path,
243268
),
244269
$env ?? array()
245270
),
246271
$input,
247272
$timeout
248273
);
274+
} catch ( \Exception $e ) {
275+
throw new RuntimeException( sprintf(
276+
'PHP script "%s" failed.',
277+
$script_path
278+
), 0, $e );
279+
}
249280

250-
return new EvalResult(
251-
file_get_contents( $outputFile ),
252-
$process
253-
);
254-
} );
281+
return new EvalResult(
282+
file_get_contents( $output_path ),
283+
$process
284+
);
255285
} );
256286
}
257287

components/Blueprints/SiteResolver/ExistingSiteResolver.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ static public function resolve( Runtime $runtime, Tracker $progress, ?VersionCon
3131

3232
// Additional check to ensure we can actually load WordPress
3333
try {
34-
$result = $runtime->evalPhpInSubProcess(
34+
$result = $runtime->evalPhpCodeInSubProcess(
3535
'<?php
3636
require_once(getenv("DOCROOT") . "/wp-load.php");
3737
$is_installed = function_exists("is_blog_installed") && is_blog_installed() ? "true" : "false";
@@ -58,7 +58,7 @@ static public function resolve( Runtime $runtime, Tracker $progress, ?VersionCon
5858
// Get current WordPress version
5959
$currentWordPressVersion = WordPressVersion::fromString(
6060
trim(
61-
$runtime->evalPhpInSubProcess(
61+
$runtime->evalPhpCodeInSubProcess(
6262
'<?php
6363
require_once(getenv("DOCROOT") . "/wp-includes/version.php");
6464
append_output( $wp_version );
@@ -89,7 +89,7 @@ static public function resolve( Runtime $runtime, Tracker $progress, ?VersionCon
8989

9090
// Check if SQLite integration plugin is active when using SQLite
9191
if ( $requiredEngine === 'sqlite' ) {
92-
$sqliteActive = $runtime->evalPhpInSubProcess(
92+
$sqliteActive = $runtime->evalPhpCodeInSubProcess(
9393
'<?php
9494
require_once(getenv("DOCROOT") . "/wp-load.php");
9595
@@ -110,7 +110,7 @@ static public function resolve( Runtime $runtime, Tracker $progress, ?VersionCon
110110
}
111111
} elseif ( $requiredEngine === 'mysql' ) {
112112
// For MySQL, verify it's not using SQLite
113-
$usingMysql = $runtime->evalPhpInSubProcess(
113+
$usingMysql = $runtime->evalPhpCodeInSubProcess(
114114
'<?php
115115
require_once(getenv("DOCROOT") . "/wp-load.php");
116116

components/Blueprints/SiteResolver/NewSiteResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static public function resolve( Runtime $runtime, Tracker $progress, ?VersionCon
9797
// Technically, this is a "new site" resolver, but it's entirely possible
9898
// the developer-provided WordPress zip already has a sqlite database with the
9999
// a WordPress site installed..
100-
$installCheck = $runtime->evalPhpInSubProcess(
100+
$installCheck = $runtime->evalPhpCodeInSubProcess(
101101
<<<'PHP'
102102
$wp_load = getenv('DOCROOT') . '/wp-load.php';
103103
if (!file_exists($wp_load)) {

components/Blueprints/Steps/ActivatePluginStep.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public function __construct( string $pluginPath ) {
2828
*/
2929
public function run( Runtime $runtime, Tracker $tracker ) {
3030
$tracker->setCaption( 'Activating plugin ' . ( $this->pluginPath ?? '' ) );
31-
$runtime->evalPhpInSubProcess(
31+
$runtime->evalPhpCodeInSubProcess(
3232
file_get_contents( __DIR__ . '/scripts/ActivatePlugin/wp_activate_plugin.php' ),
3333
[
3434
'PLUGIN_PATH' => $this->pluginPath,

components/Blueprints/Steps/ActivateThemeStep.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function __construct( string $themeFolderName ) {
2727
*/
2828
public function run( Runtime $runtime, Tracker $tracker ) {
2929
$tracker->setCaption( 'Activating theme ' . $this->themeFolderName );
30-
$runtime->evalPhpInSubProcess(
30+
$runtime->evalPhpCodeInSubProcess(
3131
file_get_contents( __DIR__ . '/scripts/ActivateTheme/wp_activate_theme.php' ),
3232
[
3333
'THEME_FOLDER_NAME' => $this->themeFolderName,

components/Blueprints/Steps/DefineConstantsStep.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function __construct( array $constants ) {
2727
*/
2828
public function run( Runtime $runtime, Tracker $tracker ) {
2929
$tracker->setCaption( 'Defining wp-config constants' );
30-
$runtime->evalPhpInSubProcess(
30+
$runtime->evalPhpCodeInSubProcess(
3131
file_get_contents( __DIR__ . '/scripts/DefineWpConfigConsts/define.php' ),
3232
array( 'CONSTS' => json_encode( $this->constants ) )
3333
);

components/Blueprints/Steps/ImportContentStep.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private function importWxr( Runtime $runtime, array $content_definition ): void
6161
}
6262

6363
$wxrPath = $runtime->saveToTemporaryFile( $resolved );
64-
$runtime->evalPhpInSubProcess(
64+
$runtime->evalPhpCodeInSubProcess(
6565
<<<'PHP'
6666
<?php
6767
require_once getenv('DOCROOT') . '/wp-load.php';
@@ -117,7 +117,7 @@ private function importPosts( Runtime $runtime, array $content_definition ): voi
117117
throw new RuntimeException( 'Invalid posts data.' );
118118
}
119119

120-
$runtime->evalPhpInSubProcess(
120+
$runtime->evalPhpCodeInSubProcess(
121121
<<<'PHP'
122122
<?php
123123
require_once getenv('DOCROOT') . '/wp-load.php';

components/Blueprints/Steps/ImportMediaStep.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function run( Runtime $runtime, Tracker $progress ) {
6161

6262
$files_imported = 0;
6363
$fs = $runtime->getTargetFilesystem();
64-
$wp_upload_dir = $runtime->evalPhpInSubProcess(
64+
$wp_upload_dir = $runtime->evalPhpCodeInSubProcess(
6565
'<?php
6666
require_once(getenv("DOCROOT") . "/wp-load.php");
6767
$upload_dir = wp_upload_dir();
@@ -121,7 +121,7 @@ public function run( Runtime $runtime, Tracker $progress ) {
121121
$write_stream->close_writing();
122122

123123
// Add to WordPress media library
124-
$attachment_id = $runtime->evalPhpInSubProcess(
124+
$attachment_id = $runtime->evalPhpCodeInSubProcess(
125125
<<<'CODE'
126126
<?php
127127
require_once(getenv("DOCROOT") . "/wp-load.php");

components/Blueprints/Steps/ImportThemeStarterContentStep.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public function __construct( ?string $themeSlug = null ) {
2222

2323
public function run( Runtime $runtime, Tracker $tracker ) {
2424
$tracker->setCaption( 'Importing theme starter content' . ( $this->themeSlug ? ' for ' . $this->themeSlug : '' ) );
25-
$runtime->evalPhpInSubProcess(
25+
$runtime->evalPhpCodeInSubProcess(
2626
file_get_contents( __DIR__ . '/scripts/ImportThemeStarterContent/import.php' ),
2727
[
2828
'THEME_SLUG' => $this->themeSlug,

components/Blueprints/Steps/InstallPluginStep.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,15 @@ public function run( Runtime $runtime, Tracker $tracker ) {
9292
$zip_stream->close_writing();
9393

9494
$tracker->set( 50 );
95-
$relative_path = $runtime->evalPhpInSubProcess(
96-
file_get_contents( __DIR__ . '/scripts/InstallPlugin/wp_install_plugin.php' ),
95+
$relative_path = $runtime->evalPhpFileInSubProcess(
96+
wp_join_paths( __DIR__, 'scripts/InstallPlugin/wp_install_plugin.php' ),
9797
[ 'PLUGIN_ZIP_PATH' => $zip_absolute_path ]
9898
)->outputFileContent;
9999

100100
if ( $this->active ) {
101101
$tracker->set( 75, 'Activating plugin ' . $plugin_data->get_human_readable_name() );
102-
$runtime->evalPhpInSubProcess(
103-
file_get_contents( __DIR__ . '/scripts/ActivatePlugin/wp_activate_plugin.php' ),
102+
$runtime->evalPhpFileInSubProcess(
103+
wp_join_paths( __DIR__, 'scripts/ActivatePlugin/wp_activate_plugin.php' ),
104104
[ 'PLUGIN_PATH' => $relative_path ]
105105
);
106106
}

components/Blueprints/Steps/InstallThemeStep.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ public function run( Runtime $runtime, Tracker $tracker ) {
8888

8989
$tracker->set( 50 );
9090

91-
$output = $runtime->evalPhpInSubProcess(
92-
file_get_contents( __DIR__ . '/scripts/InstallTheme/wp_install_theme.php' ),
91+
$output = $runtime->evalPhpFileInSubProcess(
92+
wp_join_paths( __DIR__, 'scripts/InstallTheme/wp_install_theme.php' ),
9393
[ 'THEME_ZIP_PATH' => $zip_absolute_path ]
9494
);
9595

@@ -102,8 +102,8 @@ public function run( Runtime $runtime, Tracker $tracker ) {
102102

103103
if ( $this->activate ) {
104104
$tracker->set( 75, 'Activating theme ' . $theme_folder_name );
105-
$runtime->evalPhpInSubProcess(
106-
file_get_contents( __DIR__ . '/scripts/ActivateTheme/wp_activate_theme.php' ),
105+
$runtime->evalPhpFileInSubProcess(
106+
wp_join_paths( __DIR__, 'scripts/ActivateTheme/wp_activate_theme.php' ),
107107
[ 'THEME_FOLDER_NAME' => $theme_folder_name ]
108108
);
109109
}

components/Blueprints/Steps/RunPHPStep.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ public function run( Runtime $runtime, Tracker $tracker ) {
4444
} else {
4545
throw new BlueprintExecutionException( 'The code property must be a File reference.' );
4646
}
47-
$runtime->evalPhpInSubProcess( $code, $env );
47+
$runtime->evalPhpCodeInSubProcess( $code, $env );
4848
}
4949
}

components/Blueprints/Steps/RunSqlStep.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function run( Runtime $runtime, Tracker $tracker ) {
3535
throw new InvalidArgumentException( 'The provided resource is not a file.' );
3636
}
3737

38-
$runtime->evalPhpInSubProcess(
38+
$runtime->evalPhpCodeInSubProcess(
3939
<<<'CODE'
4040
<?php
4141
require_once getenv("DOCROOT") . '/wp-load.php';

components/Blueprints/Steps/SetSiteLanguageStep.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ public function run( Runtime $runtime, Tracker $progress ) {
5454
}
5555

5656
// Get core translation package URL
57-
$wp_version = trim( $runtime->evalPhpInSubProcess(
57+
$wp_version = trim( $runtime->evalPhpCodeInSubProcess(
5858
'<?php
5959
require getenv("DOCROOT") . "/wp-includes/version.php";
6060
append_output( $wp_version );
6161
'
6262
)->outputFileContent );
6363

6464
// Get plugin translations
65-
$plugins_data = json_decode( $runtime->evalPhpInSubProcess(
65+
$plugins_data = json_decode( $runtime->evalPhpCodeInSubProcess(
6666
"<?php
6767
require_once(getenv('DOCROOT') . '/wp-load.php');
6868
require_once(getenv('DOCROOT') . '/wp-admin/includes/plugin.php');
@@ -89,7 +89,7 @@ function(\$plugin) {
8989
)->outputFileContent, true );
9090

9191
// Get theme translations
92-
$themes_data = json_decode( $runtime->evalPhpInSubProcess(
92+
$themes_data = json_decode( $runtime->evalPhpCodeInSubProcess(
9393
"<?php
9494
require_once(getenv('DOCROOT') . '/wp-load.php');
9595
require_once(getenv('DOCROOT') . '/wp-admin/includes/theme.php');

components/Blueprints/Steps/SetSiteOptionsStep.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public function __construct( array $options ) {
2424

2525
public function run( Runtime $runtime, Tracker $tracker ) {
2626
$tracker->setCaption( 'Setting site options' );
27-
$runtime->evalPhpInSubProcess(
27+
$runtime->evalPhpCodeInSubProcess(
2828
'<?php
2929
require getenv(\'DOCROOT\'). \'/wp-load.php\';
3030
$site_options = getenv("OPTIONS") ? json_decode(getenv("OPTIONS"), true) : [];

components/Blueprints/Tests/Unit/Steps/DefineConstantsStepTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public function testDefineMultipleConstants() {
128128
* @return array Results of constant verification
129129
*/
130130
private function assertWordPressConstants( array $expected_constants ) {
131-
$result = $this->runtime->evalPhpInSubProcess(
131+
$result = $this->runtime->evalPhpCodeInSubProcess(
132132
<<<'PHP'
133133
<?php
134134
// Load WordPress environment

components/Blueprints/Tests/Unit/Steps/InstallPluginStepTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function testInstallPluginWithActivation() {
5050
$this->assertTrue( $fs->exists( 'wp-content/plugins/test-plugin/test-plugin.php' ) );
5151

5252
// Check if plugin is activated
53-
$active_plugins = $this->runtime->evalPhpInSubProcess(
53+
$active_plugins = $this->runtime->evalPhpCodeInSubProcess(
5454
<<<'PHP'
5555
<?php
5656
require_once getenv('DOCROOT') . '/wp-load.php';
@@ -84,7 +84,7 @@ public function testInstallPluginWithoutActivation() {
8484
$fs = $this->runtime->getTargetFilesystem();
8585
$this->assertTrue( $fs->exists( 'wp-content/plugins/test-plugin' ) );
8686
$this->assertTrue( $fs->exists( 'wp-content/plugins/test-plugin/test-plugin.php' ) );
87-
$inactive_plugins = $this->runtime->evalPhpInSubProcess(
87+
$inactive_plugins = $this->runtime->evalPhpCodeInSubProcess(
8888
<<<'PHP'
8989
<?php
9090
require_once getenv('DOCROOT') . '/wp-load.php';
@@ -103,7 +103,7 @@ public function testInstallPluginWithoutActivation() {
103103
$this->assertContains( 'test-plugin/test-plugin.php', $inactive_plugins );
104104

105105
// Check if plugin is activated
106-
$active_plugins = $this->runtime->evalPhpInSubProcess(
106+
$active_plugins = $this->runtime->evalPhpCodeInSubProcess(
107107
<<<'PHP'
108108
<?php
109109
require_once getenv('DOCROOT') . '/wp-load.php';
@@ -138,7 +138,7 @@ public function testInstallPluginFromZip() {
138138
$this->assertTrue( $fs->exists( 'wp-content/plugins/zipped-test-plugin/test-plugin.php' ) );
139139

140140
// Check if plugin is activated
141-
$active_plugins = $this->runtime->evalPhpInSubProcess(
141+
$active_plugins = $this->runtime->evalPhpCodeInSubProcess(
142142
<<<'PHP'
143143
<?php
144144
require_once getenv('DOCROOT') . '/wp-load.php';
@@ -173,7 +173,7 @@ public function testInstallPluginFromZipWithSubfolder() {
173173
$this->assertTrue( $fs->exists( 'wp-content/plugins/subfolder-name/test-plugin.php' ) );
174174

175175
// Check if plugin is activated
176-
$active_plugins = $this->runtime->evalPhpInSubProcess(
176+
$active_plugins = $this->runtime->evalPhpCodeInSubProcess(
177177
<<<'PHP'
178178
<?php
179179
require_once getenv('DOCROOT') . '/wp-load.php';
@@ -208,7 +208,7 @@ public function testInstallPluginFromADirectory() {
208208
$this->assertTrue( $fs->exists( 'wp-content/plugins/plugin-directory/test-plugin.php' ) );
209209

210210
// Check if plugin is activated
211-
$active_plugins = $this->runtime->evalPhpInSubProcess(
211+
$active_plugins = $this->runtime->evalPhpCodeInSubProcess(
212212
<<<'PHP'
213213
<?php
214214
require_once getenv('DOCROOT') . '/wp-load.php';

0 commit comments

Comments
 (0)