Skip to content

Commit 39c8339

Browse files
authored
Support windows line endings (#2)
1 parent 5e4d6fa commit 39c8339

File tree

3 files changed

+48
-17
lines changed

3 files changed

+48
-17
lines changed

src/InlineIgnoreInliner.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
use function explode;
66
use function implode;
7+
use function rtrim;
78
use function str_contains;
9+
use function strlen;
10+
use function substr;
811

912
final class InlineIgnoreInliner
1013
{
@@ -33,17 +36,17 @@ public function inlineErrors(
3336

3437
[$trueFilePath] = explode(' (in context of class', $filePath, 2); // solve trait "filepath" in format "src/App/MyTrait.php (in context of class App\Clazz)"
3538

36-
$fileContent = $this->io->readFile($trueFilePath);
37-
$lines = explode("\n", $fileContent);
39+
$lines = $this->io->readFile($trueFilePath);
3840

39-
$lineContent = $lines[$line - 1];
41+
$lineContent = rtrim($lines[$line - 1]);
42+
$lineEnding = substr($lines[$line - 1], strlen($lineContent));
4043

4144
$append = str_contains($lineContent, '// @phpstan-ignore ')
4245
? ', ' . $identifier
4346
: ' // @phpstan-ignore ' . $identifier;
4447

45-
$lines[$line - 1] .= $append;
46-
$this->io->writeFile($trueFilePath, implode("\n", $lines));
48+
$lines[$line - 1] = $lineContent . $append . $lineEnding;
49+
$this->io->writeFile($trueFilePath, implode('', $lines));
4750
}
4851
}
4952
}

src/Io.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace ShipMonk\PHPStan\Errors;
44

5-
use function file_get_contents;
5+
use function file;
66
use function file_put_contents;
77
use function stream_get_contents;
88
use const STDIN;
@@ -29,17 +29,18 @@ public function readInput(): string
2929
}
3030

3131
/**
32+
* @return list<string>
3233
* @throws FailureException
3334
*/
34-
public function readFile(string $filePath): string
35+
public function readFile(string $filePath): array
3536
{
36-
$contents = file_get_contents($filePath);
37+
$lines = file($filePath);
3738

38-
if ($contents === false) {
39+
if ($lines === false) {
3940
throw new FailureException('Could not read file ' . $filePath);
4041
}
4142

42-
return $contents;
43+
return $lines;
4344
}
4445

4546
/**

tests/InlineIgnoreInlinerTest.php

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,30 @@
22

33
namespace ShipMonk\PHPStan\Errors;
44

5+
use PHPUnit\Framework\Attributes\DataProvider;
56
use PHPUnit\Framework\TestCase;
7+
use function file;
68
use function file_get_contents;
79
use function file_put_contents;
810
use function json_decode;
11+
use function str_replace;
912
use function sys_get_temp_dir;
1013
use function uniqid;
1114

1215
class InlineIgnoreInlinerTest extends TestCase
1316
{
1417

15-
public function testInlineErrors(): void
18+
#[DataProvider('lineEndingProvider')]
19+
public function testInlineErrors(string $lineEnding): void
1620
{
1721
$tmpFilePath = sys_get_temp_dir() . '/' . uniqid('ignore', true) . '.php';
18-
$testedFileContents = file_get_contents(__DIR__ . '/data/test.php');
19-
self::assertNotFalse($testedFileContents);
20-
self::assertNotFalse(file_put_contents($tmpFilePath, $testedFileContents));
22+
$tmpExpectedPath = sys_get_temp_dir() . '/' . uniqid('ignore-expected', true) . '.php';
23+
24+
$testContent = $this->getTestFileContent('test.php', $lineEnding);
25+
$expectedContent = $this->getTestFileContent('test.fixed.php', $lineEnding);
26+
27+
self::assertNotFalse(file_put_contents($tmpFilePath, $testContent));
28+
self::assertNotFalse(file_put_contents($tmpExpectedPath, $expectedContent));
2129

2230
$ioMock = $this->createMock(Io::class);
2331
$ioMock->expects(self::exactly(2))
@@ -27,8 +35,8 @@ public function testInlineErrors(): void
2735
});
2836
$ioMock->expects(self::exactly(2))
2937
->method('readFile')
30-
->willReturnCallback(static function (string $filePath) use ($tmpFilePath): string|false {
31-
return file_get_contents($tmpFilePath);
38+
->willReturnCallback(static function (string $filePath) use ($tmpFilePath): array|false {
39+
return file($tmpFilePath);
3240
});
3341

3442
$testJson = file_get_contents(__DIR__ . '/data/errors.json');
@@ -37,7 +45,26 @@ public function testInlineErrors(): void
3745
$inliner = new InlineIgnoreInliner($ioMock);
3846
$inliner->inlineErrors($testData);
3947

40-
self::assertFileEquals(__DIR__ . '/data/test.fixed.php', $tmpFilePath);
48+
self::assertFileEquals($tmpExpectedPath, $tmpFilePath);
49+
}
50+
51+
private function getTestFileContent(string $filename, string $lineEnding): string
52+
{
53+
$content = file_get_contents(__DIR__ . '/data/' . $filename);
54+
self::assertNotFalse($content);
55+
56+
return str_replace("\n", $lineEnding, $content);
57+
}
58+
59+
/**
60+
* @return array<string, array{string}>
61+
*/
62+
public static function lineEndingProvider(): array
63+
{
64+
return [
65+
'Unix line endings' => ["\n"],
66+
'Windows line endings' => ["\r\n"],
67+
];
4168
}
4269

4370
}

0 commit comments

Comments
 (0)