forked from jfcherng/php-diff
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDiffHelper.php
More file actions
182 lines (158 loc) · 5.28 KB
/
DiffHelper.php
File metadata and controls
182 lines (158 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<?php
declare(strict_types=1);
namespace Jfcherng\Diff;
use Jfcherng\Diff\Factory\RendererFactory;
use Jfcherng\Diff\Renderer\RendererConstant;
final class DiffHelper
{
/**
* The constructor.
*/
private function __construct()
{
}
/**
* Get the absolute path of the project root directory.
*/
public static function getProjectDirectory(): string
{
static $path;
return $path ??= realpath(__DIR__ . '/..');
}
/**
* Get the information about available renderers.
*/
public static function getRenderersInfo(): array
{
static $info;
if (isset($info)) {
return $info;
}
$glob = implode(\DIRECTORY_SEPARATOR, [
static::getProjectDirectory(),
'src',
'Renderer',
'{' . implode(',', RendererConstant::RENDERER_TYPES) . '}',
'*.php',
]);
$fileNames = array_map(
// get basename without file extension
static fn (string $file): string => pathinfo($file, \PATHINFO_FILENAME),
// paths of all Renderer files
glob($glob, \GLOB_BRACE),
);
$renderers = array_filter(
$fileNames,
// only normal class files are wanted
static fn (string $fileName): bool => (
substr($fileName, 0, 8) !== 'Abstract'
&& substr($fileName, -9) !== 'Interface'
&& substr($fileName, -5) !== 'Trait'
),
);
$info = [];
foreach ($renderers as $renderer) {
$info[$renderer] = RendererFactory::resolveRenderer($renderer)::INFO;
}
return $info;
}
/**
* Get the available renderers.
*
* @return string[] the available renderers
*/
public static function getAvailableRenderers(): array
{
return array_keys(self::getRenderersInfo());
}
/**
* Get the content of the CSS style sheet for HTML renderers.
*
* @throws \LogicException path is a directory
* @throws \RuntimeException path cannot be opened
*/
public static function getStyleSheet(): string
{
static $fileContent;
if (isset($fileContent)) {
return $fileContent;
}
$filePath = static::getProjectDirectory() . '/example/diff-table.css';
$file = new \SplFileObject($filePath, 'r');
return $fileContent = $file->fread($file->getSize());
}
/**
* Gets the diff statistics such as inserted and deleted etc...
*
* @return array<string,float> the statistics
*/
public static function getStatistics(): array
{
return Differ::getInstance()->getStatistics();
}
/**
* All-in-one static method to calculate the diff between two strings (or arrays of strings).
*
* @param string|string[] $old the old string (or array of lines)
* @param string|string[] $new the new string (or array of lines)
* @param string $renderer the renderer name
* @param array $differOptions the options for Differ object
* @param array $rendererOptions the options for renderer object
*
* @return string the rendered differences
*/
public static function calculate(
$old,
$new,
string $renderer = 'Unified',
array $differOptions = [],
array $rendererOptions = []
): string {
// always convert into array form
\is_string($old) && ($old = explode("\n", $old));
\is_string($new) && ($new = explode("\n", $new));
return RendererFactory::getInstance($renderer)
->setOptions($rendererOptions)
->render(
Differ::getInstance()
->setOldNew($old, $new)
->setOptions($differOptions),
)
;
}
/**
* All-in-one static method to calculate the diff between two files.
*
* @param string $old the path of the old file
* @param string $new the path of the new file
* @param string $renderer the renderer name
* @param array $differOptions the options for Differ object
* @param array $rendererOptions the options for renderer object
*
* @throws \LogicException path is a directory
* @throws \RuntimeException path cannot be opened
*
* @return string the rendered differences
*/
public static function calculateFiles(
string $old,
string $new,
string $renderer = 'Unified',
array $differOptions = [],
array $rendererOptions = []
): string {
// we want to leave the line-ending problem to static::calculate()
// so do not set SplFileObject::DROP_NEW_LINE flag
// otherwise, we will lose \r if the line-ending is \r\n
$oldFile = new \SplFileObject($old, 'r');
$newFile = new \SplFileObject($new, 'r');
return static::calculate(
// fread() requires the length > 0 hence we plus 1 for empty files
$oldFile->fread($oldFile->getSize() + 1),
$newFile->fread($newFile->getSize() + 1),
$renderer,
$differOptions,
$rendererOptions,
);
}
}