Skip to content

Commit

Permalink
Merge pull request #371 from Roave/feature/#342-support-github-output…
Browse files Browse the repository at this point in the history
…-format

#342 implemented GitHub Actions output format
  • Loading branch information
Ocramius authored Dec 26, 2021
2 parents 8c859ae + aad5f2f commit 316285b
Show file tree
Hide file tree
Showing 25 changed files with 536 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
run: "composer install --no-interaction --no-progress --no-suggest"

- name: "Roave Backward Compatibility Check"
run: "bin/roave-backward-compatibility-check"
run: "bin/roave-backward-compatibility-check --format=github-actions"

check-composer-dependencies:
name: "Composer Require Checker"
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ To generate additional documentation for changelogs:
vendor/bin/roave-backward-compatibility-check --format=markdown > results.md
```

### GitHub Actions

When running in GitHub Actions, it is endorsed to use the `--format=github-actions` output format:

```bash
vendor/bin/roave-backward-compatibility-check --format=github-actions
```

### Documentation

If you need further guidance:
Expand Down
62 changes: 50 additions & 12 deletions src/Change.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,15 @@ final class Change
private const REMOVED = 'removed';
private const SKIPPED = 'skipped';

/** @psalm-var self::* */
private string $modificationType;

private string $description;

private bool $isBcBreak;

/** @psalm-param self::* $modificationType */
private function __construct(string $modificationType, string $description, bool $isBcBreak)
{
$this->modificationType = $modificationType;
$this->description = $description;
$this->isBcBreak = $isBcBreak;
private function __construct(
private string $modificationType,
public string $description,
private bool $isBcBreak,
public ?string $file = null,
public ?int $line = null,
public ?int $column = null
) {
}

/** @psalm-pure */
Expand Down Expand Up @@ -75,6 +71,48 @@ public function isSkipped(): bool
return $this->modificationType === self::SKIPPED;
}

/** @internal */
public function withFilePositionsIfNotAlreadySet(
?string $file,
int $line,
?int $column
): self {
$instance = clone $this;

$instance->file ??= $file;
$instance->line ??= $line;
$instance->column ??= $column;

return $instance;
}

public function onFile(?string $file): self
{
$instance = clone $this;

$instance->file = $file;

return $instance;
}

public function onLine(int $line): self
{
$instance = clone $this;

$instance->line = $line;

return $instance;
}

public function onColumn(?int $column): self
{
$instance = clone $this;

$instance->column = $column;

return $instance;
}

public function __toString(): string
{
return Str\format(
Expand Down
24 changes: 17 additions & 7 deletions src/Command/AssertBackwardsCompatible.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\CompareApi;
use Roave\BackwardCompatibility\Factory\ComposerInstallationReflectorFactory;
use Roave\BackwardCompatibility\Formatter\GithubActionsFormatter;
use Roave\BackwardCompatibility\Formatter\MarkdownPipedToSymfonyConsoleFormatter;
use Roave\BackwardCompatibility\Formatter\SymfonyConsoleTextFormatter;
use Roave\BackwardCompatibility\Git\CheckedOutRepository;
Expand Down Expand Up @@ -94,7 +95,8 @@ protected function configure(): void
'format',
null,
InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY,
'Currently only supports "markdown"'
'Currently supports "console", "markdown" or "github-actions"',
['console']
)
->addOption(
'install-development-dependencies',
Expand Down Expand Up @@ -174,12 +176,20 @@ public function execute(InputInterface $input, OutputInterface $output): int
)
);

(new SymfonyConsoleTextFormatter($stdErr))->write($changes);

$outputFormats = Type\vec(Type\string())->coerce($input->getOption('format') ?: []);

if (Iter\contains($outputFormats, 'markdown')) {
(new MarkdownPipedToSymfonyConsoleFormatter($output))->write($changes);
$formatters = [
'console' => new SymfonyConsoleTextFormatter($stdErr),
'markdown' => new MarkdownPipedToSymfonyConsoleFormatter($output),
'github-actions' => new GithubActionsFormatter($output, $toPath),
];

foreach (
Type\vec(Type\union(
Type\literal_scalar('console'),
Type\literal_scalar('markdown'),
Type\literal_scalar('github-actions'),
))->coerce((array) $input->getOption('format')) as $format
) {
$formatters[$format]->write($changes);
}
} finally {
$this->git->remove($fromPath);
Expand Down
11 changes: 10 additions & 1 deletion src/DetectChanges/BCBreak/ClassBased/MultipleChecksOnAClass.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\SymbolStartColumn;
use Roave\BetterReflection\Reflection\ReflectionClass;

final class MultipleChecksOnAClass implements ClassBased
Expand All @@ -26,8 +27,16 @@ public function __invoke(ReflectionClass $fromClass, ReflectionClass $toClass):
/** @return iterable<int, Change> */
private function multipleChecks(ReflectionClass $fromClass, ReflectionClass $toClass): iterable
{
$toFile = $toClass->getFileName();
$toLine = $toClass->getStartLine();
$toColumn = SymbolStartColumn::get($toClass);

foreach ($this->checks as $check) {
yield from $check($fromClass, $toClass);
foreach ($check($fromClass, $toClass) as $change) {
// Note: this approach allows us to quickly add file/line/column to each change, but in future,
// we will need to push this concern into each checker instead.
yield $change->withFilePositionsIfNotAlreadySet($toFile, $toLine, $toColumn);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\SymbolStartColumn;
use Roave\BetterReflection\Reflection\ReflectionClassConstant;

final class MultipleChecksOnAClassConstant implements ClassConstantBased
Expand All @@ -20,14 +21,23 @@ public function __construct(ClassConstantBased ...$checks)

public function __invoke(ReflectionClassConstant $fromConstant, ReflectionClassConstant $toConstant): Changes
{
return Changes::fromIterator($this->multipleChecks($fromConstant, $fromConstant));
return Changes::fromIterator($this->multipleChecks($fromConstant, $toConstant));
}

/** @return iterable<int, Change> */
private function multipleChecks(ReflectionClassConstant $fromConstant, ReflectionClassConstant $toConstant): iterable
{
$toLine = $toConstant->getStartLine();
$toColumn = SymbolStartColumn::get($toConstant);
$toFile = $toConstant->getDeclaringClass()
->getFileName();

foreach ($this->checks as $check) {
yield from $check($fromConstant, $toConstant);
foreach ($check($fromConstant, $toConstant) as $change) {
// Note: this approach allows us to quickly add file/line/column to each change, but in future,
// we will need to push this concern into each checker instead.
yield $change->withFilePositionsIfNotAlreadySet($toFile, $toLine, $toColumn);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\SymbolStartColumn;
use Roave\BetterReflection\Reflection\ReflectionFunction;
use Roave\BetterReflection\Reflection\ReflectionMethod;

Expand Down Expand Up @@ -38,8 +39,16 @@ private function multipleChecks(
ReflectionMethod|ReflectionFunction $fromFunction,
ReflectionMethod|ReflectionFunction $toFunction
): iterable {
$toFile = $toFunction->getFileName();
$toLine = $toFunction->getStartLine();
$toColumn = SymbolStartColumn::get($toFunction);

foreach ($this->checks as $check) {
yield from $check($fromFunction, $toFunction);
foreach ($check($fromFunction, $toFunction) as $change) {
// Note: this approach allows us to quickly add file/line/column to each change, but in future,
// we will need to push this concern into each checker instead.
yield $change->withFilePositionsIfNotAlreadySet($toFile, $toLine, $toColumn);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\SymbolStartColumn;
use Roave\BetterReflection\Reflection\ReflectionClass;

final class MultipleChecksOnAnInterface implements InterfaceBased
Expand All @@ -26,8 +27,16 @@ public function __invoke(ReflectionClass $fromInterface, ReflectionClass $toInte
/** @return iterable<int, Change> */
private function multipleChecks(ReflectionClass $fromInterface, ReflectionClass $toInterface): iterable
{
$toFile = $toInterface->getFileName();
$toLine = $toInterface->getStartLine();
$toColumn = SymbolStartColumn::get($toInterface);

foreach ($this->checks as $check) {
yield from $check($fromInterface, $toInterface);
foreach ($check($fromInterface, $toInterface) as $change) {
// Note: this approach allows us to quickly add file/line/column to each change, but in future,
// we will need to push this concern into each checker instead.
yield $change->withFilePositionsIfNotAlreadySet($toFile, $toLine, $toColumn);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\SymbolStartColumn;
use Roave\BetterReflection\Reflection\ReflectionMethod;

final class MultipleChecksOnAMethod implements MethodBased
Expand All @@ -26,8 +27,16 @@ public function __invoke(ReflectionMethod $fromMethod, ReflectionMethod $toMetho
/** @return iterable<int, Change> */
private function multipleChecks(ReflectionMethod $fromMethod, ReflectionMethod $toMethod): iterable
{
$toFile = $toMethod->getFileName();
$toLine = $toMethod->getStartLine();
$toColumn = SymbolStartColumn::get($toMethod);

foreach ($this->checks as $check) {
yield from $check($fromMethod, $toMethod);
foreach ($check($fromMethod, $toMethod) as $change) {
// Note: this approach allows us to quickly add file/line/column to each change, but in future,
// we will need to push this concern into each checker instead.
yield $change->withFilePositionsIfNotAlreadySet($toFile, $toLine, $toColumn);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\SymbolStartColumn;
use Roave\BetterReflection\Reflection\ReflectionProperty;

final class MultipleChecksOnAProperty implements PropertyBased
Expand All @@ -26,8 +27,17 @@ public function __invoke(ReflectionProperty $fromProperty, ReflectionProperty $t
/** @return iterable<int, Change> */
private function multipleChecks(ReflectionProperty $fromProperty, ReflectionProperty $toProperty): iterable
{
$toLine = $toProperty->getStartLine();
$toColumn = SymbolStartColumn::get($toProperty);
$toFile = $toProperty->getImplementingClass()
->getFileName();

foreach ($this->checks as $check) {
yield from $check($fromProperty, $toProperty);
foreach ($check($fromProperty, $toProperty) as $change) {
// Note: this approach allows us to quickly add file/line/column to each change, but in future,
// we will need to push this concern into each checker instead.
yield $change->withFilePositionsIfNotAlreadySet($toFile, $toLine, $toColumn);
}
}
}
}
11 changes: 10 additions & 1 deletion src/DetectChanges/BCBreak/TraitBased/MultipleChecksOnATrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Roave\BackwardCompatibility\Change;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Formatter\SymbolStartColumn;
use Roave\BetterReflection\Reflection\ReflectionClass;

final class MultipleChecksOnATrait implements TraitBased
Expand All @@ -26,8 +27,16 @@ public function __invoke(ReflectionClass $fromTrait, ReflectionClass $toTrait):
/** @return iterable<int, Change> */
private function multipleChecks(ReflectionClass $fromTrait, ReflectionClass $toTrait): iterable
{
$toFile = $toTrait->getFileName();
$toLine = $toTrait->getStartLine();
$toColumn = SymbolStartColumn::get($toTrait);

foreach ($this->checks as $check) {
yield from $check($fromTrait, $toTrait);
foreach ($check($fromTrait, $toTrait) as $change) {
// Note: this approach allows us to quickly add file/line/column to each change, but in future,
// we will need to push this concern into each checker instead.
yield $change->withFilePositionsIfNotAlreadySet($toFile, $toLine, $toColumn);
}
}
}
}
38 changes: 38 additions & 0 deletions src/Formatter/GithubActionsFormatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace Roave\BackwardCompatibility\Formatter;

use Psl\Str;
use Roave\BackwardCompatibility\Changes;
use Roave\BackwardCompatibility\Git\CheckedOutRepository;
use Symfony\Component\Console\CI\GithubActionReporter;
use Symfony\Component\Console\Output\OutputInterface;

/** @internal */
final class GithubActionsFormatter implements OutputFormatter
{
public function __construct(
private OutputInterface $output,
private CheckedOutRepository $basePath
) {
}

public function write(Changes $changes): void
{
$reporter = new GithubActionReporter($this->output);
$basePath = $this->basePath->__toString() . '/';

foreach ($changes as $change) {
$reporter->error(
$change->description,
$change->file === null
? null
: Str\replace($change->file, $basePath, ''),
$change->line,
$change->column
);
}
}
}
Loading

0 comments on commit 316285b

Please sign in to comment.