Skip to content

Commit 2af196e

Browse files
committed
Simplify structured command logging
1 parent 22859e7 commit 2af196e

26 files changed

Lines changed: 134 additions & 125 deletions

src/Console/Command/Traits/LogsCommandResults.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,8 @@ private function log(
5959
...$context,
6060
];
6161

62-
match ($logLevel) {
63-
LogLevel::INFO => $this->getLogger()->info($message, $context),
64-
LogLevel::NOTICE => $this->getLogger()->notice($message, $context),
65-
LogLevel::WARNING => $this->getLogger()->warning($message, $context),
66-
default => $this->getLogger()->log($logLevel, $message, $context),
67-
};
62+
$this->getLogger()
63+
->log($logLevel, $message, $context);
6864
}
6965

7066
/**

src/Console/Logger/Processor/CommandOutputProcessor.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,15 @@ private function normalizeStructuredPayload(mixed $payload): mixed
323323
$changedFiles = [];
324324

325325
foreach ($payload['file_diffs'] as $fileDiff) {
326-
if (! \is_array($fileDiff) || ! isset($fileDiff['file']) || ! \is_string($fileDiff['file'])) {
326+
if (! \is_array($fileDiff)) {
327+
continue;
328+
}
329+
330+
if (! isset($fileDiff['file'])) {
331+
continue;
332+
}
333+
334+
if (! \is_string($fileDiff['file'])) {
327335
continue;
328336
}
329337

tests/Composer/Capability/DevToolsCommandProviderTest.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
use FastForward\DevTools\Composer\Capability\DevToolsCommandProvider;
2323
use FastForward\DevTools\Composer\Command\ProxyCommand;
2424
use FastForward\DevTools\Composer\DevToolsPluginInterface;
25+
use FastForward\DevTools\Console\DevTools;
2526
use FastForward\DevTools\Console\Command\FixtureWithoutAsCommand;
27+
use FastForward\DevTools\Console\Output\GithubActionOutput;
2628
use FastForward\DevTools\Container\ContainerFactory;
2729
use FastForward\DevTools\Container\ServiceProvider\DevToolsServiceProvider;
2830
use FastForward\DevTools\Path\DevToolsPathResolver;
29-
use FastForward\DevTools\Console\Output\GithubActionOutput;
3031
use PHPUnit\Framework\Attributes\CoversClass;
3132
use PHPUnit\Framework\Attributes\Test;
3233
use PHPUnit\Framework\Attributes\UsesClass;
@@ -91,9 +92,12 @@ protected function setUp(): void
9192
'plugin' => $this->plugin->reveal(),
9293
]);
9394

94-
ContainerFactory::set('FastForward\DevTools\Console\DevTools', new class ($this->applicationState) {
95+
ContainerFactory::set(DevTools::class, new readonly class ($this->applicationState) {
96+
/**
97+
* @param stdClass $state
98+
*/
9599
public function __construct(
96-
private readonly stdClass $state,
100+
private stdClass $state,
97101
) {}
98102

