Giter Site home page Giter Site logo

diff's Introduction

Hi!

I am Sebastian Bergmann. If you develop software using the PHP programming language then you may have come across my name. I am the creator and maintainer of PHPUnit as well as many other libraries and tools that are commonly used.


👷 Check out what I'm currently working on


🔭 Latest releases I've contributed to


📫 How to reach me

diff's People

Contributors

andreybolonin avatar ayesh avatar carusogabriel avatar dg avatar djmattyg007 avatar florentpoinsaut avatar grahamcampbell avatar henriquemoody avatar keradus avatar krizalys avatar localheinz avatar matth-- avatar mimrock avatar nafigator avatar pscheit avatar remicollet avatar sebastianbergmann avatar spacepossum avatar staabm avatar whatthejeff avatar znbailey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

diff's Issues

FR: add array keys in return from `diffToArray`

Thanks for this addon, it's amazing!

I'm trying to display the differences in two arrays but having a hard time figuring out which keys changed because only the values are returned.

It would be amazing if this was returned:

array:6 [▼
  0 => array:2 [▼
    0 => "phone"
    1 => "6045551212"
    2 => 0
  ]
  1 => array:2 [▼
    0 => "id"
    1 => "39a933d8-9879-424b-8620-852079cdb138"
    2 => 0
  ]

or even a key/value array:

"key" => "phone"
"value" => "6045551212"
"diff" => 1

Numeric array values not supported

Tested on latest main:

Psy Shell v0.11.9 (PHP 8.1.6 — cli) by Justin Hileman
> $ob = new SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder
= SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder {#2715}

> (new SebastianBergmann\Diff\Differ($ob))->diff([1], [2])
   TypeError  substr(): Argument #1 ($string) must be of type string, int given.

> wtf -a
   TypeError  substr(): Argument #1 ($string) must be of type string, int given.
--
 0:  () at vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php:98
 1:  substr() at vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php:98
 2:  SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder->writeDiffHunks() at vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php:62
 3:  SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder->getDiff() at vendor/sebastian/diff/src/Differ.php:54
 4:  SebastianBergmann\Diff\Differ->diff() at eval()'d code:1
 5:  eval() at vendor/psy/psysh/src/ExecutionLoopClosure.php:53
 6:  Psy\{closure}() at vendor/psy/psysh/src/ExecutionClosure.php:89
 7:  Psy\ExecutionClosure->execute() at vendor/psy/psysh/src/Shell.php:394
 8:  Psy\Shell->doInteractiveRun() at vendor/psy/psysh/src/Shell.php:365
 9:  Psy\Shell->doRun() at vendor/symfony/console/Application.php:168
10:  Symfony\Component\Console\Application->run() at vendor/psy/psysh/src/Shell.php:340
11:  Psy\Shell->run() at vendor/psy/psysh/src/functions.php:454
12:  Psy\{closure}() at vendor/psy/psysh/bin/psysh:148
13:  include() at vendor/bin/psysh:117

Not sure if this is a bug as the documentation doesn't say anything about diffing arrays, but the function signature suggests it's supported and PHPUnit uses it. The same command works fine with string values:

> (new SebastianBergmann\Diff\Differ($ob))->diff(['1'], ['2'])
= """
  --- Original\n
  +++ New\n
  @@ @@\n
  -1\n
  +2\n
  """

Highlight word-level changes on a line

Suppose I delete a couple of words near the start of a line. On the same line towards the end, I add a couple of words. The diff program just shows that the old line is deleted and new line is added.

It would be nice just to highlight changes at word level.

I found one alternative diff programs and it has the same problem: https://github.com/chrisboulton/php-diff

I later found another diff that does what I want (word-level highlighting) but it's too slow. It takes 40+ seconds for a small file of about 100 lines and 1500 words: https://github.com/caxy/php-htmldiff

I want to know if there's an config option that turns on word-level diff. Thx

Documentation and possibly implementation for Differ needs updated

The documentation for Differ::diff states that it accepts both arrays and strings as parameters:

/**
     * Returns the diff between two arrays or strings as string.
     *
     * @param array|string                            $from
     * @param array|string                            $to
     * @param LongestCommonSubsequenceCalculator|null $lcs
     *
     * @return string
     */
    public function diff($from, $to, LongestCommonSubsequenceCalculator $lcs = null): string

This is clearly not the case since Differ::validateDiffInput explicitly tries to cast everything to a string except arrays:

/**
     * Casts variable to string if it is not a string or array.
     *
     * @param mixed $input
     *
     * @return string
     */
    private function validateDiffInput($input): string
    {
        if (!\is_array($input) && !\is_string($input)) {
            return (string) $input;
        }
        return $input;
    }

The first fix is obvious, the documentation for Differ::diff needs to be updated. The second issue, is maybe we want to throw an InvalidArgumentException on an array instead of the much more opaque:

TypeError: Return value of SebastianBergmann\Diff\Differ::validateDiffInput() must be of the type string, array returned

Throwing InvalidArgumentException with an appropriate description would represent a better user experience.

If we agree, let me know, and I'll submit a PR with both fixes referencing this issue.

Tools directory in production package versions

Hello!

My phpstorm is out of memory every time when I'm trying to navigate class from symfony package, for example Symfony\Component\Console\Command\Command.
It happens because this class also contains in files from tools dir(php-cs-fixer, composer each of it has more than 2mb size and its really hard to open with IDE).
This files can't be fully ignored by Storm or maybe I just can't find how to do it.
Can you please give me an advice what should I do with it?

Support simple colored diffs

When doing this in PHPUnit

static::assertEquals(['aa', 'bb'], ['aa', 'cc']);

Output comes out as

Failed asserting that two arrays are equal.
--- Expected
+++ Actual
@@ @@
 Array (
     0 => 'aa'
-    1 => 'bb'
+    1 => 'cc'
 )

but, if PHPUnit is in color mode, it could come out as

Failed asserting that two arrays are equal.
--- Expected
+++ Actual
@@ @@
Array (
    0 => 'aa'
-    1 => 'bb'
+    1 => 'cc'
)

The way to go about it seems like:

  1. add color mode to output here
  2. make PHPUnit tell Comparator to be in color mode
  3. make Comparator pass the information along

Don't know if I'm missing something or if this is the correct repo to create this issue, seems like the correct way forward.

Diff for DBs?

Hi,

some time ago was working on making my own ORM, during testing I found that it was easier to create DB fixtures by having a database mirror which I could compare against.
To figure out differences between tables I wrote an abstract TestCase that compares two tables and shows you the diff. I'm not sure this belongs here but I thought it may provide some inspiration?

Out of memory

I tried lastest php-cs-fixer, which use this diff implementation. Everything is cool, until you try to generate a diff on files which size is 50kB+. For example, trying to use it on couple common wp plugins fails:

~/...../wp-content/plugins/jetpack $ php-cs-fixer fix --diff --dry-run -v .
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) in /Users/....../vendor/sebastian/diff/src/Differ.php on line 274

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) in /Users/......l/vendor/sebastian/diff/src/Differ.php on line 274

