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

[FEATURE] Add better DX for configuring fractor #45

Merged
merged 1 commit into from
Apr 24, 2024
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
.phpunit.result.cache
./run-test.sh
./run-test.sh
.run-test.sh
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,15 @@ To utilize Fractor effectively, follow these steps:
- At minimum, a configuration file must specify the paths to process:
```php
<?php

use a9f\Fractor\Configuration\Option;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator) {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [__DIR__ . '/output/']);
};

use a9f\Fractor\DependencyInjection\FractorConfiguration;

return FractorConfiguration::configure()
->withPaths([__DIR__ . '/packages/'])
->withSets([
Typo3LevelSetList::UP_TO_TYPO3_13
]);

```

3. **Running Fractor**:
Expand Down
15 changes: 7 additions & 8 deletions e2e/typo3-flexform/fractor.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<?php

use a9f\Fractor\Configuration\Option;
use a9f\Typo3Fractor\Set\Typo3LevelSetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [__DIR__ . '/output/']);
use a9f\Fractor\Configuration\FractorConfiguration;
use a9f\Typo3Fractor\Set\Typo3LevelSetList;

$containerConfigurator->import(Typo3LevelSetList::UP_TO_TYPO3_13);
};
return FractorConfiguration::configure()
->withPaths([__DIR__ . '/output/'])
->withSets([
Typo3LevelSetList::UP_TO_TYPO3_13
]);
2 changes: 1 addition & 1 deletion fractor/bin/fractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

$configFile = ConfigResolver::resolveConfigsFromInput(new ArgvInput());

$container = (new ContainerContainerBuilder())->createDependencyInjectionContainer([$configFile]);
$container = (new ContainerContainerBuilder())->createDependencyInjectionContainer($configFile);

/** @var FractorApplication $application */
$application = $container->get(FractorApplication::class);
Expand Down
4 changes: 0 additions & 4 deletions fractor/config/application.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
use a9f\Fractor\Application\FractorRunner;
use a9f\Fractor\Configuration\AllowedFileExtensionsResolver;
use a9f\Fractor\Configuration\ConfigurationFactory;
use a9f\Fractor\Configuration\Option;
use a9f\Fractor\Configuration\ValueObject\Configuration;
use a9f\Fractor\Differ\ConsoleDiffer;
use a9f\Fractor\Differ\Contract\Differ;
Expand All @@ -21,9 +20,6 @@
use function Symfony\Component\DependencyInjection\Loader\Configurator\tagged_iterator;

return static function (ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [__DIR__]);
$parameters->set(Option::SKIP, []);
$services = $containerConfigurator->services();
$services->defaults()
->autowire()
Expand Down
5 changes: 5 additions & 0 deletions fractor/config/fractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

use a9f\Fractor\Configuration\FractorConfiguration;

return FractorConfiguration::configure();
13 changes: 13 additions & 0 deletions fractor/src/Configuration/FractorConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace a9f\Fractor\Configuration;

final class FractorConfiguration
{
public static function configure(): FractorConfigurationBuilder
{
return new FractorConfigurationBuilder();
}
}
124 changes: 124 additions & 0 deletions fractor/src/Configuration/FractorConfigurationBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

declare(strict_types=1);

namespace a9f\Fractor\Configuration;

use a9f\Fractor\Application\Contract\ConfigurableFractorRule;
use a9f\Fractor\Application\Contract\FractorRule;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Webmozart\Assert\Assert;

final class FractorConfigurationBuilder
{
/**
* @var string[]
*/
private array $sets = [];

/**
* @var string[]
*/
private array $paths = [];

/**
* @var array<mixed>
*/
private array $skip = [];

/**
* @var array<class-string<FractorRule>>
*/
private array $rules = [];

/**
* @var array<class-string<ConfigurableFractorRule>, array<int|string, mixed>>
*/
private array $rulesWithConfigurations = [];

/**
* @param string[] $paths
*/
public function withPaths(array $paths): self
{
$this->paths = $paths;

return $this;
}

/**
* @param array<mixed> $skip
*/
public function withSkip(array $skip): self
{
$this->skip = array_merge($this->skip, $skip);

return $this;
}

/**
* @param string[] $sets
*/
public function withSets(array $sets): self
{
$this->sets = array_merge($this->sets, $sets);

return $this;
}

/**
* @param class-string<ConfigurableFractorRule> $fractorClass
* @param array<int|string, mixed> $configuration
*/
public function withConfiguredRule(string $fractorClass, array $configuration): self
{
$this->rulesWithConfigurations[$fractorClass][] = $configuration;

return $this;
}

/**
* @param array<class-string<FractorRule>> $rules
*/
public function withRules(array $rules): self
{
$this->rules = array_merge($this->rules, $rules);

return $this;
}

public function __invoke(ContainerConfigurator $containerConfigurator): void
{
Assert::allString($this->paths);

$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, $this->paths);
$parameters->set(Option::SKIP, $this->skip);

$services = $containerConfigurator->services();

foreach ($this->rules as $rule) {
Assert::classExists($rule);
Assert::isAOf($rule, FractorRule::class);
$services->set($rule)
->autoconfigure()
->autowire();
}

Assert::allString($this->sets);
foreach ($this->sets as $set) {
Assert::fileExists($set);
$containerConfigurator->import($set);
}

foreach ($this->rulesWithConfigurations as $configuredRule => $configuration) {
Assert::classExists($configuredRule);
Assert::isAOf($configuredRule, ConfigurableFractorRule::class);

$services->set($configuredRule)
->call('configure', $configuration)
->autoconfigure()
->autowire();
}
}
}
22 changes: 21 additions & 1 deletion fractor/src/DependencyInjection/ContainerContainerBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,16 @@
use Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Webmozart\Assert\Assert;

