Skip to content

Commit

Permalink
init compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
TomasVotruba committed Dec 1, 2019
1 parent c273bf7 commit c0d4598
Show file tree
Hide file tree
Showing 42 changed files with 581 additions and 157 deletions.
7 changes: 0 additions & 7 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
# Define the line ending behavior of the different file extensions
# Set default behavior, in case users don't have core.autocrlf set.
* text=auto
* text eol=lf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary
*.gif binary
*.ico binary

# Set syntax highlight on GitHub
# https://github.com/github/linguist/blob/master/lib/linguist/languages.yml
Expand Down
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ phpstan-paths.txt
# tests - travis
/laravel-dir

uuid-migration.json
uuid-migration.json

# compiler
/compiler/composer.lock
/compiler/vendor
/tmp
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
os: linux
dist: xenial
language: php

php:
Expand All @@ -18,6 +19,19 @@ script:

jobs:
include:
-
stage: compile
php: 7.2
name: "Compile Rector to prefixed PHAR"
before_install:
- cd compiler
install:
- composer install
script:
- bin/compile
# run prefixed Rector
- ../tmp/rector.phar

# Stage 1
-
stage: test
Expand Down
59 changes: 0 additions & 59 deletions bin/bootstrap.php

This file was deleted.

51 changes: 0 additions & 51 deletions bin/container.php

This file was deleted.

162 changes: 158 additions & 4 deletions bin/rector
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,36 @@

declare(strict_types=1);

use Psr\Container\ContainerInterface;
use Rector\Configuration\Configuration;
use Rector\Console\Application;
use Rector\Console\Style\SymfonyStyleFactory;
use Rector\DependencyInjection\RectorContainerFactory;
use Rector\Set\Set;
use Symfony\Component\Console\Input\ArgvInput;
use Symplify\PackageBuilder\Reflection\PrivatesCaller;
use Symplify\SetConfigResolver\ConfigResolver;

@ini_set('memory_limit', '-1'); // @ intentionally: continue anyway

// Performance boost
gc_disable();

// Require Composer autoload.php
require_once __DIR__ . '/bootstrap.php';
$autoloadIncluder = new AutoloadIncluder(getcwd());
$autoloadIncluder->includeCwdVendorAutoloadIfExists();
$autoloadIncluder->includeDependencyOrRepositoryVendorAutoloadIfExists();

try {
/** @var ContainerInterface $container */
$container = require_once __DIR__ . '/container.php';
$rectorConfigsResolver = new RectorConfigsResolver();
$configs = $rectorConfigsResolver->provide();

// Build DI container
$rectorContainerFactory = new RectorContainerFactory();
$container = $rectorContainerFactory->createFromConfigs($configs);

/** @var Configuration $configuration */
$configuration = $container->get(Configuration::class);
$configuration->setFirstResolverConfig($rectorConfigsResolver->getFirstResolvedConfig());
} catch (Throwable $throwable) {
$symfonyStyle = (new SymfonyStyleFactory(new PrivatesCaller()))->create();
$symfonyStyle->error($throwable->getMessage());
Expand All @@ -27,3 +41,143 @@ try {

$application = $container->get(Application::class);
exit($application->run());


final class AutoloadIncluder
{
/**
* @var string[]
*/
private const POSSIBLE_AUTOLOAD_PATHS = [
// dev repository or prefixed rector
__DIR__ . '/../vendor/autoload.php',
// composer require
__DIR__ . '/../../../../vendor/autoload.php',
];

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

public function __construct(string $currentWorkingDirectory)
{
$this->currentWorkingDirectory = $currentWorkingDirectory;
}

public function includeCwdVendorAutoloadIfExists(): void
{
$projectAutoload = $this->currentWorkingDirectory . '/vendor/autoload.php';
if (! is_file($projectAutoload)) {
return;
}

require $projectAutoload;
}

public function includeDependencyOrRepositoryVendorAutoloadIfExists(): void
{
// rector vendor is already loaded → skip
if ($this->isRectorVendorLoaded()) {
return;
}

foreach (self::POSSIBLE_AUTOLOAD_PATHS as $possibleAutoloadPath) {
if (is_file($possibleAutoloadPath)) {
require $possibleAutoloadPath;
break;
}
}

$composerJsonPath = $this->currentWorkingDirectory . '/composer.json';
if (file_exists($composerJsonPath)) {
$this->includeProjectsAutoload($composerJsonPath);
} else {
$errorMessage = sprintf(
'Composer autoload.php was not found in paths "%s".%sHave you ran "composer update"?',
PHP_EOL,
implode('", "', self::POSSIBLE_AUTOLOAD_PATHS)
);

die($errorMessage);
}
}

private function includeProjectsAutoload(string $composerJsonPath): void
{
$contents = file_get_contents($composerJsonPath);

$composerSettings = json_decode($contents, true);
if (! is_array($composerSettings)) {
die(sprintf('Failed to load "%s"', $composerJsonPath));
}

$vendorPath = $composerSettings['config']['vendor-dir'] ?? $this->currentWorkingDirectory . '/vendor';

if (! is_dir($vendorPath)) {
die(sprintf('Please check if "composer install" was run already (expected to find "%s")', $vendorPath));
}

require $vendorPath . '/autoload.php';
}

private function isRectorVendorLoaded(): bool
{
return class_exists('Rector\HttpKernel\RectorKernel');
}
}


final class RectorConfigsResolver
{
/**
* @var ConfigResolver
*/
private $configResolver;

public function __construct()
{
$this->configResolver = new ConfigResolver();
}

/**
* @return string[]
*/
public function provide(): array
{
$configs = [];

// Detect configuration from --set
$input = new ArgvInput();

$setConfig = $this->configResolver->resolveSetFromInputAndDirectory($input, Set::SET_DIRECTORY);
if ($setConfig !== null) {
$configs[] = $setConfig;
}

// And from --config or default one
$inputOrFallbackConfig = $this->configResolver->resolveFromInputWithFallback(
$input,
['rector.yml', 'rector.yaml']
);
if ($inputOrFallbackConfig !== null) {
$configs[] = $inputOrFallbackConfig;
}

// resolve: parameters > sets
$parameterSetsConfigs = $this->configResolver->resolveFromParameterSetsFromConfigFiles(
$configs,
Set::SET_DIRECTORY
);
if ($parameterSetsConfigs !== []) {
$configs = array_merge($configs, $parameterSetsConfigs);
}

return $configs;
}

public function getFirstResolvedConfig(): ?string
{
return $this->configResolver->getFirstResolvedConfig();
}
}
3 changes: 3 additions & 0 deletions compiler/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/temp
!/temp/.gitkeep
/vendor
12 changes: 12 additions & 0 deletions compiler/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# PHAR Compiler for Rector

## Compile the PHAR

```bash
composer install
php bin/compile [version] [repository]
```

Default `version` is `master`, and default `repository` is `https://github.com/rector/rector.git`.

The compiled PHAR will be in `tmp/rector.phar`.
22 changes: 22 additions & 0 deletions compiler/bin/compile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env php
<?php

declare(strict_types = 1);

use Rector\Compiler\Console\CompileCommand;
use Rector\Compiler\Process\ProcessFactory;
use Symfony\Component\Console\Application;

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

$compileCommand = new CompileCommand(
new ProcessFactory(),
__DIR__ . '/../build',
__DIR__ . '/../..'
);

/** @var Application $application */
$application = new Application();
$application->add($compileCommand);
$application->setDefaultCommand($compileCommand->getName(), true);
$application->run();
Loading

0 comments on commit c0d4598

Please sign in to comment.