Same goes on disquss plugin:

~/...../wp-content/plugins/disqus-conditional-load $ php-cs-fixer fix --diff --dry-run -v .
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) in /Users/....../vendor/sebastian/diff/src/Differ.php on line 274

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 72 bytes) in /Users/...../vendor/sebastian/diff/src/Differ.php on line 274

Last one failed on disqus-conditional-load.php file which has 57443 bytes.

Pear package missing

Hello,

README file says that Diff can be installed via PEAR package.

Actually I get an error:

$ pear install pear.phpunit.de/Diff
No releases available for package "pear.phpunit.de/Diff"
install failed

Seems like package is missing from specified channel. Could you please fix this?

Make Parser method statics

The Parser class does not manage any internal property and just has two pars method.

Making them static would make more senses and would make a simpler usage:

$diffs = Parser::parse($diffsContent);

Security Policy

Hi! I've just updated sebastian/diff from 4.x to 5.x in our application, came across the new SECURITY.md and have some questions about that:

The security policy states that the library is intended to be used in development environments only and should not be placed onto a web server. We're developing a web application where we've just replaced our home-grown diff implementation by this library within the current in-development release – thus directly going against the new security policy. We're using the library to calculate the differences between two versions of user-generated content, similar to the version history in Wikipedia.

Are there specific/concrete concerns with using the library on a web server and passing possibly untrusted user-generated data to it? Or does the policy exist because you don't want to concern yourself with possible attack vectors during development to keep things simple for you and you don't want someone shouting at you if it breaks (but you would accept well-written reports + fixes in case something pops up)?

