Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
3418b25
box init
TomasVotruba Feb 14, 2018
4824f64
fix phar strict_types error
TomasVotruba Feb 14, 2018
e866f2e
docs init
TomasVotruba Feb 15, 2018
3c27de1
gitignore: add phar for now
TomasVotruba Feb 15, 2018
e0e8413
box.json: add build path
TomasVotruba Feb 15, 2018
4d8a958
composer: add build-phar command
TomasVotruba Feb 15, 2018
2c2f7ce
gitignore: add vendor-bin as well
TomasVotruba Feb 15, 2018
f47faa1
add config for php-scoper
TomasVotruba Feb 15, 2018
a6d5f59
move split script to bin
TomasVotruba Feb 15, 2018
9331854
use /build directory for phar building
TomasVotruba Feb 15, 2018
4c91373
scoper: working config
TomasVotruba Feb 15, 2018
6c02ebe
docs: add steps description
TomasVotruba Feb 16, 2018
15e6ba0
box: fix configuration to load both PHP and YML files
TomasVotruba Feb 16, 2018
506e108
gitignore: add build dir
TomasVotruba Feb 16, 2018
ca9c0a7
README: add link to PHAR docs
TomasVotruba Feb 16, 2018
a7e8ae5
composer: add php-scopr to build-phar command
TomasVotruba Feb 16, 2018
cd85f7a
scoper: drop unused whitelist config section
TomasVotruba Feb 16, 2018
748e388
box: add compression to config
TomasVotruba Feb 16, 2018
0110da2
composer: add install scripts
TomasVotruba Feb 16, 2018
f1112e1
composer: fix bin paths
TomasVotruba Feb 16, 2018
16e234a
composer: better install script phar name
TomasVotruba Feb 16, 2018
72e982d
scoper - add comments to config
TomasVotruba Feb 16, 2018
e87b110
composer: fix version for box
TomasVotruba Feb 16, 2018
f11d6eb
travis: add test for building phar
TomasVotruba Feb 16, 2018
ba7cd2e
travis: run phar
TomasVotruba Feb 16, 2018
54f7fb1
tests: add simple Phar exists test
TomasVotruba Feb 16, 2018
c4efbf6
composer: fix scoper version
TomasVotruba Feb 16, 2018
97b00b8
scoper config: Finder order matters
TomasVotruba Feb 16, 2018
ccf720b
travis: add php-scoper fail test case
TomasVotruba Feb 17, 2018
37f5c9d
scoper: do not move .sh files
TomasVotruba Feb 17, 2018
b6840e8
travis: test phar only now
TomasVotruba Feb 17, 2018
ee90051
travis: syntax fix
TomasVotruba Feb 17, 2018
edfcb6b
phpunit: more precise method name
TomasVotruba Feb 17, 2018
b643db2
travis: always run some test suite
TomasVotruba Feb 17, 2018
8233444
tests: add Phar process test
TomasVotruba Feb 17, 2018
02aa370
tests: make Phar bin files executable
TomasVotruba Feb 17, 2018
e5a3fab
load vendor/*/composer.json as well
TomasVotruba Feb 17, 2018
e5bccf1
scoper: add installed.json, fix broken double appending
TomasVotruba Feb 19, 2018
365b12f
composer: optimize build phar
TomasVotruba Feb 20, 2018
fe5cc94
scoper config: add yaml prefixer init
TomasVotruba Feb 20, 2018
f1d8de6
composer: build-phar - remove dev deps
TomasVotruba Feb 20, 2018
47e02f3
rector_bootstrap: add scoper autoload
TomasVotruba Feb 20, 2018
35d893b
scoper: add shebang removal and Rector\* whitelist
TomasVotruba Feb 20, 2018
e5c3ebe
scoper: fix end slash on prefix
TomasVotruba Feb 20, 2018
a665480
scoper: replace only matching group
TomasVotruba Feb 20, 2018
88c7dde
wip
TomasVotruba Feb 20, 2018
d9bd03d
drop scoper from bootstrap
TomasVotruba Feb 21, 2018
820978d
typo
TomasVotruba Feb 21, 2018
866398f
run build phar only, without scoper
TomasVotruba Feb 21, 2018
111b32e
bin/rector: return strict_types
TomasVotruba Feb 21, 2018
ba81e0d
composer: drop box, add phar utils
TomasVotruba Feb 21, 2018
194ba35
remove PHP stub
TomasVotruba Feb 21, 2018
11f5cda
add bin/compile
TomasVotruba Feb 21, 2018
55b0ac4
move to PharBuilder package
TomasVotruba Feb 21, 2018
c62dc61
fix cs
TomasVotruba Feb 21, 2018
5edfed7
fix namespaces and bin dir
TomasVotruba Feb 21, 2018
ae67769
drop Stub.php
TomasVotruba Feb 21, 2018
6e8fbd0
move init() to PharBuilder
TomasVotruba Feb 21, 2018
278a566
decouple sorting method
TomasVotruba Feb 21, 2018
53e1777
decouple PharFileFinder
TomasVotruba Feb 21, 2018
1ed5300
method rename
TomasVotruba Feb 21, 2018
ce69e13
gitignore: drop vendor-bin unused
TomasVotruba Feb 21, 2018
4f55051
bin/compile: use safe path
TomasVotruba Feb 21, 2018
c043669
use SymfonyStyle
TomasVotruba Feb 21, 2018
a66e7f2
add success message
TomasVotruba Feb 21, 2018
dbb58da
add phar_name parameter
TomasVotruba Feb 21, 2018
4382f89
add bin_file_name parameter
TomasVotruba Feb 21, 2018
23d12f3
use consistent format
TomasVotruba Feb 21, 2018
0283ba1
travis: cleanup
TomasVotruba Feb 21, 2018
12dfc77
drop box and scoper configs
TomasVotruba Feb 21, 2018
9701943
composer: cleanup
TomasVotruba Feb 21, 2018
df6f909
compiler: last forgotten hardcoded phar name
TomasVotruba Feb 21, 2018
b9f9581
travis: run it all
TomasVotruba Feb 21, 2018
2423c79
docs: phar - add wip
TomasVotruba Feb 22, 2018
ee089fd
bin/compile: use the same error report as in bin/rector
TomasVotruba Feb 22, 2018
bc0a188
Compiler: remove dev deps on compile
TomasVotruba Feb 22, 2018
274858c
Compiler: dump autolaod and more info notes
TomasVotruba Feb 22, 2018
64f9703
clear ini_set without effect
TomasVotruba Feb 22, 2018
42f9167
Compiler: decouple method adding files
TomasVotruba Feb 22, 2018
4073509
drop GZ compiler for now
TomasVotruba Feb 22, 2018
b9401dd
Compiler: check for existance of bin file
TomasVotruba Feb 22, 2018
1cadd12
config: clear unused
TomasVotruba Feb 22, 2018
596eeb9
decouple PathNormalizer
TomasVotruba Feb 22, 2018
49df631
decouple FinderToPharAdder
TomasVotruba Feb 22, 2018
d72e485
wip
TomasVotruba Feb 22, 2018
e3d8c5e
fix cs
TomasVotruba Feb 22, 2018
38e46c4
PathNormalizer: use common escape sign
TomasVotruba Feb 22, 2018
074de0d
PharFilesFinder: make Rector files specific for now
TomasVotruba Feb 22, 2018
d7f5fc0
add CompileCommand to allow Input/Output services
TomasVotruba Feb 22, 2018
424d4f0
fix cs
TomasVotruba Feb 23, 2018
304c8c7
ContainerFactory: fix debug Kernel param verbosity
TomasVotruba Feb 23, 2018
290ae94
config: use SymfonyStyle as service
TomasVotruba Feb 23, 2018
058b474
[docs] cleanup
TomasVotruba Feb 25, 2018
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@
/example
/vendor
composer.lock

# phar related
/build
rector.phar
11 changes: 8 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ language: php
matrix:
include:
- php: 7.1
env: STATIC_ANALYSIS=true RUN_RECTOR=true
env: BUILD_PHAR=true PHPUNIT_FLAGS="--testsuite=main" STATIC_ANALYSIS=true
- php: 7.2
env: PHPUNIT_FLAGS="--coverage-clover coverage.xml --testsuite=contrib-rectors"
- php: 7.2
Expand All @@ -24,8 +24,13 @@ script:
- phpenv config-rm xdebug.ini || return 0
- if [[ $STATIC_ANALYSIS != "" ]]; then composer check-cs; fi
- if [[ $STATIC_ANALYSIS != "" ]]; then composer phpstan; fi
# Rector demo run
- if [[ $RUN_RECTOR != "" ]]; then bin/rector process src tests --level symfony40 --dry-run; fi
# 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
php rector.phar
vendor/bin/phpunit --testsuite=phar-build
fi

after_script:
# upload coverage to Coveralls.io
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ vendor/bin/ecs check --config vendor/rector/rector/ecs-after-rector.neon --fix
- [How to Create Rector with Fluent Builder](/docs/FluentBuilderRector.md)
- [How to Create Own Rector](/docs/HowToCreateOwnRector.md)
- [Service Name to Type Provider](/docs/ServiceNameToTypeProvider.md)
- [3 Steps to Build PHAR](/docs/BuildingRectorPhar.md)

## How to Contribute

Expand Down
11 changes: 11 additions & 0 deletions bin/subtree-split-master-and-last-tag.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash
git subsplit init [email protected]:rectorphp/rector.git

LAST_TAG=$(git tag -l --sort=committerdate | tail -n1);

git subsplit publish --heads="master" --tags=$LAST_TAG packages/NodeTypeResolver:[email protected]:rectorphp/node-type-resolver.git

rm -rf .subsplit/

# inspired by laravel: https://github.com/laravel/framework/blob/5.4/build/illuminate-split-full.sh
# they use SensioLabs now though: https://github.com/laravel/framework/pull/17048#issuecomment-269915319
5 changes: 5 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"phpdocumentor/type-resolver": "^0.4",
"rector/better-reflection": "^3.0.6",
"sebastian/diff": "^3.0",
"seld/phar-utils": "^1.0",
"symfony/console": "^4.0",
"symfony/dependency-injection": "^4.0",
"symfony/finder": "^4.0",
Expand All @@ -28,6 +29,9 @@
"phpstan/phpstan-shim": "^0.9",
"phpunit/phpunit": "^7.0",
"slam/php-cs-fixer-extensions": "^1.13",
"symfony/expression-language": "^4.0",
"symfony/form": "^4.0",
"symplify/coding-standard": "^3.2",
"tracy/tracy": "^2.4"
},
"autoload": {
Expand All @@ -36,6 +40,7 @@
"Rector\\BetterReflection\\": "packages/BetterReflection/src",
"Rector\\ConsoleDiffer\\": "packages/ConsoleDiffer/src",
"Rector\\RectorBuilder\\": "packages/RectorBuilder/src",
"Rector\\PharBuilder\\": "packages/PharBuilder/src",
"Rector\\ReflectionDocBlock\\": "packages/ReflectionDocBlock/src",
"Rector\\NodeTypeResolver\\": "packages/NodeTypeResolver/src",
"Rector\\NodeTraverserQueue\\": "packages/NodeTraverserQueue/src"
Expand Down
7 changes: 7 additions & 0 deletions docs/BuildingRectorPhar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# How to Build `rector.phar`

To build `rector.phar` just run:

```bash
packages/PharBuilder/bin/compile
```
3 changes: 3 additions & 0 deletions easy-coding-standard.neon
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ checkers:
- 'Rector\BetterReflection\SourceLocator\Located\LocatedSource'
- 'phpDocumentor\Reflection\Types\*'
- 'Rector\Reporting\FileDiff'
- 'Phar'
- 'Symfony\Component\Finder\Finder'
- 'Seld\PharUtils\Timestamps'

Symplify\CodingStandard\Fixer\Naming\PropertyNameMatchingTypeFixer:
extra_skipped_classes:
Expand Down
36 changes: 36 additions & 0 deletions packages/PharBuilder/bin/compile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env php
<?php declare(strict_types=1);

require_once __DIR__ . '/../../../vendor/autoload.php';

use Rector\PharBuilder\DependencyInjection\ContainerFactory;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symplify\PackageBuilder\Console\Style\SymfonyStyleFactory;

error_reporting(-1);
ini_set('display_errors', '1');

try {
$container = (new ContainerFactory())->create();

// 3. Run Console Application
/** @var Application $application */
$application = $container->get(Application::class);
/** @var InputInterface $input */
$input = $container->get(InputInterface::class);
/** @var OutputInterface $output */
$output = $container->get(OutputInterface::class);
$statusCode = $application->run($input, $output);
exit($statusCode);
} catch (Throwable $throwable) {
$symfonyStyle = SymfonyStyleFactory::create();
$symfonyStyle->error(sprintf(
'%s in %s on line %d',
$throwable->getMessage(),
$throwable->getFile(),
$throwable->getLine()
));
exit($throwable->getCode());
}
34 changes: 34 additions & 0 deletions packages/PharBuilder/src/Command/CompileCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php declare(strict_types=1);

