Skip to content

Commit

Permalink
Merge pull request #116 from siketyan/feat/console-reporter
Browse files Browse the repository at this point in the history
feat: Introduce console reporter, enabled by default
  • Loading branch information
siketyan authored Jul 22, 2023
2 parents 3b60f75 + b6334d6 commit bf10fd6
Show file tree
Hide file tree
Showing 14 changed files with 404 additions and 232 deletions.
16 changes: 14 additions & 2 deletions config/reporters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ services:
arguments:
- 'base_uri': 'https://api.github.com/'

Siketyan\Loxcan\Reporter\GitHub\GitHubMarkdownBuilder: ~
Siketyan\Loxcan\Reporter\MarkdownBuilder: ~

Siketyan\Loxcan\Reporter\GitHub\GitHubUserPool:
shared: true
Expand All @@ -16,5 +16,17 @@ services:

Siketyan\Loxcan\Reporter\GitHub\GitHubReporter:
arguments:
$markdownBuilder: '@Siketyan\Loxcan\Reporter\GitHub\GitHubMarkdownBuilder'
$markdownBuilder: '@Siketyan\Loxcan\Reporter\MarkdownBuilder'
$client: '@Siketyan\Loxcan\Reporter\GitHub\GitHubClient'
tags:
- 'loxcan.reporters'

Siketyan\Loxcan\Reporter\Console\ConsoleReporter:
arguments:
$markdownBuilder: '@Siketyan\Loxcan\Reporter\MarkdownBuilder'
tags:
- 'loxcan.reporters'

Siketyan\Loxcan\Reporter\ReporterResolver:
arguments:
$reporters: !tagged 'loxcan.reporters'
3 changes: 1 addition & 2 deletions config/usecases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ services:

Siketyan\Loxcan\UseCase\ReportUseCase:
arguments:
$reporters:
- '@Siketyan\Loxcan\Reporter\GitHub\GitHubReporter'
$reporterResolver: '@Siketyan\Loxcan\Reporter\ReporterResolver'
120 changes: 24 additions & 96 deletions src/Command/ScanCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@
namespace Siketyan\Loxcan\Command;

use Eloquent\Pathogen\Path;
use JetBrains\PhpStorm\Pure;
use Siketyan\Loxcan\Model\DependencyCollectionDiff;
use Siketyan\Loxcan\Model\Repository;
use Siketyan\Loxcan\Reporter\Console\ConsoleReporter;
use Siketyan\Loxcan\UseCase\ReportUseCase;
use Siketyan\Loxcan\UseCase\ScanUseCase;
use Siketyan\Loxcan\Versioning\VersionDiff;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Color;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

Expand All @@ -34,6 +32,20 @@ protected function configure(): void
$this
->addArgument('base', InputArgument::OPTIONAL)
->addArgument('head', InputArgument::OPTIONAL)
->addOption(
'reporter',
'r',
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
'Reporter names to use for exporting diffs found. [available: console, github]',
['console'],
)
->addOption(
'flavor',
null,
InputOption::VALUE_REQUIRED,
'Output flavor for console exporter. [available: pretty, markdown]',
'pretty',
)
;
}

Expand All @@ -47,102 +59,18 @@ public function execute(InputInterface $input, OutputInterface $output): int
$base = $input->getArgument('base');
/** @var null|string $head */
$head = $input->getArgument('head');
/** @var list<string> $reporters */
$reporters = $input->getOption('reporter');
/** @var string $flavor $flavor */
$flavor = $input->getOption('flavor');

$diffs = $this->useCase->scan($repository, $base, $head);

if ($diffs === []) {
$io->writeln(
'✨ No lock file changes found, looks shine!',
);
} else {
$this->printDiffs($io, $diffs);
}

$this->reportUseCase->report($diffs);
$this->reportUseCase->report($diffs, $reporters, [
ConsoleReporter::CONTEXT_SYMFONY_IO => $io,
ConsoleReporter::CONTEXT_FLAVOR => $flavor,
]);

return 0;
}

/**
* @param array<string, DependencyCollectionDiff> $diffs
*/
private function printDiffs(SymfonyStyle $io, array $diffs): void
{
foreach ($diffs as $file => $diff) {
$io->section($file);

if ($diff->count() === 0) {
$io->writeln(
'🔄 The file was updated, but no dependency changes found.',
);

continue;
}

$rows = [];

foreach ($diff->getAdded() as $dependency) {
$rows[] = [
'',
$dependency->getPackage()->getName(),
'',
$dependency->getVersion(),
];
}

foreach ($diff->getUpdated() as $dependencyDiff) {
$versionDiff = $dependencyDiff->getVersionDiff();
$rows[] = [
$this->getVersionDiffTypeEmoji($versionDiff),
$this->emphasizeBreakingChanges($versionDiff, $dependencyDiff->getPackage()->getName()),
$this->emphasizeBreakingChanges($versionDiff, (string) $versionDiff->getBefore()),
$this->emphasizeBreakingChanges($versionDiff, (string) $versionDiff->getAfter()),
];
}

foreach ($diff->getRemoved() as $dependency) {
$rows[] = [
'',
$dependency->getPackage()->getName(),
$dependency->getVersion(),
'',
];
}

$io->table(
['', 'Package', 'Before', 'After'],
$rows,
);
}
}

#[Pure]
private function getVersionDiffTypeEmoji(VersionDiff $diff): string
{
switch ($diff->getType()) {
case VersionDiff::UPGRADED:
return '⬆️';

case VersionDiff::DOWNGRADED:
return '⬇️';

case VersionDiff::CHANGED:
return '💥';

default:
case VersionDiff::UNKNOWN:
return '🔄';
}
}

