diff --git a/.gitignore b/.gitignore index 3574efd83127..daace381698c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ composer.lock # phar related /build -rector.phar +/build-phar diff --git a/.pharignore b/.pharignore new file mode 100644 index 000000000000..9080e73d2470 --- /dev/null +++ b/.pharignore @@ -0,0 +1,5 @@ +build +docs +tests +phpunit +.git \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index b7184f6e8545..ef4d8e28f93b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ script: # build phar test - 1st group is "build-phar" test step by step; 2nd group is all-together - | if [[ $BUILD_PHAR != "" ]]; then - packages/PharBuilder/bin/compile + composer compile-phar php rector.phar vendor/bin/phpunit --testsuite=phar-build fi diff --git a/composer.json b/composer.json index a6e71edafc8f..fe2a2ef92054 100644 --- a/composer.json +++ b/composer.json @@ -67,7 +67,14 @@ "vendor/bin/ecs check bin packages src tests --fix", "bin/clean_levels.sh" ], - "phpstan": "vendor/bin/phpstan.phar analyse packages src tests --level max --configuration phpstan.neon" + "phpstan": "vendor/bin/phpstan.phar analyse packages src tests --level max --configuration phpstan.neon", + "compile-phar": [ + "rm -f ./build/rector.phar", + "rsync -Rr --exclude-from '.pharignore' . ./build-phar/", + "bin/rector process ./build-phar/bin/ --config packages/PharBuilder/src/config/rector.yml --dry-run", + "php -dphar.readonly=0 packages/PharBuilder/bin/compile", + "rm -rf ./build-phar" + ] }, "bin": [ "bin/rector", diff --git a/docs/BuildingRectorPhar.md b/docs/BuildingRectorPhar.md index 7fd20eae157d..8234fcec351d 100644 --- a/docs/BuildingRectorPhar.md +++ b/docs/BuildingRectorPhar.md @@ -3,5 +3,5 @@ To build `rector.phar` just run: ```bash -packages/PharBuilder/bin/compile +packages/PharBuilder/bin/compile ``` diff --git a/packages/PharBuilder/src/Compiler/Compiler.php b/packages/PharBuilder/src/Compiler/Compiler.php index a052aabde379..898280662eb7 100644 --- a/packages/PharBuilder/src/Compiler/Compiler.php +++ b/packages/PharBuilder/src/Compiler/Compiler.php @@ -5,13 +5,10 @@ use FilesystemIterator; use Phar; use Rector\PharBuilder\Exception\BinFileNotFoundException; +use Rector\PharBuilder\Exception\BuildDirNotCreatedException; use Rector\PharBuilder\Filesystem\PathNormalizer; -use Rector\PharBuilder\Filesystem\PharFilesFinder; -use Rector\PharBuilder\FinderToPharAdder; use Seld\PharUtils\Timestamps; use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Finder\Finder; -use Symfony\Component\Process\Process; final class Compiler { @@ -20,11 +17,6 @@ final class Compiler */ private $pharName; - /** - * @var PharFilesFinder - */ - private $pharFilesFinder; - /** * @var SymfonyStyle */ @@ -41,63 +33,54 @@ final class Compiler private $pathNormalizer; /** - * @var FinderToPharAdder + * @var string + */ + private $buildPharDirectory; + + /** + * @var string */ - private $finderToPharAdder; + private $pharBaseName; /** * @var string */ - private $buildDirectory; + private $pharDirName; public function __construct( string $pharName, string $binFileName, string $buildDirectory, - PharFilesFinder $pharFilesFinder, SymfonyStyle $symfonyStyle, - PathNormalizer $pathNormalizer, - FinderToPharAdder $finderToPharAdder + PathNormalizer $pathNormalizer ) { $this->pharName = $pharName; - $this->pharFilesFinder = $pharFilesFinder; + $this->pharBaseName = basename($pharName); + $this->pharDirName = dirname($pharName); $this->binFileName = $binFileName; $this->symfonyStyle = $symfonyStyle; $this->pathNormalizer = $pathNormalizer; - $this->finderToPharAdder = $finderToPharAdder; - $this->buildDirectory = realpath($buildDirectory); + $this->buildPharDirectory = realpath($buildDirectory); } public function compile(): void { - $this->symfonyStyle->note(sprintf('Starting PHAR build in "%s" directory', $this->buildDirectory)); + $this->symfonyStyle->note(sprintf('Starting PHAR build in "%s" directory', $this->buildPharDirectory)); + + $this->ensureBuildDirExists(); // flags: KEY_AS_PATHNAME - use relative paths from Finder keys - $phar = new Phar($this->pharName, FilesystemIterator::KEY_AS_PATHNAME, $this->pharName); + $phar = new Phar($this->pharName, FilesystemIterator::KEY_AS_PATHNAME, $this->pharBaseName); $phar->setSignatureAlgorithm(Phar::SHA1); $phar->startBuffering(); - // use only dev deps + rebuild dump autoload -// $this->symfonyStyle->note('Removing dev packages from composer'); -// $process = new Process('composer update --no-dev', $buildDirectory); -// $process->run(); - - // dump autoload -// $this->symfonyStyle->note('Dumping new composer autoload'); -// $process = new Process('composer dump-autoload --optimize', $buildDirectory); -// $process->run(); + $this->symfonyStyle->note(sprintf('Adding files from directory %s', $this->buildPharDirectory)); - $finder = $this->pharFilesFinder->createForDirectory($this->buildDirectory); - - $fileCount = $this->getFileCountFromFinder($finder); - $this->symfonyStyle->note(sprintf('Adding %d files', $fileCount)); - $this->symfonyStyle->progressStart($fileCount); - - $this->finderToPharAdder->addFinderToPhar($finder, $phar); + $phar->buildFromDirectory($this->buildPharDirectory); $this->symfonyStyle->newLine(2); $this->symfonyStyle->note('Adding bin'); - $this->addRectorBin($phar, $this->buildDirectory); + $this->addRectorBin($phar, $this->buildPharDirectory); $this->symfonyStyle->note('Setting stub'); $phar->setStub($this->getStub()); @@ -106,11 +89,6 @@ public function compile(): void $timestamps = new Timestamps($this->pharName); $timestamps->save($this->pharName, Phar::SHA1); - // return dev deps -// $this->symfonyStyle->note('Returning dev packages to composer'); -// $process = new Process('composer update', $buildDirectory); -// $process->run(); - $this->symfonyStyle->success(sprintf('Phar file "%s" build successful!', $this->pharName)); } @@ -138,7 +116,7 @@ private function getStub(): string __HALT_COMPILER(); EOF; - return sprintf($stubTemplate, $this->pharName, $this->pharName, $this->binFileName); + return sprintf($stubTemplate, $this->pharBaseName, $this->pharName, $this->binFileName); } private function removeShebang(string $content): string @@ -146,11 +124,6 @@ private function removeShebang(string $content): string return preg_replace('~^#!/usr/bin/env php\s*~', '', $content); } - private function getFileCountFromFinder(Finder $finder): int - { - return count(iterator_to_array($finder->getIterator())); - } - private function ensureBinFileExists(string $binFilePath): void { if (file_exists($binFilePath)) { @@ -162,4 +135,13 @@ private function ensureBinFileExists(string $binFilePath): void $binFilePath )); } + + private function ensureBuildDirExists(): void + { + if (! is_dir($this->pharDirName) && ! mkdir($this->pharDirName, 0777, true) && ! is_dir($this->pharDirName)) { + throw new BuildDirNotCreatedException( + sprintf('Directory "%s" was not created', $this->pharDirName) + ); + } + } } diff --git a/packages/PharBuilder/src/Exception/BuildDirNotCreatedException.php b/packages/PharBuilder/src/Exception/BuildDirNotCreatedException.php new file mode 100644 index 000000000000..6b8f23a3ef90 --- /dev/null +++ b/packages/PharBuilder/src/Exception/BuildDirNotCreatedException.php @@ -0,0 +1,9 @@ +files() - ->ignoreVCS(true) - ->name('*.{yml,php}') - // "in()" and "path()" have to be split to make SplFileInfo "getRelativePathname()" get path from $directory - ->in($directory) - ->path('#(bin|src|packages)#') // |vendor - ->exclude( - ['tests', 'docs', 'Tests', 'Testing', 'phpunit', 'sebastianbergman', 'vendor', 'packages/PharBuilder'] - ) - ->sort($this->sortFilesByName()); - } - - private function sortFilesByName(): Closure - { - return function (SplFileInfo $firstFileInfo, SplFileInfo $secondFileInfo) { - return strcmp( - strtr($firstFileInfo->getRealPath(), '\\', '/'), - strtr($secondFileInfo->getRealPath(), '\\', '/') - ); - }; - } -} diff --git a/packages/PharBuilder/src/config/config.yml b/packages/PharBuilder/src/config/config.yml index ed0ef64881df..539948836423 100644 --- a/packages/PharBuilder/src/config/config.yml +++ b/packages/PharBuilder/src/config/config.yml @@ -1,8 +1,8 @@ parameters: # customizable (via %ENV()?) - pharName: 'rector.phar' + pharName: 'build/rector.phar' binFileName: 'bin/rector' - buildDirectory: '%kernel.root_dir%/../../../..' + buildDirectory: '%kernel.root_dir%/../../../../build-phar' services: _defaults: diff --git a/packages/PharBuilder/src/config/rector.yml b/packages/PharBuilder/src/config/rector.yml new file mode 100644 index 000000000000..052a746086fc --- /dev/null +++ b/packages/PharBuilder/src/config/rector.yml @@ -0,0 +1,7 @@ +parameters: + prefix: 'RectorPhar' + +services: + Rector\Rector\Dynamic\NamespaceReplacerRector: + $oldToNewNamespaces: + 'Jean85': '%prefix%Jean85' \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml index d1e8d8a6827b..9746c13162e3 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -11,5 +11,9 @@ packages/*/tests tests/Phar + + + tests/Phar + diff --git a/tests/Phar/GlobResourceTest.php b/tests/Phar/GlobResourceTest.php new file mode 100644 index 000000000000..bfe5d7ae250e --- /dev/null +++ b/tests/Phar/GlobResourceTest.php @@ -0,0 +1,16 @@ +assertNotCount(0, $resource); + } +} diff --git a/tests/Phar/PharTest.php b/tests/Phar/PharTest.php index b2f11512ee2b..95e868abf614 100644 --- a/tests/Phar/PharTest.php +++ b/tests/Phar/PharTest.php @@ -12,12 +12,13 @@ final class PharTest extends TestCase { public function testBox(): void { - $rectorPharLocation = __DIR__ . '/../../rector.phar'; + $rectorPharLocation = __DIR__ . '/../../build/rector.phar'; $this->assertFileExists($rectorPharLocation); $process = new Process($rectorPharLocation); $exitCode = $process->run(); + // binary needed for this tests $this->assertSame('', $process->getErrorOutput()); $this->assertSame(1, $exitCode); } diff --git a/tests/Phar/Source/rector.phar b/tests/Phar/Source/rector.phar new file mode 100644 index 000000000000..779fad1d6b70 Binary files /dev/null and b/tests/Phar/Source/rector.phar differ