From 87fa35ee628100242fc0c151d441e1fe85583d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Klatt?= Date: Tue, 26 Nov 2024 12:50:47 +0100 Subject: [PATCH] Feature/acp 4074/acp 4403 invalid checkout with paypalexpress in glue does not produce helpful errors (#19) * ACP-4403 Added schema merge console --- .github/workflows/ci.yml | 13 ++- composer.json | 23 ++-- phpcs.xml | 49 +++++++++ phpstan.neon | 9 +- architector.php => rector.php | 8 +- .../Console/OpenApiSchemaMergerConsole.php | 101 ++++++++++++++++++ .../GlueResourceMethodResponseArguments.php | 6 +- .../Arguments/TransferArguments.php | 2 +- .../ConsoleCommand/Command/CommandRunner.php | 4 +- .../Command/CommandRunnerInterface.php | 2 +- .../OpenApiHttpMethodInPathValidatorRule.php | 2 +- .../Rules/OpenApiPathValidatorRule.php | 6 +- src/SprykerSdk/SyncApi/SyncApiFactory.php | 2 +- .../SyncApi/Validator/AbstractValidator.php | 6 +- .../Validator/Rule/ValidatorRuleInterface.php | 4 +- 15 files changed, 187 insertions(+), 50 deletions(-) create mode 100644 phpcs.xml rename architector.php => rector.php (81%) create mode 100644 src/SprykerSdk/SyncApi/Console/OpenApiSchemaMergerConsole.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 762c656..fb36135 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,11 +18,10 @@ jobs: fail-fast: false matrix: php-version: [ - '8.0', - '8.1' + '8.2' ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -36,7 +35,7 @@ jobs: run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Composer cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} @@ -59,15 +58,15 @@ jobs: run: composer cs-check - name: Codecept tests - if: ${{ matrix.php-version == '8.0' }} + if: ${{ matrix.php-version == '8.2' }} run: composer test - name: Codecept tests with coverage - if: ${{ matrix.php-version == '8.1' }} + if: ${{ matrix.php-version == '8.2' }} run: composer test-cover - name: Code Coverage Report - if: success() && matrix.php-version == '8.1' + if: success() && matrix.php-version == '8.2' uses: codecov/codecov-action@v3 with: file: ./tests/_output/coverage.xml diff --git a/composer.json b/composer.json index c5b95c4..17862ff 100644 --- a/composer.json +++ b/composer.json @@ -4,24 +4,24 @@ "description": "SDK for SyncAPI.", "license": "proprietary", "require": { - "php": ">=8.0", + "php": ">=8.2", "cebe/php-openapi": "^1.6", "doctrine/inflector": "^1.4.0 || ^2.0", "spryker-sdk/spryk": "^0.4.0 || ^0.5.0", "symfony/console": "^4.0.0 || ^5.3 || ^6.0", "symfony/finder": "^4.0.0 || ^5.3 || ^6.0", - "symfony/process": "^4.0.0 || ^5.4 || ^6" + "symfony/process": "^4.0.0 || ^5.4 || ^6.0" }, "require-dev": { "codeception/codeception": "*", - "codeception/stub": "^4.1.0", "codeception/module-asserts": "*", + "codeception/stub": "^4.1.0", "mikey179/vfsstream": "^1.6", - "spryker-sdk/architector": "0.1.x-dev", + "phpstan/phpstan": "^2.0", + "rector/rector": "dev-main", "spryker/code-sniffer": "dev-master", "symfony/filesystem": "^4.0 || ^5.3", - "symfony/var-dumper": "*", - "phpstan/phpdoc-parser": "~1.5.1" + "symfony/var-dumper": "*" }, "autoload": { "psr-4": { @@ -46,9 +46,6 @@ } }, "config": { - "platform": { - "php": "8.0.19" - }, "sort-packages": true, "allow-plugins": { "dealerdirect/phpcodesniffer-composer-installer": true, @@ -56,13 +53,13 @@ } }, "scripts": { - "cs-check": "phpcs --colors -p -s --extensions=php --standard=vendor/spryker/code-sniffer/Spryker/ruleset.xml src/SprykerSdk/ tests/", - "cs-fix": "phpcbf --colors -p --extensions=php --standard=vendor/spryker/code-sniffer/Spryker/ruleset.xml src/SprykerSdk/ tests/", + "cs-check": "phpcs --colors -p", + "cs-fix": "phpcbf --colors -p", "stan": "phpstan analyze -l 8 src/SprykerSdk/", "test": "codecept build && codecept run", "test-cover": "codecept build && codecept run --coverage-xml", - "rector": "vendor/bin/rector process src/SprykerSdk/ --config architector.php --ansi", - "rector-diff": "vendor/bin/rector process src/SprykerSdk/ --config architector.php --ansi --dry-run", + "rector": "vendor/bin/rector process src/SprykerSdk/ --ansi", + "rector-diff": "vendor/bin/rector process src/SprykerSdk/ --ansi --dry-run", "local-ci": "composer cs-fix && composer cs-check && composer stan && composer rector-diff && composer test" } } diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..eab4bc2 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,49 @@ + + + + Spryker Coding Standard for the App Store Suite. + + Extends the main Spryker Coding Standard. + All sniffs in ./Sniffs will be auto loaded + + + + + src/SprykerSdk + tests/ + + */src/Generated/* + */src/Orm/*/Base/ + */src/Orm/*/Map/ + */src/Orm/Propel/ + */tests/_support/_generated/* + */tests/_helpers/* + */tests/_output/* + ./docker/* + ./data/cache/* + ./data/GLOBAL/cache/* + */node_modules/* + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/phpstan.neon b/phpstan.neon index 33522e1..04396f9 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,12 +1,7 @@ parameters: level: 8 - checkMissingIterableValueType: false - bootstrapFiles: - phpstan-bootstrap.php - ignoreErrors: - - '#Binary operation "\." between array\|bool\|string\|null and .+ results in an error.#' - - '#Parameter .+ of method .+Transfer::.+\(\).+ given.#' - - reportUnmatchedIgnoredErrors: false + - + identifier: missingType.iterableValue diff --git a/architector.php b/rector.php similarity index 81% rename from architector.php rename to rector.php index 4844ac5..dbb48bc 100644 --- a/architector.php +++ b/rector.php @@ -22,16 +22,12 @@ return static function (RectorConfig $rectorConfig) { $rectorConfig->import(SetList::DEAD_CODE); $rectorConfig->import(SetList::EARLY_RETURN); - $rectorConfig->import(SetList::PHP_74); + $rectorConfig->import(SetList::PHP_82); - $rectorConfig->parameters()->set(Option::SKIP, [ - ChangeAndIfToEarlyReturnRector::class, - ChangeOrIfReturnToEarlyReturnRector::class, - ClosureToArrowFunctionRector::class, + $rectorConfig->skip([ RemoveUselessParamTagRector::class, RemoveUnusedPromotedPropertyRector::class, RemoveUselessReturnTagRector::class, RemoveUselessVarTagRector::class, - ReturnBinaryAndToEarlyReturnRector::class, ]); }; diff --git a/src/SprykerSdk/SyncApi/Console/OpenApiSchemaMergerConsole.php b/src/SprykerSdk/SyncApi/Console/OpenApiSchemaMergerConsole.php new file mode 100644 index 0000000..6dbf2c4 --- /dev/null +++ b/src/SprykerSdk/SyncApi/Console/OpenApiSchemaMergerConsole.php @@ -0,0 +1,101 @@ +setName(static::COMMAND_NAME); + $this->setDescription(static::DESCRIPTION); + + $this->addArgument('source', InputArgument::REQUIRED, 'The root file of the OpenApi schema which will be used to merge with other schemas.'); + $this->addArgument('target', InputArgument::REQUIRED, 'The target file name that should be created after merge.'); + + $this->addOption('additional-schemas', 'a', InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'The additional OpenApi schema files that should be merged with the root schema.'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $source = sprintf('%s/%s', getcwd(), $input->getArgument('source')); + $target = sprintf('%s/%s', getcwd(), $input->getArgument('target')); + + $additionalSchemas = $input->getOption('additional-schemas'); + + $yaml = new Yaml(); + $sourceSchema = $yaml->parseFile($source); + + $paths = $sourceSchema['paths'] ?? []; + $schemas = $sourceSchema['components']['schemas'] ?? []; + $parameters = $sourceSchema['components']['parameters'] ?? []; + + foreach ($additionalSchemas as $additionalSchema) { + $additionalSchema = sprintf('%s/%s', getcwd(), $additionalSchema); + $coreSchema = $yaml->parseFile($additionalSchema); + $paths = $this->recursiveMerge($coreSchema['paths'] ?? [], $paths); + $schemas = $this->recursiveMerge($coreSchema['components']['schemas'] ?? [], $schemas); + $parameters = $this->recursiveMerge($coreSchema['components']['parameters'] ?? [], $parameters); + } + + $mergedOpenApi = new OpenApi([ + 'openapi' => $sourceSchema['openapi'], + 'info' => $sourceSchema['info'], + 'servers' => $sourceSchema['servers'], + 'paths' => $paths, + 'components' => [ + 'schemas' => $schemas, + 'parameters' => $parameters, + ], + 'security' => $sourceSchema['security'] ?? [], + 'tags' => $sourceSchema['tags'] ?? [], + 'externalDocs' => $sourceSchema['externalDocs'] ?? [], + ]); + + // Save the merged specification to a file + Writer::writeToYamlFile($mergedOpenApi, $target); + + return static::CODE_SUCCESS; + } + + /** + * @param array $array1 + * @param array $array2 + * + * @return array + */ + protected function recursiveMerge(array $array1, array $array2): array + { + foreach ($array2 as $key => $value) { + if (is_array($value) && isset($array1[$key]) && is_array($array1[$key])) { + $array1[$key] = $this->recursiveMerge($array1[$key], $value); + } else { + $array1[$key] = $value; + } + } + + return $array1; + } +} diff --git a/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Arguments/GlueResourceMethodResponseArguments.php b/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Arguments/GlueResourceMethodResponseArguments.php index 0ad5f0e..009176c 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Arguments/GlueResourceMethodResponseArguments.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Arguments/GlueResourceMethodResponseArguments.php @@ -52,7 +52,7 @@ class GlueResourceMethodResponseArguments implements ArgumentsInterface protected ?int $httpResponseCode = null; /** - * @var array + * @var array> */ protected array $extensions = []; @@ -159,7 +159,7 @@ public function getModuleName(): ?string } /** - * @param array $extensions + * @param array> $extensions * * @return void */ @@ -169,7 +169,7 @@ public function setExtensions(array $extensions): void } /** - * @return array + * @return array> */ public function getExtensions(): array { diff --git a/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Arguments/TransferArguments.php b/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Arguments/TransferArguments.php index 0c51a6e..e1d1701 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Arguments/TransferArguments.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Arguments/TransferArguments.php @@ -40,7 +40,7 @@ class TransferArguments implements ArgumentsInterface protected array $properties = []; /** - * @var array + * @var array> */ protected array $extensions = []; diff --git a/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Command/CommandRunner.php b/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Command/CommandRunner.php index 5665963..e1bfb52 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Command/CommandRunner.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Command/CommandRunner.php @@ -23,7 +23,7 @@ public function __construct(SyncApiConfig $config) } /** - * @param array $commands + * @param array> $commands * * @return void */ @@ -37,7 +37,7 @@ public function runCommands(array $commands): void /** * @codeCoverageIgnore * - * @param array $command + * @param array $command * * @return void */ diff --git a/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Command/CommandRunnerInterface.php b/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Command/CommandRunnerInterface.php index 3435ec4..62875b6 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Command/CommandRunnerInterface.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Builder/ConsoleCommand/Command/CommandRunnerInterface.php @@ -10,7 +10,7 @@ interface CommandRunnerInterface { /** - * @param array $commands + * @param array> $commands * * @return void */ diff --git a/src/SprykerSdk/SyncApi/OpenApi/Validator/Rules/OpenApiHttpMethodInPathValidatorRule.php b/src/SprykerSdk/SyncApi/OpenApi/Validator/Rules/OpenApiHttpMethodInPathValidatorRule.php index da985a7..55403c1 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Validator/Rules/OpenApiHttpMethodInPathValidatorRule.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Validator/Rules/OpenApiHttpMethodInPathValidatorRule.php @@ -15,7 +15,7 @@ class OpenApiHttpMethodInPathValidatorRule implements ValidatorRuleInterface { /** - * @var array + * @var array */ protected const HTTP_METHODS = [ 'get', diff --git a/src/SprykerSdk/SyncApi/OpenApi/Validator/Rules/OpenApiPathValidatorRule.php b/src/SprykerSdk/SyncApi/OpenApi/Validator/Rules/OpenApiPathValidatorRule.php index 2b122d2..ce7c928 100644 --- a/src/SprykerSdk/SyncApi/OpenApi/Validator/Rules/OpenApiPathValidatorRule.php +++ b/src/SprykerSdk/SyncApi/OpenApi/Validator/Rules/OpenApiPathValidatorRule.php @@ -30,10 +30,10 @@ public function __construct(MessageBuilderInterface $messageBuilder) /** * Validates the schema for existence of paths. * - * @param array $openApi + * @param array> $openApi * @param string $openApiFileName * @param \Transfer\ValidateResponseTransfer $validateResponseTransfer - * @param array|null $context + * @param array|null $context * * @return \Transfer\ValidateResponseTransfer */ @@ -47,7 +47,7 @@ public function validate( } /** - * @param array $openApi + * @param array> $openApi * @param string $openApiFileName * @param \Transfer\ValidateResponseTransfer $validateResponseTransfer * diff --git a/src/SprykerSdk/SyncApi/SyncApiFactory.php b/src/SprykerSdk/SyncApi/SyncApiFactory.php index b03303a..4e92e58 100644 --- a/src/SprykerSdk/SyncApi/SyncApiFactory.php +++ b/src/SprykerSdk/SyncApi/SyncApiFactory.php @@ -131,7 +131,7 @@ public function createOpenApiValidator(): OpenApiValidator } /** - * @return array + * @return array<\SprykerSdk\SyncApi\Validator\Rule\ValidatorRuleInterface> */ public function getValidatorRules(): array { diff --git a/src/SprykerSdk/SyncApi/Validator/AbstractValidator.php b/src/SprykerSdk/SyncApi/Validator/AbstractValidator.php index 8c6b23f..2b66f5b 100644 --- a/src/SprykerSdk/SyncApi/Validator/AbstractValidator.php +++ b/src/SprykerSdk/SyncApi/Validator/AbstractValidator.php @@ -31,7 +31,7 @@ abstract class AbstractValidator implements ValidatorInterface /** * @param \SprykerSdk\SyncApi\SyncApiConfig $config * @param \SprykerSdk\SyncApi\Message\MessageBuilderInterface $messageBuilder - * @param array $fileValidators + * @param array<\SprykerSdk\SyncApi\Validator\Rule\ValidatorRuleInterface> $fileValidators */ public function __construct(SyncApiConfig $config, MessageBuilderInterface $messageBuilder, array $fileValidators = []) { @@ -41,10 +41,10 @@ public function __construct(SyncApiConfig $config, MessageBuilderInterface $mess } /** - * @param array $fileData + * @param array $fileData * @param string $fileName * @param \Transfer\ValidateResponseTransfer $validateResponseTransfer - * @param array|null $context + * @param array|null $context * * @return \Transfer\ValidateResponseTransfer */ diff --git a/src/SprykerSdk/SyncApi/Validator/Rule/ValidatorRuleInterface.php b/src/SprykerSdk/SyncApi/Validator/Rule/ValidatorRuleInterface.php index 977c16a..cb91563 100644 --- a/src/SprykerSdk/SyncApi/Validator/Rule/ValidatorRuleInterface.php +++ b/src/SprykerSdk/SyncApi/Validator/Rule/ValidatorRuleInterface.php @@ -12,10 +12,10 @@ interface ValidatorRuleInterface { /** - * @param array $data + * @param array $data * @param string $fileName * @param \Transfer\ValidateResponseTransfer $validateResponseTransfer - * @param array|null $context + * @param array|null $context * * @return \Transfer\ValidateResponseTransfer */