language-command/utils/make-phar.php
Pascal Birchler 42f12caa5f
Revert "Remove conditional inclusion"
This reverts commit 30afdc571d.
2025-07-08 17:55:47 +02:00

324 lines
10 KiB
PHP

<?php
define( 'WP_CLI_BUNDLE_ROOT', rtrim( dirname( __DIR__ ), '/' ) );
if ( file_exists( WP_CLI_BUNDLE_ROOT . '/vendor/autoload.php' ) ) {
define( 'WP_CLI_BASE_PATH', WP_CLI_BUNDLE_ROOT );
define( 'WP_CLI_VENDOR_DIR', WP_CLI_BUNDLE_ROOT . '/vendor' );
} elseif ( file_exists( dirname( dirname( WP_CLI_BUNDLE_ROOT ) ) . '/autoload.php' ) ) {
define( 'WP_CLI_BASE_PATH', dirname( dirname( dirname( WP_CLI_BUNDLE_ROOT ) ) ) );
define( 'WP_CLI_VENDOR_DIR', dirname( dirname( WP_CLI_BUNDLE_ROOT ) ) );
} else {
fwrite( STDERR, 'Missing vendor/autoload.php' . PHP_EOL );
exit( 1 );
}
define( 'WP_CLI_ROOT', rtrim( WP_CLI_VENDOR_DIR, '/' ) . '/wp-cli/wp-cli' );
require WP_CLI_VENDOR_DIR . '/autoload.php';
require WP_CLI_ROOT . '/php/utils.php';
use Symfony\Component\Finder\Finder;
use WP_CLI\Utils;
use WP_CLI\Configurator;
$configurator = new Configurator( WP_CLI_BUNDLE_ROOT . '/utils/make-phar-spec.php' );
list( $args, $assoc_args, $runtime_config ) = $configurator->parse_args( array_slice( $GLOBALS['argv'], 1 ) );
if ( ! isset( $args[0] ) || empty( $args[0] ) ) {
fwrite( STDERR, "usage: php -dphar.readonly=0 $argv[0] <path> [--quiet] [--version=same|patch|minor|major|x.y.z] [--store-version] [--build=cli]" . PHP_EOL );
exit( 1 );
}
define( 'DEST_PATH', $args[0] );
define( 'BE_QUIET', isset( $runtime_config['quiet'] ) && $runtime_config['quiet'] );
define( 'BUILD', isset( $runtime_config['build'] ) ? $runtime_config['build'] : '' );
$current_version = trim( file_get_contents( WP_CLI_ROOT . '/VERSION' ) );
if ( isset( $runtime_config['version'] ) ) {
$new_version = $runtime_config['version'];
$new_version = Utils\increment_version( $current_version, $new_version );
if ( isset( $runtime_config['store-version'] ) && $runtime_config['store-version'] ) {
file_put_contents( WP_CLI_ROOT . '/VERSION', $new_version );
}
$current_version = $new_version;
}
function add_file( $phar, $path ) {
$key = str_replace( WP_CLI_BASE_PATH, '', $path );
if ( ! BE_QUIET ) {
echo "$key - $path" . PHP_EOL;
}
$basename = basename( $path );
if ( 0 === strpos( $basename, 'autoload_' ) && preg_match( '/(?:classmap|files|namespaces|psr4|static)\.php$/', $basename ) ) {
// Strip autoload maps of unused stuff.
static $strip_res = null;
if ( null === $strip_res ) {
if ( 'cli' === BUILD ) {
$strips = [
'\/(?:behat|composer|gherkin)\/src\/',
'\/behat\/',
'\/phpunit\/',
'\/phpstan\/',
'\/phpspec\/',
'\/sebastian\/',
'\/php-parallel-lint\/',
'\/nb\/oxymel\/',
'-command\/src\/',
'\/wp-cli\/[^\n]+?-command\/',
'\/symfony\/(?:config|console|debug|dependency-injection|event-dispatcher|filesystem|translation|yaml)',
'\/(?:dealerdirect|myclabs|squizlabs|wimg)\/',
'\/yoast\/',
];
} else {
$strips = [
'\/(?:behat|gherkin)\/src\/',
'\/behat\/',
'\/phpunit\/',
'\/phpstan\/',
'\/phpspec\/',
'\/sebastian\/',
'\/php-parallel-lint\/',
'\/symfony\/(?:config|debug|dependency-injection|event-dispatcher|translation|yaml)',
'\/composer\/spdx-licenses\/',
'\/Composer\/(?:Command\/|Compiler\.php|Console\/|Downloader\/Pear|Installer\/Pear|Question\/|Repository\/Pear|SelfUpdate\/)',
'\/(?:dealerdirect|myclabs|squizlabs|wimg)\/',
'\/yoast\/',
];
}
$strip_res = array_map(
static function ( $v ) {
return '/^[^,\n]+?' . $v . '[^,\n]+?, *\n/m';
},
$strips
);
}
$phar[ $key ] = preg_replace( $strip_res, '', file_get_contents( $path ) );
} else {
$phar[ $key ] = file_get_contents( $path );
}
}
function set_file_contents( $phar, $path, $content ) {
$key = str_replace( WP_CLI_BASE_PATH, '', $path );
if ( ! BE_QUIET ) {
echo "$key - $path" . PHP_EOL;
}
$phar[ $key ] = $content;
}
function get_composer_versions( $current_version ) {
$composer_lock_path = WP_CLI_BUNDLE_ROOT . '/composer.lock';
$composer_lock_file = file_get_contents( $composer_lock_path );
if ( ! $composer_lock_file ) {
fwrite( STDERR, sprintf( "Warning: Failed to read '%s'." . PHP_EOL, $composer_lock_path ) );
return '';
}
$composer_lock = json_decode( $composer_lock_file, true );
if ( ! $composer_lock ) {
fwrite( STDERR, sprintf( "Warning: Could not decode '%s'." . PHP_EOL, $composer_lock_path ) );
return '';
}
if ( ! isset( $composer_lock['packages'] ) ) {
fwrite( STDERR, sprintf( "Warning: No packages in '%s'." . PHP_EOL, $composer_lock_path ) );
return '';
}
$vendor_versions = [ implode( ' ', [ 'wp-cli/wp-cli', $current_version, gmdate( 'c' ) ] ) ];
$missing_names = 0;
$missing_versions = 0;
$missing_references = 0;
foreach ( $composer_lock['packages'] as $package ) {
if ( isset( $package['name'] ) ) {
$vendor_version = [ $package['name'] ];
if ( isset( $package['version'] ) ) {
$vendor_version[] = $package['version'];
} else {
$vendor_version[] = 'unknown_version';
++$missing_versions;
}
if ( isset( $package['source'] ) && isset( $package['source']['reference'] ) ) {
$vendor_version[] = $package['source']['reference'];
} elseif ( isset( $package['dist'] ) && isset( $package['dist']['reference'] ) ) {
$vendor_version[] = $package['dist']['reference'];
} else {
$vendor_version[] = 'unknown_reference';
++$missing_references;
}
$vendor_versions[] = implode( ' ', $vendor_version );
} else {
$vendor_versions[] = implode( ' ', [ 'unknown_package', 'unknown_version', 'unknown_reference' ] );
++$missing_names;
}
}
if ( $missing_names ) {
fwrite( STDERR, sprintf( "Warning: %d package names missing from '%s'." . PHP_EOL, $missing_names, $composer_lock_path ) );
}
if ( $missing_versions ) {
fwrite( STDERR, sprintf( "Warning: %d package versions missing from '%s'." . PHP_EOL, $missing_versions, $composer_lock_path ) );
}
if ( $missing_references ) {
fwrite( STDERR, sprintf( "Warning: %d package references missing from '%s'." . PHP_EOL, $missing_references, $composer_lock_path ) );
}
return implode( "\n", $vendor_versions );
}
if ( file_exists( DEST_PATH ) ) {
unlink( DEST_PATH );
}
$phar = new Phar( DEST_PATH, 0, 'wp-cli.phar' );
$phar->startBuffering();
// PHP files
$finder = new Finder();
$finder
->files()
->ignoreVCS( true )
->name( '/\.*.php8?/' )
->in( WP_CLI_ROOT . '/php' )
->in( WP_CLI_BUNDLE_ROOT . '/php' )
->in( WP_CLI_VENDOR_DIR . '/mustache/mustache' )
->in( WP_CLI_VENDOR_DIR . '/eftec/bladeone' )
->in( WP_CLI_ROOT . '/bundle/rmccue/requests' )
->in( WP_CLI_VENDOR_DIR . '/composer' )
->in( WP_CLI_VENDOR_DIR . '/symfony' )
->notName( 'behat-tags.php' )
->notPath( '#(?:[^/]+-command|php-cli-tools)/vendor/#' ) // For running locally, in case have composer installed or symlinked them.
->exclude( 'config' )
->exclude( 'debug' )
->exclude( 'dependency-injection' )
->exclude( 'event-dispatcher' )
->exclude( 'translation' )
->exclude( 'yaml' )
->exclude( 'examples' )
->exclude( 'features' )
->exclude( 'test' )
->exclude( 'tests' )
->exclude( 'Test' )
->exclude( 'Tests' );
if ( is_dir( WP_CLI_VENDOR_DIR . '/react' ) ) {
$finder
->in( WP_CLI_VENDOR_DIR . '/react' );
}
if ( 'cli' === BUILD ) {
$finder
->in( WP_CLI_VENDOR_DIR . '/wp-cli/mustangostang-spyc' )
->in( WP_CLI_VENDOR_DIR . '/wp-cli/php-cli-tools' )
->in( WP_CLI_VENDOR_DIR . '/seld/cli-prompt' )
->exclude( 'console' )
->exclude( 'filesystem' )
->exclude( 'composer/ca-bundle' )
->exclude( 'composer/semver' )
->exclude( 'composer/src' )
->exclude( 'composer/spdx-licenses' );
} else {
$finder
->in( WP_CLI_VENDOR_DIR . '/wp-cli' )
->in( WP_CLI_VENDOR_DIR . '/nb/oxymel' )
->in( WP_CLI_VENDOR_DIR . '/psr' )
->in( WP_CLI_VENDOR_DIR . '/seld' )
->in( WP_CLI_VENDOR_DIR . '/justinrainbow/json-schema' )
->in( WP_CLI_VENDOR_DIR . '/gettext' )
->in( WP_CLI_VENDOR_DIR . '/mck89' )
->exclude( 'demo' )
->exclude( 'nb/oxymel/OxymelTest.php' )
->exclude( 'composer/spdx-licenses' )
->exclude( 'composer/composer/src/Composer/Command' )
->exclude( 'composer/composer/src/Composer/Compiler.php' )
->exclude( 'composer/composer/src/Composer/Console' )
->exclude( 'composer/composer/src/Composer/Downloader/PearPackageExtractor.php' ) // Assuming Pear installation isn't supported by wp-cli.
->exclude( 'composer/composer/src/Composer/Installer/PearBinaryInstaller.php' )
->exclude( 'composer/composer/src/Composer/Installer/PearInstaller.php' )
->exclude( 'composer/composer/src/Composer/Question' )
->exclude( 'composer/composer/src/Composer/Repository/Pear' )
->exclude( 'composer/composer/src/Composer/SelfUpdate' );
// required by justinrainbow/json-schema v6+.
if ( is_dir( WP_CLI_VENDOR_DIR . '/marc-mabe/php-enum' ) ) {
$finder->in( WP_CLI_VENDOR_DIR . '/marc-mabe/php-enum' );
}
}
foreach ( $finder as $file ) {
add_file( $phar, $file );
}
// other files
$finder = new Finder();
$finder
->files()
->ignoreVCS( true )
->ignoreDotFiles( false )
->in( WP_CLI_ROOT . '/templates' )
->in( WP_CLI_VENDOR_DIR . '/wp-cli/*-command/templates' );
foreach ( $finder as $file ) {
add_file( $phar, $file );
}
if ( 'cli' !== BUILD ) {
// Include base project files, because the autoloader will load them
if ( WP_CLI_BASE_PATH !== WP_CLI_BUNDLE_ROOT && is_dir( WP_CLI_BASE_PATH . '/src' ) ) {
$finder = new Finder();
$finder
->files()
->ignoreVCS( true )
->name( '*.php' )
->in( WP_CLI_BASE_PATH . '/src' )
->exclude( 'test' )
->exclude( 'tests' )
->exclude( 'Test' )
->exclude( 'Tests' );
foreach ( $finder as $file ) {
add_file( $phar, $file );
}
// Any PHP files in the project root
foreach ( glob( WP_CLI_BASE_PATH . '/*.php' ) as $file ) {
add_file( $phar, $file );
}
}
}
add_file( $phar, WP_CLI_VENDOR_DIR . '/autoload.php' );
if ( 'cli' !== BUILD ) {
add_file( $phar, WP_CLI_VENDOR_DIR . '/composer/composer/LICENSE' );
add_file( $phar, WP_CLI_VENDOR_DIR . '/composer/composer/res/composer-schema.json' );
}
add_file( $phar, WP_CLI_ROOT . '/bundle/rmccue/requests/certificates/cacert.pem' );
set_file_contents( $phar, WP_CLI_ROOT . '/COMPOSER_VERSIONS', get_composer_versions( $current_version ) );
set_file_contents( $phar, WP_CLI_ROOT . '/VERSION', $current_version );
$phar_boot = str_replace( WP_CLI_BASE_PATH, '', WP_CLI_BUNDLE_ROOT . '/php/boot-phar.php' );
$phar_boot = '/' . ltrim( $phar_boot, '/' );
$phar->setStub(
<<<EOB
#!/usr/bin/env php
<?php
Phar::mapPhar();
include 'phar://wp-cli.phar{$phar_boot}';
__HALT_COMPILER();
?>
EOB
);
$phar->stopBuffering();
chmod( DEST_PATH, 0755 ); // Make executable.
if ( ! BE_QUIET ) {
echo 'Generated ' . DEST_PATH . PHP_EOL;
}