Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
76.67% |
23 / 30 |
|
50.00% |
3 / 6 |
CRAP | |
0.00% |
0 / 1 |
| ExternalTextDiffer | |
76.67% |
23 / 30 |
|
50.00% |
3 / 6 |
10.03 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getFormats | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| getFormatContext | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| doRenderBatch | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| doRender | |
80.00% |
20 / 25 |
|
0.00% |
0 / 1 |
4.13 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace MediaWiki\Diff\TextDiffer; |
| 4 | |
| 5 | use MediaWiki\Shell\Shell; |
| 6 | use RuntimeException; |
| 7 | |
| 8 | /** |
| 9 | * @since 1.41 |
| 10 | */ |
| 11 | class ExternalTextDiffer extends BaseTextDiffer { |
| 12 | /** @var string */ |
| 13 | private $externalPath; |
| 14 | |
| 15 | /** |
| 16 | * @param string $externalPath The path to the executable file which provides the diff |
| 17 | */ |
| 18 | public function __construct( $externalPath ) { |
| 19 | $this->externalPath = $externalPath; |
| 20 | } |
| 21 | |
| 22 | public function getName(): string { |
| 23 | return 'external'; |
| 24 | } |
| 25 | |
| 26 | public function getFormats(): array { |
| 27 | return [ 'external' ]; |
| 28 | } |
| 29 | |
| 30 | /** @inheritDoc */ |
| 31 | public function getFormatContext( string $format ) { |
| 32 | return self::CONTEXT_ROW; |
| 33 | } |
| 34 | |
| 35 | protected function doRenderBatch( string $oldText, string $newText, array $formats ): array { |
| 36 | return [ 'external' => $this->doRender( $oldText, $newText ) ]; |
| 37 | } |
| 38 | |
| 39 | /** |
| 40 | * @param string $oldText |
| 41 | * @param string $newText |
| 42 | * @return string |
| 43 | */ |
| 44 | private function doRender( $oldText, $newText ) { |
| 45 | $tmpDir = wfTempDir(); |
| 46 | $tempName1 = tempnam( $tmpDir, 'diff_' ); |
| 47 | $tempName2 = tempnam( $tmpDir, 'diff_' ); |
| 48 | |
| 49 | $tempFile1 = fopen( $tempName1, "w" ); |
| 50 | if ( !$tempFile1 ) { |
| 51 | throw new RuntimeException( "Could not create temporary file $tempName1 for external diffing" ); |
| 52 | } |
| 53 | $tempFile2 = fopen( $tempName2, "w" ); |
| 54 | if ( !$tempFile2 ) { |
| 55 | throw new RuntimeException( "Could not create temporary file $tempName2 for external diffing" ); |
| 56 | } |
| 57 | fwrite( $tempFile1, $oldText ); |
| 58 | fwrite( $tempFile2, $newText ); |
| 59 | fclose( $tempFile1 ); |
| 60 | fclose( $tempFile2 ); |
| 61 | $cmd = [ $this->externalPath, $tempName1, $tempName2 ]; |
| 62 | $result = Shell::command( $cmd ) |
| 63 | ->execute(); |
| 64 | $exitCode = $result->getExitCode(); |
| 65 | if ( $exitCode !== 0 ) { |
| 66 | throw new RuntimeException( "External diff command returned code {$exitCode}. Stderr: " |
| 67 | . wfEscapeWikiText( $result->getStderr() ) |
| 68 | ); |
| 69 | } |
| 70 | $diffText = $result->getStdout(); |
| 71 | unlink( $tempName1 ); |
| 72 | unlink( $tempName2 ); |
| 73 | |
| 74 | return $diffText; |
| 75 | } |
| 76 | } |