From fc58c33dddcc2d7da34d18e790bf9ba9349a1e71 Mon Sep 17 00:00:00 2001 From: ochorocho Date: Sun, 1 May 2022 12:31:34 +0200 Subject: [PATCH] [TASK] Ask for permission to modify if composer property already exists. --- Classes/Command/AcceptanceTestsCommand.php | 106 ++++++++++++++------- 1 file changed, 73 insertions(+), 33 deletions(-) diff --git a/Classes/Command/AcceptanceTestsCommand.php b/Classes/Command/AcceptanceTestsCommand.php index 3ea2e51..8b4f502 100644 --- a/Classes/Command/AcceptanceTestsCommand.php +++ b/Classes/Command/AcceptanceTestsCommand.php @@ -53,8 +53,8 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { $this->io = new SymfonyStyle($input, $output); - $packages = $this->getPackageResolver()->getPackageManager()->getActivePackages(); + $packages = $this->getPackageResolver()->getPackageManager()->getActivePackages(); $choices = array_reduce($packages, function ($result, PackageInterface $package) { if ($package->getPackageMetaData()->getPackageType() === 'typo3-cms-extension') { $packageKey = $package->getPackageKey(); @@ -65,26 +65,35 @@ protected function execute(InputInterface $input, OutputInterface $output): int $selectedPackageName = $this->io->choice('Select a package to create acceptance tests for', $choices); $this->package = $this->getPackageResolver()->resolvePackage($selectedPackageName); - $packageKey = $this->package->getPackageKey(); + $targetPackagePath = $this->package->getPackagePath(); + + if ($this->updateComposerFile($targetPackagePath)) { + $this->io->writeln('Updated composer.json for EXT:' . $packageKey . ''); + } else { + $this->io->writeln('Failed to update composer.json for EXT:' . $packageKey . ''); + } + $this->io->writeln('Selected package: ' . $packageKey); $finder = GeneralUtility::makeInstance(Finder::class); - $targetPackage = $this->package->getPackagePath(); $codeTemplatePath = '/Resources/Private/CodeTemplates/AcceptanceTests'; $templatePath = $this->getPackageResolver()->resolvePackage('b13/make')->getPackagePath() . $codeTemplatePath; $this->filesystem->mkdir([ - $targetPackage . '/Tests/Acceptance', - $targetPackage . '/Tests/Acceptance/Fixtures', - $targetPackage . '/Tests/Acceptance/Application', - $targetPackage . '/Tests/Acceptance/Support/Extension' + $targetPackagePath . '/Tests/Acceptance/Fixtures', + $targetPackagePath . '/Tests/Acceptance/Application', + $targetPackagePath . '/Tests/Acceptance/Support/Extension' ]); // Create public folder which is required for e.g. acceptance tests to work - $publicFolderPath = $targetPackage . '/Resources/Public'; + $publicFolderPath = $targetPackagePath . '/Resources/Public'; if (!is_dir($publicFolderPath)) { - $createPublic = $this->io->confirm('Resource/Public is necessary e.g. for acceptance tests. Do you want to create it now?', true); + $createPublic = $this->io->confirm( + 'Resource/Public is necessary e.g. for acceptance tests. Do you want to create it now?', + true + ); + if ($createPublic) { $this->filesystem->mkdir([$publicFolderPath]); // Ensure the folder will be detected by git and committed @@ -95,7 +104,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $files = $finder->in($templatePath)->files(); foreach ($files as $file) { - $target = $targetPackage . 'Tests' . explode('AcceptanceTests', $file->getRealPath())[1]; + $target = $targetPackagePath . 'Tests' . explode('AcceptanceTests', $file->getRealPath())[1]; if (!is_file($target)) { $content = $file->getContents(); @@ -109,12 +118,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int } } - if ($this->updateComposerFile($targetPackage)) { - $this->io->writeln('Updated composer.json for EXT:' . $packageKey . ''); - } else { - $this->io->writeln('Failed to update composer.json for EXT:' . $packageKey . ''); - } - return 0; } @@ -129,23 +132,39 @@ protected function updateComposerFile(string $packagePath): bool $composerFile = $packagePath . '/composer.json'; $composerJson = file_get_contents($composerFile); $composer = json_decode($composerJson, true); - $namespace = rtrim($this->getNamespace(), '\\'); - - // @todo: if a value already exists ask for permission to change it?! - $composer['require-dev']['codeception/codeception'] = '^4.1'; - $composer['require-dev']['codeception/module-asserts'] = '^1.2'; - $composer['require-dev']['codeception/module-webdriver'] = '^1.1'; - $composer['require-dev']['typo3/testing-framework'] = '^6.16.2'; - - $composer['autoload-dev']['psr-4'][$namespace . '\\Tests\\'] = 'Tests/'; - - $composer['config']['vendor-dir'] = '.Build/vendor'; - $composer['config']['bin-dir'] = '.Build/bin'; + if (json_last_error() !== JSON_ERROR_NONE) { + throw new \JsonException('Could not parse ' . $composerFile); + } - $composer['extra']['typo3/cms']['app-dir'] = '.Build'; - $composer['extra']['typo3/cms']['web-dir'] = '.Build/Web'; + $namespace = rtrim($this->getNamespace(), '\\'); - return GeneralUtility::writeFile($composerFile, json_encode($composer, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), true); + $addToComposerFile = [ + 'require-dev' => [ + 'codeception/codeception' => '^4.1', + 'codeception/module-asserts' => '^1.2', + 'codeception/module-webdriver' => '^1.1', + 'typo3/testing-framework' => '^6.16.2' + ], + 'autoload-dev' => [ + 'psr-4' => [ + $namespace . '\\Tests\\' => 'Tests/' + ] + ], + 'config' => [ + 'vendor-dir' => '.Build/vendor', + 'bin-dir' => '.Build/bin', + ], + 'extra' => [ + 'typo3/cms' => [ + 'app-dir' => '.Build', + 'web-dir' => '.Build/Web', + ] + ] + ]; + + $enhancedComposer = $this->enhanceComposerFile($composer, $addToComposerFile); + + return GeneralUtility::writeFile($composerFile, json_encode($enhancedComposer, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), true); } /** @@ -157,8 +176,16 @@ protected function updateComposerFile(string $packagePath): bool protected function substituteMarkersAndSave(string $content, string $target): void { $markerService = GeneralUtility::makeInstance(MarkerBasedTemplateService::class); - $templateContent = $markerService->substituteMarker($content, '{{NAMESPACE}}', rtrim($this->getNamespace(), '\\')); - $templateContent = $markerService->substituteMarker($templateContent, '{{EXTENSION_KEY}}', $this->package->getPackageKey()); + $templateContent = $markerService->substituteMarker( + $content, + '{{NAMESPACE}}', + rtrim($this->getNamespace(), '\\') + ); + $templateContent = $markerService->substituteMarker( + $templateContent, + '{{EXTENSION_KEY}}', + $this->package->getPackageKey() + ); try { $this->filesystem->dumpFile($target, $templateContent); @@ -176,4 +203,17 @@ protected function getNamespace(): string { return (string)key((array)($this->package->getValueFromComposerManifest('autoload')->{'psr-4'} ?? [])); } + + private function enhanceComposerFile(array &$composer, array &$addToComposerFile): array + { + foreach ($addToComposerFile as $key => $value) { + if (is_array($value) && isset($composer[$key])) { + $this->enhanceComposerFile($composer[$key], $value); + } else { + $composer[$key] = $value; + } + } + + return $composer; + } }