Skip to content

Commit 4630d21

Browse files
committed
refactor: cover telemetry / filesystem / postgresql bundles with mago
1 parent 917db73 commit 4630d21

82 files changed

Lines changed: 720 additions & 472 deletions

File tree

Some content is hidden

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

Justfile

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,15 @@ analyze-mago *args:
8484
src/bridge/phpunit/telemetry \
8585
src/bridge/postgresql/valinor \
8686
src/bridge/psr18/telemetry \
87-
src/bridge/psr7/telemetry
87+
src/bridge/psr7/telemetry \
88+
src/bridge/symfony/filesystem-bundle \
89+
src/bridge/symfony/filesystem-cache \
90+
src/bridge/symfony/http-foundation \
91+
src/bridge/symfony/postgresql-bundle \
92+
src/bridge/symfony/postgresql-cache \
93+
src/bridge/symfony/postgresql-messenger \
94+
src/bridge/symfony/postgresql-session \
95+
src/bridge/symfony/telemetry-bundle
8896

8997
# Auto-fix code style (Mago format + lint --fix) and GitHub Actions findings (zizmor --fix).
9098
fix:

mago.toml

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ includes = [
1818
# Generated by protoc (OTLP protocol definitions)
1919
"src/bridge/telemetry/otlp/src/Opentelemetry",
2020
"src/bridge/telemetry/otlp/src/GPBMetadata",
21+
# Symfony
22+
"src/bridge/symfony/filesystem-bundle/src/Flow/Bridge/Symfony/FilesystemBundle/FlowFilesystemBundle.php",
23+
"src/bridge/symfony/postgresql-bundle/src/Flow/Bridge/Symfony/PostgreSqlBundle/FlowPostgreSqlBundle.php",
24+
"src/bridge/symfony/telemetry-bundle/src/Flow/Bridge/Symfony/TelemetryBundle/DependencyInjection/Configuration.php",
2125
]
2226
excludes = [
2327
"src/**/vendor/**",
@@ -33,23 +37,14 @@ enable-short-tags = false
3337
plugins = ["flow-php"]
3438
excludes = [
3539
"**/Flow/Types/PHPStan/**",
40+
# Symfony bundle/config tests accessing deeply-nested processConfiguration() arrays (all mixed-array-access)
41+
"src/bridge/symfony/filesystem-bundle/tests/Flow/Bridge/Symfony/FilesystemBundle/Tests/Unit/FlowFilesystemBundleTest.php",
42+
"src/bridge/symfony/filesystem-bundle/tests/Flow/Bridge/Symfony/FilesystemBundle/Tests/Unit/ConfigurationTest.php",
43+
"src/bridge/symfony/postgresql-bundle/tests/Flow/Bridge/Symfony/PostgreSqlBundle/Tests/Unit/DependencyInjection/ConfigurationTest.php",
44+
"src/bridge/symfony/postgresql-bundle/tests/Flow/Bridge/Symfony/PostgreSqlBundle/Tests/Integration/FlowPostgreSqlExtensionTest.php",
45+
"src/bridge/symfony/telemetry-bundle/tests/Flow/Bridge/Symfony/TelemetryBundle/Tests/Unit/DependencyInjection/ConfigurationTest.php",
3646
]
37-
ignore = [
38-
{ code = "redundant-docblock-type", in = [
39-
"src/lib/postgresql/src/Flow/PostgreSql/DSL/client.php",
40-
] },
41-
{ code = "unavailable-method", in = [
42-
"src/lib/types/src/Flow/Types/Type/Logical/HTMLElementType.php",
43-
"src/lib/types/src/Flow/Types/Type/Logical/HTMLType.php",
44-
"src/lib/types/src/Flow/Types/Type/Native/StringType.php",
45-
"src/lib/types/tests/Flow/Types/Tests/Unit/Type/Logical/HTMLElementTypeTest.php",
46-
"src/lib/types/tests/Flow/Types/Tests/Unit/Type/Logical/HTMLTypeTest.php",
47-
"src/lib/types/tests/Flow/Types/Tests/Unit/Type/Native/StringTypeTest.php",
48-
"src/lib/types/tests/Flow/Types/Tests/Unit/Type/TypeDetectorTest.php",
49-
"src/core/etl/src/Flow/ETL/Row/Entry/HTMLEntry.php",
50-
"src/core/etl/src/Flow/ETL/Row/Entry/HTMLElementEntry.php",
51-
] },
52-
]
47+
ignore = []
5348

5449
[linter]
5550
integrations = ["symfony", "phpunit"]

phpstan.neon

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,27 +143,30 @@ parameters:
143143
-
144144
message: '#Dom\\(CharacterData|HTMLDocument|HTMLElement|Element)#i'
145145
identifier: class.notFound
146-
-
147-
path: src/bridge/symfony/telemetry-bundle/src/Flow/Bridge/Symfony/TelemetryBundle/DependencyInjection/FlowTelemetryExtension.php
148-
identifier: argument.type
149146
-
150147
path: src/bridge/symfony/telemetry-bundle/src/Flow/Bridge/Symfony/TelemetryBundle/DependencyInjection/FlowTelemetryExtension.php
151148
identifier: offsetAccess.nonOffsetAccessible
152149
-
153150
path: src/bridge/symfony/telemetry-bundle/src/Flow/Bridge/Symfony/TelemetryBundle/DependencyInjection/FlowTelemetryExtension.php
154151
identifier: cast.string
155152
-
156-
path: src/bridge/symfony/telemetry-bundle/src/Flow/Bridge/Symfony/TelemetryBundle/DependencyInjection/FlowTelemetryExtension.php
157-
identifier: foreach.nonIterable
153+
path: src/bridge/symfony/filesystem-cache/src/Flow/Bridge/Symfony/FilesystemCache/FlowFilesystemCacheAdapter.php
154+
identifier: cast.string
158155
-
159-
path: src/bridge/symfony/telemetry-bundle/src/Flow/Bridge/Symfony/TelemetryBundle/DependencyInjection/FlowTelemetryExtension.php
160-
identifier: binaryOp.invalid
156+
path: src/bridge/symfony/telemetry-bundle/src/Flow/Bridge/Symfony/TelemetryBundle/Instrumentation/HttpKernel/HttpKernelSpanSubscriber.php
157+
identifier: encapsedStringPart.nonString
158+
-
159+
path: src/bridge/symfony/postgresql-messenger/tests/Flow/Bridge/Symfony/PostgreSQLMessenger/Tests/Integration/FlowPostgreSqlTransportTest.php
160+
identifier: cast.string
161161
-
162162
path: src/bridge/symfony/telemetry-bundle/src/Flow/Bridge/Symfony/TelemetryBundle/DependencyInjection/Compiler/DBALTelemetryPass.php
163163
identifier: cast.int
164164
-
165-
path: src/bridge/symfony/telemetry-bundle/src/Flow/Bridge/Symfony/TelemetryBundle/Instrumentation/Doctrine/DBAL/TracingMiddleware.php
166-
identifier: return.type
165+
path: src/bridge/symfony/filesystem-cache/tests/Flow/Bridge/Symfony/FilesystemCache/Tests/Unit/Double/SpyMarshaller.php
166+
identifier: parameterByRef.unusedType
167+
-
168+
path: src/bridge/symfony/postgresql-cache/tests/Flow/Bridge/Symfony/PostgreSQLCache/Tests/Unit/Double/SpyMarshaller.php
169+
identifier: parameterByRef.unusedType
167170
# brick/math 0.12-0.14 vs 0.15+ compatibility shim — branches differ per installed version
168171
-
169172
path: src/core/etl/src/Flow/Calculator/Calculator.php

src/bridge/symfony/filesystem-bundle/src/Flow/Bridge/Symfony/FilesystemBundle/Command/FstabResolver.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
use Psr\Container\ContainerInterface;
1111

1212
use function array_keys;
13+
use function array_map;
1314
use function array_pop;
1415
use function explode;
16+
use function Flow\Types\DSL\type_instance_of;
1517
use function getcwd;
1618
use function implode;
1719
use function method_exists;
@@ -53,7 +55,7 @@ public function parseUri(string $raw): Path
5355
return Path::from($raw);
5456
}
5557

