Skip to content

Commit ef4d613

Browse files
committed
first
1 parent 9689573 commit ef4d613

13 files changed

+2271
-2
lines changed

.gitattributes

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
* text eol=lf
2+
*.serialized -text
3+
*.dat -text
4+
/tests export-ignore
5+
/stubs export-ignore
6+
/.gitattributes export-ignore
7+
/.gitignore export-ignore
8+
/.scrutinizer.yml export-ignore
9+
/.travis.yml export-ignore
10+
/.gitlab-ci.yml
11+
/phpunit.xml export-ignore
12+
/changelog.md export-ignore
13+
/Makefile export-ignore

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/vendor
2+
/.idea
3+
/json-diff
4+
/json-diff.tar.gz

.scrutinizer.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
filter:
2+
paths: [src/*]
3+
excluded_paths: [vendor/*, tests/*]
4+
before_commands:
5+
- 'composer install --dev --prefer-source'
6+
tools:
7+
external_code_coverage: true
8+
php_mess_detector: true
9+
php_code_sniffer: true
10+
sensiolabs_security_checker: true
11+
php_code_coverage: true
12+
php_pdepend: true
13+
php_loc:
14+
enabled: true
15+
excluded_dirs: [vendor, tests]
16+
php_cpd:
17+
enabled: true
18+
excluded_dirs: [vendor, tests]

.travis.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
language: php
2+
php:
3+
- nightly
4+
- hhvm
5+
- 7.1
6+
- 7.0
7+
- 5.6
8+
- 5.5
9+
- 5.4
10+
11+
sudo: false
12+
dist: trusty
13+
14+
## Cache composer bits
15+
cache:
16+
directories:
17+
- $HOME/.composer/cache
18+
19+
# execute any number of scripts before the test run, custom env's are available as variables
20+
before_script:
21+
- composer install --dev --no-interaction --prefer-dist
22+
23+
matrix:
24+
allow_failures:
25+
- php: hhvm
26+
- php: nightly
27+
fast_finish: true
28+
29+
script:
30+
- mkdir -p build/logs
31+
- ./vendor/bin/phpunit -v --configuration phpunit.xml --coverage-clover build/logs/clover.xml
32+
33+
after_script:
34+
- wget https://scrutinizer-ci.com/ocular.phar
35+
- php ocular.phar code-coverage:upload --format=php-clover build/logs/coverage.clover
36+
- if [[ $(phpenv version-name) =~ 7.1 ]] ; then php vendor/bin/coveralls -v; fi
37+
- if [[ $(phpenv version-name) =~ 7.1 ]] ; then php vendor/bin/test-reporter; fi

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
phar:
2+
composer require php-yaoi/php-yaoi:^1;composer install --no-dev;rm -rf tests/;rm ./json-diff;rm ./json-diff.tar.gz;phar-composer build;mv ./json-diff.phar ./json-diff;tar -zcvf ./json-diff.tar.gz ./json-diff;git reset --hard;composer install

README.md

Lines changed: 250 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,250 @@
1-
# json-diff
2-
A PHP implementation for finding unordered diff between two JSON documents
1+
# JSON diff and rearrange tool for PHP
2+
3+
A PHP implementation for finding unordered diff between two `JSON` documents.
4+
5+
[![Build Status](https://travis-ci.org/swaggest/json-diff.svg?branch=master)](https://travis-ci.org/swaggest/json-diff)
6+
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/swaggest/json-diff/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/swaggest/json-diff/?branch=master)
7+
[![Code Climate](https://codeclimate.com/github/swaggest/json-diff/badges/gpa.svg)](https://codeclimate.com/github/swaggest/json-diff)
8+
[![Test Coverage](https://codeclimate.com/github/swaggest/json-diff/badges/coverage.svg)](https://codeclimate.com/github/swaggest/json-diff/coverage)
9+
10+
## Purpose
11+
12+
* To simplify changes review between two `JSON` files you can use a standard `diff` tool on rearranged pretty-printed `JSON`.
13+
* To detect breaking changes by analyzing removals and changes from original `JSON`.
14+
* To keep original order of object sets (for example `swagger.json` [parameters](https://swagger.io/docs/specification/describing-parameters/) list).
15+
16+
## Installation
17+
18+
### Library
19+
20+
```bash
21+
git clone https://github.com/swaggest/json-diff.git
22+
```
23+
24+
### Composer
25+
26+
[Install PHP Composer](https://getcomposer.org/doc/00-intro.md)
27+
28+
```bash
29+
composer require swaggest/json-diff
30+
```
31+
32+
## Library usage
33+
34+
Create `JsonDiff` object from two values (`original` and `new`).
35+
36+
```php
37+
$r = new JsonDiff(json_decode($originalJson), json_decode($newJson));
38+
```
39+
40+
On construction `JsonDiff` will build `rearranged` value of `new` recursively keeping `original` keys order where possible.
41+
Keys that are missing in `original` will be appended to the end of `rearranged` value in same order they had in `new` value.
42+
43+
If two values are arrays of objects, `JsonDiff` will try to find a common unique field in those objects and use it as criteria for rearranging.
44+
You can disable this behaviour with `JsonDiff::SKIP_REARRANGE_ARRAY` option:
45+
```php
46+
$r = new JsonDiff(
47+
json_decode($originalJson),
48+
json_decode($newJson),
49+
JsonDiff::SKIP_REARRANGE_ARRAY
50+
);
51+
```
52+
53+
On created object you have several handy methods.
54+
55+
### `getRearranged`
56+
Returns new value, rearranged with original order.
57+
58+
### `getRemoved`
59+
Returns removals as partial value of original.
60+
61+
### `getRemovedPaths`
62+
Returns list of `JSON` paths that were removed from original.
63+
64+
### `getRemovedCnt`
65+
Returns number of removals.
66+
67+
### `getAdded`
68+
Returns additions as partial value of new.
69+
70+
### `getAddedPaths`
71+
Returns list of `JSON` paths that were added to new.
72+
73+
### `getAddedCnt`
74+
Returns number of additions.
75+
76+
### `getModifiedOriginal`
77+
Returns modifications as partial value of original.
78+
79+
### `getModifiedNew`
80+
Returns modifications as partial value of new.
81+
82+
### `getModifiedPaths`
83+
Returns list of `JSON` paths that were modified from original to new.
84+
85+
### `getModifiedCnt`
86+
Returns number of modifications.
87+
88+
## Example
89+
90+
```php
91+
$originalJson = <<<'JSON'
92+
{
93+
"key1": [4, 1, 2, 3],
94+
"key2": 2,
95+
"key3": {
96+
"sub0": 0,
97+
"sub1": "a",
98+
"sub2": "b"
99+
},
100+
"key4": [
101+
{"a":1, "b":true}, {"a":2, "b":false}, {"a":3}
102+
]
103+
}
104+
JSON;
105+
106+
$newJson = <<<'JSON'
107+
{
108+
"key5": "wat",
109+
"key1": [5, 1, 2, 3],
110+
"key4": [
111+
{"c":false, "a":2}, {"a":1, "b":true}, {"c":1, "a":3}
112+
],
113+
"key3": {
114+
"sub3": 0,
115+
"sub2": false,
116+
"sub1": "c"
117+
}
118+
}
119+
JSON;
120+
121+
$expected = <<<'JSON'
122+
{
123+
"key1": [5, 1, 2, 3],
124+
"key3": {
125+
"sub1": "c",
126+
"sub2": false,
127+
"sub3": 0
128+
},
129+
"key4": [
130+
{"a":1, "b":true}, {"a":2, "c":false}, {"a":3, "c":1}
131+
],
132+
"key5": "wat"
133+
}
134+
JSON;
135+
136+
$r = new JsonDiff(json_decode($originalJson), json_decode($newJson));
137+
$this->assertSame(
138+
json_encode(json_decode($expected), JSON_PRETTY_PRINT),
139+
json_encode($r->getRearranged(), JSON_PRETTY_PRINT)
140+
);
141+
$this->assertSame('{"key3":{"sub3":0},"key4":{"1":{"c":false},"2":{"c":1}},"key5":"wat"}',
142+
json_encode($r->getAdded()));
143+
$this->assertSame(array(
144+
'#/key3/sub3',
145+
'#/key4/1/c',
146+
'#/key4/2/c',
147+
'#/key5',
148+
), $r->getAddedPaths());
149+
$this->assertSame('{"key2":2,"key3":{"sub0":0},"key4":{"1":{"b":false}}}',
150+
json_encode($r->getRemoved()));
151+
$this->assertSame(array(
152+
'#/key2',
153+
'#/key3/sub0',
154+
'#/key4/1/b',
155+
), $r->getRemovedPaths());
156+
157+
$this->assertSame(array(
158+
'#/key1/0',
159+
'#/key3/sub1',
160+
'#/key3/sub2',
161+
), $r->getModifiedPaths());
162+
163+
$this->assertSame('{"key1":[4],"key3":{"sub1":"a","sub2":"b"}}', json_encode($r->getModifiedOriginal()));
164+
$this->assertSame('{"key1":[5],"key3":{"sub1":"c","sub2":false}}', json_encode($r->getModifiedNew()));
165+
```
166+
167+
## CLI tool
168+
169+
### Usage
170+
171+
```
172+
json-diff --help
173+
v1.0.0 json-diff
174+
JSON diff and rearrange tool for PHP, https://github.com/swaggest/json-diff
175+
Usage:
176+
json-diff <action> <originalPath> <newPath>
177+
action Action to perform
178+
Allowed values: rearrange, changes, removals, additions, modifications
179+
originalPath Path to old (original) json file
180+
newPath Path to new json file
181+
182+
Options:
183+
--out <out> Path to output result json file, STDOUT if not specified
184+
--show-paths Show JSON paths
185+
--show-json Show JSON result
186+
187+
Misc:
188+
--help Show usage information
189+
--version Show version
190+
--bash-completion Generate bash completion
191+
--install Install to /usr/local/bin/
192+
```
193+
194+
### Examples
195+
196+
Using with standard `diff`
197+
198+
```
199+
json-diff rearrange ./composer.json ./composer2.json --show-json | diff ./composer.json -
200+
3c3
201+
< "description": "JSON diff and merge tool for PHP",
202+
---
203+
> "description": "JSON diff and merge tool for PHPH",
204+
5,11d4
205+
< "license": "MIT",
206+
< "authors": [
207+
< {
208+
< "name": "Viacheslav Poturaev",
209+
< "email": "[email protected]"
210+
< }
211+
< ],
212+
25,28c18
213+
< },
214+
< "bin": [
215+
< "bin/json-diff"
216+
< ]
217+
---
218+
> }
219+
```
220+
221+
Showing differences in `JSON` mode
222+
223+
```
224+
bin/json-diff changes ./composer.json ./composer2.json --show-json --show-paths
225+
#/license
226+
#/authors
227+
#/bin
228+
#/description
229+
{
230+
"removals": {
231+
"license": "MIT",
232+
"authors": [
233+
{
234+
"name": "Viacheslav Poturaev",
235+
"email": "[email protected]"
236+
}
237+
],
238+
"bin": [
239+
"bin/json-diff"
240+
]
241+
},
242+
"additions": null,
243+
"modifiedOriginal": {
244+
"description": "JSON diff and merge tool for PHP"
245+
},
246+
"modifiedNew": {
247+
"description": "JSON diff and merge tool for PHPH"
248+
}
249+
}
250+
```

bin/json-diff

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env php
2+
<?php
3+
set_time_limit(20);
4+
5+
foreach (array(__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php') as $file) {
6+
if (file_exists($file)) {
7+
require_once $file;
8+
break;
9+
}
10+
}
11+
12+
\Yaoi\Cli\Command\Runner::create(new \Swaggest\JsonDiff\Cli\Diff())->run();

composer.json

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"name": "swaggest/json-diff",
3+
"description": "JSON diff and merge tool for PHP",
4+
"type": "tool",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Viacheslav Poturaev",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"require-dev": {
13+
"php-yaoi/php-yaoi": "^1",
14+
"phpunit/phpunit": "^4.8.23",
15+
"phpunit/php-code-coverage": "2.2.4",
16+
"codeclimate/php-test-reporter": "^0.4.0"
17+
},
18+
"autoload": {
19+
"psr-4": {
20+
"Swaggest\\JsonDiff\\": "src/"
21+
}
22+
},
23+
"autoload-dev": {
24+
"psr-4": {
25+
"Swaggest\\JsonDiff\\Tests\\": "tests/src"
26+
}
27+
},
28+
"bin": [
29+
"bin/json-diff"
30+
]
31+
}

0 commit comments

Comments
 (0)