For your reference: WoltLab/WCF#4918, WoltLab/WCF#5285

Values should be compared strictly when computing LCS.

$d = new \SebastianBergmann\Diff\LCS\MemoryEfficientImplementation;

var_dump( $d->calculate( array( '5' ), array( '05' ) ) );

results in:

array(1) {
  [0] =>
  string(1) "5"
}

but it should result in:

array(0) {
}

because '5' and '05' are not the same.

The practical result is that I had a file for which a line containing a single number had zeros added to the start, but the differ reported that there was no difference.

It seems this is just a matter of changing the == that is used when comparing input values to ===.

Affected line numbers missing

Hi,

When creating a diff of following two files, the affected line numbers are not being added to the diff:

Original: https://testing.enuvo.ch/diff/a.txt
New: https://testing.enuvo.ch/diff/b.txt

Here are the first couple of lines from the diff:

--- Original
+++ New
@@ @@
- <a contenteditable="true">Analisi risultati</a>
+ <a contenteditable="true">Analizza risultati</a>

@@ @@
- <p contenteditable="true">Puoi iniziare a creare il tuo sondaggio online subito dopo la tua registrazione gratuita. La nostra interfaccia facile da usare e che non ha bisogno di spiegazioni ti aiuta a costruire questionari meravigliosi in pochi minuti. Puoi scegliere tra una varietà di diverse tipologie di domanda, componi le tue proprie domande, aggiungi testo esplicativo, carica immagini e molto altro; di conseguenza progettare sistematicamente il tuo sondaggio un pezzo alla volta. Sarai sempre in grado di vedere un'anteprima esatta di domande singole come pure il tuo intero questionario. Inoltre, puoi modificare il tema del tuo questionario utilizzando i tuoi propri colori e logo. Prenditi tutto il tempo necessario per creare i tuoi questionari online - non vi sono limiti di tempo.</p>
+ <p contenteditable="true">Puoi iniziare a creare il tuo sondaggio online subito dopo la tua registrazione gratuita. La nostra interfaccia, facile da usare e che non ha bisogno di spiegazioni, ti aiuta a costruire questionari meravigliosi in pochi minuti. Puoi scegliere tra una varietà di diverse tipologie di domanda, comporre le tue domande, aggiungere testo esplicativo, caricare immagini e molto altro; e, di conseguenza, progettare sistematicamente il tuo sondaggio un pezzo alla volta. Sarai sempre in grado di vedere un'anteprima esatta di domande singole come anche il tuo intero questionario. Inoltre, puoi modificare il tema del tuo questionario utilizzando i tuoi colori e il tuo logo. Prenditi tutto il tempo necessario per creare i tuoi questionari online - non ci sono limiti di tempo.</p>

As you can see, there is no info between the @@ @@.

Any idea what is going on?

Thanks,
Lionel

feature request: patch

It would be fantastic if there was a method to use a diff already created and patch it against a string.

Cannot diff two arrays

I am not sure if this is a bug or if it is just unclear documentation.

The doc comments would lead one to believe that you can take the diff of two arrays. However in diffToArray the first thing that happens is the $from arg is passed as the second arg to preg_match_all which only takes a string for the second argumet making it so that this has to be an array.

