diff --git a/.php_cs.php b/.php_cs.php index 589c022..b1f7da4 100644 --- a/.php_cs.php +++ b/.php_cs.php @@ -12,6 +12,7 @@ '@PSR2' => true, 'array_syntax' => ['syntax' => 'short'], 'no_multiline_whitespace_before_semicolons' => true, + 'no_blank_lines_after_class_opening' => true, 'no_short_echo_tag' => true, 'no_unused_imports' => true, 'blank_line_after_opening_tag' => true, diff --git a/CHANGELOG.md b/CHANGELOG.md index d09f870..9e585e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [7.2.2] - 2021-10-15 +### Fixed +- ext- in generated clients composer.json is added according to what is actually being used + +## [7.2.1] - 2021-10-07 +### Fixed +- Changed default php-cs-fixer configuration to remove blank lines after class opening, according to PSR12 (`no_blank_lines_after_class_opening`) + ## [7.2.0] - 2021-09-24 ### Removed - Remove virtual package dependency (psr/http-client-implementation) ## [7.1.1] - 2021-09-09 ### Fixed -- Changed default php-cs-fixer configuration to add blank line after opening tag, according to PSR12 +- Changed default php-cs-fixer configuration to add blank line after opening tag, according to PSR12 (`blank_line_after_opening_tag`) ## [7.1.0] - 2021-08-30 ### Added diff --git a/composer.json b/composer.json index d15ea63..427985a 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,7 @@ "twig/twig": "^3.0" }, "require-dev": { - "composer/composer": "^2.0", + "composer/composer": "^2.1", "php-coveralls/php-coveralls": "^2.2", "phpstan/phpstan": "^0.12.32", "phpunit/phpunit": "^9.2", diff --git a/composer.lock b/composer.lock index c8b8001..31e45be 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "dc7d581b88bef789d27072d1c5a5b610", + "content-hash": "5dedb53342561c5f84834e8b1292f8ff", "packages": [ { "name": "cebe/php-openapi", @@ -155,21 +155,21 @@ }, { "name": "composer/xdebug-handler", - "version": "1.4.6", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "f27e06cd9675801df441b3656569b328e04aa37c" + "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f27e06cd9675801df441b3656569b328e04aa37c", - "reference": "f27e06cd9675801df441b3656569b328e04aa37c", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/84674dd3a7575ba617f5a76d7e9e29a7d3891339", + "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0", - "psr/log": "^1.0" + "psr/log": "^1 || ^2 || ^3" }, "require-dev": { "phpstan/phpstan": "^0.12.55", @@ -199,7 +199,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/1.4.6" + "source": "https://github.com/composer/xdebug-handler/tree/2.0.2" }, "funding": [ { @@ -215,7 +215,7 @@ "type": "tidelift" } ], - "time": "2021-03-25T17:01:18+00:00" + "time": "2021-07-31T17:03:58+00:00" }, { "name": "docler-labs/api-client-exception", @@ -421,21 +421,21 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v2.18.0", + "version": "v2.18.6", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "cbc5b50bfa2688a1afca20e5a8c71f058e9ccbef" + "reference": "5fed214993e7863cef88a08f214344891299b9e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/cbc5b50bfa2688a1afca20e5a8c71f058e9ccbef", - "reference": "cbc5b50bfa2688a1afca20e5a8c71f058e9ccbef", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/5fed214993e7863cef88a08f214344891299b9e4", + "reference": "5fed214993e7863cef88a08f214344891299b9e4", "shasum": "" }, "require": { "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^1.2", + "composer/xdebug-handler": "^1.2 || ^2.0", "doctrine/annotations": "^1.2", "ext-json": "*", "ext-tokenizer": "*", @@ -492,6 +492,7 @@ "tests/Test/IntegrationCaseFactoryInterface.php", "tests/Test/InternalIntegrationCaseFactory.php", "tests/Test/IsIdenticalConstraint.php", + "tests/Test/TokensWithObservedTransformers.php", "tests/TestCase.php" ] }, @@ -512,7 +513,7 @@ "description": "A tool to automatically fix PHP code style", "support": { "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.18.0" + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.18.6" }, "funding": [ { @@ -520,7 +521,7 @@ "type": "github" } ], - "time": "2021-01-18T03:31:06+00:00" + "time": "2021-04-19T19:45:11+00:00" }, { "name": "guzzlehttp/psr7", @@ -712,16 +713,16 @@ }, { "name": "justinrainbow/json-schema", - "version": "5.2.10", + "version": "5.2.11", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" + "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", - "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ab6744b7296ded80f8cc4f9509abbff393399aa", + "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa", "shasum": "" }, "require": { @@ -776,9 +777,9 @@ ], "support": { "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/5.2.10" + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.11" }, - "time": "2020-05-27T16:41:55+00:00" + "time": "2021-07-22T09:24:00+00:00" }, { "name": "nikic/php-parser", @@ -3094,16 +3095,16 @@ }, { "name": "composer/composer", - "version": "2.0.13", + "version": "2.1.9", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "986e8b86b7b570632ad0a905c3726c33dd4c0efb" + "reference": "e558c88f28d102d497adec4852802c0dc14c7077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/986e8b86b7b570632ad0a905c3726c33dd4c0efb", - "reference": "986e8b86b7b570632ad0a905c3726c33dd4c0efb", + "url": "https://api.github.com/repos/composer/composer/zipball/e558c88f28d102d497adec4852802c0dc14c7077", + "reference": "e558c88f28d102d497adec4852802c0dc14c7077", "shasum": "" }, "require": { @@ -3111,21 +3112,21 @@ "composer/metadata-minifier": "^1.0", "composer/semver": "^3.0", "composer/spdx-licenses": "^1.2", - "composer/xdebug-handler": "^1.1", - "justinrainbow/json-schema": "^5.2.10", + "composer/xdebug-handler": "^2.0", + "justinrainbow/json-schema": "^5.2.11", "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1.0", "react/promise": "^1.2 || ^2.7", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.0", - "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0", - "symfony/filesystem": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0", - "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0", - "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0" + "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", + "symfony/filesystem": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", + "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", + "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0" }, "require-dev": { "phpspec/prophecy": "^1.10", - "symfony/phpunit-bridge": "^4.2 || ^5.0" + "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", @@ -3138,7 +3139,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -3170,9 +3171,9 @@ "package" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.0.13" + "source": "https://github.com/composer/composer/tree/2.1.9" }, "funding": [ { @@ -3188,7 +3189,7 @@ "type": "tidelift" } ], - "time": "2021-04-27T11:11:08+00:00" + "time": "2021-10-05T07:47:38+00:00" }, { "name": "composer/metadata-minifier", diff --git a/example/gen/composer.json b/example/gen/composer.json index ab77f42..5adeca7 100644 --- a/example/gen/composer.json +++ b/example/gen/composer.json @@ -11,7 +11,8 @@ "require": { "php": ">=7.4", "docler-labs/api-client-exception": "^1.0", - "ext-intl": "*", + "ext-dom": "*", + "ext-json": "*", "guzzlehttp/psr7": "^1.6", "pimple/pimple": "^3.3", "psr/container": "^1.0", diff --git a/src/Input/Specification.php b/src/Input/Specification.php index 51eb1ef..9d04b88 100644 --- a/src/Input/Specification.php +++ b/src/Input/Specification.php @@ -5,6 +5,10 @@ namespace DoclerLabs\ApiClientGenerator\Input; use cebe\openapi\spec\OpenApi; +use DoclerLabs\ApiClientGenerator\Entity\Constraint\ConstraintInterface; +use DoclerLabs\ApiClientGenerator\Entity\Constraint\MaxLengthConstraint; +use DoclerLabs\ApiClientGenerator\Entity\Constraint\MinLengthConstraint; +use DoclerLabs\ApiClientGenerator\Entity\Field; use DoclerLabs\ApiClientGenerator\Entity\FieldCollection; use DoclerLabs\ApiClientGenerator\Entity\Operation; use DoclerLabs\ApiClientGenerator\Entity\OperationCollection; @@ -100,4 +104,50 @@ public function getAllContentTypes(): array return array_keys(array_filter($allContentTypes)); } + + public function requiresIntlExtension(): bool + { + /** @var Operation $operation */ + foreach ($this->getOperations() as $operation) { + foreach ($operation->getRequest()->getFields() as $fields) { + /** @var Field $field */ + foreach ($fields as $field) { + if ($this->fieldRequiresIntlExtension($field)) { + return true; + } + } + } + } + + return false; + } + + private function fieldRequiresIntlExtension(Field $field): bool + { + /** @var ConstraintInterface $constraint */ + foreach ($field->getConstraints() as $constraint) { + if ( + ( + $constraint instanceof MinLengthConstraint + || $constraint instanceof MaxLengthConstraint + ) + && $constraint->exists() + ) { + return true; + } + } + + if ( + $field->isObject() + && !empty($field->getObjectProperties()) + ) { + foreach ($field->getObjectProperties() as $field) { + if ($this->fieldRequiresIntlExtension($field)) { + return true; + } + } + } + + return false; + } } diff --git a/src/Meta/ComposerJsonTemplate.php b/src/Meta/ComposerJsonTemplate.php index 9d2ac97..0a84761 100644 --- a/src/Meta/ComposerJsonTemplate.php +++ b/src/Meta/ComposerJsonTemplate.php @@ -8,6 +8,8 @@ use DoclerLabs\ApiClientGenerator\Generator\Implementation\HttpMessageImplementationStrategy; use DoclerLabs\ApiClientGenerator\Input\Configuration; use DoclerLabs\ApiClientGenerator\Input\Specification; +use DoclerLabs\ApiClientGenerator\Output\Copy\Serializer\ContentType\JsonContentTypeSerializer; +use DoclerLabs\ApiClientGenerator\Output\Copy\Serializer\ContentType\XmlContentTypeSerializer; use DoclerLabs\ApiClientGenerator\Output\Meta\MetaFile; use DoclerLabs\ApiClientGenerator\Output\Meta\MetaFileCollection; use Twig\Environment; @@ -40,6 +42,7 @@ public function render(Specification $specification, MetaFileCollection $fileReg { $packages = array_merge( $this->getCommonPackages(), + $this->getPackagesForSpecification($specification), $this->messageImplementation->getPackages(), $this->containerImplementation->getPackages() ); @@ -63,9 +66,27 @@ private function getCommonPackages(): array { return [ 'docler-labs/api-client-exception' => '^1.0', - 'ext-intl' => '*', 'psr/container' => '^1.0', 'psr/http-client' => '^1.0', ]; } + + private function getPackagesForSpecification(Specification $specification): array + { + $packages = []; + + if ($specification->requiresIntlExtension()) { + $packages['ext-intl'] = '*'; + } + + if (in_array(JsonContentTypeSerializer::MIME_TYPE, $specification->getAllContentTypes(), true)) { + $packages['ext-json'] = '*'; + } + + if (in_array(XmlContentTypeSerializer::MIME_TYPE, $specification->getAllContentTypes(), true)) { + $packages['ext-dom'] = '*'; + } + + return $packages; + } } diff --git a/test/suite/functional/Input/SpecificationTest.php b/test/suite/functional/Input/SpecificationTest.php index 7936beb..478be1d 100644 --- a/test/suite/functional/Input/SpecificationTest.php +++ b/test/suite/functional/Input/SpecificationTest.php @@ -22,7 +22,8 @@ class SpecificationTest extends TestCase public function testAllContentTypesArrayPopulatedCorrectly(array $data, array $expectedResult): void { $specification = $this->sut->parse($data, '/openapi.yaml'); - static::assertSame($specification->getAllContentTypes(), $expectedResult); + + static::assertSame($expectedResult, $specification->getAllContentTypes()); } public function contentTypesTestProvider(): array diff --git a/test/suite/functional/Meta/ComposerJson/composer_default.json b/test/suite/functional/Meta/ComposerJson/composer_default.json index da314e3..1937338 100644 --- a/test/suite/functional/Meta/ComposerJson/composer_default.json +++ b/test/suite/functional/Meta/ComposerJson/composer_default.json @@ -10,7 +10,7 @@ "require": { "php": ">=7.4", "docler-labs/api-client-exception": "^1.0", - "ext-intl": "*", + "ext-json": "*", "guzzlehttp/psr7": "^1.6", "pimple/pimple": "^3.3", "psr/container": "^1.0", diff --git a/test/suite/functional/Meta/ComposerJson/composer_guzzle_message.json b/test/suite/functional/Meta/ComposerJson/composer_guzzle_message.json index da314e3..1937338 100644 --- a/test/suite/functional/Meta/ComposerJson/composer_guzzle_message.json +++ b/test/suite/functional/Meta/ComposerJson/composer_guzzle_message.json @@ -10,7 +10,7 @@ "require": { "php": ">=7.4", "docler-labs/api-client-exception": "^1.0", - "ext-intl": "*", + "ext-json": "*", "guzzlehttp/psr7": "^1.6", "pimple/pimple": "^3.3", "psr/container": "^1.0", diff --git a/test/suite/functional/Meta/ComposerJson/composer_nyholm_message.json b/test/suite/functional/Meta/ComposerJson/composer_nyholm_message.json index 49ed187..98d04ba 100644 --- a/test/suite/functional/Meta/ComposerJson/composer_nyholm_message.json +++ b/test/suite/functional/Meta/ComposerJson/composer_nyholm_message.json @@ -10,7 +10,7 @@ "require": { "php": ">=7.4", "docler-labs/api-client-exception": "^1.0", - "ext-intl": "*", + "ext-json": "*", "nyholm/psr7": "^1.3", "pimple/pimple": "^3.3", "psr/container": "^1.0", diff --git a/test/suite/functional/Meta/ComposerJson/composer_with_intl_requirement.json b/test/suite/functional/Meta/ComposerJson/composer_with_intl_requirement.json new file mode 100644 index 0000000..dbc5d61 --- /dev/null +++ b/test/suite/functional/Meta/ComposerJson/composer_with_intl_requirement.json @@ -0,0 +1,29 @@ +{ + "name": "test/test-api-client", + "description": "Client library for Swagger Petstore", + "keywords": [ + "api-client" + ], + "config": { + "sort-packages": true + }, + "require": { + "php": ">=7.4", + "docler-labs/api-client-exception": "^1.0", + "ext-intl": "*", + "ext-json": "*", + "guzzlehttp/psr7": "^1.6", + "pimple/pimple": "^3.3", + "psr/container": "^1.0", + "psr/http-client": "^1.0" + }, + "autoload": { + "psr-4": { + "Test\\": "src/" + } + }, + "suggest": { + "guzzlehttp/guzzle": "PSR-18 provided by Guzzle 7", + "php-http/guzzle6-adapter": "PSR-18 wrapper for Guzzle 6" + } +} diff --git a/test/suite/functional/Meta/ComposerJson/petstore_with_intl_requirement.yaml b/test/suite/functional/Meta/ComposerJson/petstore_with_intl_requirement.yaml new file mode 100644 index 0000000..13608ce --- /dev/null +++ b/test/suite/functional/Meta/ComposerJson/petstore_with_intl_requirement.yaml @@ -0,0 +1,66 @@ +openapi: "3.0.0" +info: + version: 1.0.0 + title: Swagger Petstore + description: A sample API that uses a petstore as an example to demonstrate features in the OpenAPI 3.0 specification +servers: + - url: http://petstore.swagger.io/api +paths: + /pets: + post: + operationId: addPet + requestBody: + description: Pet to add to the store + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/NewPet' + responses: + '200': + description: pet response + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + default: + description: unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' +components: + schemas: + Pet: + allOf: + - $ref: '#/components/schemas/NewPet' + - type: object + required: + - id + properties: + id: + type: integer + format: int64 + + NewPet: + type: object + required: + - name + properties: + name: + type: string + maxLength: 50 + tag: + type: string + + Error: + type: object + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/test/suite/functional/Meta/ComposerJsonTemplateTest.php b/test/suite/functional/Meta/ComposerJsonTemplateTest.php index 2fda07a..0b0d778 100644 --- a/test/suite/functional/Meta/ComposerJsonTemplateTest.php +++ b/test/suite/functional/Meta/ComposerJsonTemplateTest.php @@ -30,6 +30,12 @@ public function exampleProvider(): array 'composer.json', ConfigurationBuilder::fake()->build(), ], + 'composer.json with intl' => [ + '/ComposerJson/petstore_with_intl_requirement.yaml', + '/ComposerJson/composer_with_intl_requirement.json', + 'composer.json', + ConfigurationBuilder::fake()->build(), + ], 'Guzzle message composer.json' => [ '/ComposerJson/petstore.yaml', '/ComposerJson/composer_guzzle_message.json',