namespace Rector\PharBuilder\Command;

use Rector\PharBuilder\Compiler\Compiler;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symplify\PackageBuilder\Console\Command\CommandNaming;

final class CompileCommand extends Command
{
/**
* @var Compiler
*/
private $compiler;

public function __construct(Compiler $compiler)
{
$this->compiler = $compiler;

parent::__construct();
}

protected function configure(): void
{
$this->setName(CommandNaming::classToName(self::class));
}

protected function execute(InputInterface $input, OutputInterface $output): void
{
$this->compiler->compile();
}
}
165 changes: 165 additions & 0 deletions packages/PharBuilder/src/Compiler/Compiler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
<?php declare(strict_types=1);

namespace Rector\PharBuilder\Compiler;

use FilesystemIterator;
use Phar;
use Rector\PharBuilder\Exception\BinFileNotFoundException;
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
{
/**
* @var string
*/
private $pharName;

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

/**
* @var SymfonyStyle
*/
private $symfonyStyle;

/**
* @var string
*/
private $binFileName;

/**
* @var PathNormalizer
*/
private $pathNormalizer;

/**
* @var FinderToPharAdder
*/
private $finderToPharAdder;

/**
* @var string
*/
private $buildDirectory;

public function __construct(
string $pharName,
string $binFileName,
string $buildDirectory,
PharFilesFinder $pharFilesFinder,
SymfonyStyle $symfonyStyle,
PathNormalizer $pathNormalizer,
FinderToPharAdder $finderToPharAdder
) {
$this->pharName = $pharName;
$this->pharFilesFinder = $pharFilesFinder;
$this->binFileName = $binFileName;
$this->symfonyStyle = $symfonyStyle;
$this->pathNormalizer = $pathNormalizer;
$this->finderToPharAdder = $finderToPharAdder;
$this->buildDirectory = realpath($buildDirectory);
}

public function compile(): void
{
$this->symfonyStyle->note(sprintf('Starting PHAR build in "%s" directory', $this->buildDirectory));

// flags: KEY_AS_PATHNAME - use relative paths from Finder keys
$phar = new Phar($this->pharName, FilesystemIterator::KEY_AS_PATHNAME, $this->pharName);
$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();

$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);

$this->symfonyStyle->newLine(2);
$this->symfonyStyle->note('Adding bin');
$this->addRectorBin($phar, $this->buildDirectory);

$this->symfonyStyle->note('Setting stub');
$phar->setStub($this->getStub());
$phar->stopBuffering();

$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));
}

