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 a process command to apply the compactors and replacement values on a single file #248

Merged
merged 2 commits into from
May 31, 2018
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
1 change: 1 addition & 0 deletions doc/code-isolation.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ there is two recommendations:
- Make use of Box `--debug` option in the `compile` command. It dumps the code added to the PHAR in a `.box-dump`
directory. This allows you to more easily inspect, alter and test the code shipped in the PHAR. This way, you can
make sure the code shipped is working before worrying about whether that code is going to work inside a PHAR.
- Use the `process` command on a specific file to check the result and the effects of the configuration on it


<br />
Expand Down
7 changes: 7 additions & 0 deletions doc/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,10 @@ The following compactors are included with Box:
- `KevinGH\Box\Compactor\Php`: strip down classes from phpdocs & comments
- `KevinGH\Box\Compactor\PhpScoper`: isolate the code using [PHP-Scoper][phpscoper]

The effects of the [compactors][compactors] and [replacement values][placeholders] can be tested with the `process`
command ✨.


### Annotations (`annotations`)

// TODO: review this setting + doc, default value...]
Expand Down Expand Up @@ -714,6 +718,9 @@ The `@` is the default value of the [sigil][replacement-sigil] which is the plac
which you can find bellow, but you can also specify any replacement value via the
[`replacements` setting][replacements].

The effects of the [compactors][compactors] and [replacement values][placeholders] can be tested with the `process`
command ✨.


### Replacements (`replacements`)

Expand Down
1 change: 1 addition & 0 deletions src/Console/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ protected function getDefaultCommands(): array
$commands[] = new Command\Compile();
$commands[] = new Command\Diff();
$commands[] = new Command\Info();
$commands[] = new Command\Process();
$commands[] = new Command\Validate();
$commands[] = new Command\Verify();

Expand Down
2 changes: 2 additions & 0 deletions src/Console/Command/Configurable.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ final protected function getConfig(InputInterface $input, OutputInterface $outpu
throw $exception;
}

$io->comment('Loading without a configuration file.');

$configPath = null;
}

Expand Down
216 changes: 216 additions & 0 deletions src/Console/Command/Process.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
<?php

declare(strict_types=1);

/*
* This file is part of the box project.
*
* (c) Kevin Herrera <kevin@herrera.io>
* Théo Fidry <theo.fidry@gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/

namespace KevinGH\Box\Console\Command;

use KevinGH\Box\Box;
use KevinGH\Box\Compactor;
use KevinGH\Box\Compactor\Placeholder;
use KevinGH\Box\Compactors;
use KevinGH\Box\Configuration;
use KevinGH\Box\PhpSettingsHandler;
use stdClass;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Logger\ConsoleLogger;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use const KevinGH\Box\BOX_ALLOW_XDEBUG;
use function array_shift;
use function array_unshift;
use function explode;
use function get_class;
use function getcwd;
use function implode;
use function KevinGH\Box\FileSystem\file_contents;
use function KevinGH\Box\FileSystem\make_path_absolute;
use function putenv;
use function sprintf;
use function strlen;
use function substr;

final class Process extends Configurable
{
use ChangeableWorkingDirectory;

private const FILE_ARGUMENT = 'file';

private const NO_RESTART_OPTION = 'no-restart';
private const NO_CONFIG_OPTION = 'no-config';

/**
* {@inheritdoc}
*/
protected function configure(): void
{
parent::configure();

$this->setName('process');
$this->setDescription('Apply the registered compactors and replacement values on a file');
$this->setHelp(
'The <info>%command.name%</info> command will apply the registered compactors and replacement values '
.'on the the given file. This is useful to debug the scoping of a specific file for example.'
);

$this->addArgument(
self::FILE_ARGUMENT,
InputArgument::REQUIRED,
'Path to the file to process'
);
$this->addOption(
self::NO_RESTART_OPTION,
null,
InputOption::VALUE_NONE,
'Do not restart the PHP process. Box restarts the process by default to disable xdebug'
);
$this->addOption(
self::NO_CONFIG_OPTION,
null,
InputOption::VALUE_NONE,
'Ignore the config file even when one is specified with the --config option'
);

$this->configureWorkingDirOption();
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output): void
{
$io = new SymfonyStyle($input, $output);

if ($input->getOption(self::NO_RESTART_OPTION)) {
putenv(BOX_ALLOW_XDEBUG.'=1');
}

(new PhpSettingsHandler(new ConsoleLogger($output)))->check();

$this->changeWorkingDirectory($input);

$io->writeln('');

$config = $input->getOption(self::NO_CONFIG_OPTION)
? Configuration::create(null, new stdClass())
: $this->getConfig($input, $output, true)
;

$path = make_path_absolute($input->getArgument(self::FILE_ARGUMENT), getcwd());

$compactors = $this->retrieveCompactors($config);

$fileContents = file_contents($path);

$io->writeln([
sprintf(
'Processing the contents of the file <info>%s</info>',
$path
),
'',
]);

$this->logPlaceholders($io, $config);
$this->logCompactors($io, $compactors);

$fileProcessedContents = $compactors->compactContents($path, $fileContents);

$io->writeln([
'Processed contents:',
'',
'<comment>"""</comment>',
$fileProcessedContents,
'<comment>"""</comment>',
]);
}

private function retrieveCompactors(Configuration $config): Compactors
{
$compactors = $config->getCompactors();

array_unshift(
$compactors,
new Placeholder($config->getReplacements())
);

return new Compactors(...$compactors);
}

private function logPlaceholders(SymfonyStyle $io, Configuration $config): void
{
if ([] === $config->getReplacements()) {
$io->writeln([
'No replacement values registered',
'',
]);

return;
}

$io->writeln('Registered replacement values:');

foreach ($config->getReplacements() as $key => $value) {
$io->writeln(
sprintf(
' <comment>+</comment> %s: %s',
$key,
$value
)
);
}

$io->writeln('');
}

private function logCompactors(SymfonyStyle $io, Compactors $compactors): void
{
$compactors = $compactors->toArray();

foreach ($compactors as $index => $compactor) {
if ($compactor instanceof Placeholder) {
unset($compactors[$index]);
}
}

if ([] === $compactors) {
$io->writeln([
'No compactor registered',
'',
]);

return;
}

$io->writeln('Registered compactors:');

$logCompactors = function (Compactor $compactor) use ($io): void {
$compactorClassParts = explode('\\', get_class($compactor));

if ('_HumbugBox' === substr($compactorClassParts[0], 0, strlen('_HumbugBox'))) {
// Keep the non prefixed class name for the user
array_shift($compactorClassParts);
}

$io->writeln(
sprintf(
' <comment>+</comment> %s',
implode('\\', $compactorClassParts)
)
);
};

array_map($logCompactors, $compactors);
$io->writeln('');
}
}
1 change: 1 addition & 0 deletions tests/Console/ApplicationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public function test_get_helper_menu(): void
help Displays help for a command
info Displays information about the PHAR extension or file
list Lists commands
process Apply the registered compactors and replacement values on a file
validate Validates the configuration file
verify Verifies the PHAR signature

Expand Down
3 changes: 3 additions & 0 deletions tests/Console/Command/CompileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,9 @@ public function test_it_can_build_a_PHAR_without_any_configuration(): void

Box (repo)


// Loading without a configuration file.

Building the PHAR "/path/to/tmp/index.phar"
? No compactor to register
? Adding main file: /path/to/tmp/index.php
Expand Down
Loading