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

[v5] #1549

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open

[v5] #1549

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
19 changes: 1 addition & 18 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,8 @@ jobs:
fail-fast: true
matrix:
operating-system: [ ubuntu-latest ]
php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
dependencies: [ 'lowest', 'highest' ]
exclude:
- php: '8.1'
dependencies: 'lowest'
- php: '8.2'
dependencies: 'lowest'
- php: '8.3'
dependencies: 'lowest'
- php: '8.4'
dependencies: 'lowest'
include:
- php: '8.2'
composer-options: "--ignore-platform-req=php+"

name: PHP ${{ matrix.php }} on ${{ matrix.operating-system }} with ${{ matrix.dependencies }} dependencies

Expand All @@ -50,8 +38,3 @@ jobs:

- name: PHPUnit Tests
run: bin/phpunit --configuration phpunit.xml.dist --coverage-text

- name: PHPUnit Legacy Tests
run: bin/phpunit --configuration phpunit.xml.dist --coverage-text
env:
PHPUNIT_ANALYSER: 'legacy'
2 changes: 1 addition & 1 deletion .github/workflows/security-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
fail-fast: true
matrix:
operating-system: [ ubuntu-latest ]
php: [ '7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3' ]
php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4' ]
dependencies: [ 'highest' ]

name: PHP ${{ matrix.php }} on ${{ matrix.operating-system }} with ${{ matrix.dependencies }} dependencies
Expand Down
13 changes: 10 additions & 3 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,15 @@
$finder = PhpCsFixer\Finder::create()
->path('src')->name('*.php')
->path('tests')->name('*.php')
// ContextTest::testFullyQualifiedName relies on the 'use Exception' statement...
->filter(function (\SplFileInfo $file) {
return !strpos($file->getPathname(), 'tests/Fixtures/Customer.php');
return
// ContextTest::testFullyQualifiedName relies on the 'use Exception' statement...
!strpos($file->getPathname(), 'tests/Fixtures/Customer.php')
// multi arg use; 'use a, b;`
&& !strpos($file->getPathname(), 'tests/Fixtures/Parser/HelloTrait.php')
// FQDN in docblock
&& !strpos($file->getPathname(), 'tests/Fixtures/TypedProperties.php')
;
})
->path('Examples')->name('*.php')
->filter(function (\SplFileInfo $file) {
Expand All @@ -24,10 +30,11 @@
(new ScopedDeclareStrictTypesFixer())->scope(['/src/', '/tests/']),
])
->setRules([
'@PSR2' => true,
'@PSR12' => true,
'@DoctrineAnnotation' => true,
'OpenApi/license' => true,
'OpenApi/declare_strict_types' => true,
'blank_line_after_opening_tag' => false,
'array_syntax' => ['syntax' => 'short'],
'no_unused_imports' => true,
'blank_line_before_statement' => ['statements' => ['return']],
Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# swagger-php

Generate interactive [OpenAPI](https://www.openapis.org) documentation for your RESTful API using [PHP attributes](https://www.php.net/manual/en/language.attributes.overview.php) (preferred) or
Generate interactive [OpenAPI](https://www.openapis.org) documentation for your RESTful API using [PHP attributes](https://www.php.net/manual/en/language.attributes.overview.php) (preferred) or
[doctrine annotations](https://www.doctrine-project.org/projects/annotations.html) (requires additional `doctrine/annotations` library).

See the [documentation website](https://zircote.github.io/swagger-php/guide/attributes.html) for supported attributes and annotations.
Expand Down Expand Up @@ -98,9 +98,6 @@ The `openapi` command line interface can be used to generate the documentation t
```shell
./vendor/bin/openapi --help
```
Starting with version 4 the default analyser used on the command line is the new `ReflectionAnalyser`.

Using the `--legacy` flag (`-l`) the legacy `TokenAnalyser` can still be used.

### Usage from the Deserializer

Expand Down
8 changes: 1 addition & 7 deletions bin/openapi
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
use OpenApi\Analysers\AttributeAnnotationFactory;
use OpenApi\Analysers\DocBlockAnnotationFactory;
use OpenApi\Analysers\ReflectionAnalyser;
use OpenApi\Analysers\TokenAnalyser;
use OpenApi\Annotations\OpenApi;
use OpenApi\Generator;
use OpenApi\Util;
Expand All @@ -23,7 +22,6 @@ error_reporting(E_ALL);
// Possible options and their default values.
$options = [
'config' => [],
'legacy' => false,
'output' => false,
'format' => 'auto',
'exclude' => [],
Expand All @@ -36,7 +34,6 @@ $options = [
];
$aliases = [
'c' => 'config',
'l' => 'legacy',
'o' => 'output',
'e' => 'exclude',
'n' => 'pattern',
Expand Down Expand Up @@ -132,7 +129,6 @@ Usage: openapi [--option value] [/path/to/project ...]
Options:
--config (-c) Generator config
ex: -c operationId.hash=false
--legacy (-l) Use legacy TokenAnalyser; default is the new ReflectionAnalyser
--output (-o) Path to store the generated documentation.
ex: --output openapi.yaml
--exclude (-e) Exclude path(s).
Expand Down Expand Up @@ -222,9 +218,7 @@ foreach ($options["processor"] as $processor) {
$generator->getProcessorPipeline()->add($processor);
}

$analyser = $options['legacy']
? new TokenAnalyser()
: new ReflectionAnalyser([new DocBlockAnnotationFactory(), new AttributeAnnotationFactory()]);
$analyser = new ReflectionAnalyser([new DocBlockAnnotationFactory(), new AttributeAnnotationFactory()]);

$openapi = $generator
->setVersion($options['version'])
Expand Down
36 changes: 18 additions & 18 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,17 @@
"minimum-stability": "stable",
"extra": {
"branch-alias": {
"dev-master": "4.x-dev"
"dev-master": "5.x-dev"
}
},
"require": {
"php": ">=7.2",
"php": ">=7.4",
"ext-json": "*",
"nikic/php-parser": "^4.19",
"psr/log": "^1.1 || ^2.0 || ^3.0",
"symfony/deprecation-contracts": "^2 || ^3",
"symfony/finder": ">=2.2",
"symfony/yaml": ">=3.3"
"symfony/finder": "^5.0 || ^6.0 || ^7.0",
"symfony/yaml": "^5.0 || ^6.0 || ^7.0"
},
"autoload": {
"psr-4": {
Expand All @@ -58,17 +59,18 @@
},
"require-dev": {
"composer/package-versions-deprecated": "^1.11",
"doctrine/annotations": "^1.7 || ^2.0",
"friendsofphp/php-cs-fixer": "^2.17 || 3.62.0",
"doctrine/annotations": "^2.0",
"friendsofphp/php-cs-fixer": "^3.62.0",
"phpstan/phpstan": "^1.6",
"phpunit/phpunit": ">=8",
"vimeo/psalm": "^4.23"
"phpunit/phpunit": "^9.0",
"rector/rector": "^1.0",
"vimeo/psalm": "^4.30"
},
"conflict": {
"symfony/process": ">=6, <6.4.14"
},
"suggest": {
"doctrine/annotations": "^1.7 || ^2.0"
"doctrine/annotations": "^2.0"
},
"autoload-dev": {
"exclude-from-classmap": [
Expand All @@ -82,10 +84,9 @@
},
"scripts-descriptions": {
"cs": "Fix all codestyle issues",
"rector": "Automatic refactoring",
"lint": "Test codestyle",
"test": "Run all non-legacy and codestyle tests",
"testlegacy": "Run tests using the legacy TokenAnalyser",
"testall": "Run all tests (test + testlegacy)",
"test": "Run all PHP, codestyle and rector tests",
"analyse": "Run static analysis (phpstan/psalm)",
"spectral-examples": "Run spectral lint over all .yaml files in the Examples folder",
"spectral-scratch": "Run spectral lint over all .yaml files in the tests/Fixtures/Scratch folder",
Expand All @@ -96,16 +97,15 @@
},
"scripts": {
"cs": "export XDEBUG_MODE=off && php-cs-fixer fix --allow-risky=yes",
"lint": "@cs --dry-run",
"rector": "rector process src",
"lint": [
"@cs --dry-run",
"@rector --dry-run"
],
"test": [
"export XDEBUG_MODE=off && phpunit",
"@lint"
],
"testlegacy": "export XDEBUG_MODE=off && export PHPUNIT_ANALYSER=legacy && phpunit",
"testall": [
"@test",
"@testlegacy"
],
"analyse": [
"export XDEBUG_MODE=off && phpstan analyse --memory-limit=2G",
"export XDEBUG_MODE=off && psalm"
Expand Down
1 change: 1 addition & 0 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function getGuideSidebar() {
{
text: 'Upgrading',
children: [
{ text: 'Migration from 4.x to 5.x', link: '/guide/migrating-to-v5' },
{ text: 'Migration from 3.x to 4.x', link: '/guide/migrating-to-v4' },
{ text: 'Migration from 2.x to 3.x', link: '/guide/migrating-to-v3' },
]
Expand Down
1 change: 0 additions & 1 deletion docs/guide/generating-openapi-documents.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ Usage: openapi [--option value] [/path/to/project ...]
Options:
--config (-c) Generator config
ex: -c operationId.hash=false
--legacy (-l) Use legacy TokenAnalyser; default is the new ReflectionAnalyser
--output (-o) Path to store the generated documentation.
ex: --output openapi.yaml
--exclude (-e) Exclude path(s).
Expand Down
15 changes: 15 additions & 0 deletions docs/guide/migrating-to-v5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Migrating to v5

## Overview

v5 is mostly a cleanup release with updated dependencies. The main changes are:

* Minimum required PHP version is now 7.4
* The legacy `TokenAnalyser` and the `--legacy` CLI option have been removed
* Defaults now prefer attributes over annotations
* PHP parsing now uses `nicic/php-parser`
* Removal of deprecated features
* empty/unused `ProcessorInterface`
* `Context::clone()` and `Context::detect()`

For most installations upgrading should not require any changes.
5 changes: 3 additions & 2 deletions docs/guide/under-the-hood.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- The `Generator` iterates over the given sources (Symfony `Finder`, file/directory list, etc)
- The configured analyser (`AnalyserInterface`) reads the files and builds an `Analysis` object.
Default (as of v4) is the `ReflectionAnalyser`. Alternatively, there is the `TokenAnalyser` which was the default in v3.
- The legacy `TokenAnalyser` was removed in v5.
- The `Analysis` object and its annotations are then processed by the configured processors.
- If enabled, the analysis/annotations are validated.
- The root `OpenApi` annotation then contains all annotations and is serialized into YAML/JSON.
Expand All @@ -16,7 +17,7 @@ about the PHP context where the annotation was found.

Typically, there will be a processor that uses the data to augment/enrich the annotation.

**Examples of the data collected:**
**Examples of the data collected:**
- class/interface/trait/enum names
- property names
- doctype or native type hints
Expand All @@ -35,7 +36,7 @@ This documentation is generated with [VitePress](https://vitepress.vuejs.org/)
### Installation
```shell
cd docs
npm install vitepress
npm install vitepress
```

### Workflow
Expand Down
8 changes: 6 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ features:

### 2. Update your code

Add `swagger-php` attributes or annotations to your source code.
Add `swagger-php` attributes (or legacy annotations) to your source code.

⚠️ `doctrine/annotations` is going to be deprecated in the future, so wherever
possible attributes should be used.

<codeblock id="minimal">
<template v-slot:at>
Expand Down Expand Up @@ -53,4 +56,5 @@ Use an OpenAPI tool like [Swagger UI ](https://swagger.io/tools/swagger-ui/) to
- [OpenApi Specification](https://spec.openapis.org/oas/v3.1.0.html)
- [Learn by example](https://github.com/zircote/swagger-php/tree/master/Examples)
- [Related projects](related-projects.md)
- [Swagger-php 2.x documentation](https://github.com/zircote/swagger-php/tree/2.x/docs)
- [swagger-php 2.x documentation](https://github.com/zircote/swagger-php/tree/2.x/docs)
- [swagger-php 3.x documentation](https://github.com/zircote/swagger-php/tree/3.x/docs)
7 changes: 1 addition & 6 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ parameters:
path: Examples/using-links-php81/User.php

-
message: "#^Strict comparison using \\=\\=\\= between array\\|string and false will always evaluate to false\\.$#"
message: "#^Call to function array_key_exists\\(\\) with string and array\\{\\} will always evaluate to false\\.$#"
count: 1
path: src/Analysers/TokenScanner.php

Expand Down Expand Up @@ -50,11 +50,6 @@ parameters:
count: 1
path: src/Annotations/Schema.php

-
message: "#^If condition is always true\\.$#"
count: 1
path: src/Generator.php

-
message: "#^Result of && is always false\\.$#"
count: 3
Expand Down
31 changes: 31 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

use Rector\CodeQuality\Rector\ClassMethod\ExplicitReturnNullRector;
use Rector\CodeQuality\Rector\For_\ForRepeatedCountToOwnVariableRector;
use Rector\CodeQuality\Rector\If_\CombineIfRector;
use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
use Rector\CodeQuality\Rector\If_\ShortenElseIfRector;
use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\If_\RemoveAlwaysTrueIfConditionRector;
use Rector\DeadCode\Rector\If_\RemoveDeadInstanceOfRector;
use Rector\TypeDeclaration\Rector\Property\TypedPropertyFromStrictConstructorRector;
use Rector\ValueObject\PhpVersion;

return RectorConfig::configure()
->withRules([
TypedPropertyFromStrictConstructorRector::class
])
->withSkip([
CombineIfRector::class,
ExplicitBoolCompareRector::class,
ForRepeatedCountToOwnVariableRector::class,
RemoveAlwaysTrueIfConditionRector::class => [
__DIR__ . '/src/Processors/ExpandEnums.php',
] ,
RemoveDeadInstanceOfRector::class => [
__DIR__ . '/src/Processors/ExpandEnums.php',
],
ShortenElseIfRector::class,
])
->withPreparedSets(true, true)
->withPhpVersion(PhpVersion::PHP_74);
14 changes: 3 additions & 11 deletions src/Analysers/AttributeAnnotationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,13 @@

class AttributeAnnotationFactory implements AnnotationFactoryInterface
{
/** @var Generator|null */
protected $generator;
use GeneratorAwareTrait;

public function isSupported(): bool
{
return \PHP_VERSION_ID >= 80100;
}

public function setGenerator(Generator $generator): void
{
$this->generator = $generator;
}

public function build(\Reflector $reflector, Context $context): array
{
if (!$this->isSupported() || !method_exists($reflector, 'getAttributes')) {
Expand Down Expand Up @@ -116,9 +110,7 @@ public function build(\Reflector $reflector, Context $context): array
Generator::$context = null;
}

$annotations = array_values(array_filter($annotations, function ($a) {
return $a instanceof OA\AbstractAnnotation;
}));
$annotations = array_values(array_filter($annotations, fn ($a) => $a instanceof OA\AbstractAnnotation));

// merge backwards into parents...
$isParent = function (OA\AbstractAnnotation $annotation, OA\AbstractAnnotation $possibleParent): bool {
Expand All @@ -141,7 +133,7 @@ public function build(\Reflector $reflector, Context $context): array

// Attachables can always be nested (unless explicitly restricted)
return ($isAttachable && $isParentAllowed)
|| ($annotation->getRoot() != $possibleParent->getRoot() && $explicitParent);
|| ($annotation->getRoot() !== $possibleParent->getRoot() && $explicitParent);
};

$annotationsWithoutParent = [];
Expand Down
6 changes: 2 additions & 4 deletions src/Analysers/DocBlockAnnotationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@

class DocBlockAnnotationFactory implements AnnotationFactoryInterface
{
/** @var DocBlockParser|null */
protected $docBlockParser = null;
use GeneratorAwareTrait;

/** @var Generator|null */
protected $generator = null;
protected ?DocBlockParser $docBlockParser = null;

public function __construct(?DocBlockParser $docBlockParser = null)
{
Expand Down
Loading
Loading