Skip to content

Commit b871f04

Browse files
committed
refactor: preserve absolute paths until report rendering
1 parent 4d87315 commit b871f04

10 files changed

Lines changed: 106 additions & 26 deletions

File tree

src/RelativePath.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DocbookCS;
6+
7+
final class RelativePath
8+
{
9+
public static function fromWorkingDirectory(string $filePath): string
10+
{
11+
$workingDirectory = getcwd();
12+
if ($workingDirectory === false) {
13+
return $filePath; // @codeCoverageIgnore
14+
}
15+
16+
$prefix = rtrim(str_replace('\\', '/', $workingDirectory), '/') . '/';
17+
$normalisedPath = str_replace('\\', '/', $filePath);
18+
19+
return str_starts_with($normalisedPath, $prefix)
20+
? substr($normalisedPath, strlen($prefix))
21+
: $filePath;
22+
}
23+
}

src/Report/Reporter/CheckstyleReporter.php

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

55
namespace DocbookCS\Report\Reporter;
66

7+
use DocbookCS\RelativePath;
78
use DocbookCS\Report\Report;
89

910
final class CheckstyleReporter implements ReporterInterface
@@ -28,7 +29,7 @@ public function generate(Report $report): string
2829
}
2930

3031
$fileNode = $dom->createElement('file');
31-
$fileNode->setAttribute('name', $fileReport->filePath);
32+
$fileNode->setAttribute('name', RelativePath::fromWorkingDirectory($fileReport->filePath));
3233

3334
foreach ($fileReport->getViolations() as $violation) {
3435
$errorNode = $dom->createElement('error');

src/Report/Reporter/ConsoleReporter.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace DocbookCS\Report\Reporter;
66

7+
use DocbookCS\RelativePath;
78
use DocbookCS\Report\Report;
89
use DocbookCS\Report\Severity;
910

@@ -27,9 +28,11 @@ public function generate(Report $report): string
2728
continue;
2829
}
2930

31+
$filePath = RelativePath::fromWorkingDirectory($fileReport->filePath);
32+
3033
$output .= PHP_EOL;
31-
$output .= $this->bold('FILE: ' . $fileReport->filePath) . PHP_EOL;
32-
$output .= str_repeat('-', min(80, 6 + strlen($fileReport->filePath))) . PHP_EOL;
34+
$output .= $this->bold('FILE: ' . $filePath) . PHP_EOL;
35+
$output .= str_repeat('-', min(80, 6 + strlen($filePath))) . PHP_EOL;
3336

3437
foreach ($fileReport->getViolations() as $violation) {
3538
$output .= sprintf(
@@ -41,7 +44,7 @@ public function generate(Report $report): string
4144
) . PHP_EOL;
4245
}
4346

44-
$output .= str_repeat('-', min(80, 6 + strlen($fileReport->filePath))) . PHP_EOL;
47+
$output .= str_repeat('-', min(80, 6 + strlen($filePath))) . PHP_EOL;
4548
}
4649

4750
$output .= PHP_EOL;

src/Report/Reporter/JsonReporter.php

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

55
namespace DocbookCS\Report\Reporter;
66

7+
use DocbookCS\RelativePath;
78
use DocbookCS\Report\Report;
89

910
final class JsonReporter implements ReporterInterface
@@ -38,7 +39,7 @@ public function generate(Report $report): string
3839
];
3940
}
4041

41-
$data['files'][$fileReport->filePath] = [
42+
$data['files'][RelativePath::fromWorkingDirectory($fileReport->filePath)] = [
4243
'violations' => count($violations),
4344
'messages' => $violations,
4445
];

src/Runner/SniffRunner.php

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public function run(RunPlan $plan): Report
4747
$fileReport = $processor->processFile(
4848
$file,
4949
$changedLines,
50-
$this->makeRelative($file),
50+
$file,
5151
);
5252

5353
$violationCount = $fileReport->getViolationCount();
@@ -104,21 +104,4 @@ private function instantiateSniffs(array $entries): array
104104

105105
return $sniffs;
106106
}
107-
108-
private function makeRelative(string $absolutePath): string
109-
{
110-
$cwd = getcwd();
111-
if ($cwd === false) {
112-
return $absolutePath; // @codeCoverageIgnore
113-
}
114-
115-
$prefix = rtrim(str_replace('\\', '/', $cwd), '/') . '/';
116-
$normalized = str_replace('\\', '/', $absolutePath);
117-
118-
if (str_starts_with($normalized, $prefix)) {
119-
return substr($normalized, strlen($prefix));
120-
}
121-
122-
return $absolutePath; // @codeCoverageIgnore
123-
}
124107
}

