Skip to content

Commit 52b0f49

Browse files
authored
Merge pull request #14 from IonBazan/feature/github-annotations
add GitHub formatter
2 parents f7f96d2 + a7901c3 commit 52b0f49

File tree

5 files changed

+149
-2
lines changed

5 files changed

+149
-2
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ composer diff --help # Display detailed usage instructions
7171
- `--no-prod` - ignore prod dependencies (`require`)
7272
- `--with-platform` (`-p`) - include platform dependencies (PHP, extensions, etc.)
7373
- `--with-links` (`-l`) - include compare/release URLs
74-
- `--format` (`-f`) - output format (mdtable, mdlist, json) - default: `mdtable`
74+
- `--format` (`-f`) - output format (mdtable, mdlist, json, github) - default: `mdtable`
7575
- `--gitlab-domains` - custom gitlab domains for compare/release URLs - default: use composer config
7676

7777
## Advanced usage

src/Command/DiffCommand.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use IonBazan\ComposerDiff\Diff\DiffEntries;
77
use IonBazan\ComposerDiff\Diff\DiffEntry;
88
use IonBazan\ComposerDiff\Formatter\Formatter;
9+
use IonBazan\ComposerDiff\Formatter\GitHubFormatter;
910
use IonBazan\ComposerDiff\Formatter\JsonFormatter;
1011
use IonBazan\ComposerDiff\Formatter\MarkdownListFormatter;
1112
use IonBazan\ComposerDiff\Formatter\MarkdownTableFormatter;
@@ -58,7 +59,7 @@ protected function configure()
5859
->addOption('no-prod', null, InputOption::VALUE_NONE, 'Ignore prod dependencies')
5960
->addOption('with-platform', 'p', InputOption::VALUE_NONE, 'Include platform dependencies (PHP version, extensions, etc.)')
6061
->addOption('with-links', 'l', InputOption::VALUE_NONE, 'Include compare/release URLs')
61-
->addOption('format', 'f', InputOption::VALUE_REQUIRED, 'Output format (mdtable, mdlist, json)', 'mdtable')
62+
->addOption('format', 'f', InputOption::VALUE_REQUIRED, 'Output format (mdtable, mdlist, json, github)', 'mdtable')
6263
->addOption('gitlab-domains', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'Extra Gitlab domains (inherited from Composer config by default)', array())
6364
->addOption('strict', 's', InputOption::VALUE_NONE, 'Return non-zero exit code if there are any changes')
6465
->setHelp(<<<'EOF'
@@ -202,6 +203,8 @@ private function getFormatter(InputInterface $input, OutputInterface $output)
202203
return new JsonFormatter($output, $urlGenerators);
203204
case 'mdlist':
204205
return new MarkdownListFormatter($output, $urlGenerators);
206+
case 'github':
207+
return new GitHubFormatter($output, $urlGenerators);
205208
// case 'mdtable':
206209
default:
207210
return new MarkdownTableFormatter($output, $urlGenerators);

src/Formatter/GitHubFormatter.php

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace IonBazan\ComposerDiff\Formatter;
4+
5+
use Composer\DependencyResolver\Operation\InstallOperation;
6+
use Composer\DependencyResolver\Operation\UninstallOperation;
7+
use Composer\DependencyResolver\Operation\UpdateOperation;
8+
use IonBazan\ComposerDiff\Diff\DiffEntries;
9+
use IonBazan\ComposerDiff\Diff\DiffEntry;
10+
11+
class GitHubFormatter extends AbstractFormatter
12+
{
13+
/**
14+
* {@inheritdoc}
15+
*/
16+
public function render(DiffEntries $prodEntries, DiffEntries $devEntries, $withUrls)
17+
{
18+
$this->renderSingle($prodEntries, 'Prod Packages', $withUrls);
19+
$this->renderSingle($devEntries, 'Dev Packages', $withUrls);
20+
}
21+
22+
/**
23+
* {@inheritdoc}
24+
*/
25+
public function renderSingle(DiffEntries $entries, $title, $withUrls)
26+
{
27+
if (!\count($entries)) {
28+
return;
29+
}
30+
31+
$message = str_replace("\n", '%0A', implode("\n", $this->transformEntries($entries, $withUrls)));
32+
$this->output->writeln(sprintf('::notice title=%s::%s', $title, $message));
33+
}
34+
35+
/**
36+
* @param bool $withUrls
37+
*
38+
* @return string[]
39+
*/
40+
private function transformEntries(DiffEntries $entries, $withUrls)
41+
{
42+
$rows = array();
43+
44+
foreach ($entries as $entry) {
45+
$rows[] = $this->transformEntry($entry, $withUrls);
46+
}
47+
48+
return $rows;
49+
}
50+
51+
/**
52+
* @param bool $withUrls
53+
*
54+
* @return string
55+
*/
56+
private function transformEntry(DiffEntry $entry, $withUrls)
57+
{
58+
$operation = $entry->getOperation();
59+
$url = $withUrls ? $this->getUrl($entry) : null;
60+
$url = (null !== $url) ? ' '.$url : '';
61+
62+
if ($operation instanceof InstallOperation) {
63+
return sprintf(
64+
' - Install %s (%s)%s',
65+
$operation->getPackage()->getName(),
66+
$operation->getPackage()->getFullPrettyVersion(),
67+
$url
68+
);
69+
}
70+
71+
if ($operation instanceof UpdateOperation) {
72+
return sprintf(
73+
' - %s %s (%s => %s)%s',
74+
ucfirst($entry->getType()),
75+
$operation->getInitialPackage()->getName(),
76+
$operation->getInitialPackage()->getFullPrettyVersion(),
77+
$operation->getTargetPackage()->getFullPrettyVersion(),
78+
$url
79+
);
80+
}
81+
82+
if ($operation instanceof UninstallOperation) {
83+
return sprintf(
84+
' - Uninstall %s (%s)%s',
85+
$operation->getPackage()->getName(),
86+
$operation->getPackage()->getFullPrettyVersion(),
87+
$url
88+
);
89+
}
90+
91+
throw new \InvalidArgumentException('Invalid operation');
92+
}
93+
}

tests/Command/DiffCommandTest.php

+11
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,17 @@ public function outputDataProvider()
252252
'-f' => 'json',
253253
),
254254
),
255+
'GitHub' => array(
256+
<<<OUTPUT
257+
::notice title=Prod Packages:: - Install a/package-1 (1.0.0)%0A - Upgrade a/package-2 (1.0.0 => 1.2.0)%0A - Uninstall a/package-3 (0.1.1)%0A - Uninstall a/package-4 (0.1.1)%0A - Uninstall a/package-5 (0.1.1)%0A - Uninstall a/package-6 (0.1.1)%0A - Downgrade a/package-7 (1.2.0 => 1.0.0)
258+
259+
OUTPUT
260+
,
261+
array(
262+
'--no-dev' => null,
263+
'-f' => 'github',
264+
),
265+
),
255266
);
256267
}
257268
}
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace IonBazan\ComposerDiff\Tests\Formatter;
4+
5+
use Composer\DependencyResolver\Operation\InstallOperation;
6+
use Composer\DependencyResolver\Operation\UninstallOperation;
7+
use Composer\DependencyResolver\Operation\UpdateOperation;
8+
use IonBazan\ComposerDiff\Formatter\GitHubFormatter;
9+
use IonBazan\ComposerDiff\Formatter\JsonFormatter;
10+
use IonBazan\ComposerDiff\Url\GeneratorContainer;
11+
use Symfony\Component\Console\Output\OutputInterface;
12+
use Symfony\Component\Console\Output\StreamOutput;
13+
14+
class GitHubFormatterTest extends FormatterTest
15+
{
16+
protected function getSampleOutput($withUrls)
17+
{
18+
if ($withUrls) {
19+
return <<<OUTPUT
20+
::notice title=Prod Packages:: - Install a/package-1 (1.0.0) https://example.com/r/1.0.0%0A - Install a/no-link-1 (1.0.0)%0A - Upgrade a/package-2 (1.0.0 => 1.2.0) https://example.com/c/1.0.0..1.2.0%0A - Downgrade a/package-3 (2.0.0 => 1.1.1) https://example.com/c/2.0.0..1.1.1%0A - Downgrade a/no-link-2 (2.0.0 => 1.1.1)%0A - Change php (>=7.4.6 => ^8.0)
21+
::notice title=Dev Packages:: - Change a/package-5 (dev-master 1234567 => 1.1.1) https://example.com/c/dev-master..1.1.1%0A - Uninstall a/package-4 (0.1.1) https://example.com/r/0.1.1%0A - Uninstall a/no-link-2 (0.1.1)
22+
23+
OUTPUT;
24+
}
25+
26+
return <<<OUTPUT
27+
::notice title=Prod Packages:: - Install a/package-1 (1.0.0)%0A - Install a/no-link-1 (1.0.0)%0A - Upgrade a/package-2 (1.0.0 => 1.2.0)%0A - Downgrade a/package-3 (2.0.0 => 1.1.1)%0A - Downgrade a/no-link-2 (2.0.0 => 1.1.1)%0A - Change php (>=7.4.6 => ^8.0)
28+
::notice title=Dev Packages:: - Change a/package-5 (dev-master 1234567 => 1.1.1)%0A - Uninstall a/package-4 (0.1.1)%0A - Uninstall a/no-link-2 (0.1.1)
29+
30+
OUTPUT;
31+
}
32+
33+
/**
34+
* {@inheritdoc}
35+
*/
36+
protected function getFormatter(OutputInterface $output, GeneratorContainer $generators)
37+
{
38+
return new GitHubFormatter($output, $generators);
39+
}
40+
}

0 commit comments

Comments
 (0)