Skip to content

Commit 51665a5

Browse files
committed
Add hyperlinks support
1 parent 87063f9 commit 51665a5

File tree

9 files changed

+90
-37
lines changed

9 files changed

+90
-37
lines changed

.github/workflows/test.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,14 @@ jobs:
5959
- name: Upload coverage to Codecov
6060
uses: codecov/codecov-action@v1
6161
- name: Run mutation tests
62-
if: ${{ matrix.php-versions == 8.0 && matrix.operating-system == 'ubuntu-latest' }}
62+
if: ${{ matrix.php-versions == 8.1 && matrix.operating-system == 'ubuntu-latest' }}
6363
env:
6464
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
6565
run: |
6666
composer req infection/infection -W
6767
vendor/bin/infection --ignore-msi-with-no-mutations --min-covered-msi=100 --min-msi=100 -s -j4
6868
- name: Run phpstan
69-
if: ${{ matrix.php-versions == 8.0 && matrix.operating-system == 'ubuntu-latest' }}
69+
if: ${{ matrix.php-versions == 8.1 && matrix.operating-system == 'ubuntu-latest' }}
7070
run: |
7171
composer req phpstan/phpstan
7272
vendor/bin/phpstan

infection.json.dist

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@
1616
"ignore": [
1717
"IonBazan\\ComposerDiff\\Formatter\\JsonFormatter::format"
1818
]
19+
},
20+
"Ternary": {
21+
"ignore": [
22+
"IonBazan\\ComposerDiff\\Formatter\\AbstractFormatter::terminalLink"
23+
]
1924
}
2025
}
2126
}

src/Diff/DiffEntry.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Composer\DependencyResolver\Operation\OperationInterface;
77
use Composer\DependencyResolver\Operation\UninstallOperation;
88
use Composer\DependencyResolver\Operation\UpdateOperation;
9+
use Composer\Package\PackageInterface;
910

1011
class DiffEntry
1112
{
@@ -83,6 +84,24 @@ public function isChange()
8384
return self::TYPE_CHANGE === $this->type;
8485
}
8586

87+
/**
88+
* @return PackageInterface|null
89+
*/
90+
public function getPackage()
91+
{
92+
$operation = $this->getOperation();
93+
94+
if ($operation instanceof UpdateOperation) {
95+
return $operation->getInitialPackage();
96+
}
97+
98+
if ($operation instanceof InstallOperation || $operation instanceof UninstallOperation) {
99+
return $operation->getPackage();
100+
}
101+
102+
return null;
103+
}
104+
86105
/**
87106
* @return string
88107
*/

src/Formatter/AbstractFormatter.php

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
use Composer\DependencyResolver\Operation\OperationInterface;
77
use Composer\DependencyResolver\Operation\UninstallOperation;
88
use Composer\DependencyResolver\Operation\UpdateOperation;
9-
use Composer\Package\PackageInterface;
109
use IonBazan\ComposerDiff\Diff\DiffEntry;
1110
use IonBazan\ComposerDiff\Url\GeneratorContainer;
1211
use Symfony\Component\Console\Output\OutputInterface;
@@ -37,11 +36,11 @@ public function getUrl(DiffEntry $entry)
3736
$operation = $entry->getOperation();
3837

3938
if ($operation instanceof UpdateOperation) {
40-
return $this->getCompareUrl($operation->getInitialPackage(), $operation->getTargetPackage());
39+
return $this->generators->getCompareUrl($operation->getInitialPackage(), $operation->getTargetPackage());
4140
}
4241

4342
if ($operation instanceof InstallOperation || $operation instanceof UninstallOperation) {
44-
return $this->getReleaseUrl($operation->getPackage());
43+
return $this->generators->getReleaseUrl($operation->getPackage());
4544
}
4645

4746
return null;
@@ -64,40 +63,35 @@ public function getProjectUrl(OperationInterface $operation)
6463
return null;
6564
}
6665

67-
$generator = $this->generators->get($package);
68-
69-
if (!$generator) {
70-
return null;
71-
}
72-
73-
return $generator->getProjectUrl($package);
66+
return $this->generators->getProjectUrl($package);
7467
}
7568

