Skip to content
Open
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
118 changes: 65 additions & 53 deletions .github/workflows/analysis.yaml
Original file line number Diff line number Diff line change
@@ -1,58 +1,70 @@
name: Code Analysis

on:
pull_request: ~
push:
branches:
- main
pull_request: ~
push:
branches:
- main

jobs:
code-validation:
name: ${{ matrix.actions.name }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
actions:
- name: Composer validate
run: composer validate --ansi --strict

- name: Static analysis
run: composer phpstan

- name: Style check
run: composer check-cs

- name: Unit tests
run: composer coverage
steps:
- uses: actions/checkout@v2

- uses: shivammathur/setup-php@v2
with:
php-version: 8.2
coverage: pcov
tools: composer:v2
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Install dependencies
uses: "ramsey/composer-install@v2"

- run: ${{ matrix.actions.run }}

- name: Coverage diff
uses: OpenClassrooms/[email protected]
if: ${{ hashFiles('build/coverage/coverage.xml') != '' && github.event_name == 'pull_request' }}
with:
action: check
files: '[{"coverage": "build/coverage/coverage.xml", "summary": "coverage-summary.json", "label": "Coverage", "badge": "coverage.svg"}]'
token: ${{ secrets.GITHUB_TOKEN }}

- name: Coverage update
uses: OpenClassrooms/[email protected]
if: ${{ hashFiles('build/coverage/coverage.xml') != '' && github.event_name == 'push' && github.ref_name == 'main' }}
with:
action: update
files: '[{"coverage": "build/coverage/coverage.xml", "summary": "coverage-summary.json", "label": "Coverage", "badge": "coverage.svg"}]'
token: ${{ secrets.GITHUB_TOKEN }}
code-validation:
name: ${{ matrix.actions.name }} - PHP ${{ matrix.php }} - Symfony ${{ matrix.symfony }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: [8.3, 8.4, 8.5]
symfony: [6.4, 7.4]
actions:
- name: Composer validate
run: composer validate --ansi --strict

- name: Static analysis
run: composer phpstan

- name: Style check
run: composer check-cs

- name: Unit tests
run: composer coverage
steps:
- uses: actions/checkout@v6

- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
coverage: pcov
tools: composer:v2
env:
COMPOSER_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: symfony/flex is required to install the correct symfony version
if: ${{ matrix.symfony }}
run: |
composer global config --no-plugins allow-plugins.symfony/flex true
composer global require symfony/flex

- name: Configure Symfony version for symfony/flex
if: ${{ matrix.symfony }}
run: composer config extra.symfony.require "${{ matrix.symfony }}.*"

- name: Install dependencies
run: composer install --no-interaction --prefer-dist --optimize-autoloader

- run: ${{ matrix.actions.run }}

- name: Coverage diff
uses: OpenClassrooms/[email protected]
if: ${{ hashFiles('build/coverage/coverage.xml') != '' && github.event_name == 'pull_request' }}
with:
action: check
files: '[{"coverage": "build/coverage/coverage.xml", "summary": "coverage-summary.json", "label": "Coverage", "badge": "coverage.svg"}]'
token: ${{ secrets.GITHUB_TOKEN }}

- name: Coverage update
uses: OpenClassrooms/[email protected]
if: ${{ hashFiles('build/coverage/coverage.xml') != '' && github.event_name == 'push' && github.ref_name == 'main' }}
with:
action: update
files: '[{"coverage": "build/coverage/coverage.xml", "summary": "coverage-summary.json", "label": "Coverage", "badge": "coverage.svg"}]'
token: ${{ secrets.GITHUB_TOKEN }}
57 changes: 28 additions & 29 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,45 +26,44 @@
}
},
"require": {
"php": ">=8.1",
"doctrine/annotations": "^1.2 || ^2.0" ,
"php": "^8.3",
"doctrine/annotations": "^2.0" ,
"friendsofphp/proxy-manager-lts": "^1.0",
"symfony/expression-language": "^5.0 || ^6.0",
"symfony/filesystem": "^5.0 || ^6.0",
"symfony/property-info": "^5.0 || ^6.0",
"symfony/expression-language": "^6.0 || ^7.0",
"symfony/filesystem": "^6.0 || ^7.0",
"phpdocumentor/reflection-docblock": "^5.0",
"phpstan/phpdoc-parser": "^1.24",
"phpstan/phpdoc-parser": "^2.3",
"webmozart/assert": "^1.11",
"jolicode/automapper": "^9.2"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"phpstan/phpstan": "^1.9",
"phpstan/phpstan-strict-rules": "^1.4",
"phpstan/phpstan-deprecation-rules": "^1.1",
"phpstan/phpstan-phpunit": "^1.3",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0",
"phpstan/phpstan-phpunit": "^2.0",
"roave/security-advisories": "dev-latest",
"phpstan/extension-installer": "^1.2",
"ergebnis/composer-normalize": "^2.28",
"thecodingmachine/phpstan-strict-rules": "^1.0",
"korbeil/phpstan-generic-rules": "^1.0",
"ergebnis/phpstan-rules": "^1.0",
"symplify/easy-coding-standard": "^11.2",
"symfony/dependency-injection": "^5.0 || ^6.0",
"symfony/config": "^5.0 || ^6.0",
"symfony/cache": "^5.0 || ^6.0",
"symfony/http-kernel": "^5.0 || ^6.0",
"symfony/event-dispatcher": "^5.0 || ^6.0",
"symfony/security-bundle": "^5.0 || ^6.0",
"symfony/messenger": "^5.0 || ^6.0",
"kcs/phpstan-strict-rules": "^2.0",
"korbeil/phpstan-generic-rules": "^2.1",
"ergebnis/phpstan-rules": "^2.0",
"symplify/easy-coding-standard": "^13.0",
"symfony/dependency-injection": "^6.0 || ^7.0",
"symfony/config": "^6.0 || ^7.0",
"symfony/cache": "^6.0 || ^7.0",
"symfony/http-kernel": "^6.0 || ^7.0",
"symfony/event-dispatcher": "^6.0 || ^7.0",
"symfony/security-bundle": "^6.0 || ^7.0",
"symfony/messenger": "^6.0 || ^7.0",
"doctrine/orm": "~2.5 || ^3.0",
"symfony/stopwatch": "^5.0 || ^6.0",
"symfony/serializer": "^5.0 || ^6.0",
"symfony/http-client": "^5.0 || ^6.0",
"symfony/uid": "^5.0 || ^6.0",
"symfony/http-foundation": "^5.0 || ^6.0",
"symfony/lock": "^5.0 || ^6.0",
"phpstan/phpstan-webmozart-assert": "^1.2"
"symfony/stopwatch": "^6.0 || ^7.0",
"symfony/serializer": "^6.0 || ^7.0",
"symfony/http-client": "^6.0 || ^7.0",
"symfony/uid": "^6.0 || ^7.0",
"symfony/http-foundation": "^6.0 || ^7.0",
"symfony/lock": "^6.0 || ^7.0",
"phpstan/phpstan-webmozart-assert": "^2.0"
},
"suggest": {
"symfony/dependency-injection": "For Symfony integration",
Expand Down Expand Up @@ -119,7 +118,7 @@
],
"unit": "vendor/bin/phpunit -c phpunit.xml.dist --testdox",
"coverage": "vendor/bin/phpunit -c phpunit.xml.dist --testdox --coverage-clover build/coverage/coverage.xml",
"phpstan": "vendor/bin/phpstan analyse -c phpstan.neon --ansi",
"phpstan": "vendor/bin/phpstan analyse --memory-limit=512M -c phpstan.neon --ansi",
"ecs": "@check-cs"
}
}
5 changes: 4 additions & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ parameters:
- '/Method .+ServiceProxy.+ has a parameter \$container/'
- '/Call to static method Webmozart\\Assert\\Assert::allIsInstanceOf\(\) with/'
- '/Function compact\(\) should not be used/'
- '/In method .+, caught "Throwable" must be rethrown. Either catch a more specific exception or add a "throw" clause in the "catch" block to propagate the exception./'
- '/Class OpenClassrooms\\ServiceProxy\\Model\\Event is neither abstract nor final./'
- '/Closure has parameter .* that is passed by reference./'
- '/Method .* has parameter .* that is passed by reference./'
- '/Call to function array_filter\(\) requires parameter #2 to be passed to avoid loose comparison semantics./'
- '/Binary operation "." between .* results in an error./'
exceptions:
check:
missingCheckedExceptionInThrows: true
Expand Down
6 changes: 3 additions & 3 deletions src/Annotation/Annotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public function __construct(array $data = [])
final public function __get(string $name): void
{
throw new \BadMethodCallException(
sprintf("Unknown property '%s' on annotation '%s'.", $name, static::class)
\sprintf("Unknown property '%s' on annotation '%s'.", $name, static::class)
);
}

