Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ composer.lock

# phar related
/build
rector.phar
/build-phar
5 changes: 5 additions & 0 deletions .pharignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
build
docs
tests
phpunit
.git
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion docs/BuildingRectorPhar.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
To build `rector.phar` just run:

```bash
packages/PharBuilder/bin/compile
packages/PharBuilder/bin/compile
```
78 changes: 30 additions & 48 deletions packages/PharBuilder/src/Compiler/Compiler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -20,11 +17,6 @@ final class Compiler
*/
private $pharName;

/**
* @var PharFilesFinder
*/
private $pharFilesFinder;

/**
* @var SymfonyStyle
*/
Expand All @@ -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());
Expand All @@ -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));
}

Expand Down Expand Up @@ -138,19 +116,14 @@ 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
{
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)) {
Expand All @@ -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)
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php declare(strict_types=1);

namespace Rector\PharBuilder\Exception;

use Exception;

final class BuildDirNotCreatedException extends Exception
{
}
35 changes: 0 additions & 35 deletions packages/PharBuilder/src/Filesystem/PharFilesFinder.php

This file was deleted.

4 changes: 2 additions & 2 deletions packages/PharBuilder/src/config/config.yml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
7 changes: 7 additions & 0 deletions packages/PharBuilder/src/config/rector.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
parameters:
prefix: 'RectorPhar'

services:
Rector\Rector\Dynamic\NamespaceReplacerRector:
$oldToNewNamespaces:
'Jean85': '%prefix%Jean85'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very creative use of Rector, like it 👍

Love the param! :)
There could be dynamic Rector (via RectorProvider), that would replace every namespace node with prefix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every except specified would be even better:) We don't need to prefix Rector itself.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see :) That would require new Rector, probably NamespacePrefixerRector

services:
    Rector\Rector\Dynamic\NamespaceReplacerRector:
        !Rector: Prefixed # all but "Rector" prefix by "Prefixed"

What do you need to know from me to write it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will know that, after I try it:) But I feel like performance is bigger issue here, can we somehow speed it up?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First things first. When PHAR is done, we can improve performance.

Doing both at same time improved neither of both, tried for you :D

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm with Tomas here. Let's first fix this PHAR issue, than we can join forces together and make Rector as fast as we can 💪

4 changes: 4 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@
<directory>packages/*/tests</directory>
<exclude>tests/Phar</exclude>
</testsuite>
<!-- only Phar -->
<testsuite name="phar-build">
<directory>tests/Phar</directory>
</testsuite>
</testsuites>
</phpunit>
16 changes: 16 additions & 0 deletions tests/Phar/GlobResourceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php declare(strict_types=1);

namespace Rector\Tests\Phar;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Config\Resource\GlobResource;

final class GlobResourceTest extends TestCase
{
public function testGlobResource(): void
{
$resource = new GlobResource('phar://' . __DIR__ . '/Source/rector.phar/src/', '', true);

$this->assertNotCount(0, $resource);
}
}
Copy link
Member

@TomasVotruba TomasVotruba Apr 21, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edobarnas Here it's needed to override getContainerLoader() in AppKernel with own PharAwaretGlobFileLoader class:

final class RectorKernel extends Kernel
{

    /**
     * @param ContainerInterface|ContainerBuilder $container
     */
    protected function getContainerLoader(ContainerInterface $container): DelegatingLoader
    {
        $kernelFileLocator = new FileLocator($this);

        $loaderResolver = new LoaderResolver([
            // @todo - create this clsas
            return PharAwareGlobFileLoader($container, $kernelFileLocator));
            // ...
        ]);

        return new DelegatingLoader($loaderResolver);
    }

}

As done in here https://github.com/symplify/packagebuilder#10-do-you-need-to-merge-parameters-in-yaml-files-instead-of-override


PharAwareGlobFileLoader might look like this:

namespace Symfony\Component\Config\Loader\GlobFileLoader;

final class PharAwareGlobFileLoader extends GlobFileLoader
{
    protected function glob(string $pattern, bool $recursive, &$resource = null, bool $ignoreErrors = false)
    {
        // override parent glob() method logic to not-use "glob" function
    }
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think @mssimi ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check GlobResource usages, I think it is not only used in loader.

3 changes: 2 additions & 1 deletion tests/Phar/PharTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
Binary file added tests/Phar/Source/rector.phar
Binary file not shown.