Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add patchers #67

Merged
merged 8 commits into from
Jul 6, 2017
Merged
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
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ help:
## Build
##---------------------------------------------------------------------------

build: ## Build the PHAR
build: ## Build the PHAR
build: vendor
# Cleanup existing artefacts
rm -f bin/php-scoper.phar
Expand Down Expand Up @@ -42,18 +42,18 @@ build: vendor
## Tests
##---------------------------------------------------------------------------

test: ## Run all the tests
test: ## Run all the tests
test: tu e2e

tu: ## Run PHPUnit tests
tu: ## Run PHPUnit tests
tu: vendor
php -d zend.enable_gc=0 $(PHPUNIT)

tc: ## Run PHPUnit tests with test coverage
tc: ## Run PHPUnit tests with test coverage
tc: vendor
phpdbg -qrr -d zend.enable_gc=0 $(PHPUNIT) --coverage-html=dist/coverage --coverage-text

e2e: ## Run end-to-end tests
e2e: ## Run end-to-end tests
e2e: scoper
php -d zend.enable_gc=0 $(PHPSCOPER) add-prefix fixtures/set004 -o build/set004 -f
composer -d=build/set004 dump-autoload
Expand All @@ -67,7 +67,7 @@ e2e: scoper
php build/set005/bin/greet.phar > build/output
diff fixtures/set005/expected-output build/output

tb: ## Run Blackfire profiling
tb: ## Run Blackfire profiling
tb: vendor
rm -rf build
#
Expand Down
9 changes: 9 additions & 0 deletions fixtures/set006/scoper.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

return [
function () {
return 'Hello world!';
}
];
Empty file added fixtures/set007/.gitkeep
Empty file.
5 changes: 5 additions & 0 deletions fixtures/set008/scoper.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

declare(strict_types=1);

return 'string value';
7 changes: 7 additions & 0 deletions fixtures/set009/scoper.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

declare(strict_types=1);

return [
'string value'
];
43 changes: 43 additions & 0 deletions scoper.inc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

/*
* This file is part of the humbug/php-scoper package.
*
* Copyright (c) 2017 Théo FIDRY <[email protected]>,
* Pádraic Brady <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

return [
function (string $filePath, string $prefix, string $content): string {
//
// PHP-Parser patch
//

if ($filePath === realpath(__DIR__.'vendor/nikic/php-parser/lib/PhpParser/Lexer.php')) {
return preg_replace(
'%if \(defined\(\$name \= \'PhpParser\\\\Parser\\\\Tokens\:\:\'%',
<<<'PHP'
$ns = explode(\'\\\\\', __NAMESPACE__);
if (defined($name = array_shift($ns) . '\\\\' . 'PhpParser\\\\Parser\\\\Tokens::'
PHP
,
$content
);
}

if ($filePath === realpath(__DIR__.'vendor/nikic/php-parser/lib/PhpParser/NodeAbstract.php')) {
return preg_replace(
'%rtrim\(get_class\(\$this\), \'\'_\'\'\), 15\)%',
'rtrim(get_class($this), \'_\'), 15+23)',
$content
);
}

return $content;
},
];
99 changes: 97 additions & 2 deletions src/Console/Command/AddPrefixCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ final class AddPrefixCommand extends Command
const OUTPUT_DIR_OPT = 'output-dir';
/** @internal */
const FORCE_OPT = 'force';
/** @internal */
const PATCH_FILE = 'patch-file';
/** @internal */
const PATCH_FILE_DEFAULT = 'scoper.inc.php';

private $fileSystem;
private $handle;
Expand Down Expand Up @@ -69,7 +73,7 @@ protected function configure()
self::PREFIX_OPT,
'p',
InputOption::VALUE_REQUIRED,
'The namespace prefix to add'
'The namespace prefix to add.'
)
->addOption(
self::OUTPUT_DIR_OPT,
Expand All @@ -82,7 +86,17 @@ protected function configure()
self::FORCE_OPT,
'f',
InputOption::VALUE_NONE,
'Deletes any existing content in the output directory without any warning'
'Deletes any existing content in the output directory without any warning.'
)
->addOption(
self::PATCH_FILE,
'c',
InputOption::VALUE_REQUIRED,
sprintf(
'Configuration file for the patchers. Will use "%s" if found by default',
self::PATCH_FILE_DEFAULT
),
null
)
;
}
Expand All @@ -97,6 +111,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->validatePrefix($input);
$this->validatePaths($input);
$this->validateOutputDir($input, $io);
$patchers = $this->validatePatchers($input, $io);

$logger = new ConsoleLogger(
$this->getApplication(),
Expand All @@ -113,6 +128,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
$input->getOption(self::PREFIX_OPT),
$input->getArgument(self::PATH_ARG),
$input->getOption(self::OUTPUT_DIR_OPT),
$patchers,
$logger
);
} catch (Throwable $throwable) {
Expand Down Expand Up @@ -234,4 +250,83 @@ private function validateOutputDir(InputInterface $input, OutputStyle $io)
$this->fileSystem->remove($outputDir);
}
}