class ContainerContainerBuilder
{
/**
* @param string[] $additionalConfigFiles
*/
public function createDependencyInjectionContainer(array $additionalConfigFiles = []): ContainerInterface
public function createDependencyInjectionContainer(?string $fractorConfigFile, array $additionalConfigFiles = []): ContainerInterface
{
$containerBuilder = new ContainerBuilder();

Expand All @@ -23,6 +25,11 @@ public function createDependencyInjectionContainer(array $additionalConfigFiles
$configFiles = [
__DIR__ . '/../../config/application.php'
];

$fractorConfigFile ??= __DIR__ . '/../../config/fractor.php';

$this->loadFractorConfigFile($fractorConfigFile, $containerBuilder);

$configFiles = array_merge($configFiles, $additionalConfigFiles);
$configFiles = array_merge($configFiles, $this->collectConfigFilesFromExtensions());

Expand Down Expand Up @@ -56,4 +63,17 @@ private function collectConfigFilesFromExtensions(): array

return $collectedConfigFiles;
}

private function loadFractorConfigFile(string $fractorConfigFile, ContainerBuilder $containerBuilder): void
{
Assert::fileExists($fractorConfigFile);

$self = $this;
$callable = (require $fractorConfigFile);

Assert::isCallable($callable);
$instanceOf = [];
/** @var callable(ContainerConfigurator $container): void $callable */
$callable(new ContainerConfigurator($containerBuilder, new PhpFileLoader($containerBuilder, new FileLocator(dirname($fractorConfigFile))), $instanceOf, dirname($fractorConfigFile), basename($fractorConfigFile)));
}
}
7 changes: 6 additions & 1 deletion fractor/src/Testing/PHPUnit/AbstractFractorTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ protected function additionalConfigurationFiles(): array
return [];
}

protected function provideFractorConfigFile(): ?string
{
return null;
}

protected function setUp(): void
{
$this->bootFromConfigFile();
Expand All @@ -35,7 +40,7 @@ protected function setUp(): void

protected function bootFromConfigFile(): void
{
$this->currentContainer = (new ContainerContainerBuilder())->createDependencyInjectionContainer($this->additionalConfigurationFiles());
$this->currentContainer = (new ContainerContainerBuilder())->createDependencyInjectionContainer($this->provideFractorConfigFile(), $this->additionalConfigurationFiles());
}

protected function doTest(): void
Expand Down
5 changes: 5 additions & 0 deletions fractor/tests/Application/FractorRunner/FractorRunnerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,9 @@ protected function additionalConfigurationFiles(): array
__DIR__ . '/config/config.php'
];
}

protected function provideFractorConfigFile(): ?string
{
return __DIR__ . '/config/fractor.php';
}
}
5 changes: 0 additions & 5 deletions fractor/tests/Application/FractorRunner/config/config.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
<?php

use a9f\Fractor\Configuration\Option;
use a9f\Fractor\Tests\Fixture\DummyProcessor\Contract\TextRule;
use a9f\Fractor\Tests\Fixture\DummyProcessor\FileProcessor\TextFileProcessor;
use a9f\Fractor\Tests\Fixture\DummyProcessor\Rules\ReplaceXXXTextRule;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use function Symfony\Component\DependencyInjection\Loader\Configurator\tagged_iterator;

return static function (ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder): void {
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [__DIR__ . '/../Fixtures/']);
$services = $containerConfigurator->services();
$services->defaults()
->autowire()
->autoconfigure();

$services->set(ReplaceXXXTextRule::class);
$services->set(TextFileProcessor::class)->arg('$rules', tagged_iterator('fractor.text_rules'));
$containerBuilder->registerForAutoconfiguration(TextRule::class)->addTag('fractor.text_rules');
};
14 changes: 14 additions & 0 deletions fractor/tests/Application/FractorRunner/config/fractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

use a9f\Fractor\Configuration\FractorConfiguration;
use a9f\Fractor\Tests\Fixture\DummyProcessor\Rules\ReplaceXXXTextRule;

return FractorConfiguration::configure()
->withRules([
ReplaceXXXTextRule::class
])
->withPaths(
[
__DIR__ . '/../Fixtures/'
]
);
4 changes: 2 additions & 2 deletions fractor/tests/FileSystem/FilesFinder/FilesFinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ private function getFileBasename(string $foundFile): string
return pathinfo($foundFile, PATHINFO_BASENAME);
}

protected function additionalConfigurationFiles(): array
protected function provideFractorConfigFile(): ?string
{
return [__DIR__ . '/config/config.php'];
return __DIR__ . '/config/fractor.php';
}
}
9 changes: 0 additions & 9 deletions fractor/tests/FileSystem/FilesFinder/config/config.php

This file was deleted.

6 changes: 6 additions & 0 deletions fractor/tests/FileSystem/FilesFinder/config/fractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php

use a9f\Fractor\Configuration\FractorConfiguration;

return FractorConfiguration::configure()
->withSkip([__DIR__ . '/../Fixtures/SourceWithBrokenSymlinks/folder2']);
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ protected function additionalConfigurationFiles(): array
__DIR__ . '/config/config.php',
];
}

protected function provideFractorConfigFile(): ?string
{
return __DIR__ . '/config/fractor.php';
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
<?php

use a9f\Fractor\Configuration\Option;
use a9f\Typo3Fractor\Set\Typo3SetList;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
$containerConfigurator->import(__DIR__ . '/../../../../../../config/application.php');
$containerConfigurator->import(__DIR__ . '/../../../../../../../fractor-xml/config/application.php');
$containerConfigurator->import(Typo3SetList::TYPO3_7);

$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [__DIR__ . '/../Fixtures/']);
};
Loading