-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit a6d7a36
Showing
14 changed files
with
337 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/.github export-ignore | ||
/tests export-ignore | ||
.gitignore export-ignore | ||
phpstan.neon export-ignore | ||
phpunit.xml export-ignore | ||
README.md export-ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
name: CI | ||
|
||
on: | ||
push: ~ | ||
workflow_dispatch: ~ | ||
|
||
jobs: | ||
tests: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- # Copies the repository files to the Action Runner | ||
name: Checkout Repository | ||
uses: actions/checkout@v3 | ||
|
||
- # Installs PHP and other necessary tools | ||
name: Setup PHP | ||
uses: shivammathur/[email protected] | ||
with: | ||
php-version: 8.3 | ||
|
||
- # Installs and caches PHP dependencies | ||
name: Install Dependencies | ||
uses: ramsey/[email protected] | ||
|
||
- # Validates composer.json structure and required fields | ||
name: Validate composer.json | ||
run: composer validate --ansi --strict --no-check-publish | ||
|
||
- # Runs code quality tools, like phpstan etc. | ||
name: Run Code Quality Tools | ||
run: composer analyse | ||
|
||
- # Runs unit and integration tests, like phpspec, phpunit etc. | ||
name: Run Tests | ||
run: composer test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/var/ | ||
/vendor/ | ||
/composer.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
ARG COMPOSER_VERSION | ||
ARG PHP_VERSION | ||
ARG EXTENSION_INSTALLER_VERSION | ||
|
||
FROM composer:${COMPOSER_VERSION} AS composer | ||
FROM mlocati/php-extension-installer:${EXTENSION_INSTALLER_VERSION} AS extensions | ||
|
||
FROM php:${PHP_VERSION}-cli-alpine AS php | ||
|
||
COPY --from=composer /usr/bin/composer /usr/bin/composer | ||
COPY --from=extensions /usr/bin/install-php-extensions /usr/bin/install-php-extensions | ||
|
||
RUN install-php-extensions xdebug | ||
|
||
WORKDIR /app/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
APP := @docker compose run --rm app | ||
|
||
.PHONY: | ||
ci: analyse test | ||
|
||
.PHONY: | ||
install: | ||
$(APP) composer install | ||
|
||
.PHONY: | ||
update: | ||
$(APP) composer update | ||
|
||
.PHONY: | ||
analyse: | ||
$(APP) composer analyse | ||
|
||
.PHONY: | ||
test: | ||
$(APP) composer test | ||
|
||
.PHONY: | ||
coverage: | ||
$(APP) composer coverage | ||
|
||
.PHONY: | ||
sh: | ||
$(APP) sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
{ | ||
"name": "ferror/openapi-coverage", | ||
"type": "library", | ||
"license": "MIT", | ||
"require": { | ||
"php": "^8.2", | ||
"nelmio/api-doc-bundle": "^4.12", | ||
"symfony/console": "^6.4", | ||
"symfony/dependency-injection": "^6.4", | ||
"symfony/http-kernel": "^6.4", | ||
"symfony/routing": "^6.4" | ||
}, | ||
"require-dev": { | ||
"phpstan/phpstan": "^1.10", | ||
"phpstan/phpstan-symfony": "^1.3", | ||
"phpstan/phpstan-phpunit": "^1.3", | ||
"phpunit/phpunit": "^10.5" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"Ferror\\OpenapiCoverage\\": "src/" | ||
} | ||
}, | ||
"autoload-dev": { | ||
"psr-4": { | ||
"Ferror\\OpenapiCoverage\\": "tests/" | ||
} | ||
}, | ||
"scripts": { | ||
"test": "vendor/bin/phpunit", | ||
"coverage": "vendor/bin/phpunit --coverage-html=var/coverage", | ||
"analyse": "vendor/bin/phpstan analyse" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
services: | ||
app: | ||
build: | ||
context: . | ||
target: php | ||
args: | ||
PHP_VERSION: 8.2 | ||
COMPOSER_VERSION: 2.5 | ||
EXTENSION_INSTALLER_VERSION: 2.1 | ||
command: ["composer", "install", "--no-interaction"] | ||
environment: | ||
XDEBUG_MODE: coverage | ||
# XDEBUG_MODE: debug | ||
# XDEBUG_CONFIG: "profiler_enable=on idekey=PHPSTORM client_host=host.docker.internal" | ||
volumes: | ||
- ./:/app:delegate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
includes: | ||
- vendor/phpstan/phpstan-symfony/extension.neon | ||
- vendor/phpstan/phpstan-phpunit/extension.neon | ||
- vendor/phpstan/phpstan-symfony/rules.neon | ||
- vendor/phpstan/phpstan-phpunit/rules.neon | ||
|
||
parameters: | ||
level: 6 | ||
paths: | ||
- src | ||
- tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd" | ||
bootstrap="vendor/autoload.php" | ||
cacheDirectory="var/cache/phpunit" | ||
executionOrder="random" | ||
requireCoverageMetadata="false" | ||
beStrictAboutCoverageMetadata="true" | ||
beStrictAboutOutputDuringTests="true" | ||
failOnRisky="true" | ||
failOnWarning="true" | ||
colors="true" | ||
displayDetailsOnTestsThatTriggerWarnings="true" | ||
> | ||
<testsuites> | ||
<testsuite name="all"> | ||
<directory>tests</directory> | ||
</testsuite> | ||
</testsuites> | ||
|
||
<php> | ||
<env name="KERNEL_CLASS" value="Ferror\OpenapiCoverage\Integration\Service\Kernel" /> | ||
</php> | ||
|
||
<source | ||
restrictDeprecations="true" | ||
restrictNotices="true" | ||
restrictWarnings="true" | ||
> | ||
<include> | ||
<directory>src</directory> | ||
</include> | ||
</source> | ||
</phpunit> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Ferror\OpenapiCoverage\Symfony; | ||
|
||
use Ferror\OpenapiCoverage\Symfony\Console\CheckCoverageCommand; | ||
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator; | ||
use Symfony\Component\DependencyInjection\ContainerBuilder; | ||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; | ||
use Symfony\Component\DependencyInjection\Reference; | ||
use Symfony\Component\HttpKernel\Bundle\AbstractBundle; | ||
|
||
class Bundle extends AbstractBundle | ||
{ | ||
protected string $extensionAlias = 'ferror_openapi_coverage'; | ||
|
||
public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void | ||
{ | ||
$builder | ||
->register('ferror.openapi_coverage.console', CheckCoverageCommand::class) | ||
->addArgument(new Reference('router')) | ||
->addArgument(new Reference('nelmio_api_doc.render_docs')) | ||
->addTag('console.command') | ||
; | ||
} | ||
|
||
public function configure(DefinitionConfigurator $definition): void | ||
{ | ||
$definition->rootNode() | ||
->children() | ||
->arrayNode('excluded_routes') | ||
->scalarPrototype()->end() | ||
->end() | ||
->end() | ||
; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Ferror\OpenapiCoverage\Symfony\Console; | ||
|
||
use Nelmio\ApiDocBundle\Render\RenderOpenApi; | ||
use Symfony\Component\Console\Command\Command; | ||
use Symfony\Component\Console\Input\InputArgument; | ||
use Symfony\Component\Console\Input\InputInterface; | ||
use Symfony\Component\Console\Output\OutputInterface; | ||
use Symfony\Component\Routing\Route; | ||
use Symfony\Component\Routing\RouterInterface; | ||
|
||
class CheckCoverageCommand extends Command | ||
{ | ||
protected static $defaultName = 'ferror:check-openapi-coverage'; | ||
|
||
public function __construct( | ||
private RouterInterface $router, | ||
private RenderOpenApi $renderOpenApi, | ||
private array $excludedPaths = [], | ||
) { | ||
parent::__construct(); | ||
} | ||
|
||
protected function configure(): void | ||
{ | ||
$this | ||
->setDescription('Check OpenAPI coverage against Symfony routes') | ||
->addArgument('openapi-schema', InputArgument::OPTIONAL, 'Path to OpenAPI schema YAML file') | ||
; | ||
} | ||
|
||
public function execute(InputInterface $input, OutputInterface $output): int | ||
{ | ||
$symfonyPaths = $this->router->getRouteCollection(); | ||
$symfonyPaths = array_map(fn (Route $route) => $route->getPath(), $symfonyPaths->all()); | ||
$symfonyPaths = array_values($symfonyPaths); | ||
$symfonyPaths = array_filter($symfonyPaths, fn (string $route) => str_starts_with($route, '/risk/v1')); | ||
$symfonyPaths = array_map(fn (string $route) => str_replace('/risk/v1', '', $route), $symfonyPaths); | ||
$symfonyPaths = array_filter($symfonyPaths, fn(string $route) => !in_array($route, $this->excludedPaths, true)); | ||
|
||
$openApi = $this->renderOpenApi->render('json', 'default'); | ||
$openApi = json_decode($openApi, true, 512, JSON_THROW_ON_ERROR); | ||
|
||
$openApiPaths = array_keys($openApi['paths']); | ||
|
||
$missingPaths = array_diff($symfonyPaths, $openApiPaths); | ||
|
||
$missingPathCoverage = count($openApiPaths) / count($symfonyPaths); | ||
$output->writeln('Open API coverage: ' . round($missingPathCoverage * 100, 2) . '%'); | ||
|
||
if (empty($missingPaths)) { | ||
$output->writeln('OpenAPI schema covers all Symfony routes. Good job!'); | ||
} else { | ||
$output->writeln('Missing paths in OpenAPI schema:'); | ||
foreach ($missingPaths as $path) { | ||
$output->writeln("- $path"); | ||
} | ||
} | ||
|
||
return Command::SUCCESS; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Ferror\OpenapiCoverage\Integration; | ||
|
||
use Symfony\Bundle\FrameworkBundle\Console\Application; | ||
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; | ||
use Symfony\Component\Console\Tester\CommandTester; | ||
|
||
class CheckCoverageCommandTest extends KernelTestCase | ||
{ | ||
public function testExecuteClass(): void | ||
{ | ||
$kernel = self::bootKernel(); | ||
$application = new Application($kernel); | ||
|
||
$command = $application->find('ferror:check-openapi-coverage'); | ||
$commandTester = new CommandTester($command); | ||
$commandTester->execute([]); | ||
|
||
$commandTester->assertCommandIsSuccessful(); | ||
|
||
$display = $commandTester->getDisplay(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Ferror\OpenapiCoverage\Integration\Service; | ||
|
||
use Ferror\OpenapiCoverage\Symfony\Bundle; | ||
use Symfony\Component\Config\Loader\LoaderInterface; | ||
use Symfony\Component\HttpKernel\Kernel as SymfonyKernel; | ||
|
||
class Kernel extends SymfonyKernel | ||
{ | ||
public function registerBundles(): iterable | ||
{ | ||
yield new Bundle(); | ||
} | ||
|
||
public function registerContainerConfiguration(LoaderInterface $loader): void | ||
{ | ||
$loader->load(__DIR__ . '/config/library.yaml'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
ferror_openapi_coverage: | ||
excluded_routes: | ||
- rest-docs.json |