Skip to content

Commit 89cc3a9

Browse files
committed
PoC - logger + check packages upgrade
1 parent 0b214bb commit 89cc3a9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1132
-229
lines changed

.github/workflows/check-code.yml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: "Code check"
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
workflow_call:
9+
10+
pull_request:
11+
paths:
12+
- "src/**"
13+
- "tests/**"
14+
- "composer.json"
15+
- "ecs.php"
16+
- "rector.php"
17+
- "phpstan.neon"
18+
- "phpstan-baseline.neon"
19+
- "phpunit.xml"
20+
21+
concurrency:
22+
group: php-sdk-builder-check-${{ github.ref }}
23+
cancel-in-progress: true
24+
25+
jobs:
26+
code:
27+
name: "Code check"
28+
uses: wrk-flow/reusable-workflows/.github/workflows/php-check.yml@b0886c7fa81dab2fb2615c06eb66e94711652056
29+
secrets: inherit
30+
31+
tests:
32+
name: "Run tests"
33+
strategy:
34+
matrix:
35+
php-version: [ "8.1", "8.2" ]
36+
uses: wrk-flow/reusable-workflows/.github/workflows/php-tests.yml@7b6e90f753beb05d979bf4ad39a009b353a7c6cc
37+
secrets: inherit
38+

.github/workflows/check.yml

-15
This file was deleted.

composer.json

+13-10
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,17 @@
2323
"guzzlehttp/guzzle": "^7.4",
2424
"http-interop/http-factory-guzzle": "^1.2",
2525
"laravel/framework": "^9.25",
26-
"mockery/mockery": "^1.5",
27-
"nyholm/psr7": "^1.5",
28-
"phpstan/phpstan": "^1.6.3",
29-
"phpstan/phpstan-deprecation-rules": "^1.0.0",
30-
"phpstan/phpstan-mockery": "^1.0",
31-
"phpstan/phpstan-phpunit": "^1.1.1",
26+
"laravel/telescope": "v4.14.2",
27+
"league/flysystem": "^3.14",
28+
"mockery/mockery": "^1.5.1",
29+
"nyholm/psr7": "^1.8.0",
30+
"phpstan/phpstan": "^1.10.14",
31+
"phpstan/phpstan-deprecation-rules": "^1.1.3",
32+
"phpstan/phpstan-mockery": "^1.1.1",
33+
"phpstan/phpstan-phpunit": "^1.3.11",
3234
"phpunit/phpunit": "^9.5.20",
33-
"rector/rector": "^0.12.22",
34-
"symplify/easy-coding-standard": "^10.2.2"
35+
"rector/rector": "^0.15.25",
36+
"symplify/easy-coding-standard": "^11.3.2"
3537
},
3638
"suggest": {
3739
"laravel/framework": "SDKs work great with Laravel - solid container.",
@@ -60,7 +62,7 @@
6062
"extra": {
6163
"laravel": {
6264
"providers": [
63-
"WrkFlow\\ApiSdkBuilder\\Frameworks\\LaravelServiceProvider"
65+
"WrkFlow\\ApiSdkBuilder\\Laravel\\LaravelServiceProvider"
6466
]
6567
}
6668
},
@@ -69,7 +71,8 @@
6971
"sort-packages": true,
7072
"optimize-autoloader": true,
7173
"allow-plugins": {
72-
"symfony/thanks": false
74+
"symfony/thanks": false,
75+
"php-http/discovery": false
7376
}
7477
},
7578
"archive": {

ecs.php

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
declare(strict_types=1);
44

5+
use PhpCsFixer\Fixer\ClassNotation\ClassAttributesSeparationFixer;
56
use PhpCsFixer\Fixer\ControlStructure\YodaStyleFixer;
67
use Symplify\EasyCodingStandard\Config\ECSConfig;
78
use Symplify\EasyCodingStandard\ValueObject\Set\SetList;
@@ -17,4 +18,12 @@
1718
[__DIR__ . '/src', __DIR__ . '/tests', __DIR__ . '/ecs.php', __DIR__ . '/rector.php']
1819
);
1920
$containerConfigurator->skip([YodaStyleFixer::class]);
21+
22+
$containerConfigurator->rulesWithConfiguration([
23+
ClassAttributesSeparationFixer::class => [
24+
'elements' => [
25+
'const' => 'only_if_meta',
26+
],
27+
],
28+
]);
2029
};

rector.php

+8-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
declare(strict_types=1);
44