56-
$absolute = str_starts_with($raw, '/') ? $raw : getcwd() . '/' . $raw;
58+
$absolute = str_starts_with($raw, '/') ? $raw : (getcwd() ?: '') . '/' . $raw;
5759
$real = realpath($absolute);
5860

5961
return Path::from('file://' . ($real !== false ? $real : self::normalizePath($absolute)));
@@ -71,29 +73,29 @@ public function resolve(?string $fstabName): FilesystemTable
7173
));
7274
}
7375

74-
/** @phpstan-ignore return.type */
75-
return $this->locator->get($name);
76+
return type_instance_of(FilesystemTable::class)->assert($this->locator->get($name));
7677
}
7778

7879
private static function normalizePath(string $path): string
7980
{
8081
$isAbsolute = str_starts_with($path, '/');
81-
$segments = [];
82+
$parts = explode('/', $path);
83+
$normalized = [];
8284

83-
foreach (explode('/', $path) as $segment) {
84-
if ($segment === '' || $segment === '.') {
85+
foreach ($parts as $part) {
86+
if ($part === '' || $part === '.') {
8587
continue;
8688
}
8789

88-
if ($segment === '..') {
89-
array_pop($segments);
90+
if ($part === '..') {
91+
array_pop($normalized);
9092

9193
continue;
9294
}
9395

94-
$segments[] = $segment;
96+
$normalized[] = $part;
9597
}
9698

97-
return ($isAbsolute ? '/' : '') . implode('/', $segments);
99+
return ($isAbsolute ? '/' : '') . implode('/', array_map(static fn (mixed $s): string => (string) $s, $normalized));
98100
}
99101
}

src/bridge/symfony/filesystem-bundle/src/Flow/Bridge/Symfony/FilesystemBundle/Command/LsCommand.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
100100
$fstabName = type_union(type_string(), type_null())->assert($input->getOption('fstab'));
101101
$recursive = type_boolean()->assert($input->getOption('recursive'));
102102
$long = !type_boolean()->assert($input->getOption('short'));
103+
// @mago-expect analysis:mixed-assignment
103104
$limitOpt = $input->getOption('limit');
104105
$limit = $limitOpt === null ? null : type_integer()->cast($limitOpt);
105106
$offset = type_integer()->cast($input->getOption('offset'));
@@ -183,7 +184,7 @@ private function renderNdjson(OutputInterface $output, iterable $iterator, int $
183184
break;
184185
}
185186

186-
$output->writeln((string) json_encode([
187+
$output->writeln(json_encode([
187188
'uri' => $status->path->uri(),
188189
'type' => $status->isFile() ? 'file' : 'directory',
189190
'size' => $status->size,

src/bridge/symfony/filesystem-bundle/src/Flow/Bridge/Symfony/FilesystemBundle/Command/StatCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
9999
}
100100

101101
if ($format === 'json') {
102-
$output->writeln((string) json_encode([
102+
$output->writeln(json_encode([
103103
'uri' => $uri,
104104
'protocol' => $protocolName,
105105
'path' => $cleanPath,

src/bridge/symfony/filesystem-bundle/src/Flow/Bridge/Symfony/FilesystemBundle/DependencyInjection/Compiler/BuildFstabsPass.php

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,14 @@ public function process(ContainerBuilder $container): void
3838
return;
3939
}
4040

41-
/** @var array{default_fstab: null|string, fstabs: array<string, array{filesystems: array<string, array<string, mixed>&array{type: string}>, telemetry?: array<string, mixed>}>} $config */
4241
$config = $container->getParameter(self::CONFIG_PARAMETER);
4342

44-
$fstabs = $config['fstabs'];
45-
$defaultFstab = $config['default_fstab'];
43+
if (!is_array($config)) {
44+
return;
45+
}
46+
47+
$fstabs = is_array($config['fstabs'] ?? null) ? $config['fstabs'] : [];
48+
$defaultFstab = is_string($config['default_fstab'] ?? null) ? $config['default_fstab'] : null;
4649

4750
if ($defaultFstab !== null && !array_key_exists($defaultFstab, $fstabs)) {
4851
throw new LogicException(sprintf(
@@ -54,43 +57,63 @@ public function process(ContainerBuilder $container): void
5457

5558
$availableTypes = $this->collectAvailableTypes($container);
5659

60+
// @mago-expect analysis:mixed-assignment
5761
foreach ($fstabs as $fstabName => $fstabConfig) {
62+
$fstabNameStr = (string) $fstabName;
5863
$resolvedFilesystems = [];
5964

60-
foreach ($fstabConfig['filesystems'] as $mountName => $entry) {
61-
if (!array_key_exists($entry['type'], $availableTypes)) {
65+
if (!is_array($fstabConfig)) {
66+
continue;
67+
}
68+
69+
$filesystems = is_array($fstabConfig['filesystems'] ?? null) ? $fstabConfig['filesystems'] : [];
70+
71+
// @mago-expect analysis:mixed-assignment
72+
foreach ($filesystems as $mountName => $entry) {
73+
if (!is_array($entry)) {
74+
continue;
75+
}
76+
77+
$entryType = is_string($entry['type'] ?? null) ? $entry['type'] : '';
78+
79+
if (!array_key_exists($entryType, $availableTypes)) {
6280
throw new LogicException(sprintf(
6381
'Fstab "%s" mount "%s": no filesystem factory registered for type "%s". Available types: [%s].',
64-
$fstabName,
65-
$mountName,
66-
$entry['type'],
82+
$fstabNameStr,
83+
(string) $mountName,
84+
$entryType,
6785
implode(', ', array_keys($availableTypes)),
6886
));
6987
}
7088

71-
$resolvedFilesystems[$mountName] = $this->resolveServiceReferences($entry);
89+
$entry['type'] = $entryType;
90+
$resolvedFilesystems[(string) $mountName] = $this->resolveServiceReferences($entry);
7291
}
7392

93+
// @mago-expect analysis:mixed-assignment
94+
$telemetryRaw = $fstabConfig['telemetry'] ?? [];
95+
$telemetryArray = is_array($telemetryRaw) ? $telemetryRaw : [];
96+
7497
$telemetryReference = $this->buildTelemetryConfigReference(
7598
$container,
76-
$fstabName,
77-
$fstabConfig['telemetry'] ?? [],
99+
$fstabNameStr,
100+
$telemetryArray,
78101
);
79102

80103
$definition = new Definition(FilesystemTable::class);
81104
$definition->setFactory([FstabBuilder::class, 'build']);
82105
$definition->setArguments([
83106
new Reference(RegisterFilesystemFactoriesPass::REGISTRY_SERVICE_ID),
84-
$fstabName,
107+
$fstabNameStr,
85108
$resolvedFilesystems,
86109
$telemetryReference,
87110
]);
88111
$definition->setPublic(false);
89112

90-
$serviceId = self::FSTAB_SERVICE_PREFIX . $fstabName;
113+
$serviceId = self::FSTAB_SERVICE_PREFIX . $fstabNameStr;
91114
$container->setDefinition($serviceId, $definition);
92115

93-
$aliasId = FilesystemTable::class . ' $' . $this->camelCase($fstabName) . 'Fstab';
116+
$aliasId = FilesystemTable::class . ' $' . $this->camelCase($fstabNameStr) . 'Fstab';
94117
$container->setAlias($aliasId, $serviceId)->setPublic(true);
95118
}
96119

@@ -100,7 +123,7 @@ public function process(ContainerBuilder $container): void
100123
}
101124

102125
/**
103-
* @param array<string, mixed> $telemetry
126+
* @param array<array-key, mixed> $telemetry
104127
*/
105128
private function buildTelemetryConfigReference(
106129
ContainerBuilder $container,
@@ -111,7 +134,9 @@ private function buildTelemetryConfigReference(
111134
return null;
112135
}
113136

137+
// @mago-expect analysis:mixed-assignment
114138
$telemetryServiceId = $telemetry['telemetry_service_id'] ?? null;
139+
// @mago-expect analysis:mixed-assignment
115140
$clockServiceId = $telemetry['clock_service_id'] ?? null;
116141

117142
if (!is_string($telemetryServiceId) || $telemetryServiceId === '') {
@@ -128,10 +153,11 @@ private function buildTelemetryConfigReference(
128153
));
129154
}
130155

131-
/** @var array<string, mixed> $optionsConfig */
132-
$optionsConfig = $telemetry['options'] ?? [];
133-
$traceStreams = (bool) ($optionsConfig['trace_streams'] ?? true);
134-
$collectMetrics = (bool) ($optionsConfig['collect_metrics'] ?? true);
156+
// @mago-expect analysis:mixed-assignment
157+
$optionsRaw = $telemetry['options'] ?? [];
158+
$optionsConfig = is_array($optionsRaw) ? $optionsRaw : [];
159+
$traceStreams = ($optionsConfig['trace_streams'] ?? true) === true;
160+
$collectMetrics = ($optionsConfig['collect_metrics'] ?? true) === true;
135161

136162
$optionsDefinition = new Definition(FilesystemTelemetryOptions::class);
137163
$optionsDefinition->setArguments([$traceStreams, $collectMetrics]);
@@ -164,8 +190,9 @@ private function collectAvailableTypes(ContainerBuilder $container): array
164190
$types = [];
165191

166192
foreach ($container->findTaggedServiceIds(RegisterFilesystemFactoriesPass::TAG) as $serviceId => $tags) {
193+
// @mago-expect analysis:mixed-assignment
167194
foreach ($tags as $tag) {
168-
if (array_key_exists('type', $tag) && is_string($tag['type']) && $tag['type'] !== '') {
195+
if (is_array($tag) && array_key_exists('type', $tag) && is_string($tag['type']) && $tag['type'] !== '') {
169196
$types[$tag['type']] = $serviceId;
170197
}
171198
}
@@ -175,9 +202,9 @@ private function collectAvailableTypes(ContainerBuilder $container): array
175202
}
176203

177204
/**
178-
* @param array<string, mixed>&array{type: string} $entry
205+
* @param array<array-key, mixed> $entry
179206
*
180-
* @return array<string, mixed>&array{type: string}
207+
* @return array<array-key, mixed>
181208
*/
182209
private function resolveAwsS3References(array $entry): array
183210
{
@@ -218,9 +245,9 @@ private function resolveAwsS3References(array $entry): array
218245
}
219246

220247
/**
221-
* @param array<string, mixed>&array{type: string} $entry
248+
* @param array<array-key, mixed> $entry
222249
*
223-
* @return array<string, mixed>&array{type: string}
250+
* @return array<array-key, mixed>
224251
*/
225252
private function resolveAzureBlobReferences(array $entry): array
226253
{
@@ -261,9 +288,9 @@ private function resolveAzureBlobReferences(array $entry): array
261288
}
262289

263290
/**
264-
* @param array<string, mixed>&array{type: string} $entry
291+
* @param array<array-key, mixed> $entry
265292
*
266-
* @return array<string, mixed>&array{type: string}
293+
* @return array<array-key, mixed>
267294
*/
268295
private function resolveServiceReferences(array $entry): array
269296
{

src/bridge/symfony/filesystem-bundle/src/Flow/Bridge/Symfony/FilesystemBundle/DependencyInjection/Compiler/RegisterFilesystemFactoriesPass.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Symfony\Component\DependencyInjection\Reference;
1111

1212
use function array_key_exists;
13+
use function is_array;
1314
use function is_string;
1415
use function sprintf;
1516

@@ -29,8 +30,9 @@ public function process(ContainerBuilder $container): void
2930
$seen = [];
3031

3132
foreach ($container->findTaggedServiceIds(self::TAG) as $serviceId => $tags) {
33+
// @mago-expect analysis:mixed-assignment
3234
foreach ($tags as $tag) {
33-
if (!array_key_exists('type', $tag) || !is_string($tag['type']) || $tag['type'] === '') {
35+
if (!is_array($tag) || !array_key_exists('type', $tag) || !is_string($tag['type']) || $tag['type'] === '') {
3436
throw new LogicException(sprintf(
3537
'Service "%s" is tagged with "%s" but is missing a non-empty "type" attribute.',
3638
$serviceId,

src/bridge/symfony/filesystem-bundle/src/Flow/Bridge/Symfony/FilesystemBundle/DependencyInjection/Compiler/RegisterFstabLocatorPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@ public function process(ContainerBuilder $container): void
4040

4141
$container->setDefinition(self::LOCATOR_SERVICE_ID, $locator);
4242

43-
$container->setParameter(self::DEFAULT_FSTAB_PARAMETER, (string) ($config['default_fstab'] ?? ''));
43+
$container->setParameter(self::DEFAULT_FSTAB_PARAMETER, $config['default_fstab'] ?? '');
4444
}
4545
}

0 commit comments

Comments
 (0)