Expand All @@ -44,7 +44,7 @@ final public function __get(string $name): void
final public function __isset(string $name): bool
{
throw new \BadMethodCallException(
sprintf("Unknown property '%s' on annotation '%s'.", $name, static::class)
\sprintf("Unknown property '%s' on annotation '%s'.", $name, static::class)
);
}

Expand All @@ -54,7 +54,7 @@ final public function __isset(string $name): bool
final public function __set(string $name, mixed $value): void
{
throw new \BadMethodCallException(
sprintf("Unknown property '%s' on annotation '%s'.", $name, static::class)
\sprintf("Unknown property '%s' on annotation '%s'.", $name, static::class)
);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Attribute/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ final class Cache extends Attribute
* @param array<int, string> $tags
*/
public function __construct(
array|string|null $handler = null,
array|string|null $handler = null,
public readonly array $pools = [],
public readonly ?int $ttl = null,
public readonly ?int $ttl = null,
public readonly array $tags = [],
) {
parent::__construct();
Expand Down
10 changes: 5 additions & 5 deletions src/Attribute/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,17 @@ final class Event extends Attribute
* @param class-string|null $messageClass
*/
public function __construct(
array|string|null $handler = null,
array|string|null $transport = null,
array|string|null $handler = null,
array|string|null $transport = null,
public readonly ?string $name = null,
public readonly ?string $queue = null,
public readonly array $dispatch = [On::POST],
public readonly ?string $queue = null,
public readonly array $dispatch = [On::POST],
public readonly ?string $messageClass = null,
public readonly ?int $delay = null,
) {
parent::__construct();
Assert::allIsInstanceOf($dispatch, On::class);
$this->setHandlers(aliases: compact('handler', 'transport'));
$this->setHandlers(null, compact('handler', 'transport'));
}

public function isOnException(): bool
Expand Down
6 changes: 3 additions & 3 deletions src/Attribute/Event/Listen.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ final class Listen extends Attribute
*/
public function __construct(
public readonly string $name,
?array $handler = null,
public ?Transport $transport = null,
public readonly int $priority = 0,
?array $handler = null,
public ?Transport $transport = null,
public readonly int $priority = 0,
) {
$this->setHandlers($handler);
parent::__construct();
Expand Down
2 changes: 1 addition & 1 deletion src/Attribute/InvalidateCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final class InvalidateCache extends Attribute
* @param array<int, string> $tags
*/
public function __construct(
array|string|null $handler = null,
array|string|null $handler = null,
public readonly array $pools = [],
public readonly array $tags = [],
) {
Expand Down
53 changes: 53 additions & 0 deletions src/FrameworkBridge/Symfony/CacheWarmer/ProxyCacheWarmer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\CacheWarmer;

use ProxyManager\Proxy\LazyLoadingInterface;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
use Symfony\Component\VarExporter\LazyObjectInterface;

final class ProxyCacheWarmer implements CacheWarmerInterface
{
/**
* @var iterable<object>
*/
private iterable $proxies;

/**
* @param iterable<object> $proxies
*/
public function __construct(iterable $proxies)
{
$this->proxies = $proxies;
}

/**
* {@inheritdoc}
*/
public function warmUp(string $cacheDir, ?string $buildDir = null): array
{
foreach ($this->proxies as $proxy) {
if ($proxy instanceof LazyLoadingInterface && !$proxy->isProxyInitialized()) {
$proxy->initializeProxy();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add continue

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is LazyLoadingInterface doesn't exist

}

if (class_exists(LazyObjectInterface::class)
&& $proxy instanceof LazyObjectInterface
&& !$proxy->isLazyObjectInitialized()) {
$proxy->initializeLazyObject();
}
}

return [];
}

/**
* {@inheritdoc}
*/
public function isOptional(): bool
{
return true;
}
}
9 changes: 9 additions & 0 deletions src/FrameworkBridge/Symfony/Config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

declare(strict_types=1);

use OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\CacheWarmer\ProxyCacheWarmer;
use OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\Messenger\Transport\Serialization\MessageSerializer;
use OpenClassrooms\ServiceProxy\FrameworkBridge\Symfony\Subscriber\ServiceProxySubscriber;
use OpenClassrooms\ServiceProxy\Handler\Impl\Cache\SymfonyCacheHandler;
Expand Down Expand Up @@ -76,6 +77,14 @@
])
->tag('kernel.event_subscriber');

$services->set(ProxyCacheWarmer::class)
->args([
tagged_iterator('openclassrooms.service_proxy'),
])
->tag('kernel.cache_warmer', [
'priority' => 128,
]);

$services->set(ServiceProxyEventFactory::class)
->autowire()
->autoconfigure();
Expand Down
Loading