5+
use Rector\CodingStyle\Rector\ClassConst\VarConstantCommentRector;
6+
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
57
use Rector\Config\RectorConfig;
68
use Rector\Core\ValueObject\PhpVersion;
79
use Rector\Set\ValueObject\LevelSetList;
@@ -20,15 +22,18 @@
2022
$config->import(SetList::CODING_STYLE);
2123
$config->importNames();
2224

23-
$config->rule(AddVoidReturnTypeWhereNoReturnRector::class);
25+
$config->rule(rectorClass: AddVoidReturnTypeWhereNoReturnRector::class);
2426
$config->ruleWithConfiguration(
25-
BooleanInBooleanNotRuleFixerRector::class,
26-
[
27+
rectorClass: BooleanInBooleanNotRuleFixerRector::class,
28+
configuration: [
2729
AbstractFalsyScalarRuleFixerRector::TREAT_AS_NON_EMPTY => false,
2830
]
2931
);
3032

3133
$config->skip([
3234
AddVoidReturnTypeWhereNoReturnRector::class => [__DIR__ . '/src/Testing/Response.php'],
35+
VarConstantCommentRector::class,
36+
// Collides with ECS ClassAttributesSeparationFixer
37+
NewlineAfterStatementRector::class,
3338
]);
3439
};

src/AbstractApi.php

+23-5
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ abstract class AbstractApi implements ApiContract
3737
private readonly array $overrideEndpoints;
3838

