Skip to content

Commit

Permalink
Merge pull request #39 from Chemiker90
Browse files Browse the repository at this point in the history
Ignore "\ No newline at end of file" while parsing git diff output
  • Loading branch information
sebastianfeldmann authored Aug 26, 2022
2 parents 853066c + 3e7cb39 commit b324b6b
Show file tree
Hide file tree
Showing 3 changed files with 194 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/Command/Diff/Compare/FullDiffList.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ private function isChangePositionLine(string $line): bool
private function isChangeCodeLine(string $line): bool
{
$line = $this->parseCodeLine($line);
if ($line === null) {
return false;
}
$this->currentChanges[$this->currentPosition]->addLine($line);
return true;
}
Expand All @@ -289,15 +292,18 @@ private function isChangeCodeLine(string $line): bool
* Determines the line type and cleans up the line.
*
* @param string $line
* @return \SebastianFeldmann\Git\Diff\Line
* @return \SebastianFeldmann\Git\Diff\Line|null
*/
private function parseCodeLine(string $line): Line
private function parseCodeLine(string $line): ?Line
{
if (strlen($line) == 0) {
return new Line(Line::EXISTED, '');
}

$firstChar = $line[0];
if (!array_key_exists($firstChar, Line::$opsMap)) {
return null;
}
$cleanLine = rtrim(substr($line, 1));

return new Line(Line::$opsMap[$firstChar], $cleanLine);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
diff --git a/src/Command/Diff/Compare.php b/src/Command/Diff/Compare.php
index a2a41d1..a17881b 100644
--- a/src/Command/Diff/Compare.php
+++ b/src/Command/Diff/Compare.php
@@ -67,0 +68,7 @@ class Compare extends Base
+ /**
+ * View the changes staged for the next commit.
+ *
+ * @var string
+ */
+ private $staged = '';
+
@@ -80,0 +88,12 @@ class Compare extends Base
+ /**
+ * Compares the working tree or index to a given commit-ish
+ *
+ * @param string $to
+ * @return \SebastianFeldmann\Git\Command\Diff\Compare
+ */
+ public function to(string $to = 'HEAD'): Compare
+ {
+ $this->compare = $to;
+ return $this;
+ }
+
@@ -83,0 +103,2 @@ class Compare extends Base
+ * This method is a shortcut for calling {@see staged()} and {@see to()}.
+ *
@@ -89 +110,13 @@ class Compare extends Base
- $this->compare = '--staged ' . $to;
+ return $this->staged()->to($to);
+ }
+
+ /**
+ * View the changes staged for the next commit relative to the <commit>
+ * named with {@see to()}.
+ *
+ * @param bool $bool
+ * @return \SebastianFeldmann\Git\Command\Diff\Compare
+ */
+ public function staged(bool $bool = true): Compare
+ {
+ $this->stats = $this->useOption('--staged', $bool);
@@ -167 +200,3 @@ class Compare extends Base
- . ' ' . $this->compare;
+ . $this->staged
+ . ' ' . $this->compare
+ . ' -- ';
\ No newline at end of file
diff --git a/src/Command/Diff/Compare/FullDiffList.php b/src/Command/Diff/Compare/FullDiffList.php
index 4e85eba..f5e9ca7 100644
--- a/src/Command/Diff/Compare/FullDiffList.php
+++ b/src/Command/Diff/Compare/FullDiffList.php
@@ -267 +267 @@ class FullDiffList implements OutputFormatter
- if (preg_match('#^@@ (\-[0-9,]{3,} \+[0-9,]{3,}) @@ ?(.*)$#', $line, $matches)) {
+ if (preg_match('#^@@ (-\d+(?:,\d+)? \+\d+(?:,\d+)?) @@ ?(.*)$#', $line, $matches)) {
diff --git a/src/Diff/Change.php b/src/Diff/Change.php
index ff95c05..972b5db 100644
--- a/src/Diff/Change.php
+++ b/src/Diff/Change.php
@@ -31 +31 @@ class Change
- * Pre range ['from' => x, 'to' => y]
+ * Pre range.
@@ -33 +33 @@ class Change
- * @var array
+ * @var array{from: int|null, to: int|null}
@@ -38 +38 @@ class Change
- * Post range ['from' => x, 'to' => y]
+ * Post range.
@@ -40 +40 @@ class Change
- * @var array
+ * @var array{from: int|null, to: int|null}
@@ -140 +140 @@ class Change
- if (!preg_match('#^[\-|\+]{1}([0-9]+),([0-9]+) [\-\+]{1}([0-9]+),([0-9]+)$#', $ranges, $matches)) {
+ if (!preg_match('#^[\-|+](\d+)(?:,(\d+))? [\-+](\d+)(?:,(\d+))?$#', $ranges, $matches)) {
@@ -143,2 +143,10 @@ class Change
- $this->pre = ['from' => (int)$matches[1], 'to' => (int)$matches[2]];
- $this->post = ['from' => (int)$matches[3], 'to' => (int)$matches[4]];
+
+ $this->pre = [
+ 'from' => isset($matches[1]) ? (int) $matches[1] : null,
+ 'to' => isset($matches[2]) ? (int) $matches[2] : null,
+ ];
+
+ $this->post = [
+ 'from' => isset($matches[3]) ? (int) $matches[3] : null,
+ 'to' => isset($matches[4]) ? (int) $matches[4] : null,
+ ];
diff --git a/src/Operator/Diff.php b/src/Operator/Diff.php
index e05d7bb..b93b976 100644
--- a/src/Operator/Diff.php
+++ b/src/Operator/Diff.php
@@ -48 +48 @@ class Diff extends Base
- * Returns a list of files and their changes
+ * Returns a list of files and their changes staged for the next commit
@@ -63,0 +64,17 @@ class Diff extends Base
+ /**
+ * Returns a list of files and their changes not yet staged
+ *
+ * @param string $to
+ * @return \SebastianFeldmann\Git\Diff\File[]
+ */
+ public function compareTo(string $to = 'HEAD'): iterable
+ {
+ $compare = (new Compare($this->repo->getRoot()))->to($to)
+ ->ignoreSubmodules()
+ ->withContextLines(0);
+
+ $result = $this->runner->run($compare, new Compare\FullDiffList());
+
+ return $result->getFormattedOutput();
+ }
+
diff --git a/tests/git/Command/Diff/CompareTest.php b/tests/git/Command/Diff/CompareTest.php
index a67881c..c895131 100644
--- a/tests/git/Command/Diff/CompareTest.php
+++ b/tests/git/Command/Diff/CompareTest.php
@@ -34 +34 @@ class CompareTest extends TestCase
- $this->assertEquals('git diff --no-ext-diff \'1.0.0\' \'1.1.0\'', $compare->getCommand());
+ $this->assertEquals('git diff --no-ext-diff \'1.0.0\' \'1.1.0\' -- ', $compare->getCommand());
@@ -46 +46 @@ class CompareTest extends TestCase
- $this->assertEquals('git diff --no-ext-diff --numstat \'1.0.0\' \'1.1.0\'', $compare->getCommand());
+ $this->assertEquals('git diff --no-ext-diff --numstat \'1.0.0\' \'1.1.0\' -- ', $compare->getCommand());
@@ -59 +59 @@ class CompareTest extends TestCase
- 'git diff --no-ext-diff --ignore-space-at-eol \'1.0.0\' \'1.1.0\'',
+ 'git diff --no-ext-diff --ignore-space-at-eol \'1.0.0\' \'1.1.0\' -- ',
@@ -72 +72 @@ class CompareTest extends TestCase
- $this->assertEquals('git diff --no-ext-diff --staged HEAD', $compare->getCommand());
+ $this->assertEquals('git diff --no-ext-diff --staged HEAD -- ', $compare->getCommand());
@@ -84 +84 @@ class CompareTest extends TestCase
- $this->assertEquals('git diff --no-ext-diff --unified=2 --staged HEAD', $compare->getCommand());
+ $this->assertEquals('git diff --no-ext-diff --unified=2 --staged HEAD -- ', $compare->getCommand());
@@ -96 +96 @@ class CompareTest extends TestCase
- $this->assertEquals('git diff --no-ext-diff -w \'1.0.0\' \'1.1.0\'', $compare->getCommand());
+ $this->assertEquals('git diff --no-ext-diff -w \'1.0.0\' \'1.1.0\' -- ', $compare->getCommand());
@@ -110 +110 @@ class CompareTest extends TestCase
- 'git diff --no-ext-diff -w --ignore-space-at-eol \'1.0.0\' \'1.1.0\'',
+ 'git diff --no-ext-diff -w --ignore-space-at-eol \'1.0.0\' \'1.1.0\' -- ',
@@ -120 +120 @@ class CompareTest extends TestCase
- $this->assertEquals('git diff --no-ext-diff --ignore-submodules ', $compare->getCommand());
+ $this->assertEquals('git diff --no-ext-diff --ignore-submodules -- ', $compare->getCommand());
45 changes: 45 additions & 0 deletions tests/git/Command/Diff/Compare/FullDiffListTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,49 @@ public function testFullDiffList01(): void
$this->assertSame('tests/git/Command/Diff/CompareTest.php', $files[4]->getName());
$this->assertCount(8, $files[4]->getChanges());
}

public function testFullDiffListWithNoNewlineNotice(): void
{
$output = file(__DIR__ . '/FullDiffList-with-no-newline-notice.diff', FILE_IGNORE_NEW_LINES);

$formatter = new FullDiffList();

/** @var File[] $files */
$files = $formatter->format($output);

$this->assertCount(5, $files);

$firstFile = $files[0];
$firstFileChanges = $firstFile->getChanges();

$this->assertSame('src/Command/Diff/Compare.php', $firstFile->getName());
$this->assertCount(5, $firstFileChanges);
$this->assertSame(['from' => 67, 'to' => 0], $firstFileChanges[0]->getPre());
$this->assertSame(['from' => 68, 'to' => 7], $firstFileChanges[0]->getPost());
$this->assertSame(['from' => 80, 'to' => 0], $firstFileChanges[1]->getPre());
$this->assertSame(['from' => 88, 'to' => 12], $firstFileChanges[1]->getPost());
$this->assertSame(['from' => 83, 'to' => 0], $firstFileChanges[2]->getPre());
$this->assertSame(['from' => 103, 'to' => 2], $firstFileChanges[2]->getPost());
$this->assertSame(['from' => 89, 'to' => null], $firstFileChanges[3]->getPre());
$this->assertSame(['from' => 110, 'to' => 13], $firstFileChanges[3]->getPost());
$this->assertSame(['from' => 167, 'to' => null], $firstFileChanges[4]->getPre());
$this->assertSame(['from' => 200, 'to' => 3], $firstFileChanges[4]->getPost());

$secondFile = $files[1];
$secondFileChanges = $secondFile->getChanges();

$this->assertSame('src/Command/Diff/Compare/FullDiffList.php', $secondFile->getName());
$this->assertCount(1, $secondFileChanges);
$this->assertSame(['from' => 267, 'to' => null], $secondFileChanges[0]->getPre());
$this->assertSame(['from' => 267, 'to' => null], $secondFileChanges[0]->getPost());

$this->assertSame('src/Diff/Change.php', $files[2]->getName());
$this->assertCount(6, $files[2]->getChanges());

$this->assertSame('src/Operator/Diff.php', $files[3]->getName());
$this->assertCount(2, $files[3]->getChanges());

$this->assertSame('tests/git/Command/Diff/CompareTest.php', $files[4]->getName());
$this->assertCount(8, $files[4]->getChanges());
}
}

0 comments on commit b324b6b

Please sign in to comment.