The readme mentions nothing about arrays, so like I said, may just need to be reflected correctly in the phpdocs.

Regression in unified diff output of identical strings between 2.x and 3.x

Hi,

While working on upgrading some dependencies, we have been testing an upgrade of this package from 2.0.1 to 3.0.2, and came across the following behavior which appears to be a regression. Can you please investigate and confirm whether this is intended or not?

Expected Behavior / Behavior in 2.0.1
Diffing two identical one-line strings, such as 'these strings contain no differences', and using the UnifiedDiffOutputBuilder returns an empty string, i.e. a string with length 0 ("").

Observed Behavior in 3.0.2
Diffing two identical one-line strings returns the string "\n", i.e. a one-byte length string with the newline character in it.

Reproduction
Using composer to manage the dependency, the following test harness file can enable you to quickly test between different versions.

<?php
require_once('vendor/autoload.php');

use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;

$a = 'something that is the same';
$b = 'something that is the same';

$differ = new Differ(new UnifiedDiffOutputBuilder(''));
$diff = $differ->diff($a, $b);

echo "The diff is:\n";
echo serialize($diff);

Running the above script with composer pulling in sebastian/diff version 2.0.1 outputs:

The diff is:
s:0:""

Whereas running the script with sebastian/diff 3.0.2 outputs:

The diff is:
s:1:"
"

We are using this library to detect differences and treat any non-zero length output as a "difference". I suspect other consumers of this library likely do the same.

Note also that using the command-line diff tool on two identical files on linux outputs a zero-length response as well, so the expected behavior is consistent with built-in tools on common platforms.

getting difference between more than two texts

Hi, thanks for your great job.
I want to get differences between 3 texts like first getting differences between text 1 and text 2 , then text 2 and text 3, and then merge all the differences. Any idea to how to implement it?

Ability to change header without creating new diff builder

Hey,

It would be great to have an ability to change header on the go.

My usecase is that I'm looping through posts in database and after doing some changes to them I'm doing a string diff on that using StrictUnifiedDiffOutputBuilder and then I'm concatenating it into single report file. I've ended up creating new instance of builder each loop just to change the header. Would be nice to have some interface allowing me to change the header for already created diff builder.

Unless I've missed something....

Cheers,
Furai

Difference or bug in 1.4.2 makes phpunit fail.

Hi,
I've been working on phpunit and found out there's a difference or bug.
sebastianbergmann/phpunit#2664
With package sebastian/diff 1.4.1 phpunit passes, and with package sebastian/diff 1.4.2 it fails.

