Skip to content

Commit 93fab65

Browse files
authored
chore: components dependencies (#6113)
* chore: components dependencies * test
1 parent ce9ab82 commit 93fab65

File tree

238 files changed

+6157
-877
lines changed

Some content is hidden

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

238 files changed

+6157
-877
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ jobs:
5252
ini-values: memory_limit=-1
5353
tools: pecl, composer
5454
coverage: none
55-
- name: Download PHPArkitect PHAR
56-
run: |
57-
wget -q https://github.com/phparkitect/arkitect/releases/latest/download/phparkitect.phar
58-
chmod +x phparkitect.phar
5955
- name: Get composer cache directory
6056
id: composercache
6157
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
@@ -68,8 +64,7 @@ jobs:
6864
- name: Update project dependencies
6965
run: |
7066
composer update --no-interaction --no-progress --ansi
71-
- name: Run PHPArkitect
72-
run: ./phparkitect.phar check
67+
- run: php components.php
7368

7469
php-cs-fixer:
7570
name: PHP CS Fixer (PHP ${{ matrix.php }})
@@ -145,8 +140,6 @@ jobs:
145140
rm -Rf tests/Fixtures/app/var/cache/*
146141
tests/Fixtures/app/console cache:warmup
147142
- name: Run PHPStan analysis
148-
env:
149-
SYMFONY_PHPUNIT_VERSION: '9.5'
150143
run: |
151144
./vendor/bin/phpstan --version
152145
./vendor/bin/phpstan analyse --no-interaction --no-progress --ansi
@@ -244,6 +237,9 @@ jobs:
244237
- GraphQl
245238
- Serializer
246239
- Symfony
240+
- Doctrine/Common
241+
- Doctrine/Orm
242+
- Doctrine/Odm
247243
include:
248244
- php: '8.1'
249245
coverage: true
@@ -768,8 +764,6 @@ jobs:
768764
restore-keys: ${{ runner.os }}-composer-
769765
- name: Update project dependencies
770766
run: composer update --prefer-lowest --no-interaction --no-progress --ansi
771-
- name: Install PHPUnit
772-
run: vendor/bin/simple-phpunit --version
773767
- name: Clear test app cache
774768
run: tests/Fixtures/app/console cache:clear --ansi
775769
- name: Run Behat tests
@@ -1033,12 +1027,10 @@ jobs:
10331027
run: rm -Rf tests/Fixtures/app/var/cache/*
10341028
- name: Update project dependencies
10351029
run: composer update --prefer-lowest --no-interaction --no-progress --ansi
1036-
- name: Install PHPUnit
1037-
run: vendor/bin/simple-phpunit --version
10381030
- name: Clear test app cache
10391031
run: tests/Fixtures/app/console cache:clear --ansi
10401032
- name: Run PHPUnit tests
1041-
run: vendor/bin/simple-phpunit
1033+
run: vendor/bin/phpunit
10421034
env:
10431035
SYMFONY_DEPRECATIONS_HELPER: max[self]=0&ignoreFile=./tests/.ignored-deprecations
10441036

@@ -1077,8 +1069,6 @@ jobs:
10771069
run: rm -Rf tests/Fixtures/app/var/cache/*
10781070
- name: Update project dependencies
10791071
run: composer update --prefer-lowest --no-interaction --no-progress --ansi
1080-
- name: Install PHPUnit
1081-
run: vendor/bin/simple-phpunit --version
10821072
- name: Clear test app cache
10831073
run: tests/Fixtures/app/console cache:clear --ansi
10841074
- name: Run Behat tests

.php-cs-fixer.dist.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
'tests/Fixtures/app/var',
1919
'docs/guides',
2020
'docs/var',
21-
'**vendor**'
21+
'src/Doctrine/Orm/Tests/var',
22+
'src/Doctrine/Odm/Tests/var'
2223
])
2324
->notPath('src/Symfony/Bundle/DependencyInjection/Configuration.php')
2425
->notPath('src/Annotation/ApiFilter.php') // temporary

components.php

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
/*
15+
* This script checks for dependencies between our components
16+
* and fails if a component has a wrong dependency.
17+
*/
18+
use Symfony\Component\Filesystem\Path;
19+
use Symfony\Component\Finder\Finder;
20+
21+
$loader = require './vendor/autoload.php';
22+
$namespace = 'ApiPlatform';
23+
$prefix = 'api-platform';
24+
$ignoreList = ['ApiPlatform\\Api', 'ApiPlatform\\Exception', 'ApiPlatform\\Util'];
25+
$stopOnFailure = in_array('--stop-on-failure', $_SERVER['argv'], true);
26+
$skipPaths = [__DIR__.'/src/GraphQl/Resolver/Stage'];
27+
28+
/**
29+
* Reads the beginning of a PHP class and returns "use" instructions matching our namespace.
30+
*/
31+
$class_uses_namespaces = function (ReflectionClass $r) use ($namespace): \Generator {
32+
$fp = fopen($r->getFileName(), 'r');
33+
$u = 'use';
34+
$c = false;
35+
while (($buffer = fgets($fp, 4096)) !== false) {
36+
if ($c && \PHP_EOL === $buffer) {
37+
break;
38+
}
39+
40+
if (!str_starts_with($buffer, $u)) {
41+
continue;
42+
}
43+
44+
$c = true;
45+
$buffer = substr($buffer, 4, -2);
46+
if (str_starts_with($buffer, $namespace)) {
47+
yield substr($buffer, 0, strpos($buffer, ' ') ?: null);
48+
}
49+
}
50+
51+
fclose($fp);
52+
};
53+
54+
// Creates and require the map of dependencies
55+
$directories = [];
56+
$map = [];
57+
foreach (Finder::create()->in('src')->notPath('vendor')->name('composer.json') as $f) {
58+
if (null === ($component = json_decode($f->getContents(), true))) {
59+
continue;
60+
}
61+
62+
$filter = fn ($v) => str_starts_with($v, $prefix);
63+
$dependencies =
64+
array_merge(
65+
array_filter(array_keys((array) $component['require']), $filter),
66+
array_filter(array_keys((array) $component['require-dev'] ?? []), $filter)
67+
);
68+
69+
$map[$component['name']] = ['namespace' => substr(key($component['autoload']['psr-4']), 0, -1), 'dependencies' => $dependencies];
70+
$directories[] = substr($f->getRealPath(), 0, -14);
71+
72+
foreach (Finder::create()->in($f->getPath())->notPath('vendor')->notPath('var')->name('*.php')->notName('*.tpl.php')->notName('bootstrap.php') as $f) {
73+
require_once $f->getRealPath();
74+
}
75+
}
76+
77+
// create a PSR map of dependencies
78+
$psrMap = [];
79+
foreach ($map as $component) {
80+
$depsPsr = [];
81+
foreach ($component['dependencies'] as $d) {
82+
$depsPsr[] = $map[$d]['namespace'];
83+
}
84+
85+
$psrMap[$component['namespace']] = $depsPsr;
86+
}
87+
88+
$warned = [];
89+
$getComponentNamespace = function (ReflectionClass $r, ReflectionClass $inside = null) use ($psrMap, $warned, $ignoreList, $namespace) {
90+
$ns = $r->getNamespaceName();
91+
// Find this components namespace
92+
$nsParts = explode('\\', $ns);
93+
$n = count($nsParts);
94+
$componentNs = $nsParts[0].'\\'.$nsParts[1];
95+
$i = 2;
96+
97+
while (!isset($psrMap[$componentNs]) && $i < $n) {
98+
if ($part = ($nsParts[$i++] ?? null)) {
99+
$componentNs .= '\\'.$part;
100+
}
101+
}
102+
103+
if (!isset($psrMap[$componentNs])) {
104+
if (in_array($componentNs, $ignoreList, true)) {
105+
return null;
106+
}
107+
108+
$guess = $nsParts[0].'\\'.$nsParts[1];
109+
if ($warned[$guess] ?? true) {
110+
echo sprintf('"%s" is not an %s component at "%s" %s', $guess, $namespace, ($inside ?? $r)->getFileName(), \PHP_EOL);
111+
$warned[$guess] = false;
112+
}
113+
114+
return null;
115+
}
116+
117+
return $componentNs;
118+
};
119+
120+
$exitCode = 0;
121+
$lnamespace = strlen($namespace);
122+
foreach (array_merge(get_declared_classes(), get_declared_interfaces(), get_declared_traits()) as $className) {
123+
$r = new ReflectionClass($className);
124+
$ns = $r->getNamespaceName();
125+
126+
foreach ($skipPaths as $base) {
127+
if (!($fileName = $r->getFileName())) {
128+
continue;
129+
}
130+
131+
if (Path::isBasePath($skipPaths[0], $fileName)) {
132+
continue 2;
133+
}
134+
}
135+
136+
if (!str_starts_with($ns, $namespace)) {
137+
continue;
138+
}
139+
140+
$componentNs = $getComponentNamespace($r);
141+
142+
if (!$componentNs) {
143+
continue;
144+
}
145+
146+
foreach ($class_uses_namespaces($r) as $u) {
147+
if (str_starts_with($u, $componentNs)) {
148+
continue;
149+
}
150+
151+
$useNs = $getComponentNamespace(new ReflectionClass($u), $r);
152+
153+
if (!$useNs || $useNs === $componentNs) {
154+
continue;
155+
}
156+
157+
if (!in_array($useNs, $psrMap[$componentNs], true)) {
158+
echo sprintf('"%s" uses "%s" although "%s" is not one of its dependencies %s', $className, $u, $useNs, \PHP_EOL);
159+
$exitCode = 1;
160+
161+
if ($stopOnFailure) {
162+
exit($exitCode);
163+
}
164+
}
165+
}
166+
}
167+
168+
exit($exitCode);

composer.json

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@
2828
"psr/cache": "^1.0 || ^2.0 || ^3.0",
2929
"psr/container": "^1.0 || ^2.0",
3030
"symfony/deprecation-contracts": "^3.1",
31-
"symfony/http-foundation": "^6.1 || ^7.0",
32-
"symfony/http-kernel": "^6.1 || ^7.0",
33-
"symfony/property-access": "^6.1 || ^7.0",
34-
"symfony/property-info": "^6.1 || ^7.0",
35-
"symfony/serializer": "^6.1 || ^7.0",
31+
"symfony/http-foundation": "^6.4 || ^7.0",
32+
"symfony/http-kernel": "^6.4 || ^7.0",
33+
"symfony/property-access": "^6.4 || ^7.0",
34+
"symfony/property-info": "^6.4 || ^7.0",
35+
"symfony/serializer": "^6.4 || ^7.0",
3636
"symfony/translation-contracts": "^3.3",
37-
"symfony/web-link": "^6.1 || ^7.0",
37+
"symfony/web-link": "^6.4 || ^7.0",
3838
"willdurand/negotiation": "^3.0"
3939
},
4040
"require-dev": {
@@ -57,47 +57,47 @@
5757
"phpspec/prophecy-phpunit": "^2.0",
5858
"phpstan/extension-installer": "^1.1",
5959
"phpstan/phpdoc-parser": "^1.13",
60-
"phpstan/phpstan": "^1.1",
60+
"phpstan/phpstan": "^1.10",
6161
"phpstan/phpstan-doctrine": "^1.0",
6262
"phpstan/phpstan-phpunit": "^1.0",
6363
"phpstan/phpstan-symfony": "^1.0",
64-
"phpunit/phpunit": "^9.5",
64+
"phpunit/phpunit": "^9.6",
6565
"psr/log": "^1.0 || ^2.0 || ^3.0",
6666
"ramsey/uuid": "^3.9.7 || ^4.0",
6767
"ramsey/uuid-doctrine": "^1.4 || ^2.0",
6868
"sebastian/comparator": "<5.0",
6969
"soyuka/contexts": "v3.3.9",
7070
"soyuka/stubs-mongodb": "^1.0",
71-
"symfony/asset": "^6.1 || ^7.0",
72-
"symfony/browser-kit": "^6.1 || ^7.0",
73-
"symfony/cache": "^6.1 || ^7.0",
74-
"symfony/config": "^6.1 || ^7.0",
75-
"symfony/console": "^6.1 || ^7.0",
76-
"symfony/css-selector": "^6.1 || ^7.0",
77-
"symfony/dependency-injection": "^6.1 || ^7.0.12",
78-
"symfony/doctrine-bridge": "^6.1 || ^7.0",
79-
"symfony/dom-crawler": "^6.1 || ^7.0",
80-
"symfony/error-handler": "^6.1 || ^7.0",
81-
"symfony/event-dispatcher": "^6.1 || ^7.0",
82-
"symfony/expression-language": "^6.1 || ^7.0",
83-
"symfony/finder": "^6.1 || ^7.0",
84-
"symfony/form": "^6.1 || ^7.0",
85-
"symfony/framework-bundle": "^6.1 || ^7.0",
86-
"symfony/http-client": "^6.1 || ^7.0",
87-
"symfony/intl": "^6.1 || ^7.0",
71+
"symfony/asset": "^6.4 || ^7.0",
72+
"symfony/browser-kit": "^6.4 || ^7.0",
73+
"symfony/cache": "^6.4 || ^7.0",
74+
"symfony/config": "^6.4 || ^7.0",
75+
"symfony/console": "^6.4 || ^7.0",
76+
"symfony/css-selector": "^6.4 || ^7.0",
77+
"symfony/dependency-injection": "^6.4 || ^7.0.12",
78+
"symfony/doctrine-bridge": "^6.4 || ^7.0",
79+
"symfony/dom-crawler": "^6.4 || ^7.0",
80+
"symfony/error-handler": "^6.4 || ^7.0",
81+
"symfony/event-dispatcher": "^6.4 || ^7.0",
82+
"symfony/expression-language": "^6.4 || ^7.0",
83+
"symfony/finder": "^6.4 || ^7.0",
84+
"symfony/form": "^6.4 || ^7.0",
85+
"symfony/framework-bundle": "^6.4 || ^7.0",
86+
"symfony/http-client": "^6.4 || ^7.0",
87+
"symfony/intl": "^6.4 || ^7.0",
8888
"symfony/maker-bundle": "^1.24",
8989
"symfony/mercure-bundle": "*",
90-
"symfony/messenger": "^6.1 || ^7.0",
91-
"symfony/phpunit-bridge": "^6.1 || ^7.0",
92-
"symfony/routing": "^6.1 || ^7.0",
93-
"symfony/security-bundle": "^6.1 || ^7.0",
94-
"symfony/security-core": "^6.1 || ^7.0",
95-
"symfony/stopwatch": "^6.1 || ^7.0",
96-
"symfony/twig-bundle": "^6.1 || ^7.0",
97-
"symfony/uid": "^6.1 || ^7.0",
98-
"symfony/validator": "^6.1 || ^7.0",
99-
"symfony/web-profiler-bundle": "^6.1 || ^7.0",
100-
"symfony/yaml": "^6.1 || ^7.0",
90+
"symfony/messenger": "^6.4 || ^7.0",
91+
"symfony/phpunit-bridge": "^6.4 || ^7.0",
92+
"symfony/routing": "^6.4 || ^7.0",
93+
"symfony/security-bundle": "^6.4 || ^7.0",
94+
"symfony/security-core": "^6.4 || ^7.0",
95+
"symfony/stopwatch": "^6.4 || ^7.0",
96+
"symfony/twig-bundle": "^6.4 || ^7.0",
97+
"symfony/uid": "^6.4 || ^7.0",
98+
"symfony/validator": "^6.4 || ^7.0",
99+
"symfony/web-profiler-bundle": "^6.4 || ^7.0",
100+
"symfony/yaml": "^6.4 || ^7.0",
101101
"twig/twig": "^1.42.3 || ^2.12 || ^3.0",
102102
"webonyx/graphql-php": "^14.0 || ^15.0"
103103
},
@@ -157,7 +157,7 @@
157157
"dev-main": "3.3.x-dev"
158158
},
159159
"symfony": {
160-
"require": "^6.1 || ^7.0"
160+
"require": "^6.4 || ^7.0"
161161
}
162162
}
163163
}

phparkitect-baseline.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)