tests/Unit/Report/ReportTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace DocbookCS\Tests\Unit\Report;
66

7+
use DocbookCS\RelativePath;
78
use DocbookCS\Report\FileReport;
89
use DocbookCS\Report\Report;
910
use DocbookCS\Report\Severity;
@@ -14,6 +15,7 @@
1415

1516
#[
1617
CoversClass(FileReport::class),
18+
CoversClass(RelativePath::class),
1719
CoversClass(Report::class),
1820
CoversClass(Violation::class),
1921
]
@@ -94,6 +96,16 @@ public function itOverwritesFileReportWithSamePath(): void
9496
self::assertSame($second, $report->getFileReports()['file.xml']);
9597
}
9698

99+
#[Test]
100+
public function itKeepsTheFileReportPathWhileRenderingItRelativeToWorkingDirectory(): void
101+
{
102+
$filePath = (getcwd() ?: '') . '/src/chapter.xml';
103+
$fileReport = new FileReport($filePath);
104+
105+
self::assertSame($filePath, $fileReport->filePath);
106+
self::assertSame('src/chapter.xml', RelativePath::fromWorkingDirectory($fileReport->filePath));
107+
}
108+
97109
#[Test]
98110
public function itReturnsTotalViolationsAcrossAllFiles(): void
99111
{

tests/Unit/Report/Reporter/CheckstyleReporterTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@
44

55
namespace DocbookCS\Tests\Unit\Report\Reporter;
66

7+
use DocbookCS\RelativePath;
78
use DocbookCS\Report\FileReport;
89
use DocbookCS\Report\Report;
910
use DocbookCS\Report\Reporter\CheckstyleReporter;
1011
use DocbookCS\Report\Severity;
1112
use DocbookCS\Report\Violation;
1213
use PHPUnit\Framework\Attributes\CoversClass;
1314
use PHPUnit\Framework\Attributes\Test;
15+
use PHPUnit\Framework\Attributes\UsesClass;
1416
use PHPUnit\Framework\TestCase;
1517

1618
#[
1719
CoversClass(CheckstyleReporter::class),
1820
CoversClass(FileReport::class),
1921
CoversClass(Report::class),
2022
CoversClass(Violation::class),
23+
//
24+
UsesClass(RelativePath::class),
2125
]
2226
final class CheckstyleReporterTest extends TestCase
2327
{
@@ -113,6 +117,23 @@ public function itIncludesFileNodeWithNameAttribute(): void
113117
self::assertSame('src/broken.xml', $fileNodes->item(0)?->getAttribute('name'));
114118
}
115119

120+
#[Test]
121+
public function itRendersAbsoluteFilePathRelativeToWorkingDirectory(): void
122+
{
123+
$fileReport = new FileReport((getcwd() ?: '') . '/src/broken.xml');
124+
$fileReport->addViolation($this->createViolation());
125+
126+
$report = new Report();
127+
$report->addFileReport($fileReport);
128+
129+
$dom = $this->parseOutput($this->reporter->generate($report));
130+
131+
self::assertSame(
132+
'src/broken.xml',
133+
$dom->getElementsByTagName('file')->item(0)?->getAttribute('name'),
134+
);
135+
}
136+
116137
#[Test]
117138
public function itSetsLineAttribute(): void
118139
{

tests/Unit/Report/Reporter/ConsoleReporterTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@
44

55
namespace DocbookCS\Tests\Unit\Report\Reporter;
66

7+
use DocbookCS\RelativePath;
78
use DocbookCS\Report\FileReport;
89
use DocbookCS\Report\Report;
910
use DocbookCS\Report\Reporter\ConsoleReporter;
1011
use DocbookCS\Report\Severity;
1112
use DocbookCS\Report\Violation;
1213
use PHPUnit\Framework\Attributes\CoversClass;
1314
use PHPUnit\Framework\Attributes\Test;
15+
use PHPUnit\Framework\Attributes\UsesClass;
1416
use PHPUnit\Framework\TestCase;
1517

1618
#[
1719
CoversClass(ConsoleReporter::class),
1820
CoversClass(FileReport::class),
1921
CoversClass(Report::class),
2022
CoversClass(Violation::class),
23+
//
24+
UsesClass(RelativePath::class),
2125
]
2226
final class ConsoleReporterTest extends TestCase
2327
{
@@ -90,6 +94,20 @@ public function itShowsFilePathInHeader(): void
9094
self::assertStringContainsString('FILE: src/broken.xml', $output);
9195
}
9296