7669
/**
77-
* @return string|null
70+
* @return string
7871
*/
79-
private function getCompareUrl(PackageInterface $basePackage, PackageInterface $targetPackage)
72+
protected function getDecoratedPackageName(DiffEntry $entry)
8073
{
81-
$generator = $this->generators->get($targetPackage);
74+
$package = $entry->getPackage();
8275

83-
if (!$generator) {
84-
return null;
76+
if (null === $package) {
77+
return '';
8578
}
8679

87-
return $generator->getCompareUrl($basePackage, $targetPackage);
80+
return $this->terminalLink($this->getProjectUrl($entry->getOperation()), $package->getName());
8881
}
8982

9083
/**
91-
* @return string|null
84+
* @param string|null $url
85+
* @param string $title
86+
*
87+
* @return string
9288
*/
93-
private function getReleaseUrl(PackageInterface $package)
89+
private function terminalLink($url, $title)
9490
{
95-
$generator = $this->generators->get($package);
96-
97-
if (!$generator) {
98-
return null;
91+
if (null === $url) {
92+
return $title;
9993
}
10094

101-
return $generator->getReleaseUrl($package);
95+
return method_exists('Symfony\Component\Console\Formatter\OutputFormatterStyle', 'setHref') ? sprintf('<href=%s>%s</>', $url, $title) : $title;
10296
}
10397
}

src/Formatter/MarkdownTableFormatter.php

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ public function renderSingle(DiffEntries $entries, $title, $withUrls)
6060
private function getTableRow(DiffEntry $entry, $withUrls)
6161
{
6262
$operation = $entry->getOperation();
63-
if ($operation instanceof InstallOperation) {
64-
$packageName = $operation->getPackage()->getName();
65-
$packageUrl = $withUrls ? $this->formatUrl($this->getProjectUrl($operation), $packageName) : $packageName;
63+
$packageName = $this->getDecoratedPackageName($entry);
64+
$packageUrl = $withUrls ? $this->formatUrl($this->getProjectUrl($operation), $packageName) : $packageName;
6665

66+
if ($operation instanceof InstallOperation) {
6767
return array(
6868
$packageUrl ?: $packageName,
6969
'<fg=green>New</>',
@@ -73,21 +73,15 @@ private function getTableRow(DiffEntry $entry, $withUrls)
7373
}
7474

7575
if ($operation instanceof UpdateOperation) {
76-
$packageName = $operation->getInitialPackage()->getName();
77-
$projectUrl = $withUrls ? $this->formatUrl($this->getProjectUrl($operation), $packageName) : $packageName;
78-
7976
return array(
80-
$projectUrl ?: $packageName,
77+
$packageUrl ?: $packageName,
8178
$entry->isChange() ? '<fg=magenta>Changed</>' : ($entry->isUpgrade() ? '<fg=cyan>Upgraded</>' : '<fg=yellow>Downgraded</>'),
8279
$operation->getInitialPackage()->getFullPrettyVersion(),
8380
$operation->getTargetPackage()->getFullPrettyVersion(),
8481
);
8582
}
8683

8784
if ($operation instanceof UninstallOperation) {
88-
$packageName = $operation->getPackage()->getName();
89-
$packageUrl = $withUrls ? $this->formatUrl($this->getProjectUrl($operation), $packageName) : $packageName;
90-
9185
return array(
9286
$packageUrl ?: $packageName,
9387
'<fg=red>Removed</>',

src/Url/GeneratorContainer.php

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Composer\Package\PackageInterface;
66

7-
class GeneratorContainer
7+
class GeneratorContainer implements UrlGenerator
88
{
99
/**
1010
* @var UrlGenerator[]
@@ -42,4 +42,36 @@ public function get(PackageInterface $package)
4242

4343
return null;
4444
}
45+
46+
public function supportsPackage(PackageInterface $package)
47+
{
48+
return null !== $this->get($package);
49+
}
50+
51+
public function getCompareUrl(PackageInterface $initialPackage, PackageInterface $targetPackage)
52+
{
53+
if (!$generator = $this->get($targetPackage)) {
54+
return null;
55+
}
56+
57+
return $generator->getCompareUrl($initialPackage, $targetPackage);
58+
}
59+
60+
public function getReleaseUrl(PackageInterface $package)
61+
{
62+
if (!$generator = $this->get($package)) {
63+
return null;
64+
}
65+
66+
return $generator->getReleaseUrl($package);
67+
}
68+
69+
public function getProjectUrl(PackageInterface $package)
70+
{
71+
if (!$generator = $this->get($package)) {
72+
return null;
73+
}
74+
75+
return $generator->getProjectUrl($package);
76+
}
4577
}

tests/Formatter/FormatterTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ protected function getGenerators()
125125

126126
$generators = $this->getMockBuilder('IonBazan\ComposerDiff\Url\GeneratorContainer')
127127
->disableOriginalConstructor()
128+
->setMethods(array('get'))
128129
->getMock();
129130
$generators->method('get')
130131
->willReturnCallback(function (PackageInterface $package) use ($generator) {

tests/TestCase.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ protected function getPackage($name, $version, $fullVersion = null)
4747
/**
4848
* @param string $name
4949
* @param string $version
50-
* @param string $sourceUrl
50+
* @param string|null $sourceUrl
5151
* @param string|null $sourceReference
5252
*
5353
* @return mixed

tests/Url/GeneratorContainerTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,13 @@ public function testGetsProperGenerator()
1818
$this->assertInstanceOf('IonBazan\ComposerDiff\Url\GitlabGenerator', $gitlab2Generator);
1919
$this->assertNotSame($gitlabGenerator, $gitlab2Generator);
2020
$this->assertNull($container->get($this->getPackageWithSource('', '', 'https://gitlab3.org')));
21+
$this->assertNull($container->get($this->getPackageWithSource('', '', null)));
22+
}
23+
24+
public function testItSupportsPackageSupportedByOneOfTheGenerators()
25+
{
26+
$generator = new GeneratorContainer(array());
27+
self::assertTrue($generator->supportsPackage($this->getPackageWithSource('acme/package', '3.12.0', 'https://bitbucket.org/acme/package.git')));
28+
self::assertFalse($generator->supportsPackage($this->getPackageWithSource('acme/package', '3.12.0', 'https://non-existent.org/acme/package.git')));
2129
}
2230
}

0 commit comments

Comments
 (0)