From 36be90af72563b0f25092a71272bcf62ed35e84a Mon Sep 17 00:00:00 2001 From: Simon Schaufelberger Date: Wed, 28 Aug 2024 00:00:56 +0200 Subject: [PATCH] [FEATURE] Keep TypoScript format Resolves: #197 --- README.md | 20 +++++++ .../fractor-typoscript/config/application.php | 6 ++ .../TypoScriptProcessorOption.php | 18 ++++++ .../PrettyPrinterConfigurationFactory.php | 41 +++++++++++--- .../Factory/PrettyPrinterFormatFactory.php | 48 ++++++++++++++++ .../src/TypoScriptFileProcessor.php | 9 ++- ...ScriptPrettyPrinterFormatConfiguration.php | 55 +++++++++++++++++++ .../Fixtures/DummyTypoScriptFractorRule.php | 35 ++++++++++++ .../Fixtures/fixture.typoscript | 17 ++++++ .../TypoScriptFileProcessorTest.php | 29 ++++++++++ .../config/fractor.php | 19 +++++++ .../Fixture/StatementCollectingVisitor.php | 2 +- .../TypoScriptStatementsIteratorTest.php | 4 +- .../config/config.php | 2 +- .../config/fractor.php | 0 .../FractorConfigurationBuilder.php | 4 +- ...rotectEmailAddressesAsciiOptionFractor.php | 3 +- 17 files changed, 294 insertions(+), 18 deletions(-) create mode 100644 packages/fractor-typoscript/src/Configuration/TypoScriptProcessorOption.php create mode 100644 packages/fractor-typoscript/src/Factory/PrettyPrinterFormatFactory.php create mode 100644 packages/fractor-typoscript/src/ValueObject/TypoScriptPrettyPrinterFormatConfiguration.php create mode 100644 packages/fractor-typoscript/tests/Fixtures/DummyTypoScriptFractorRule.php create mode 100644 packages/fractor-typoscript/tests/TypoScriptFileProcessor/Fixtures/fixture.typoscript create mode 100644 packages/fractor-typoscript/tests/TypoScriptFileProcessor/TypoScriptFileProcessorTest.php create mode 100644 packages/fractor-typoscript/tests/TypoScriptFileProcessor/config/fractor.php rename packages/fractor-typoscript/tests/{ => TypoScriptStatementsIterator}/Fixture/StatementCollectingVisitor.php (94%) rename packages/fractor-typoscript/tests/{ => TypoScriptStatementsIterator}/TypoScriptStatementsIteratorTest.php (95%) rename packages/fractor-typoscript/tests/{ => TypoScriptStatementsIterator}/config/config.php (78%) rename packages/fractor-typoscript/tests/{ => TypoScriptStatementsIterator}/config/fractor.php (100%) diff --git a/README.md b/README.md index 6ced4f4b..10357f3e 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,26 @@ return FractorConfiguration::configure() ]) ``` +If you want to adjust the format of your typoscript files, you can configure it this way: + +```php +withOptions([ + TypoScriptProcessorOption::INDENT_SIZE => 2, + TypoScriptProcessorOption::INDENT_CHARACTER => PrettyPrinterConfiguration::INDENTATION_STYLE_SPACES, + //TypoScriptProcessorOption::INDENT_CHARACTER => 'auto', // this detects the indent from the file and keeps it + TypoScriptProcessorOption::ADD_CLOSING_GLOBAL => false, + TypoScriptProcessorOption::INCLUDE_EMPTY_LINE_BREAKS => true, + TypoScriptProcessorOption::INDENT_CONDITIONS => true, + ]) +``` + ## Processing Execute Fractor from the command line, passing the path to your configuration file as an argument: diff --git a/packages/fractor-typoscript/config/application.php b/packages/fractor-typoscript/config/application.php index 6924cf5a..633efbca 100644 --- a/packages/fractor-typoscript/config/application.php +++ b/packages/fractor-typoscript/config/application.php @@ -3,7 +3,9 @@ declare(strict_types=1); use a9f\FractorTypoScript\Contract\TypoScriptFractor; +use a9f\FractorTypoScript\Factory\PrettyPrinterFormatFactory; use a9f\FractorTypoScript\TypoScriptFileProcessor; +use a9f\FractorTypoScript\ValueObject\TypoScriptPrettyPrinterFormatConfiguration; use Helmich\TypoScriptParser\Parser\Parser; use Helmich\TypoScriptParser\Parser\Printer\PrettyPrinter; use Helmich\TypoScriptParser\Tokenizer\Tokenizer; @@ -26,7 +28,11 @@ ->public(); $services->set(PrettyPrinter::class); + $services->set('fractor.typoscript_processor.pretty_printer', TypoScriptPrettyPrinterFormatConfiguration::class) + ->factory([service(PrettyPrinterFormatFactory::class), 'create']); + $services->set(TypoScriptFileProcessor::class) + ->arg('$typoScriptPrettyPrinterFormatConfiguration', service('fractor.typoscript_processor.pretty_printer')) ->arg('$rules', tagged_iterator('fractor.typoscript_rule')); $containerBuilder->registerForAutoconfiguration(TypoScriptFractor::class) diff --git a/packages/fractor-typoscript/src/Configuration/TypoScriptProcessorOption.php b/packages/fractor-typoscript/src/Configuration/TypoScriptProcessorOption.php new file mode 100644 index 00000000..f5a35552 --- /dev/null +++ b/packages/fractor-typoscript/src/Configuration/TypoScriptProcessorOption.php @@ -0,0 +1,18 @@ +isSpace()) { - $prettyPrinterConfiguration = $prettyPrinterConfiguration->withSpaceIndentation($indent->length()); - } else { + if ($prettyPrinterFormatConfiguration->getStyle() === 'auto') { + // keep original TypoScript format + $indent = Indent::fromFile($file); + + if ($indent->isSpace()) { + $prettyPrinterConfiguration = $prettyPrinterConfiguration->withSpaceIndentation($indent->length()); + } else { + $prettyPrinterConfiguration = $prettyPrinterConfiguration->withTabs(); + } + } elseif ($prettyPrinterFormatConfiguration->getStyle() === PrettyPrinterConfiguration::INDENTATION_STYLE_TABS) { $prettyPrinterConfiguration = $prettyPrinterConfiguration->withTabs(); + } else { + $prettyPrinterConfiguration = $prettyPrinterConfiguration->withSpaceIndentation( + $prettyPrinterFormatConfiguration->getSize() + ); + } + + if ($prettyPrinterFormatConfiguration->shouldIndentConditions()) { + $prettyPrinterConfiguration = $prettyPrinterConfiguration->withIndentConditions(); + } + + if ($prettyPrinterFormatConfiguration->shouldAddClosingGlobal()) { + $prettyPrinterConfiguration = $prettyPrinterConfiguration->withClosingGlobalStatement(); + } + + if ($prettyPrinterFormatConfiguration->shouldIncludeEmptyLineBreaks()) { + return $prettyPrinterConfiguration->withEmptyLineBreaks(); } - return $prettyPrinterConfiguration->withEmptyLineBreaks(); + return $prettyPrinterConfiguration; } } diff --git a/packages/fractor-typoscript/src/Factory/PrettyPrinterFormatFactory.php b/packages/fractor-typoscript/src/Factory/PrettyPrinterFormatFactory.php new file mode 100644 index 00000000..b701fad0 --- /dev/null +++ b/packages/fractor-typoscript/src/Factory/PrettyPrinterFormatFactory.php @@ -0,0 +1,48 @@ +parameterBag->has(TypoScriptProcessorOption::INDENT_SIZE) + ? $this->parameterBag->get(TypoScriptProcessorOption::INDENT_SIZE) + : 4; + + $style = $this->parameterBag->has(TypoScriptProcessorOption::INDENT_CHARACTER) + ? $this->parameterBag->get(TypoScriptProcessorOption::INDENT_CHARACTER) + : 'auto'; + + $addClosingGlobal = $this->parameterBag->has(TypoScriptProcessorOption::ADD_CLOSING_GLOBAL) + ? $this->parameterBag->get(TypoScriptProcessorOption::ADD_CLOSING_GLOBAL) + : true; + + $includeEmptyLineBreaks = $this->parameterBag->has(TypoScriptProcessorOption::INCLUDE_EMPTY_LINE_BREAKS) + ? $this->parameterBag->get(TypoScriptProcessorOption::INCLUDE_EMPTY_LINE_BREAKS) + : true; + + $indentConditions = $this->parameterBag->has(TypoScriptProcessorOption::INDENT_CONDITIONS) + ? $this->parameterBag->get(TypoScriptProcessorOption::INDENT_CONDITIONS) + : false; + + return TypoScriptPrettyPrinterFormatConfiguration::fromValues( + $size, + $style, + $addClosingGlobal, + $includeEmptyLineBreaks, + $indentConditions + ); + } +} diff --git a/packages/fractor-typoscript/src/TypoScriptFileProcessor.php b/packages/fractor-typoscript/src/TypoScriptFileProcessor.php index 13d16df0..263f62de 100644 --- a/packages/fractor-typoscript/src/TypoScriptFileProcessor.php +++ b/packages/fractor-typoscript/src/TypoScriptFileProcessor.php @@ -8,6 +8,7 @@ use a9f\Fractor\Application\ValueObject\File; use a9f\FractorTypoScript\Contract\TypoScriptFractor; use a9f\FractorTypoScript\Factory\PrettyPrinterConfigurationFactory; +use a9f\FractorTypoScript\ValueObject\TypoScriptPrettyPrinterFormatConfiguration; use Helmich\TypoScriptParser\Parser\ParseError; use Helmich\TypoScriptParser\Parser\Parser; use Helmich\TypoScriptParser\Parser\Printer\PrettyPrinter; @@ -28,7 +29,8 @@ public function __construct( private iterable $rules, private Parser $parser, private PrettyPrinter $printer, - private PrettyPrinterConfigurationFactory $prettyPrinterConfigurationFactory + private PrettyPrinterConfigurationFactory $prettyPrinterConfigurationFactory, + private TypoScriptPrettyPrinterFormatConfiguration $typoScriptPrettyPrinterFormatConfiguration ) { $this->output = new BufferedOutput(); } @@ -47,7 +49,10 @@ public function handle(File $file, iterable $appliedRules): void $statements = $statementsIterator->traverseDocument($file, $statements); $this->printer->setPrettyPrinterConfiguration( - $this->prettyPrinterConfigurationFactory->createPrettyPrinterConfiguration($file) + $this->prettyPrinterConfigurationFactory->createPrettyPrinterConfiguration( + $file, + $this->typoScriptPrettyPrinterFormatConfiguration + ) ); $this->printer->printStatements($statements, $this->output); diff --git a/packages/fractor-typoscript/src/ValueObject/TypoScriptPrettyPrinterFormatConfiguration.php b/packages/fractor-typoscript/src/ValueObject/TypoScriptPrettyPrinterFormatConfiguration.php new file mode 100644 index 00000000..4d3b3065 --- /dev/null +++ b/packages/fractor-typoscript/src/ValueObject/TypoScriptPrettyPrinterFormatConfiguration.php @@ -0,0 +1,55 @@ +size; + } + + public function getStyle(): string + { + return $this->style; + } + + public function shouldAddClosingGlobal(): bool + { + return $this->addClosingGlobal; + } + + public function shouldIncludeEmptyLineBreaks(): bool + { + return $this->includeEmptyLineBreaks; + } + + public function shouldIndentConditions(): bool + { + return $this->indentConditions; + } +} diff --git a/packages/fractor-typoscript/tests/Fixtures/DummyTypoScriptFractorRule.php b/packages/fractor-typoscript/tests/Fixtures/DummyTypoScriptFractorRule.php new file mode 100644 index 00000000..b82d309a --- /dev/null +++ b/packages/fractor-typoscript/tests/Fixtures/DummyTypoScriptFractorRule.php @@ -0,0 +1,35 @@ +object->absoluteName !== 'config.spamProtectEmailAddresses' + || $statement->value->value !== 'ascii' + ) { + return null; + } + + return TypoScriptStatementsIterator::REMOVE_NODE; + } + + public function getRuleDefinition(): RuleDefinition + { + throw new BadMethodCallException('Not implemented yet'); + } +} diff --git a/packages/fractor-typoscript/tests/TypoScriptFileProcessor/Fixtures/fixture.typoscript b/packages/fractor-typoscript/tests/TypoScriptFileProcessor/Fixtures/fixture.typoscript new file mode 100644 index 00000000..e2c0c22f --- /dev/null +++ b/packages/fractor-typoscript/tests/TypoScriptFileProcessor/Fixtures/fixture.typoscript @@ -0,0 +1,17 @@ +page = PAGE +page.10 = TEXT +page.10.value = german + +[siteLanguage('languageId') == 1] + page.10.value = english +[global] + +config.spamProtectEmailAddresses = ascii +----- +page = PAGE +page.10 = TEXT +page.10.value = german + +[siteLanguage('languageId') == 1] + page.10.value = english +[global] diff --git a/packages/fractor-typoscript/tests/TypoScriptFileProcessor/TypoScriptFileProcessorTest.php b/packages/fractor-typoscript/tests/TypoScriptFileProcessor/TypoScriptFileProcessorTest.php new file mode 100644 index 00000000..deec0ac1 --- /dev/null +++ b/packages/fractor-typoscript/tests/TypoScriptFileProcessor/TypoScriptFileProcessorTest.php @@ -0,0 +1,29 @@ +doTestFile($filePath); + $this->assertThatRuleIsApplied($filePath, DummyTypoScriptFractorRule::class); + } + + public static function provideData(): \Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixtures', '*.typoscript'); + } + + public function provideConfigFilePath(): ?string + { + return __DIR__ . '/config/fractor.php'; + } +} diff --git a/packages/fractor-typoscript/tests/TypoScriptFileProcessor/config/fractor.php b/packages/fractor-typoscript/tests/TypoScriptFileProcessor/config/fractor.php new file mode 100644 index 00000000..89cacded --- /dev/null +++ b/packages/fractor-typoscript/tests/TypoScriptFileProcessor/config/fractor.php @@ -0,0 +1,19 @@ +withOptions([ + TypoScriptProcessorOption::INDENT_SIZE => 4, + TypoScriptProcessorOption::INDENT_CHARACTER => PrettyPrinterConfiguration::INDENTATION_STYLE_SPACES, + //TypoScriptProcessorOption::INDENT_CHARACTER => 'auto', + TypoScriptProcessorOption::ADD_CLOSING_GLOBAL => false, + TypoScriptProcessorOption::INCLUDE_EMPTY_LINE_BREAKS => true, + TypoScriptProcessorOption::INDENT_CONDITIONS => true, + ]) + ->withRules([DummyTypoScriptFractorRule::class]); diff --git a/packages/fractor-typoscript/tests/Fixture/StatementCollectingVisitor.php b/packages/fractor-typoscript/tests/TypoScriptStatementsIterator/Fixture/StatementCollectingVisitor.php similarity index 94% rename from packages/fractor-typoscript/tests/Fixture/StatementCollectingVisitor.php rename to packages/fractor-typoscript/tests/TypoScriptStatementsIterator/Fixture/StatementCollectingVisitor.php index ef44af00..5786d632 100644 --- a/packages/fractor-typoscript/tests/Fixture/StatementCollectingVisitor.php +++ b/packages/fractor-typoscript/tests/TypoScriptStatementsIterator/Fixture/StatementCollectingVisitor.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace a9f\FractorTypoScript\Tests\Fixture; +namespace a9f\FractorTypoScript\Tests\TypoScriptStatementsIterator\Fixture; use a9f\Fractor\Application\ValueObject\File; use a9f\FractorTypoScript\Contract\TypoScriptNodeVisitor; diff --git a/packages/fractor-typoscript/tests/TypoScriptStatementsIteratorTest.php b/packages/fractor-typoscript/tests/TypoScriptStatementsIterator/TypoScriptStatementsIteratorTest.php similarity index 95% rename from packages/fractor-typoscript/tests/TypoScriptStatementsIteratorTest.php rename to packages/fractor-typoscript/tests/TypoScriptStatementsIterator/TypoScriptStatementsIteratorTest.php index 85fcfbcb..44efad16 100644 --- a/packages/fractor-typoscript/tests/TypoScriptStatementsIteratorTest.php +++ b/packages/fractor-typoscript/tests/TypoScriptStatementsIterator/TypoScriptStatementsIteratorTest.php @@ -2,12 +2,12 @@ declare(strict_types=1); -namespace a9f\FractorTypoScript\Tests; +namespace a9f\FractorTypoScript\Tests\TypoScriptStatementsIterator; use a9f\Fractor\Application\ValueObject\File; use a9f\Fractor\DependencyInjection\ContainerContainerBuilder; use a9f\Fractor\Exception\ShouldNotHappenException; -use a9f\FractorTypoScript\Tests\Fixture\StatementCollectingVisitor; +use a9f\FractorTypoScript\Tests\TypoScriptStatementsIterator\Fixture\StatementCollectingVisitor; use a9f\FractorTypoScript\TypoScriptStatementsIterator; use Helmich\TypoScriptParser\Parser\Parser; use PHPUnit\Framework\Attributes\Test; diff --git a/packages/fractor-typoscript/tests/config/config.php b/packages/fractor-typoscript/tests/TypoScriptStatementsIterator/config/config.php similarity index 78% rename from packages/fractor-typoscript/tests/config/config.php rename to packages/fractor-typoscript/tests/TypoScriptStatementsIterator/config/config.php index 06f5da90..167bbdc0 100644 --- a/packages/fractor-typoscript/tests/config/config.php +++ b/packages/fractor-typoscript/tests/TypoScriptStatementsIterator/config/config.php @@ -6,5 +6,5 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; return static function (ContainerConfigurator $containerConfigurator, ContainerBuilder $containerBuilder): void { - $containerConfigurator->import(__DIR__ . '/../../config/application.php'); + $containerConfigurator->import(__DIR__ . '/../../../config/application.php'); }; diff --git a/packages/fractor-typoscript/tests/config/fractor.php b/packages/fractor-typoscript/tests/TypoScriptStatementsIterator/config/fractor.php similarity index 100% rename from packages/fractor-typoscript/tests/config/fractor.php rename to packages/fractor-typoscript/tests/TypoScriptStatementsIterator/config/fractor.php diff --git a/packages/fractor/src/Configuration/FractorConfigurationBuilder.php b/packages/fractor/src/Configuration/FractorConfigurationBuilder.php index e777137b..9b2973f2 100644 --- a/packages/fractor/src/Configuration/FractorConfigurationBuilder.php +++ b/packages/fractor/src/Configuration/FractorConfigurationBuilder.php @@ -42,7 +42,7 @@ final class FractorConfigurationBuilder private array $imports = []; /** - * @var array + * @var array */ private array $options = []; @@ -157,7 +157,7 @@ public function import(string $import): self } /** - * @param array $options + * @param array $options */ public function withOptions(array $options): self { diff --git a/packages/typo3-fractor/rules/TYPO3v12/TypoScript/RemoveConfigSpamProtectEmailAddressesAsciiOptionFractor.php b/packages/typo3-fractor/rules/TYPO3v12/TypoScript/RemoveConfigSpamProtectEmailAddressesAsciiOptionFractor.php index c863414f..8dc19987 100644 --- a/packages/typo3-fractor/rules/TYPO3v12/TypoScript/RemoveConfigSpamProtectEmailAddressesAsciiOptionFractor.php +++ b/packages/typo3-fractor/rules/TYPO3v12/TypoScript/RemoveConfigSpamProtectEmailAddressesAsciiOptionFractor.php @@ -23,7 +23,8 @@ public function refactor(Statement $statement): null|Statement|int } if ($statement->object->absoluteName !== 'config.spamProtectEmailAddresses' - || $statement->value->value !== 'ascii') { + || $statement->value->value !== 'ascii' + ) { return null; }