Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. Fixer.php

function Fixer::generateDiff

Generates a text diff of the original file and the new content.

Parameters

string $filePath Optional file path to diff the file against.: If not specified, the original version of the file will be used.

boolean $colors Print coloured output or not.:

Return value

string

Throws

\PHP_CodeSniffer\Exceptions\RuntimeException When the diff command fails.

File

vendor/squizlabs/php_codesniffer/src/Fixer.php, line 233

Class

Fixer

Namespace

PHP_CodeSniffer

Code

public function generateDiff($filePath = null, $colors = true) {
    if ($filePath === null) {
        $filePath = $this->currentFile
            ->getFilename();
    }
    $cwd = getcwd() . DIRECTORY_SEPARATOR;
    if (strpos($filePath, $cwd) === 0) {
        $filename = substr($filePath, strlen($cwd));
    }
    else {
        $filename = $filePath;
    }
    $contents = $this->getContents();
    $tempName = tempnam(sys_get_temp_dir(), 'phpcs-fixer');
    $fixedFile = fopen($tempName, 'w');
    fwrite($fixedFile, $contents);
    // We must use something like shell_exec() or proc_open() because whitespace at the end
    // of lines is critical to diff files.
    // Using proc_open() instead of shell_exec improves performance on Windows significantly,
    // while the results are the same (though more code is needed to get the results).
    // This is specifically due to proc_open allowing to set the "bypass_shell" option.
    $filename = escapeshellarg($filename);
    $cmd = "diff -u -L{$filename} -LPHP_CodeSniffer {$filename} \"{$tempName}\"";
    // Stream 0 = STDIN, 1 = STDOUT, 2 = STDERR.
    $descriptorspec = [
        0 => [
            'pipe',
            'r',
        ],
        1 => [
            'pipe',
            'w',
        ],
        2 => [
            'pipe',
            'w',
        ],
    ];
    $options = null;
    if (stripos(PHP_OS, 'WIN') === 0) {
        $options = [
            'bypass_shell' => true,
        ];
    }
    $process = proc_open($cmd, $descriptorspec, $pipes, $cwd, null, $options);
    if (is_resource($process) === false) {
        throw new RuntimeException('Could not obtain a resource to execute the diff command.');
    }
    // We don't need these.
    fclose($pipes[0]);
    fclose($pipes[2]);
    // Stdout will contain the actual diff.
    $diff = stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    proc_close($process);
    fclose($fixedFile);
    if (is_file($tempName) === true) {
        unlink($tempName);
    }
    if ($diff === false || $diff === '') {
        return '';
    }
    if ($colors === false) {
        return $diff;
    }
    $diffLines = explode(PHP_EOL, $diff);
    if (count($diffLines) === 1) {
        // Seems to be required for cygwin.
        $diffLines = explode("\n", $diff);
    }
    $diff = [];
    foreach ($diffLines as $line) {
        if (isset($line[0]) === true) {
            switch ($line[0]) {
                case '-':
                    $diff[] = "\x1b[31m{$line}\x1b[0m";
                    break;
                case '+':
                    $diff[] = "\x1b[32m{$line}\x1b[0m";
                    break;
                default:
                    $diff[] = $line;
            }
        }
    }
    $diff = implode(PHP_EOL, $diff);
    return $diff;
}
RSS feed
Powered by Drupal