Making WordPress.org

Changeset 10786


Ignore:
Timestamp:
03/05/2021 02:44:35 AM (6 years ago)
Author:
dd32
Message:

Theme Directory: Update the uploader to use an exec() wrapper which triggers PHP Notices/Warnings on errors to help determine if there's anything failing in the shell commands component of uploads.

Previously an error in one of these steps would not be seen until a developer were to get the problematic uploaded ZIP file and debug it interactively, this causes the warnings/errors to end up in the WordPress.org PHP Logging instead.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/theme-directory/class-wporg-themes-upload.php

    r10785 r10786  
    442442
    443443                // Unzip it into the theme directory.
    444                 exec( escapeshellcmd( "{$unzip} -DD {$zip_file} -d {$tmp_dir}/{$base_name}" ) );
     444                $this->exec_with_notify( escapeshellcmd( "{$unzip} -DD {$zip_file} -d {$tmp_dir}/{$base_name}" ) );
    445445
    446446                // Fix any permissions issues with the files. Sets 755 on directories, 644 on files
    447                 exec( escapeshellcmd( "chmod -R 755 {$tmp_dir}/{$base_name}" ) );
    448                 exec( escapeshellcmd( "find {$tmp_dir}/{$base_name} -type f -print0" ) . ' | xargs -I% -0 chmod 644 %' );
     447                $this->exec_with_notify( escapeshellcmd( "chmod -R 755 {$tmp_dir}/{$base_name}" ) );
     448                $this->exec_with_notify( escapeshellcmd( "find {$tmp_dir}/{$base_name} -type f -print0" ) . ' | xargs -I% -0 chmod 644 %' );
    449449        }
    450450
    … …  
    948948                $new_version_dir = escapeshellarg( "{$this->tmp_svn_dir}/{$this->theme->display( 'Version' )}" );
    949949
     950                // Keeps a copy of the output of the commands for debugging.
     951                $output = array();
     952
    950953                // Theme exists, attempt to do a copy from old version to new.
    951                 exec( self::SVN . " co https://themes.svn.wordpress.org/{$this->theme_slug}/ {$this->tmp_svn_dir} --depth=empty  2>&1", $output, $return_var );
     954                $this->exec_with_notify( self::SVN . " co https://themes.svn.wordpress.org/{$this->theme_slug}/ {$this->tmp_svn_dir} --depth=empty", $output, $return_var );
    952955                if ( $return_var > 0 ) {
    953956                        return $this->add_to_svn_via_svn_import();
    … …  
    956959                // Try to copy the previous version over.
    957960                $prev_version = escapeshellarg( "https://themes.svn.wordpress.org/{$this->theme_slug}/{$this->theme_post->max_version}" );
    958                 exec( self::SVN . " cp $prev_version $new_version_dir 2>&1", $output, $return_var );
     961                $this->exec_with_notify( self::SVN . " cp $prev_version $new_version_dir", $output, $return_var );
    959962                if ( $return_var > 0 ) {
    960963                        return $this->add_to_svn_via_svn_import();
    … …  
    962965
    963966                // Remove the files from the old version, so that we can track file removals.
    964                 exec( self::RM . " -rf {$new_version_dir}/*" );
     967                $this->exec_with_notify( self::RM . " -rf {$new_version_dir}/*", $output );
    965968
    966969                $theme_dir = escapeshellarg( $this->theme_dir );
    967                 exec( self::CP . " -R {$theme_dir}/* {$new_version_dir}" );
     970                $this->exec_with_notify( self::CP . " -R {$theme_dir}/* {$new_version_dir}", $output );
    968971
    969972                // Process file additions and removals.
    970                 exec( self::SVN . " st {$new_version_dir} | grep '^?' | cut -c 2- | xargs -I{} " . self::SVN . " add {}" );
    971                 exec( self::SVN . " st {$new_version_dir} | grep '^!' | cut -c 2- | xargs -I{} " . self::SVN . " rm {}" );
     973                $this->exec_with_notify( self::SVN . " st {$new_version_dir} | grep '^?' | cut -c 2- | xargs -I% " . self::SVN . " add %", $output );
     974                $this->exec_with_notify( self::SVN . " st {$new_version_dir} | grep '^!' | cut -c 2- | xargs -I% " . self::SVN . " rm %", $output );
    972975
    973976                // Commit it to SVN.
    … …  
    978981                        $this->theme->display( 'Version' )
    979982                ) );
    980                 exec( self::SVN . " ci --non-interactive --username themedropbox --password {$password} -m {$message} {$new_version_dir} 2>&1", $output, $return_var );
     983
     984                /* DEBUGGING
     985                        dump the output of $output here and return false;
     986                */
     987
     988                $last_line = $this->exec_with_notify( self::SVN . " ci --non-interactive --username themedropbox --password {$password} -m {$message} {$new_version_dir}", $output, $return_var );
    981989                if ( $return_var > 0 ) {
    982990                        return $this->add_to_svn_via_svn_import();
    983991                }
    984992
    985                 if ( preg_match( '/Committed revision (\d+)./i', implode( '', $output ), $m ) ) {
     993                if ( preg_match( '/Committed revision (\d+)\./i', $last_line, $m ) ) {
    986994                        $this->trac_changeset = $m[1];
    987995                        return true;
    … …  
    10021010                $password   = escapeshellarg( THEME_DROPBOX_PASSWORD );
    10031011
    1004                 $result = exec( "{$svn} --non-interactive --username themedropbox --password {$password} --no-auto-props -m {$import_msg} import {$theme_path} {$svn_path} 2>&1" );
    1005 
    1006                 if ( preg_match( '/Committed revision (\d+)./i', $result, $m ) ) {
     1012                $last_line = $this->exec_with_notify( "{$svn} --non-interactive --username themedropbox --password {$password} --no-auto-props -m {$import_msg} import {$theme_path} {$svn_path}" );
     1013
     1014                if ( preg_match( '/Committed revision (\d+)\./i', $last_line, $m ) ) {
    10071015                        $this->trac_changeset = $m[1];
    10081016                        return true;
    … …  
    12111219                $files = escapeshellarg( $this->tmp_dir );
    12121220
    1213                 exec( escapeshellcmd( "{$rm} -rf {$files}" ) );
     1221                $this->exec_with_notify( escapeshellcmd( "{$rm} -rf {$files}" ) );
    12141222        }
    12151223
    … …  
    12381246                return strlen( $b ) - strlen( $a );
    12391247        }
     1248
     1249        /**
     1250         * Execute a shell process, same behaviour as `exec()` but with PHP Warnings/Notices generated on errors.
     1251         *
     1252         * @param string $command    Command to execute. Escape it.
     1253         * @param array  $output     Array to append program output to. Passed by reference.
     1254         * @param int    $return_var The commands return value. Passed by reference.
     1255         *
     1256         * @return false|string False on failure, last line of output on success, as per exec().
     1257         */
     1258        public function exec_with_notify( $command, &$output = null, &$return_var = null ) {
     1259                $proc = proc_open(
     1260                        $command,
     1261                        [
     1262                                1 => [ 'pipe', 'w' ], // STDOUT
     1263                                2 => [ 'pipe', 'w' ], // STDERR
     1264                        ],
     1265                        $pipes
     1266                );
     1267
     1268                $stdout = stream_get_contents( $pipes[1] );
     1269                $stderr = stream_get_contents( $pipes[2] );
     1270                fclose( $pipes[1] );
     1271                fclose( $pipes[2] );
     1272
     1273                $return_var = proc_close( $proc );
     1274
     1275                // Append to $output, as `exec()` does.
     1276                if ( ! is_array( $output ) ) {
     1277                        $output = [];
     1278                }
     1279                if ( $stdout ) {
     1280                        $output = array_merge( $output, explode( "\n", rtrim( $stdout, "\r\n" ) ) );
     1281                }
     1282
     1283                if ( $return_var > 0 ) {
     1284                        trigger_error( "Command failed, `{$command}` return value: {$return_var} STDOUT: ```{$stdout}``` STDERR: ```{$stderr}```", E_USER_WARNING );
     1285                } elseif ( $stderr ) {
     1286                        trigger_error( "Command produced errors, `{$command}` return value: {$return_var} STDOUT: ```{$stdout}``` STDERR: ```{$stderr}```", E_USER_NOTICE );
     1287                }
     1288
     1289                // Execution failed.
     1290                if ( $return_var > 0 ) {
     1291                        return false;
     1292                }
     1293
     1294                // Successful, return the last output line.
     1295                return $stdout ? end( $output ) : '';
     1296        }
    12401297}
Note: See TracChangeset for help on using the changeset viewer.