HEX
Server: Apache
System: Linux pdx1-shared-a1-38 6.6.104-grsec-jammy+ #3 SMP Tue Sep 16 00:28:11 UTC 2025 x86_64
User: mmickelson (3396398)
PHP: 8.1.31
Disabled: NONE
Upload Files
File: //usr/local/wp/vendor/wp-cli/wp-cli-tests/utils/generate-coverage.php
<?php

/**
 * This script is added via the `WP_CLI_REQUIRE` environment variable to the WP-CLI commands executed by the Behat test runner.
 * It starts coverage collection right away and registers a shutdown hook to complete it
 * after the respective WP-CLI command has finished.
 */

use SebastianBergmann\CodeCoverage\CodeCoverage;
use SebastianBergmann\CodeCoverage\Driver\Selector;
use SebastianBergmann\CodeCoverage\Driver\Xdebug;
use SebastianBergmann\CodeCoverage\Filter;
use SebastianBergmann\CodeCoverage\Report\PHP as PHPReport;

/*
 * The names of the current feature and scenario are passed on from the Behat test runner
 * to this script through environment variables.
 */
$feature   = getenv( 'BEHAT_FEATURE_TITLE' );
$scenario  = getenv( 'BEHAT_SCENARIO_TITLE' );
$step_line = (int) getenv( 'BEHAT_STEP_LINE' );
$name      = "{$feature} - {$scenario} - {$step_line}";

/*
 * Do not run coverage if they are empty, which means we are running some command
 * during test preparation, e.g. the `wp core download` in `FeatureContext::prepare()`.
 */
if ( empty( $feature ) | empty( $scenario ) ) {
	return;
}

$project_dir = (string) getenv( 'TEST_RUN_DIR' );

if ( ! class_exists( 'SebastianBergmann\CodeCoverage\Filter' ) ) {
	if ( ! file_exists( $project_dir . '/vendor/autoload.php' ) ) {
		die( 'Could not load dependencies for generating code coverage' );
	}
	require "{$project_dir}/vendor/autoload.php";
}

$filtered_items = new CallbackFilterIterator(
	new DirectoryIterator( $project_dir ),
	function ( $file ) {
		// Allow directories named "php" or "src"
		if ( $file->isDir() && in_array( $file->getFilename(), [ 'php', 'src' ], true ) ) {
			return true;
		}

		// Allow top-level files ending in "-command.php"
		if ( $file->isFile() && false !== strpos( $file->getFilename(), '-command.php' ) ) {
			return true;
		}

		return false;
	}
);

$files = [];

foreach ( $filtered_items as $item ) {
	if ( $item->isDir() ) {
		foreach (
			new RecursiveIteratorIterator(
				new RecursiveDirectoryIterator( $item->getPathname(), RecursiveDirectoryIterator::SKIP_DOTS )
			) as $file
		) {
			if ( $file->isFile() && $file->getExtension() === 'php' ) {
				$files[] = $file->getPathname();
			}
		}
	} else {
		$files[] = $item->getPathname();
	}
}

$filter = new Filter();

if ( method_exists( $filter, 'includeFiles' ) ) {
	$filter->includeFiles( $files );
} else {
	$filter->addFilesToWhitelist( $files );
}

$coverage = new CodeCoverage(
	// Selector class was only added in v9.1 of the php-code-coverage library.
	class_exists( Selector::class ) ? ( new Selector() )->forLineCoverage( $filter ) : ( new Xdebug() ),
	$filter
);

$coverage->start( $name );

register_shutdown_function(
	static function () use ( $coverage, $feature, $scenario, $step_line, $name, $project_dir ) {
		$coverage->stop();

		$feature_suffix  = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $feature ) );
		$scenario_suffix = preg_replace( '/[^a-z0-9]+/', '-', strtolower( $scenario ) );
		$db_type         = strtolower( getenv( 'WP_CLI_TEST_DBTYPE' ) );
		$destination     = "$project_dir/build/logs/$feature_suffix-$scenario_suffix-$step_line-$db_type.cov";

		$dir = dirname( $destination );
		if ( ! file_exists( $dir ) ) {
			mkdir( $dir, 0777, true /*recursive*/ );
		}

		( new PHPReport() )->process( $coverage, $destination );
	}
);