private function addRectorBin(Phar $phar, string $buildDirectory): void
{
$binFilePath = $buildDirectory . DIRECTORY_SEPARATOR . $this->binFileName;
$this->ensureBinFileExists($binFilePath);

$content = file_get_contents($binFilePath);
$content = $this->removeShebang($content);

// replace absolute paths by phar:// paths
$content = $this->pathNormalizer->normalizeAbsoluteToPharInContent($content);

$phar->addFromString($this->binFileName, $content);
}

private function getStub(): string
{
$stubTemplate = <<<'EOF'
#!/usr/bin/env php
<?php
Phar::mapPhar('%s');
require 'phar://%s/%s';
__HALT_COMPILER();
EOF;

return sprintf($stubTemplate, $this->pharName, $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)) {
return;
}

throw new BinFileNotFoundException(sprintf(
'Bin file not found in "%s". Have you set it up in config.yml file?',
$binFilePath
));
}
}
20 changes: 20 additions & 0 deletions packages/PharBuilder/src/DependencyInjection/ContainerFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types=1);

namespace Rector\PharBuilder\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerInterface;

final class ContainerFactory
{
public function create(): ContainerInterface
{
$appKernel = new PharBuilderKernel();
$appKernel->boot();

// this is require to keep CLI verbosity independent on AppKernel dev/prod mode
// see: https://github.com/symfony/symfony/blob/c12c07865a6fe3a8e0edd8540ac3ab9a3bc75543/src/Symfony/Component/HttpKernel/Kernel.php#L115
putenv('SHELL_VERBOSITY=0');

return $appKernel->getContainer();
}
}
39 changes: 39 additions & 0 deletions packages/PharBuilder/src/DependencyInjection/PharBuilderKernel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php declare(strict_types=1);

namespace Rector\PharBuilder\DependencyInjection;

use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
use Symfony\Component\HttpKernel\Kernel;

final class PharBuilderKernel extends Kernel
{
public function __construct()
{
// debug: true is require to invalidate container on service files change
parent::__construct('cli' . random_int(1, 1000), true);
}

public function registerContainerConfiguration(LoaderInterface $loader): void
{
$loader->load(__DIR__ . '/../config/config.yml');
}

public function getCacheDir(): string
{
return sys_get_temp_dir() . '/_rector_phar_builder_cache';
}

public function getLogDir(): string
{
return sys_get_temp_dir() . '/_rector_phar_bulider_log';
}

/**
* @return BundleInterface[]
*/
public function registerBundles(): array
{
return [];
}
}
Loading