Difference causes the first two failures. (remaining errors appear because I don't have TeamCity)

[arturdev@localhost phpunit]$ ./phpunit
PHPUnit 6.2-g298838d by Sebastian Bergmann and contributors.

Runtime: PHP 7.0.18 with Xdebug 2.5.1
Configuration: /home/arturdev/projects/phpunit/phpunit.xml

............................................................. 61 / 1541 ( 3%)
............................................................. 122 / 1541 ( 7%)
............................................................. 183 / 1541 ( 11%)
............................................................. 244 / 1541 ( 15%)
............................................................. 305 / 1541 ( 19%)
............................................................. 366 / 1541 ( 23%)
............................................................. 427 / 1541 ( 27%)
............................................................. 488 / 1541 ( 31%)
............................................................. 549 / 1541 ( 35%)
............................................................. 610 / 1541 ( 39%)
............................................................. 671 / 1541 ( 43%)
............................................................. 732 / 1541 ( 47%)
........................F........F........................... 793 / 1541 ( 51%)
............................................................. 854 / 1541 ( 55%)
............................................................. 915 / 1541 ( 59%)
............................................................. 976 / 1541 ( 63%)
............................................................. 1037 / 1541 ( 67%)
............................................................. 1098 / 1541 ( 71%)
............................................................. 1159 / 1541 ( 75%)
............................................................. 1220 / 1541 ( 79%)
............................................................. 1281 / 1541 ( 83%)
............................................................. 1342 / 1541 ( 87%)
............................................................. 1403 / 1541 ( 91%)
.S........................................................... 1464 / 1541 ( 95%)
.....................FF..........F........................... 1525 / 1541 ( 98%)
................ 1541 / 1541 (100%)

Time: 37.03 seconds, Memory: 14.00MB

There were 5 failures:

  1. PHPUnit\Framework\ConstraintTest::testConstraintIsEqual2 with data set #3 ('a\nb\nc\nd\ne\nf\ng\nh\ni\nj\nk', 'a\np\nc\nd\ne\nf\ng\nh\ni\nw\nk', 'Failed asserting that two str...n k'\n')
    Failed asserting that two strings are equal.

--- Expected
+++ Actual
@@ @@
'custom message\n
Failed asserting that two strings are equal.\n
+\n
@@ @@
+p\n\n
-\n
@@ @@\n
i\n\n
-j\n\n
+w\n\n
k'\n
'

/home/arturdev/projects/phpunit/src/Framework/Constraint/IsEqual.php:140
/home/arturdev/projects/phpunit/src/Framework/Assert.php:2116
/home/arturdev/projects/phpunit/src/Framework/Assert.php:541
/home/arturdev/projects/phpunit/tests/Framework/ConstraintTest.php:850
/home/arturdev/projects/phpunit/src/Framework/TestCase.php:1056
/home/arturdev/projects/phpunit/src/Framework/TestCase.php:915
/home/arturdev/projects/phpunit/src/Framework/TestResult.php:696
/home/arturdev/projects/phpunit/src/Framework/TestCase.php:870
/home/arturdev/projects/phpunit/src/Framework/TestSuite.php:746
/home/arturdev/projects/phpunit/src/Framework/TestSuite.php:746
/home/arturdev/projects/phpunit/src/Framework/TestSuite.php:746
/home/arturdev/projects/phpunit/src/Framework/TestSuite.php:746
/home/arturdev/projects/phpunit/src/TextUI/TestRunner.php:534
/home/arturdev/projects/phpunit/src/TextUI/Command.php:209
/home/arturdev/projects/phpunit/src/TextUI/Command.php:140

  1. PHPUnit\Framework\ConstraintTest::testConstraintIsEqual2 with data set #12 (stdClass Object (...), stdClass Object (...), 'Failed asserting that two obj...\n )\n')
    Failed asserting that two strings are equal.

--- Expected
+++ Actual
@@ @@
'custom message\n
Failed asserting that two objects are equal.\n
+\n
+\n
@@ @@

  •        0 => 4\n
    

-\n
@@ @@\n
'foo' => 'a\n\n

  •    b\n\n
    
  •    p\n\n
    

-\n
@@ @@\n
i\n\n

  •    j\n\n
    
  •    w\n\n
       k'\n
    
    )\n
    'self' => stdClass Object (...)\n
    'c' => stdClass Object (...)\n
    )\n
    '

/home/arturdev/projects/phpunit/src/Framework/Constraint/IsEqual.php:140
/home/arturdev/projects/phpunit/src/Framework/Assert.php:2116
/home/arturdev/projects/phpunit/src/Framework/Assert.php:541
/home/arturdev/projects/phpunit/tests/Framework/ConstraintTest.php:850
/home/arturdev/projects/phpunit/src/Framework/TestCase.php:1056
/home/arturdev/projects/phpunit/src/Framework/TestCase.php:915
/home/arturdev/projects/phpunit/src/Framework/TestResult.php:696
/home/arturdev/projects/phpunit/src/Framework/TestCase.php:870
/home/arturdev/projects/phpunit/src/Framework/TestSuite.php:746
/home/arturdev/projects/phpunit/src/Framework/TestSuite.php:746
/home/arturdev/projects/phpunit/src/Framework/TestSuite.php:746
/home/arturdev/projects/phpunit/src/Framework/TestSuite.php:746
/home/arturdev/projects/phpunit/src/TextUI/TestRunner.php:534
/home/arturdev/projects/phpunit/src/TextUI/Command.php:209
/home/arturdev/projects/phpunit/src/TextUI/Command.php:140