private function emphasizeBreakingChanges(VersionDiff $diff, string $str): string
{
$emphasize = new Color('bright-white', '', ['bold']);

if (!$diff->isCompatible()) {
return $emphasize->apply($str);
}

return $str;
}
}
17 changes: 17 additions & 0 deletions src/Exception/InvalidReporterException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Siketyan\Loxcan\Exception;

class InvalidReporterException extends RuntimeException
{
public function __construct(string $name, int $code = 0, ?\Throwable $previous = null)
{
parent::__construct(
sprintf('The reporter "%s" is not valid.', $name),
$code,
$previous,
);
}
}
132 changes: 132 additions & 0 deletions src/Reporter/Console/ConsoleReporter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<?php

declare(strict_types=1);

namespace Siketyan\Loxcan\Reporter\Console;

use JetBrains\PhpStorm\Pure;
use Siketyan\Loxcan\Reporter\MarkdownBuilder;
use Siketyan\Loxcan\Reporter\ReporterInterface;
use Siketyan\Loxcan\Versioning\VersionDiff;
use Symfony\Component\Console\Color;
use Symfony\Component\Console\Style\SymfonyStyle;

class ConsoleReporter implements ReporterInterface
{
public const CONTEXT_SYMFONY_IO = 'console.symfony-style';
public const CONTEXT_FLAVOR = 'console.flavor';

public const FLAVOR_MARKDOWN = 'markdown';

public function __construct(
private readonly MarkdownBuilder $markdownBuilder,
) {
}

public function report(array $diffs, array $context = []): void
{
$io = $context[self::CONTEXT_SYMFONY_IO] ?? null;
\assert($io instanceof SymfonyStyle);

if ($diffs === []) {
$io->writeln(
'✨ No lock file changes found, looks shine!',
);

return;
}

if (($context[self::CONTEXT_FLAVOR] ?? null) === self::FLAVOR_MARKDOWN) {
echo $this->markdownBuilder->build($diffs) . \PHP_EOL;

return;
}

foreach ($diffs as $file => $diff) {
$io->section($file);

if ($diff->count() === 0) {
$io->writeln(
'🔄 The file was updated, but no dependency changes found.',
);

continue;
}

$rows = [];

foreach ($diff->getAdded() as $dependency) {
$rows[] = [
'',
$dependency->getPackage()->getName(),
'',
$dependency->getVersion(),
];
}

foreach ($diff->getUpdated() as $dependencyDiff) {
$versionDiff = $dependencyDiff->getVersionDiff();
$rows[] = [
$this->getVersionDiffTypeEmoji($versionDiff),
$this->emphasizeBreakingChanges($versionDiff, $dependencyDiff->getPackage()->getName()),
$this->emphasizeBreakingChanges($versionDiff, (string) $versionDiff->getBefore()),
$this->emphasizeBreakingChanges($versionDiff, (string) $versionDiff->getAfter()),
];
}

foreach ($diff->getRemoved() as $dependency) {
$rows[] = [
'',
$dependency->getPackage()->getName(),
$dependency->getVersion(),
'',
];
}

$io->table(
['', 'Package', 'Before', 'After'],
$rows,
);
}
}

#[Pure]
private function getVersionDiffTypeEmoji(VersionDiff $diff): string
{
switch ($diff->getType()) {
case VersionDiff::UPGRADED:
return '⬆️';

case VersionDiff::DOWNGRADED:
return '⬇️';

case VersionDiff::CHANGED:
return '💥';

default:
case VersionDiff::UNKNOWN:
return '🔄';
}
}

private function emphasizeBreakingChanges(VersionDiff $diff, string $str): string
{
$emphasize = new Color('bright-white', '', ['bold']);

if (!$diff->isCompatible()) {
return $emphasize->apply($str);
}

return $str;
}

public function supports(): bool
{
return true;
}

public function name(): string
{
return 'console';
}
}
10 changes: 8 additions & 2 deletions src/Reporter/GitHub/GitHubReporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,23 @@
namespace Siketyan\Loxcan\Reporter\GitHub;

use Siketyan\Loxcan\Reporter\EnvironmentTrait;
use Siketyan\Loxcan\Reporter\MarkdownBuilder;
use Siketyan\Loxcan\Reporter\ReporterInterface;

class GitHubReporter implements ReporterInterface
{
use EnvironmentTrait;

public function __construct(
private readonly GitHubMarkdownBuilder $markdownBuilder,
private readonly MarkdownBuilder $markdownBuilder,
private readonly GitHubClient $client,
) {
}

/**
* @throws \JsonException
*/
public function report(array $diffs): void
public function report(array $diffs, array $context = []): void
{
$owner = $this->getEnv('LOXCAN_REPORTER_GITHUB_OWNER');
$repo = $this->getEnv('LOXCAN_REPORTER_GITHUB_REPO');
Expand Down Expand Up @@ -54,4 +55,9 @@ public function supports(): bool

return \is_string($env) && $env !== '';
}

public function name(): string
{
return 'github';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

declare(strict_types=1);

namespace Siketyan\Loxcan\Reporter\GitHub;
namespace Siketyan\Loxcan\Reporter;

use JetBrains\PhpStorm\Pure;
use Siketyan\Loxcan\Model\DependencyCollectionDiff;
use Siketyan\Loxcan\Versioning\VersionDiff;

class GitHubMarkdownBuilder
class MarkdownBuilder
{
/**
* @param array<string, DependencyCollectionDiff> $diffs
Expand Down
Loading

0 comments on commit bf10fd6

Please sign in to comment.