|
| 1 | +#!/usr/bin/env php |
| 2 | +<?php |
| 3 | + |
| 4 | +/* |
| 5 | + * This file is part of the Symfony package. |
| 6 | + * |
| 7 | + * (c) Fabien Potencier <[email protected]> |
| 8 | + * |
| 9 | + * For the full copyright and license information, please view the LICENSE |
| 10 | + * file that was distributed with this source code. |
| 11 | + */ |
| 12 | + |
| 13 | +// Please update when phpunit needs to be reinstalled with fresh deps: |
| 14 | +// Cache-Id-Version: 2016-09-12 09:00 UTC |
| 15 | + |
| 16 | +error_reporting(-1); |
| 17 | + |
| 18 | +// PHPUnit 4.8 does not support PHP 7, while 5.1 requires PHP 5.6+ |
| 19 | +$PHPUNIT_VERSION = PHP_VERSION_ID >= 50600 ? '5.1' : '4.8'; |
| 20 | +$oldPwd = getcwd(); |
| 21 | +$PHPUNIT_DIR = getenv('SYMFONY_PHPUNIT_DIR') ?: (__DIR__.'/.phpunit'); |
| 22 | +$PHP = defined('PHP_BINARY') ? PHP_BINARY : 'php'; |
| 23 | +$PHP = escapeshellarg($PHP); |
| 24 | +if ('phpdbg' === PHP_SAPI) { |
| 25 | + $PHP .= ' -qrr'; |
| 26 | +} |
| 27 | + |
| 28 | +$COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar`)) |
| 29 | + ? $PHP.' '.escapeshellarg($COMPOSER) |
| 30 | + : 'composer'; |
| 31 | + |
| 32 | +if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__FILE__) !== @file_get_contents("$PHPUNIT_DIR/.$PHPUNIT_VERSION.md5")) { |
| 33 | + // Build a standalone phpunit without symfony/yaml nor prophecy |
| 34 | + |
| 35 | + @mkdir($PHPUNIT_DIR); |
| 36 | + chdir($PHPUNIT_DIR); |
| 37 | + if (file_exists("phpunit-$PHPUNIT_VERSION")) { |
| 38 | + passthru(sprintf('\\' === DIRECTORY_SEPARATOR ? '(del /S /F /Q %s & rmdir %1$s) >nul': 'rm -rf %s', "phpunit-$PHPUNIT_VERSION")); |
| 39 | + } |
| 40 | + if (extension_loaded('openssl') && ini_get('allow_url_fopen')) { |
| 41 | + stream_copy_to_stream(fopen("https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip", 'rb'), fopen("$PHPUNIT_VERSION.zip", 'wb')); |
| 42 | + } else { |
| 43 | + @unlink("$PHPUNIT_VERSION.zip"); |
| 44 | + passthru("wget https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip"); |
| 45 | + } |
| 46 | + $zip = new ZipArchive(); |
| 47 | + $zip->open("$PHPUNIT_VERSION.zip"); |
| 48 | + $zip->extractTo(getcwd()); |
| 49 | + $zip->close(); |
| 50 | + chdir("phpunit-$PHPUNIT_VERSION"); |
| 51 | + passthru("$COMPOSER remove --no-update phpspec/prophecy"); |
| 52 | + passthru("$COMPOSER remove --no-update symfony/yaml"); |
| 53 | + if (5.1 <= $PHPUNIT_VERSION && $PHPUNIT_VERSION < 5.4) { |
| 54 | + passthru("$COMPOSER require --no-update phpunit/phpunit-mock-objects \"~3.1.0\""); |
| 55 | + } |
| 56 | + passthru("$COMPOSER require --dev --no-update symfony/phpunit-bridge \">=3.2@dev\""); |
| 57 | + passthru("$COMPOSER install --prefer-dist --no-progress --ansi", $exit); |
| 58 | + if ($exit) { |
| 59 | + exit($exit); |
| 60 | + } |
| 61 | + file_put_contents('phpunit', <<<'EOPHP' |
| 62 | +<?php |
| 63 | +
|
| 64 | +define('PHPUNIT_COMPOSER_INSTALL', __DIR__.'/vendor/autoload.php'); |
| 65 | +require PHPUNIT_COMPOSER_INSTALL; |
| 66 | +Symfony\Bridge\PhpUnit\TextUI\Command::main(); |
| 67 | + |
| 68 | +EOPHP |
| 69 | + ); |
| 70 | + chdir('..'); |
| 71 | + file_put_contents(".$PHPUNIT_VERSION.md5", md5_file(__FILE__)); |
| 72 | + chdir($oldPwd); |
| 73 | + |
| 74 | +} |
| 75 | + |
| 76 | +$cmd = array_map('escapeshellarg', $argv); |
| 77 | +$exit = 0; |
| 78 | + |
| 79 | +if (isset($argv[1]) && 'symfony' === $argv[1] && !file_exists('symfony') && file_exists('src/Symfony')) { |
| 80 | + $argv[1] = 'src/Symfony'; |
| 81 | +} |
| 82 | +if (isset($argv[1]) && is_dir($argv[1]) && !file_exists($argv[1].'/phpunit.xml.dist')) { |
| 83 | + array_shift($cmd); |
| 84 | +} |
| 85 | + |
| 86 | +$cmd[0] = sprintf('%s %s --colors=always', $PHP, escapeshellarg("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit")); |
| 87 | +$cmd = str_replace('%', '%%', implode(' ', $cmd)).' %1$s'; |
| 88 | + |
| 89 | +if ('\\' === DIRECTORY_SEPARATOR) { |
| 90 | + $cmd = 'cmd /v:on /d /c "('.$cmd.')%2$s"'; |
| 91 | +} else { |
| 92 | + $cmd .= '%2$s'; |
| 93 | +} |
| 94 | + |
| 95 | +if (isset($argv[1]) && is_dir($argv[1]) && !file_exists($argv[1].'/phpunit.xml.dist')) { |
| 96 | + // Find Symfony components in plain php for Windows portability |
| 97 | + |
| 98 | + $finder = new RecursiveDirectoryIterator($argv[1], FilesystemIterator::KEY_AS_FILENAME | FilesystemIterator::UNIX_PATHS); |
| 99 | + $finder = new RecursiveIteratorIterator($finder); |
| 100 | + $finder->setMaxDepth(getenv('SYMFONY_PHPUNIT_MAX_DEPTH') ?: 3); |
| 101 | + |
| 102 | + $skippedTests = isset($_SERVER['SYMFONY_PHPUNIT_SKIPPED_TESTS']) ? $_SERVER['SYMFONY_PHPUNIT_SKIPPED_TESTS'] : false; |
| 103 | + $runningProcs = array(); |
| 104 | + |
| 105 | + foreach ($finder as $file => $fileInfo) { |
| 106 | + if ('phpunit.xml.dist' === $file) { |
| 107 | + $component = dirname($fileInfo->getPathname()); |
| 108 | + |
| 109 | + // Run phpunit tests in parallel |
| 110 | + |
| 111 | + if ($skippedTests) { |
| 112 | + putenv("SYMFONY_PHPUNIT_SKIPPED_TESTS=$component/$skippedTests"); |
| 113 | + } |
| 114 | + |
| 115 | + $c = escapeshellarg($component); |
| 116 | + |
| 117 | + if ($proc = proc_open(sprintf($cmd, $c, " > $c/phpunit.stdout 2> $c/phpunit.stderr"), array(), $pipes)) { |
| 118 | + $runningProcs[$component] = $proc; |
| 119 | + } else { |
| 120 | + $exit = 1; |
| 121 | + echo "\033[41mKO\033[0m $component\n\n"; |
| 122 | + } |
| 123 | + } |
| 124 | + } |
| 125 | + |
| 126 | + // Fixes for colors support on appveyor |
| 127 | + // See https://github.com/appveyor/ci/issues/373 |
| 128 | + $colorFixes = array( |
| 129 | + array("S\033[0m\033[0m\033[36m\033[1mS", "E\033[0m\033[0m\033[31m\033[1mE", "I\033[0m\033[0m\033[33m\033[1mI", "F\033[0m\033[0m\033[41m\033[37mF"), |
| 130 | + array("SS", "EE", "II", "FF"), |
| 131 | + ); |
| 132 | + $colorFixes[0] = array_merge($colorFixes[0], $colorFixes[0]); |
| 133 | + $colorFixes[1] = array_merge($colorFixes[1], $colorFixes[1]); |
| 134 | + |
| 135 | + while ($runningProcs) { |
| 136 | + usleep(300000); |
| 137 | + $terminatedProcs = array(); |
| 138 | + foreach ($runningProcs as $component => $proc) { |
| 139 | + $procStatus = proc_get_status($proc); |
| 140 | + if (!$procStatus['running']) { |
| 141 | + $terminatedProcs[$component] = $procStatus['exitcode']; |
| 142 | + unset($runningProcs[$component]); |
| 143 | + proc_close($proc); |
| 144 | + } |
| 145 | + } |
| 146 | + |
| 147 | + foreach ($terminatedProcs as $component => $procStatus) { |
| 148 | + foreach (array('out', 'err') as $file) { |
| 149 | + $file = "$component/phpunit.std$file"; |
| 150 | + |
| 151 | + if ('\\' === DIRECTORY_SEPARATOR) { |
| 152 | + $h = fopen($file, 'rb'); |
| 153 | + while (false !== $line = fgets($h)) { |
| 154 | + echo str_replace($colorFixes[0], $colorFixes[1], preg_replace( |
| 155 | + '/(\033\[[0-9]++);([0-9]++m)(?:(.)(\033\[0m))?/', |
| 156 | + "$1m\033[$2$3$4$4", |
| 157 | + $line |
| 158 | + )); |
| 159 | + } |
| 160 | + fclose($h); |
| 161 | + } else { |
| 162 | + readfile($file); |
| 163 | + } |
| 164 | + unlink($file); |
| 165 | + } |
| 166 | + |
| 167 | + // Fail on any individual component failures but ignore some error codes on Windows when APCu is enabled: |
| 168 | + // STATUS_STACK_BUFFER_OVERRUN (-1073740791/0xC0000409) |
| 169 | + // STATUS_ACCESS_VIOLATION (-1073741819/0xC0000005) |
| 170 | + // STATUS_HEAP_CORRUPTION (-1073740940/0xC0000374) |
| 171 | + if ($procStatus && ('\\' !== DIRECTORY_SEPARATOR || !extension_loaded('apcu') || !ini_get('apc.enable_cli') || !in_array($procStatus, array(-1073740791, -1073741819, -1073740940)))) { |
| 172 | + $exit = $procStatus; |
| 173 | + echo "\033[41mKO\033[0m $component\n\n"; |
| 174 | + } else { |
| 175 | + echo "\033[32mOK\033[0m $component\n\n"; |
| 176 | + } |
| 177 | + } |
| 178 | + } |
| 179 | +} elseif (!isset($argv[1]) || 'install' !== $argv[1] || file_exists('install')) { |
| 180 | + // Run regular phpunit in a subprocess |
| 181 | + |
| 182 | + $errFile = tempnam(sys_get_temp_dir(), 'phpunit.stderr.'); |
| 183 | + if ($proc = proc_open(sprintf($cmd, '', ' 2> '.escapeshellarg($errFile)), array(1 => array('pipe', 'w')), $pipes)) { |
| 184 | + stream_copy_to_stream($pipes[1], STDOUT); |
| 185 | + fclose($pipes[1]); |
| 186 | + $exit = proc_close($proc); |
| 187 | + |
| 188 | + readfile($errFile); |
| 189 | + unlink($errFile); |
| 190 | + } |
| 191 | + |
| 192 | + if (!file_exists($component = array_pop($argv))) { |
| 193 | + $component = basename($oldcwd); |
| 194 | + } |
| 195 | + |
| 196 | + if ($exit) { |
| 197 | + echo "\033[41mKO\033[0m $component\n\n"; |
| 198 | + } else { |
| 199 | + echo "\033[32mOK\033[0m $component\n\n"; |
| 200 | + } |
| 201 | +} |
| 202 | + |
| 203 | +exit($exit); |
0 commit comments