99103
/**

tests/Console/Command/AgentsCommandTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public function executeWillFailWhenPackagedAgentsDirectoryDoesNotExist(): void
104104
$this->filesystem->exists($agentsPath)
105105
->willReturn(false);
106106
$this->synchronizer->synchronize(Argument::cetera())->shouldNotBeCalled();
107-
$this->logger->info('Starting agents synchronization...', [
107+
$this->logger->log('info', 'Starting agents synchronization...', [
108108
'input' => $this->input->reveal(),
109109
])
110110
->shouldBeCalledOnce();
@@ -139,11 +139,11 @@ public function executeWillCreateAgentsDirectoryWhenItDoesNotExist(): void
139139
$this->synchronizer->synchronize($agentsPath, $agentsPath, '.agents/agents')
140140
->willReturn($result)
141141
->shouldBeCalledOnce();
142-
$this->logger->info('Starting agents synchronization...', [
142+
$this->logger->log('info', 'Starting agents synchronization...', [
143143
'input' => $this->input->reveal(),
144144
])
145145
->shouldBeCalledOnce();
146-
$this->logger->info('Created .agents/agents directory.', [
146+
$this->logger->log('info', 'Created .agents/agents directory.', [
147147
'input' => $this->input->reveal(),
148148
])
149149
->shouldBeCalledOnce();
@@ -176,7 +176,7 @@ public function executeWillReturnFailureWhenSynchronizerFails(): void
176176
$this->synchronizer->synchronize($agentsPath, $agentsPath, '.agents/agents')
177177
->willReturn($result)
178178
->shouldBeCalledOnce();
179-
$this->logger->info('Starting agents synchronization...', [
179+
$this->logger->log('info', 'Starting agents synchronization...', [
180180
'input' => $this->input->reveal(),
181181
])
182182
->shouldBeCalledOnce();

tests/Console/Command/CodeOwnersCommandTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ protected function setUp(): void
131131
->willReturn(false);
132132
$this->output->writeln(Argument::any());
133133
$this->fileDiffer->formatForConsole(Argument::cetera())->willReturn(null);
134-
$this->logger->info(Argument::cetera())->will(static function (): void {});
135-
$this->logger->notice(Argument::cetera())->will(static function (): void {});
134+
$this->logger->log('info', Argument::cetera())->will(static function (): void {});
135+
$this->logger->log('notice', Argument::cetera())->will(static function (): void {});
136136
$this->logger->log(Argument::cetera())->will(static function (): void {});
137137
$this->logger->error(Argument::cetera())->will(static function (): void {});
138138
$this->command = new CodeOwnersCommand(

tests/Console/Command/CodeStyleCommandTest.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public function executeWillReturnSuccessWhenProcessQueueSucceeds(): void
132132
$this->processQueue->run(Argument::type('object'))
133133
->willReturn(CodeStyleCommand::SUCCESS)
134134
->shouldBeCalled();
135-
$this->logger->info('Running code style checks and fixes...', Argument::that(
135+
$this->logger->log('info', 'Running code style checks and fixes...', Argument::that(
136136
fn(array $context): bool => $this->input->reveal() === $context['input']
137137
))
138138
->shouldBeCalled();
@@ -157,7 +157,7 @@ public function executeWillReturnFailureWhenProcessQueueFails(): void
157157
$this->processQueue->run(Argument::type('object'))
158158
->willReturn(CodeStyleCommand::FAILURE)
159159
->shouldBeCalled();
160-
$this->logger->info('Running code style checks and fixes...', Argument::that(
160+
$this->logger->log('info', 'Running code style checks and fixes...', Argument::that(
161161
fn(array $context): bool => $this->input->reveal() === $context['input']
162162
))
163163
->shouldBeCalled();
@@ -190,8 +190,6 @@ public function executeWillCaptureBufferedOutputWhenJsonIsRequested(): void
190190
$this->processQueue->run(Argument::type('object'))
191191
->willReturn(CodeStyleCommand::SUCCESS)
192192
->shouldBeCalled();
193-
$this->logger->info(Argument::cetera())
194-
->shouldNotBeCalled();
195193
$this->logger->log(
196194
'info',
197195
'Code style checks completed successfully.',

tests/Console/Command/CopyResourceCommandTest.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ protected function setUp(): void
119119
->willReturn(false);
120120
$this->fileDiffer->formatForConsole(Argument::cetera())
121121
->will(static fn(array $arguments): ?string => $arguments[0]);
122-
$this->logger->info(Argument::cetera())->will(static function (): void {});
123-
$this->logger->notice(Argument::cetera())->will(static function (): void {});
122+
$this->logger->log('info', Argument::cetera())->will(static function (): void {});
123+
$this->logger->log('notice', Argument::cetera())->will(static function (): void {});
124124
$this->logger->error(Argument::cetera())->will(static function (): void {});
125125
$this->command = new CopyResourceCommand(
126126
$this->filesystem->reveal(),
@@ -273,11 +273,13 @@ public function executeWillShowDiffBeforeOverwritingChangedFile(): void
273273
))
274274
->shouldBeCalledOnce();
275275

276-
$this->logger->notice(
276+
$this->logger->log(
277+
'notice',
277278
'Overwriting resource /project/.editorconfig from /package/.editorconfig.',
278279
Argument::type('array'),
279280
)->shouldBeCalledOnce();
280-
$this->logger->notice(
281+
$this->logger->log(
282+
'notice',
281283
"--- Current: /project/.editorconfig\n+++ Source: /package/.editorconfig\n@@ -1 +1 @@\n-old\n+new",
282284
Argument::type('array'),
283285
)->shouldBeCalledOnce();
@@ -316,7 +318,8 @@ public function executeWillReportUnchangedOverwriteAsNoOp(): void
316318
))
317319
->shouldBeCalledOnce();
318320

319-
$this->logger->notice(
321+
$this->logger->log(
322+
'notice',
320323
'Target /project/.editorconfig already matches source /package/.editorconfig; overwrite skipped.',
321324
Argument::type('array'),
322325
)->shouldBeCalledOnce();
@@ -355,7 +358,8 @@ public function executeWillHandleBinaryOverwriteGracefully(): void
355358
))
356359
->shouldBeCalledOnce();
357360

358-
$this->logger->notice(
361+
$this->logger->log(
362+
'notice',
359363
'Target /project/.editorconfig will be overwritten from /package/.editorconfig, but a text diff is unavailable for binary content.',
360364
Argument::type('array'),
361365
)->shouldBeCalledOnce();
@@ -391,9 +395,9 @@ public function executeWillReturnFailureInCheckModeWhenFileWouldChange(): void
391395
$this->fileDiffer->diff('/package/.editorconfig', '/project/.editorconfig')
392396
->willReturn(new FileDiff(FileDiff::STATUS_CHANGED, 'Changed summary', "@@ -1 +1 @@\n-old\n+new"))
393397
->shouldBeCalledOnce();
394-
$this->logger->notice('Changed summary', Argument::type('array'))
398+
$this->logger->log('notice', 'Changed summary', Argument::type('array'))
395399
->shouldBeCalledOnce();
396-
$this->logger->notice("@@ -1 +1 @@\n-old\n+new", Argument::type('array'))
400+
$this->logger->log('notice', "@@ -1 +1 @@\n-old\n+new", Argument::type('array'))
397401
->shouldBeCalledOnce();
398402
$this->filesystem->copy(Argument::cetera())->shouldNotBeCalled();
399403

tests/Console/Command/DependenciesCommandTest.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public function executeWillReturnSuccessWhenPreviewAndAnalyzersSucceed(): void
126126
$this->processQueue->run(Argument::type('object'))
127127
->willReturn(DependenciesCommand::SUCCESS)
128128
->shouldBeCalledOnce();
129-
$this->logger->info('Running dependency analysis...', Argument::that(
129+
$this->logger->log('info', 'Running dependency analysis...', Argument::that(
130130
static fn(array $context): bool => $context['input'] instanceof InputInterface
131131
))
132132
->shouldBeCalledOnce();
@@ -170,7 +170,7 @@ public function executeWillIgnoreJackFailuresWhenMaxOutdatedIsDisabled(): void
170170
$this->processQueue->run(Argument::type('object'))
171171
->willReturn(DependenciesCommand::SUCCESS)
172172
->shouldBeCalledOnce();
173-
$this->logger->info('Running dependency analysis...', Argument::that(
173+
$this->logger->log('info', 'Running dependency analysis...', Argument::that(
174174
static fn(array $context): bool => $context['input'] instanceof InputInterface
175175
))
176176
->shouldBeCalledOnce();
@@ -198,8 +198,6 @@ public function executeWillSuppressProgressLogWhenJsonIsRequested(): void
198198
$this->processQueue->run(Argument::type(OutputInterface::class))
199199
->willReturn(DependenciesCommand::SUCCESS)
200200
->shouldBeCalledOnce();
201-
$this->logger->info(Argument::cetera())
202-
->shouldNotBeCalled();
203201
$this->logger->log(
204202
'info',
205203
'Dependency analysis completed successfully.',

tests/Console/Command/DocsCommandTest.php

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ public function executeWillSkipWhenGuideAndApiSourcesAreMissing(): void
189189
->willReturn(new ProjectCapabilities([], null, false, false, false, false));
190190
$this->processQueue->add(Argument::cetera())
191191
->shouldNotBeCalled();
192-
$this->logger->info('Generating API documentation...', Argument::that(
192+
$this->logger->log('info', 'Generating API documentation...', Argument::that(
193193
static fn(array $context): bool => $context['input'] instanceof InputInterface
194194
))
195195
->shouldBeCalled();
@@ -216,7 +216,7 @@ public function executeWillFailWhenCustomGuideSourceDoesNotExist(): void
216216
->willReturn(new ProjectCapabilities(['src/'], 'FastForward\\DevTools', false, false, false, true));
217217
$this->processQueue->add(Argument::cetera())
218218
->shouldNotBeCalled();
219-
$this->logger->info('Generating API documentation...', Argument::that(
219+
$this->logger->log('info', 'Generating API documentation...', Argument::that(
220220
static fn(array $context): bool => $context['input'] instanceof InputInterface
221221
))
222222
->shouldBeCalled();
@@ -250,7 +250,7 @@ public function executeWillTreatEquivalentDefaultGuideSourcesAsDefault(string $s
250250
$this->processQueue->run($this->output->reveal())
251251
->willReturn(DocsCommand::SUCCESS)
252252
->shouldBeCalled();
253-
$this->logger->info('Generating API documentation...', Argument::that(
253+
$this->logger->log('info', 'Generating API documentation...', Argument::that(
254254
static fn(array $context): bool => $context['input'] instanceof InputInterface
255255
))
256256
->shouldBeCalled();
@@ -282,7 +282,7 @@ public function executeWillReturnSuccessWhenProcessQueueSucceeds(): void
282282
$this->processQueue->run($this->output->reveal())
283283
->willReturn(DocsCommand::SUCCESS)
284284
->shouldBeCalled();
285-
$this->logger->info('Generating API documentation...', Argument::that(
285+
$this->logger->log('info', 'Generating API documentation...', Argument::that(
286286
static fn(array $context): bool => $context['input'] instanceof InputInterface
287287
))
288288
->shouldBeCalled();
@@ -316,8 +316,6 @@ public function executeWillSuppressProgressLogWhenJsonIsRequested(): void
316316
$this->processQueue->run(Argument::type(OutputInterface::class))
317317
->willReturn(DocsCommand::SUCCESS)
318318
->shouldBeCalled();
319-
$this->logger->info(Argument::cetera())
320-
->shouldNotBeCalled();
321319
$this->logger->log(
322320
'info',
323321
'API documentation generated successfully.',

tests/Console/Command/FundingCommandTest.php

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use Symfony\Component\Console\Style\SymfonyStyle;
2424
use FastForward\DevTools\Console\Command\FundingCommand;
2525
use FastForward\DevTools\Console\Command\Traits\LogsCommandResults;
26+
use FastForward\DevTools\Console\Output\GithubActionOutput;
2627
use FastForward\DevTools\Filesystem\FilesystemInterface;
2728
use FastForward\DevTools\Funding\ComposerFundingCodec;
2829
use FastForward\DevTools\Funding\FundingProfile;
@@ -61,6 +62,7 @@
6162
#[UsesClass(DevToolsEnvironment::class)]
6263
#[UsesClass(RuntimeEnvironment::class)]
6364
#[CoversClass(FundingCommand::class)]
65+
#[UsesClass(GithubActionOutput::class)]
6466
#[UsesClass(FileDiff::class)]
6567
#[UsesClass(ComposerFundingCodec::class)]
6668
#[UsesClass(FundingProfile::class)]
@@ -116,9 +118,9 @@ protected function setUp(): void
116118
->willReturn(false);
117119
$this->output->writeln(Argument::any());
118120
$this->fileDiffer->formatForConsole(Argument::cetera())->willReturn(null);
119-
$this->logger->info(Argument::cetera())->will(static function (): void {});
121+
$this->logger->log('info', Argument::cetera())->will(static function (): void {});
120122
$this->logger->log(Argument::cetera())->will(static function (): void {});
121-
$this->logger->notice(Argument::cetera())->will(static function (): void {});
123+
$this->logger->log('notice', Argument::cetera())->will(static function (): void {});
122124
$this->logger->error(Argument::cetera())->will(static function (): void {});
123125
$this->input->getOption('composer-file')
124126
->willReturn('composer.json');
@@ -363,11 +365,12 @@ public function executeWillReturnSuccessWhenComposerFileDoesNotExist(): void
363365
{
364366
$this->filesystem->exists('composer.json')
365367
->willReturn(false);
366-
$this->logger->info('Synchronizing funding metadata...', [
368+
$this->logger->log('info', 'Synchronizing funding metadata...', [
367369
'input' => $this->input->reveal(),
368370
])
369371
->shouldBeCalledOnce();
370-
$this->logger->notice(
372+
$this->logger->log(
373+
'notice',
371374
'Composer file {composer_file} does not exist. Skipping funding synchronization.',
372375
[
373376
'input' => $this->input->reveal(),
@@ -509,7 +512,7 @@ public function executeWillSkipComposerWriteWhenInteractiveConfirmationIsDecline
509512
$fundingYaml,
510513
'Updating managed file .github/FUNDING.yml from generated funding metadata synchronization.',
511514
)->willReturn(new FileDiff(FileDiff::STATUS_UNCHANGED, 'Funding unchanged'))->shouldBeCalledOnce();
512-
$this->logger->notice('Skipped updating {composer_file}.', Argument::type('array'))
515+
$this->logger->log('notice', 'Skipped updating {composer_file}.', Argument::type('array'))
513516
->shouldBeCalledOnce();
514517
$this->logger->log(
515518
'notice',
@@ -664,7 +667,8 @@ public function executeWillSkipFundingFileSynchronizationWhenNoSupportedFundingM
664667
$composerContents,
665668
'Updating managed file composer.json from generated funding metadata synchronization.',
666669
)->willReturn(new FileDiff(FileDiff::STATUS_UNCHANGED, 'Composer unchanged'))->shouldBeCalledOnce();
667-
$this->logger->notice(
670+
$this->logger->log(
671+
'notice',
668672
'No supported funding metadata found. Skipping .github/FUNDING.yml synchronization.',
669673
[
670674
'input' => $this->input->reveal(),

0 commit comments

Comments
 (0)