[...]

Colored output

Any chance to get colored output from the diff, in HTML form maybe or something like that ?

Modify size of context shown

Sometimes it is helpful to show more than one or two lines of context around a diff.

There should be an option to set the context size in number of lines.

Roadmap For 1.2?

I'm just interested to know when the v1.2.0 release will be stamped. Have you got anything else planned before the release? There are some really nice changes here.

how to get more detail

    function get_diff($old,$new){
        $differ=new Differ();
        return $differ->diff($old,$new);
    }

and get_diff return a string.


@@ @@
!
-!
+ !
@@ @@
switchport mode access
-!
+ !
@@ @@
!
-interface GigabitEthernet1/0/23            //how can i get the previous three lines
+ interface GigabitEthernet1/0/23
@@ @@
interface GigabitEthernet1/0/32
-!
+ !
@@ @@
!
-interface GigabitEthernet1/0/44
+ interface GigabitEthernet1/0/44
@@ @@
!

thanks

PHP 8 support

PHP 8.0.0alpha1 has been released, and this package is passing the CI tests on 8.0.0-dev. Is now a sensible time to allow PHP ^8.0 in composer.json?

Missing `\ No newline at end of file` on `UnifiedDiffOutputBuilder`

With the UnifiedDiffOutputBuilder, when the $to content has no new line at end of file, the \ No newline at end of file is missing.

Here is a simple code snippet that shows the difference between StrictUnifiedDiffOutputBuilder result and UnifiedDiffOutputBuilder result.

<?php
include __DIR__ . '/vendor/autoload.php';

use SebastianBergmann\Diff\Differ;
use SebastianBergmann\Diff\Output\StrictUnifiedDiffOutputBuilder;
use SebastianBergmann\Diff\Output\UnifiedDiffOutputBuilder;

$differ = new Differ(new UnifiedDiffOutputBuilder("--- /dev/null\n+++ /path/to/file.txt\n", true));
echo $differ->diff(
    '',
    "This is a text file\nwith no newline at end of file."
);
echo PHP_EOL;
$differ = new Differ(new StrictUnifiedDiffOutputBuilder(['fromFile' => '/dev/null', 'toFile' => '/path/to/file.txt']));
echo $differ->diff(
    '',
    "This is a text file\nwith no newline at end of file."
);

Result will be

--- /dev/null
+++ /path/to/file.txt
@@ -1,0 +1,2 @@
+This is a text file
+with no newline at end of file.

--- /dev/null
+++ /path/to/file.txt
@@ -1,0 +1,2 @@
+This is a text file
+with no newline at end of file.
\ No newline at end of file

Diff with multiple chunks not working correctly

The Parser fails on diffs with multiple chunks. Reason seems to be that after matching the first chunk in a file more chunks are not processed any further and are just considered as normal lines.

Example diff to reproduce:

diff --git a/test.php b/test.php
index c35bc79..eb1d4c5 100644
--- a/test.php
+++ b/test.php
@@ -9,7 +9,7 @@ use Foo as Bar;
  */
 class Baz {

-       private $args;
+       private $argsWhichHasBeenEdited;

        public function __construct($args, Bar $bar = null) {
                $this->args = $args;
@@ -18,6 +18,10 @@ class Baz {
        public function getArgs() {
                return $this->args;
        }
+
+       public function aNewFunction() {
+               return $this->args;
+       }
 }

only the chunk @-9,7 +9,7 is available as its own object

Parse diff string

Is it possible to parse a diff string using this library? My use-case is for Anorak which receives a diff for a commit and I only want to get the additions.

[Feature] Percent change

I would like to be able to indicate (similar to git GitHub) the relative amount a file has changed. I could not find any convenient way to do that currently, other than creating a diff string and calculating the size of the changes. I think it would make a nice addition to this library.

Diff lines decorator

The idea is to create a DiffLinesDecorator interface that will be called here:

diff/src/Differ.php

Lines 106 to 112 in 13edfd8

if ($diff[$i][1] === 1 /* ADDED */) {
$buffer .= '+' . $diff[$i][0] . "\n";
} elseif ($diff[$i][1] === 2 /* REMOVED */) {
$buffer .= '-' . $diff[$i][0] . "\n";
} elseif ($this->showNonDiffLines === true) {
$buffer .= ' ' . $diff[$i][0] . "\n";
}

This will permit users to easily customize the diff rendering, like I did here: https://travis-ci.org/sonata-project/dev-kit/builds/127322216#L246

What do you think? I could work on a PR for that.

Clarification of the unified output format

The unified output format looks a bit different from the one implemented in GNU diff. Consider the two files:

↪  cat a.txt 
1
2
3
4
5
6
7
8

↪  cat b.txt 
1
2
3
4
5
6'
7
8

If compared by GNU diff, the comparison result is the following:

--- a.txt	2017-10-11 12:40:59.304512847 -0700
+++ b.txt	2017-10-11 12:41:14.776322246 -0700
@@ -3,6 +3,6 @@
 3
 4
 5
-6
+6'
 7
 8

The changed line is surrounded by unchanged lines (3 at most, by default) to represent the context.

If compared by the Differ, the result is the following:

--- Original
+++ New
@@ @@
 1
 2
 3
 4
 5
-6
+6'

The context is represented by 5 lines before and none after.

If the number of non-changed lines before the change is greater than 5 (must be controlled by AbstractChunkOutputBuilder::getCommonChunks(int $lineThreshold)), then they are entirely dropped:

--- Original
+++ New
@@ @@
-7
+7'

At the same time, the non-changed lines after the change are dropped independently on the size of the chunk.

Is this behavior by design? If yes, what's the exact meaning of $lineThreshold.

Whitespace changes from php-cs-fixer

@SpacePossum @keradus When I run php-cs-fixer on master then I get the following changes:

diff --git a/tests/Output/UnifiedDiffOutputBuilderDataProvider.php b/tests/Output/UnifiedDiffOutputBuilderDataProvider.php
index de7da25..391a9b1 100644
--- a/tests/Output/UnifiedDiffOutputBuilderDataProvider.php
+++ b/tests/Output/UnifiedDiffOutputBuilderDataProvider.php
@@ -55,8 +55,7 @@ final class UnifiedDiffOutputBuilderDataProvider
 -
  A
  1
-'
-                ,
+',
                 "\n\nA\n1",
                 "A\n1",
             ],
diff --git a/tests/Utils/UnifiedDiffAssertTraitTest.php b/tests/Utils/UnifiedDiffAssertTraitTest.php
index e15d13a..7d5cc65 100644
--- a/tests/Utils/UnifiedDiffAssertTraitTest.php
+++ b/tests/Utils/UnifiedDiffAssertTraitTest.php
@@ -101,7 +101,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 -A
 +B
  " . '
-');
+'
+        );
     }
 
     public function testInvalidStartHeader4(): void
@@ -116,7 +117,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 -A
 +B
  ' . '
-');
+'
+        );
     }
 
     public function testInvalidLine1(): void
@@ -131,7 +133,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 -Z
 1
 +U
-');
+'
+        );
     }
 
     public function testInvalidLine2(): void
@@ -145,7 +148,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 @@ -8 +8 @@
 
 
-');
+'
+        );
     }
 
     public function testHunkInvalidFormat(): void
@@ -159,7 +163,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 @@ INVALID -1,1 +1,1 @@
 -Z
 +U
-');
+'
+        );
     }
 
     public function testHunkOverlapFrom(): void
@@ -176,7 +181,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 @@ -7,1 +9,1 @@
 -Z
 +U
-');
+'
+        );
     }
 
     public function testHunkOverlapTo(): void
@@ -193,7 +199,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 @@ -17,1 +7,1 @@
 -Z
 +U
-');
+'
+        );
     }
 
     public function testExpectHunk1(): void