3939
/**
40-
* @param AbstractEnvironment $environment
41-
* @param ApiFactoryContract $factory
4240
* @param array<class-string<AbstractEndpoint>, class-string<AbstractEndpoint>> $overrideEndpoints
4341
*/
4442
public function __construct(
@@ -91,7 +89,13 @@ public function get(
9189
->createRequest('GET', $uri->toString());
9290

9391
return $this->sendRequestAction
94-
->execute($this, $request, $responseClass, null, $headers, $expectedResponseStatusCode);
92+
->execute(
93+
api: $this,
94+
request: $request,
95+
responseClass: $responseClass,
96+
headers: $headers,
97+
expectedResponseStatusCode: $expectedResponseStatusCode
98+
);
9599
}
96100

97101
/**
@@ -116,7 +120,14 @@ public function post(
116120
->createRequest('POST', $uri->toString());
117121

118122
return $this->sendRequestAction
119-
->execute($this, $request, $responseClass, $body, $headers, $expectedResponseStatusCode);
123+
->execute(
124+
api: $this,
125+
request: $request,
126+
responseClass: $responseClass,
127+
body: $body,
128+
headers: $headers,
129+
expectedResponseStatusCode: $expectedResponseStatusCode
130+
);
120131
}
121132

122133
/**
@@ -141,7 +152,14 @@ public function put(
141152
->createRequest('PUT', $uri->toString());
142153

143154
return $this->sendRequestAction
144-
->execute($this, $request, $responseClass, $body, $headers, $expectedResponseStatusCode);
155+
->execute(
156+
api: $this,
157+
request: $request,
158+
responseClass: $responseClass,
159+
body: $body,
160+
headers: $headers,
161+
expectedResponseStatusCode: $expectedResponseStatusCode
162+
);
145163
}
146164

147165
/**

src/Actions/GetLoggerAction.php

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WrkFlow\ApiSdkBuilder\Actions;
6+
7+
use WrkFlow\ApiSdkBuilder\Contracts\SDKContainerFactoryContract;
8+
use WrkFlow\ApiSdkBuilder\Log\Contracts\LoggerContract;
9+
use WrkFlow\ApiSdkBuilder\Log\Entities\LoggerConfigEntity;
10+
use WrkFlow\ApiSdkBuilder\Log\Loggers\StackLogger;
11+
12+
/**
13+
* This action is responsible for getting the logger from the logger config.
14+
* - We expect, that container should make Loggers singletons (for performance reasons while mixing multiple APIs).
15+
* - We expect that cache holds in AbstractApi lifetime (SendRequestAction is created in API constructor
16+
* GetLoggerAction is its own dependency - cache will live between requests).
17+
*/
18+
class GetLoggerAction
19+
{
20+
private array $cache = [];
21+
22+
public function __construct(
23+
private readonly SDKContainerFactoryContract $container,
24+
) {
25+
}
26+
27+
public function execute(LoggerConfigEntity $config, string $host): ?LoggerContract
28+
{
29+
$loggerKey = $config->loggerByHost[$host] ?? $config->logger;
30+
31+
if (array_key_exists($loggerKey, $config->loggersMap->loggers) === false) {
32+
return null;
33+
}
34+
35+
if (array_key_exists($loggerKey, $this->cache)) {
36+
return $this->cache[$loggerKey];
37+
}
38+
39+
$logger = $this->getLogger(config: $config, loggerKey: $loggerKey);
40+
41+
$this->cache[$loggerKey] = $logger;
42+
43+
return $logger;
44+
}
45+
46+
protected function getLogger(LoggerConfigEntity $config, mixed $loggerKey): mixed
47+
{
48+
$loggers = $config->loggersMap->loggers[$loggerKey];
49+
50+
if ($loggers === []) {
51+
return null;
52+
}
53+
54+
if (count($loggers) === 1) {
55+
return $this->container->make($loggers[0]);
56+
}
57+
58+
return new StackLogger(
59+
loggers: array_map(callback: fn (string $logger) => $this->container->make($logger), array: $loggers)
60+
);
61+
}
62+
}

src/Actions/MakeApiFactory.php

+15-15
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use Closure;
88
use Http\Discovery\Psr17FactoryDiscovery;
99
use Http\Discovery\Psr18ClientDiscovery;
10-
use Psr\Container\ContainerInterface;
1110
use Psr\EventDispatcher\EventDispatcherInterface;
1211
use Psr\Http\Client\ClientInterface;
1312
use Psr\Http\Message\RequestFactoryInterface;
@@ -16,47 +15,48 @@
1615
use WrkFlow\ApiSdkBuilder\Contracts\ApiFactoryContract;
1716
use WrkFlow\ApiSdkBuilder\Contracts\SDKContainerFactoryContract;
1817
use WrkFlow\ApiSdkBuilder\Factories\ApiFactory;
18+
use WrkFlow\ApiSdkBuilder\Log\Entities\LoggerConfigEntity;
1919

2020
class MakeApiFactory
2121
{
2222
public function __construct(
23-
private readonly ContainerInterface $container,
24-
private readonly SDKContainerFactoryContract $factoryContract,
23+
private readonly SDKContainerFactoryContract $container,
2524
) {
2625
}
2726

2827
/**
2928
* Builds API factory using http discovery package
3029
*/
31-
public function execute(): ApiFactoryContract
30+
public function execute(LoggerConfigEntity $loggerConfig = null): ApiFactoryContract
3231
{
3332
$request = $this->containerOr(
34-
RequestFactoryInterface::class,
35-
fn () => Psr17FactoryDiscovery::findRequestFactory()
33+
interface: RequestFactoryInterface::class,
34+
create: static fn () => Psr17FactoryDiscovery::findRequestFactory()
3635
);
3736

38-
$client = $this->containerOr(ClientInterface::class, fn () => Psr18ClientDiscovery::find());
37+
$client = $this->containerOr(ClientInterface::class, static fn () => Psr18ClientDiscovery::find());
3938
$response = $this->containerOr(
40-
ResponseFactoryInterface::class,
41-
fn () => Psr17FactoryDiscovery::findResponseFactory()
39+
interface: ResponseFactoryInterface::class,
40+
create: static fn () => Psr17FactoryDiscovery::findResponseFactory()
4241
);
4342

4443
$stream = $this->containerOr(
45-
StreamFactoryInterface::class,
46-
fn () => Psr17FactoryDiscovery::findStreamFactory()
44+
interface: StreamFactoryInterface::class,
45+
create: static fn () => Psr17FactoryDiscovery::findStreamFactory()
4746
);
4847

4948
$eventDispatcher = $this->container->has(EventDispatcherInterface::class)
50-
? $this->container->get(EventDispatcherInterface::class)
49+
? $this->container->make(EventDispatcherInterface::class)
5150
: null;
5251

5352
return new ApiFactory(
5453
request: $request,
5554
client: $client,
5655
stream: $stream,
57-
container: $this->factoryContract,
56+
container: $this->container,
5857
response: $response,
59-
eventDispatcher: $eventDispatcher
58+
eventDispatcher: $eventDispatcher,
59+
loggerConfig: $loggerConfig
6060
);
6161
}
6262

@@ -71,7 +71,7 @@ public function execute(): ApiFactoryContract
7171
protected function containerOr(string $interface, Closure $create): mixed
7272
{
7373
if ($this->container->has($interface)) {
74-
return $this->container->get($interface);
74+
return $this->container->make($interface);
7575
}
7676

7777
return $create();

0 commit comments

Comments
 (0)