/**
* @param InputInterface $input
* @param OutputStyle $io
*
* @return callable[]
*/
private function validatePatchers(InputInterface $input, OutputStyle $io): array
{
$patchFile = $input->getOption(self::PATCH_FILE);

if (null === $patchFile) {
$patchFile = $this->makeAbsolutePath(self::PATCH_FILE_DEFAULT);

if (false === file_exists($patchFile)) {
$io->writeln(
sprintf(
'Patch file "%s" not found. Skipping.',
$patchFile
),
OutputStyle::VERBOSITY_DEBUG
);

return [];
}
} else {
$patchFile = $this->makeAbsolutePath($patchFile);
}

if (false === file_exists($patchFile)) {
throw new RuntimeException(
sprintf(
'Could not find the file "%s".',
$patchFile
)
);
}

$io->writeln(
sprintf(
'Using the configuration file "%s".',
$patchFile
),
OutputStyle::VERBOSITY_DEBUG
);

$patchers = include $patchFile;

if (false === is_array($patchers)) {
throw new RuntimeException(
sprintf(
'Expected patchers to be an array of callables, found "%s" instead.',
gettype($patchers)
)
);
}

foreach ($patchers as $index => $patcher) {
if (false === is_callable($patcher)) {
throw new RuntimeException(
sprintf(
'Expected patchers to be an array of callables, the "%d" element is not.',
$index
)
);
}
}

return $patchers;
}

private function makeAbsolutePath(string $path): string
{
if (false === $this->fileSystem->isAbsolutePath($path)) {
$path = getcwd().DIRECTORY_SEPARATOR.$path;
}

return $path;
}
}
34 changes: 24 additions & 10 deletions src/Handler/HandleAddPrefix.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,20 @@ public function __construct(Scoper $scoper)
/**
* Apply prefix to all the code found in the given paths, AKA scope all the files found.
*
* @param string $prefix e.g. 'Foo'
* @param string[] $paths List of files to scan (absolute paths)
* @param string $output absolute path to the output directory
* @param string $prefix e.g. 'Foo'
* @param string[] $paths List of files to scan (absolute paths)
* @param string $output absolute path to the output directory
* @param callable[] $patchers
* @param ConsoleLogger $logger
*/
public function __invoke(string $prefix, array $paths, string $output, ConsoleLogger $logger)
public function __invoke(string $prefix, array $paths, string $output, array $patchers, ConsoleLogger $logger)
{
$this->fileSystem->mkdir($output);

try {
$files = $this->retrieveFiles($paths, $output);

$this->scopeFiles($files, $prefix, $logger);
$this->scopeFiles($files, $prefix, $patchers, $logger);
} catch (Throwable $throwable) {
$this->fileSystem->remove($output);

Expand Down Expand Up @@ -141,22 +142,35 @@ function (array $files, string $file) use ($output, $commonPath): array {
/**
* @param string[] $files
* @param string $prefix
* @param callable[] $patchers
* @param ConsoleLogger $logger
*/
private function scopeFiles(array $files, string $prefix, ConsoleLogger $logger)
private function scopeFiles(array $files, string $prefix, array $patchers, ConsoleLogger $logger)
{
$count = count($files);
$logger->outputFileCount($count);

foreach ($files as $inputFilePath => $outputFilePath) {
$this->scopeFile($inputFilePath, $outputFilePath, $prefix, $logger);
$this->scopeFile($inputFilePath, $outputFilePath, $prefix, $patchers, $logger);
}
}

private function scopeFile(string $inputFilePath, string $outputFilePath, string $prefix, ConsoleLogger $logger)
{
/**
* @param string $inputFilePath
* @param string $outputFilePath
* @param string $prefix
* @param callable[] $patchers
* @param ConsoleLogger $logger
*/
private function scopeFile(
string $inputFilePath,
string $outputFilePath,
string $prefix,
array $patchers,
ConsoleLogger $logger
) {
try {
$scoppedContent = $this->scoper->scope($inputFilePath, $prefix);
$scoppedContent = $this->scoper->scope($inputFilePath, $prefix, $patchers);
} catch (PhpParserError $error) {
throw new ParsingException(
sprintf(
Expand Down
7 changes: 4 additions & 3 deletions src/Scoper.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ interface Scoper
/**
* Scope AKA. apply the given prefix to the file in the appropriate way.
*
* @param string $filePath File to scope
* @param string $prefix Prefix to apply to the file
* @param string $filePath File to scope
* @param string $prefix Prefix to apply to the file
* @param callable[] $patchers
*
* @throws ParsingException
*
* @return string Content of the file with the prefix applied
*/
public function scope(string $filePath, string $prefix): string;
public function scope(string $filePath, string $prefix, array $patchers): string;
}
4 changes: 2 additions & 2 deletions src/Scoper/Composer/InstalledPackagesScoper.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ public function __construct(Scoper $decoratedScoper)
*
* {@inheritdoc}
*/
public function scope(string $filePath, string $prefix): string
public function scope(string $filePath, string $prefix, array $patchers): string
{
if (null === self::$filePattern) {
throw new LogicException('Cannot be used without being initialised first.');
}

if (1 !== preg_match(self::$filePattern, $filePath)) {
return $this->decoratedScoper->scope($filePath, $prefix);
return $this->decoratedScoper->scope($filePath, $prefix, $patchers);
}

$decodedJson = json_decode(
Expand Down
4 changes: 2 additions & 2 deletions src/Scoper/Composer/JsonFileScoper.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ public function __construct(Scoper $decoratedScoper)
*
* {@inheritdoc}
*/
public function scope(string $filePath, string $prefix): string
public function scope(string $filePath, string $prefix, array $patchers): string
{
if (1 !== preg_match('/composer\.json$/', $filePath)) {
return $this->decoratedScoper->scope($filePath, $prefix);
return $this->decoratedScoper->scope($filePath, $prefix, $patchers);
}

$decodedJson = json_decode(
Expand Down
2 changes: 1 addition & 1 deletion src/Scoper/NullScoper.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ final class NullScoper implements Scoper
/**
* @inheritdoc
*/
public function scope(string $filePath, string $prefix): string
public function scope(string $filePath, string $prefix, array $patchers): string
{
return file_get_contents($filePath);
}
Expand Down
Loading