@@ -208,7 +215,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 -Z
 +U
 +O
-');
+'
+        );
     }
 
     public function testExpectHunk2(): void
@@ -223,7 +231,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
  ' . '
  ' . '
 @@ -38,12 +48,12 @@
-');
+'
+        );
     }
 
     public function testMisplacedLineAfterComments1(): void
@@ -240,7 +249,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 +U
 \ No newline at end of file
 +A
-');
+'
+        );
     }
 
     public function testMisplacedLineAfterComments2(): void
@@ -256,7 +266,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 \ No newline at end of file
 \ No newline at end of file
 \ No newline at end of file
-');
+'
+        );
     }
 
     public function testMisplacedLineAfterComments3(): void
@@ -272,7 +283,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 \ No newline at end of file
 \ No newline at end of file
 +A
-');
+'
+        );
     }
 
     public function testMisplacedComment(): void
@@ -282,7 +294,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 
         $this->assertValidUnifiedDiffFormat(
 '\ No newline at end of file
-');
+'
+        );
     }
 
     public function testUnexpectedDuplicateNoNewLineEOF(): void
@@ -299,7 +312,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 \ No newline at end of file
  ' . '
 \ No newline at end of file
-');
+'
+        );
     }
 
     public function testFromAfterClose(): void
@@ -315,7 +329,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 \ No newline at end of file
 -A
 \ No newline at end of file
-');
+'
+        );
     }
 
     public function testSameAfterFromClose(): void
@@ -331,7 +346,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 \ No newline at end of file
  A
 \ No newline at end of file
-');
+'
+        );
     }
 
     public function testToAfterClose(): void
@@ -347,7 +363,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 \ No newline at end of file
 +A
 \ No newline at end of file
-');
+'
+        );
     }
 
     public function testSameAfterToClose(): void
@@ -363,7 +380,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 \ No newline at end of file
  A
 \ No newline at end of file
-');
+'
+        );
     }
 
     public function testUnexpectedEOFFromMissingLines(): void
@@ -378,7 +396,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 -A
 +B
  ' . '
-');
+'
+        );
     }
 
     public function testUnexpectedEOFToMissingLines(): void
@@ -393,7 +412,8 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 -A
 +B
  ' . '
-');
+'
+        );
     }
 
     public function testUnexpectedEOFBothFromAndToMissingLines(): void
@@ -408,6 +428,7 @@ final class UnifiedDiffAssertTraitTest extends TestCase
 -A
 +B
  ' . '
-');
+'
+        );
     }
 }

The tests pass with and without these changes but I am not sure whether the changes are correct. Could you have a look? Thanks!

Diff wrapper with some utils

Instead of returning a simple array of Diff for Parser::parse, we may return a DiffWrapper object with some functionalities:

  • Make it iterable to work as an array. Plus, this may keep BC.
  • Add a getPosition method which return the diff position of a given path and line number, if exist.
  • Maybe more? Just tell! :-)

WDYT? I can propose a POC PR.

Modernize build automation

  • Use GitHub Actions instead of Travis CI
  • Have Composer in tools/composer and managed through composer self-update (see update-tools target in build.xml
  • Install Psalm using Phive as tools/psalm (phive install --copy psalm)
  • Install PHP-CS-Fixer using Phive as tools/php-cs-fixer (phive install --copy php-cs-fixer)
  • Create Psalm configuration
  • Add Psalm build step to GitHub Actions-based CI workflow
  • Add PHP-CS-Fixer build step to GitHub Actions-based CI workflow

Fatal when diffing integers

<?php
use SebastianBergmann\Diff\Differ;
$differ = new Differ;
print $differ->diff(1, 2);

results in

PHP Catchable fatal error:  Argument 1 passed to 
SebastianBergmann\Diff\Differ::selectLcsImplementation() 
must be of the type array, integer given, called in src/Differ.php 
on line 198 and defined in src/Differ.php on line 254

diff('foo', 'bar') (with string arguments) works as expected. A workaround is to to cast the arguments to string.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.