97+
#[Test]
98+
public function itRendersAbsoluteFilePathRelativeToWorkingDirectory(): void
99+
{
100+
$fileReport = new FileReport((getcwd() ?: '') . '/src/broken.xml');
101+
$fileReport->addViolation($this->createViolation());
102+
103+
$report = new Report();
104+
$report->addFileReport($fileReport);
105+
106+
$output = $this->reporter->generate($report);
107+
108+
self::assertStringContainsString('FILE: src/broken.xml', $output);
109+
}
110+
93111
#[Test]
94112
public function itShowsDashSeparatorAfterFileHeader(): void
95113
{

tests/Unit/Report/Reporter/JsonReporterTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,24 @@
44

55
namespace DocbookCS\Tests\Unit\Report\Reporter;
66

7+
use DocbookCS\RelativePath;
78
use DocbookCS\Report\FileReport;
89
use DocbookCS\Report\Report;
910
use DocbookCS\Report\Reporter\JsonReporter;
1011
use DocbookCS\Report\Severity;
1112
use DocbookCS\Report\Violation;
1213
use PHPUnit\Framework\Attributes\CoversClass;
1314
use PHPUnit\Framework\Attributes\Test;
15+
use PHPUnit\Framework\Attributes\UsesClass;
1416
use PHPUnit\Framework\TestCase;
1517

1618
#[
1719
CoversClass(FileReport::class),
1820
CoversClass(JsonReporter::class),
1921
CoversClass(Report::class),
2022
CoversClass(Violation::class),
23+
//
24+
UsesClass(RelativePath::class),
2125
]
2226
final class JsonReporterTest extends TestCase
2327
{
@@ -312,6 +316,20 @@ public function itDoesNotEscapeSlashesInOutput(): void
312316
self::assertStringNotContainsString('path\/to\/file.xml', $output);
313317
}
314318

319+
#[Test]
320+
public function itRendersAbsoluteFilePathRelativeToWorkingDirectory(): void
321+
{
322+
$fileReport = new FileReport((getcwd() ?: '') . '/path/to/file.xml');
323+
$fileReport->addViolation($this->createViolation());
324+
325+
$report = new Report();
326+
$report->addFileReport($fileReport);
327+
328+
$data = $this->parseOutput($this->reporter->generate($report));
329+
330+
self::assertArrayHasKey('path/to/file.xml', $data['files']);
331+
}
332+
315333
#[Test]
316334
public function itUsesPrettyPrintedJson(): void
317335
{

tests/Unit/Runner/SniffRunnerTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public function setProperty(string $name, string $value): void
154154
}
155155

156156
#[Test]
157-
public function itStoresRelativePathsInFileReports(): void
157+
public function itStoresAbsolutePathsInFileReports(): void
158158
{
159159
$sniff = new class implements SniffInterface {
160160
public function getCode(): string
@@ -186,9 +186,9 @@ public function setProperty(string $name, string $value): void
186186
$report = $runner->run($this->planPaths($config));
187187

188188
foreach ($report->getFileReports() as $fileReport) {
189-
self::assertFalse(
189+
self::assertTrue(
190190
str_starts_with($fileReport->filePath, '/'),
191-
'Expected relative path, got: ' . $fileReport->filePath,
191+
'Expected absolute path, got: ' . $fileReport->filePath,
192192
);
193193
}
194194
}

0 commit comments

Comments
 (0)