Page MenuHomeSealhub

No OneTemporary

diff --git a/src/difference/ArcanistDiffUtils.php b/src/difference/ArcanistDiffUtils.php
index 38207ff5..4006235e 100644
--- a/src/difference/ArcanistDiffUtils.php
+++ b/src/difference/ArcanistDiffUtils.php
@@ -1,332 +1,332 @@
<?php
/**
* Dumping ground for diff- and diff-algorithm-related miscellany.
*
* @group diff
*/
final class ArcanistDiffUtils {
/**
* Make a best-effort attempt to determine if a file is definitely binary.
*
* @return bool If true, the file is almost certainly binary. If false, the
* file might still be binary but is subtle about it.
*/
public static function isHeuristicBinaryFile($data) {
// Detect if a file is binary according to the Git heuristic, which is the
// presence of NULL ("\0") bytes. Git only examines the first "few" bytes of
// each file (8KB or so) as an optimization, but we don't have a reasonable
// equivalent in PHP, so just look at all of it.
return (strpos($data, "\0") !== false);
}
public static function renderDifferences(
$old,
$new,
$context_lines = 3,
$diff_options = "-L 'Old Value' -L 'New Value'") {
if ((string)$old === (string)$new) {
$new .= "\n(Old and new values are identical.)";
}
$file_old = new TempFile();
$file_new = new TempFile();
Filesystem::writeFile($file_old, (string)$old."\n");
Filesystem::writeFile($file_new, (string)$new."\n");
list($err, $stdout) = exec_manual(
"/usr/bin/diff {$diff_options} -U {$context_lines} %s %s",
$file_old,
$file_new);
return $stdout;
}
public static function generateIntralineDiff($o, $n) {
if (!strlen($o) || !strlen($n)) {
return array(
array(array(0, strlen($o))),
array(array(0, strlen($n)))
);
}
// This algorithm is byte-oriented and thus not safe for UTF-8, so just
// mark all the text as changed if either string has multibyte characters
// in it. TODO: Fix this so that this algorithm is UTF-8 aware.
if (preg_match('/[\x80-\xFF]/', $o.$n)) {
return array(
array(array(1, strlen($o))),
array(array(1, strlen($n))),
);
}
$result = self::buildLevenshteinDifferenceString($o, $n);
do {
$orig = $result;
$result = preg_replace(
'/([xdi])(s{3})([xdi])/',
'$1xxx$3',
$result);
$result = preg_replace(
'/([xdi])(s{2})([xdi])/',
'$1xx$3',
$result);
$result = preg_replace(
'/([xdi])(s{1})([xdi])/',
'$1x$3',
$result);
} while ($result != $orig);
$o_bright = array();
$n_bright = array();
$rlen = strlen($result);
$len = -1;
$cur = $result[0];
$result .= '-';
for ($ii = 0; $ii < strlen($result); $ii++) {
$len++;
$now = $result[$ii];
if ($result[$ii] == $cur) {
continue;
}
if ($cur == 's') {
$o_bright[] = array(0, $len);
$n_bright[] = array(0, $len);
} else if ($cur == 'd') {
$o_bright[] = array(1, $len);
} else if ($cur == 'i') {
$n_bright[] = array(1, $len);
} else if ($cur == 'x') {
$o_bright[] = array(1, $len);
$n_bright[] = array(1, $len);
}
$cur = $now;
$len = 0;
}
$o_bright = self::collapseIntralineRuns($o_bright);
$n_bright = self::collapseIntralineRuns($n_bright);
return array($o_bright, $n_bright);
}
public static function applyIntralineDiff($str, $intra_stack) {
$buf = '';
$p = $s = $e = 0; // position, start, end
$highlight = $tag = $ent = false;
$highlight_o = '<span class="bright">';
$highlight_c = '</span>';
$n = strlen($str);
for ($i = 0; $i < $n; $i++) {
if ($p == $e) {
do {
if (empty($intra_stack)) {
$buf .= substr($str, $i);
break 2;
}
$stack = array_shift($intra_stack);
$s = $e;
$e += $stack[1];
} while ($stack[0] == 0);
}
if (!$highlight && !$tag && !$ent && $p == $s) {
$buf .= $highlight_o;
$highlight = true;
}
if ($str[$i] == '<') {
$tag = true;
if ($highlight) {
$buf .= $highlight_c;
}
}
if (!$tag) {
if ($str[$i] == '&') {
$ent = true;
}
if ($ent && $str[$i] == ';') {
$ent = false;
}
if (!$ent) {
$p++;
}
}
$buf .= $str[$i];
if ($tag && $str[$i] == '>') {
$tag = false;
if ($highlight) {
$buf .= $highlight_o;
}
}
if ($highlight && ($p == $e || $i == $n - 1)) {
$buf .= $highlight_c;
$highlight = false;
}
}
return $buf;
}
private static function collapseIntralineRuns($runs) {
$count = count($runs);
for ($ii = 0; $ii < $count - 1; $ii++) {
if ($runs[$ii][0] == $runs[$ii + 1][0]) {
$runs[$ii + 1][1] += $runs[$ii][1];
unset($runs[$ii]);
}
}
return array_values($runs);
}
public static function buildLevenshteinDifferenceString($o, $n) {
$olt = strlen($o);
$nlt = strlen($n);
if (!$olt) {
return str_repeat('i', $nlt);
}
if (!$nlt) {
return str_repeat('d', $olt);
}
$min = min($olt, $nlt);
$t_start = microtime(true);
$pre = 0;
while ($pre < $min && $o[$pre] == $n[$pre]) {
$pre++;
}
$end = 0;
while ($end < $min && $o[($olt - 1) - $end] == $n[($nlt - 1) - $end]) {
$end++;
}
if ($end + $pre >= $min) {
$end = min($end, $min - $pre);
$prefix = str_repeat('s', $pre);
$suffix = str_repeat('s', $end);
$infix = null;
if ($olt > $nlt) {
$infix = str_repeat('d', $olt - ($end + $pre));
} else if ($nlt > $olt) {
$infix = str_repeat('i', $nlt - ($end + $pre));
}
return $prefix.$infix.$suffix;
}
if ($min - ($end + $pre) > 80) {
$max = max($olt, $nlt);
return str_repeat('x', $min) .
str_repeat($olt < $nlt ? 'i' : 'd', $max - $min);
}
$prefix = str_repeat('s', $pre);
$suffix = str_repeat('s', $end);
$o = substr($o, $pre, $olt - $end - $pre);
$n = substr($n, $pre, $nlt - $end - $pre);
$ol = strlen($o);
$nl = strlen($n);
$m = array_fill(0, $ol + 1, array_fill(0, $nl + 1, array()));
- $T_D = 'd';
- $T_I = 'i';
- $T_S = 's';
- $T_X = 'x';
+ $t_d = 'd';
+ $t_i = 'i';
+ $t_s = 's';
+ $t_x = 'x';
$m[0][0] = array(
0,
null);
for ($ii = 1; $ii <= $ol; $ii++) {
$m[$ii][0] = array(
$ii * 1000,
- $T_D);
+ $t_d);
}
for ($jj = 1; $jj <= $nl; $jj++) {
$m[0][$jj] = array(
$jj * 1000,
- $T_I);
+ $t_i);
}
$ii = 1;
do {
$jj = 1;
do {
if ($o[$ii - 1] == $n[$jj - 1]) {
$sub_t_cost = $m[$ii - 1][$jj - 1][0] + 0;
- $sub_t = $T_S;
+ $sub_t = $t_s;
} else {
$sub_t_cost = $m[$ii - 1][$jj - 1][0] + 2000;
- $sub_t = $T_X;
+ $sub_t = $t_x;
}
if ($m[$ii - 1][$jj - 1][1] != $sub_t) {
$sub_t_cost += 1;
}
$del_t_cost = $m[$ii - 1][$jj][0] + 1000;
- if ($m[$ii - 1][$jj][1] != $T_D) {
+ if ($m[$ii - 1][$jj][1] != $t_d) {
$del_t_cost += 1;
}
$ins_t_cost = $m[$ii][$jj - 1][0] + 1000;
- if ($m[$ii][$jj - 1][1] != $T_I) {
+ if ($m[$ii][$jj - 1][1] != $t_i) {
$ins_t_cost += 1;
}
if ($sub_t_cost <= $del_t_cost && $sub_t_cost <= $ins_t_cost) {
$m[$ii][$jj] = array(
$sub_t_cost,
$sub_t);
} else if ($ins_t_cost <= $del_t_cost) {
$m[$ii][$jj] = array(
$ins_t_cost,
- $T_I);
+ $t_i);
} else {
$m[$ii][$jj] = array(
$del_t_cost,
- $T_D);
+ $t_d);
}
} while ($jj++ < $nl);
} while ($ii++ < $ol);
$result = '';
$ii = $ol;
$jj = $nl;
do {
$r = $m[$ii][$jj][1];
$result .= $r;
switch ($r) {
- case $T_S:
- case $T_X:
+ case $t_s:
+ case $t_x:
$ii--;
$jj--;
break;
- case $T_I:
+ case $t_i:
$jj--;
break;
- case $T_D:
+ case $t_d:
$ii--;
break;
}
} while ($ii || $jj);
return $prefix.strrev($result).$suffix;
}
}
diff --git a/src/lint/linter/ArcanistJSHintLinter.php b/src/lint/linter/ArcanistJSHintLinter.php
index e01e43cd..7aa9c561 100644
--- a/src/lint/linter/ArcanistJSHintLinter.php
+++ b/src/lint/linter/ArcanistJSHintLinter.php
@@ -1,155 +1,161 @@
<?php
/**
* Uses "JSHint" to detect errors and potential problems in JavaScript code.
* To use this linter, you must install jshint through NPM (Node Package
* Manager). You can configure different JSHint options on a per-file basis.
*
* If you have NodeJS installed you should be able to install jshint with
* ##npm install jshint -g## (don't forget the -g flag or NPM will install
* the package locally). If your system is unusual, you can manually specify
* the location of jshint and its dependencies by configuring these keys in
* your .arcconfig:
*
* lint.jshint.prefix
* lint.jshint.bin
*
* If you want to configure custom options for your project, create a JSON
* file with these options and add the path to the file to your .arcconfig
* by configuring this key:
*
* lint.jshint.config
*
* Example JSON file (config.json):
*
* {
* "predef": [ // Custom globals
* "myGlobalVariable",
* "anotherGlobalVariable"
* ],
*
* "es5": true, // Allow ES5 syntax
* "strict": true // Require strict mode
* }
*
* For more options see http://www.jshint.com/options/.
*
* @group linter
*/
final class ArcanistJSHintLinter extends ArcanistLinter {
const JSHINT_ERROR = 1;
public function getLinterName() {
return 'JSHint';
}
public function getLintSeverityMap() {
return array(
self::JSHINT_ERROR => ArcanistLintSeverity::SEVERITY_ERROR
);
}
public function getLintNameMap() {
return array(
self::JSHINT_ERROR => "JSHint Error"
);
}
public function getJSHintOptions() {
$working_copy = $this->getEngine()->getWorkingCopy();
$options = '--reporter '.dirname(realpath(__FILE__)).'/reporter.js';
$config = $working_copy->getConfig('lint.jshint.config');
if ($config !== null) {
- $config = Filesystem::resolvePath($config, $working_copy->getProjectRoot());
+ $config = Filesystem::resolvePath(
+ $config,
+ $working_copy->getProjectRoot());
if (!Filesystem::pathExists($config)) {
throw new ArcanistUsageException(
- "Unable to find custom options file defined by 'lint.jshint.config'. ".
- "Make sure that the path is correct.");
+ "Unable to find custom options file defined by ".
+ "'lint.jshint.config'. Make sure that the path is correct.");
}
$options .= ' --config '.$config;
}
return $options;
}
private function getJSHintPath() {
$working_copy = $this->getEngine()->getWorkingCopy();
$prefix = $working_copy->getConfig('lint.jshint.prefix');
$bin = $working_copy->getConfig('lint.jshint.bin');
if ($bin === null) {
$bin = "jshint";
}
if ($prefix !== null) {
$bin = $prefix."/".$bin;
if (!Filesystem::pathExists($bin)) {
throw new ArcanistUsageException(
"Unable to find JSHint binary in a specified directory. Make sure ".
"that 'lint.jshint.prefix' and 'lint.jshint.bin' keys are set ".
- "correctly. If you'd rather use a copy of JSHint installed globally, ".
- "you can just remove these keys from your .arcconfig");
+ "correctly. If you'd rather use a copy of JSHint installed ".
+ "globally, you can just remove these keys from your .arcconfig");
}
return $bin;
}
// Look for globally installed JSHint
$cmd = (phutil_is_windows()) ? 'where %s' : 'which %s';
list($err) = exec_manual($cmd, $bin);
if ($err) {
throw new ArcanistUsageException(
"JSHint does not appear to be installed on this system. Install it ".
"(e.g., with 'npm install jshint -g') or configure ".
"'lint.jshint.prefix' in your .arcconfig to point to the directory ".
"where it resides.");
}
return $bin;
}
public function willLintPaths(array $paths) {
$jshint_bin = $this->getJSHintPath();
$jshint_options = $this->getJSHintOptions();
$futures = array();
foreach ($paths as $path) {
$filepath = $this->getEngine()->getFilePathOnDisk($path);
- $futures[$path] = new ExecFuture("{$jshint_bin} {$filepath} ${jshint_options}");
+ $futures[$path] = new ExecFuture(
+ "%s %s %C",
+ $jshint_bin,
+ $filepath,
+ $jshint_options);
}
foreach (Futures($futures)->limit(8) as $path => $future) {
$this->results[$path] = $future->resolve();
}
}
public function lintPath($path) {
list($rc, $stdout, $stderr) = $this->results[$path];
if ($rc === 0) {
return;
}
$errors = json_decode($stdout);
if (!is_array($errors)) {
// Something went wrong and we can't decode the output. Exit abnormally.
throw new ArcanistUsageException(
"JSHint returned unparseable output.\n".
"stdout:\n\n{$stdout}".
"stderr:\n\n{$stderr}");
}
foreach ($errors as $err) {
$this->raiseLintAtLine(
$err->line,
$err->col,
self::JSHINT_ERROR,
$err->reason);
}
}
}
diff --git a/src/lint/linter/ArcanistPyFlakesLinter.php b/src/lint/linter/ArcanistPyFlakesLinter.php
index 87054330..7f9bb842 100644
--- a/src/lint/linter/ArcanistPyFlakesLinter.php
+++ b/src/lint/linter/ArcanistPyFlakesLinter.php
@@ -1,104 +1,106 @@
<?php
/**
* Uses "PyFlakes" to detect various errors in Python code.
*
* @group linter
*/
final class ArcanistPyFlakesLinter extends ArcanistLinter {
public function willLintPaths(array $paths) {
return;
}
public function getLinterName() {
return 'PyFlakes';
}
public function getLintSeverityMap() {
return array();
}
public function getLintNameMap() {
return array(
);
}
public function getPyFlakesOptions() {
return null;
}
public function lintPath($path) {
$working_copy = $this->getEngine()->getWorkingCopy();
$pyflakes_path = $working_copy->getConfig('lint.pyflakes.path');
$pyflakes_prefix = $working_copy->getConfig('lint.pyflakes.prefix');
// Default to just finding pyflakes in the users path
$pyflakes_bin = 'pyflakes';
$python_path = '';
// If a pyflakes path was specified, then just use that as the
// pyflakes binary and assume that the libraries will be imported
// correctly.
//
// If no pyflakes path was specified and a pyflakes prefix was
// specified, then use the binary from this prefix and add it to
// the PYTHONPATH environment variable so that the libs are imported
// correctly. This is useful when pyflakes is installed into a
// non-default location.
if ($pyflakes_path !== null) {
$pyflakes_bin = $pyflakes_path;
} else if ($pyflakes_prefix !== null) {
$pyflakes_bin = $pyflakes_prefix.'/bin/pyflakes';
$python_path = $pyflakes_prefix.'/lib/python2.6/site-packages:';
}
$options = $this->getPyFlakesOptions();
$f = new ExecFuture(
"/usr/bin/env PYTHONPATH=%s\$PYTHONPATH ".
"{$pyflakes_bin} {$options}", $python_path);
$f->write($this->getData($path));
try {
list($stdout, $_) = $f->resolvex();
} catch (CommandException $e) {
// PyFlakes will return an exit code of 1 if warnings/errors
// are found but print nothing to stderr in this case. Therefore,
// if we see any output on stderr or a return code other than 1 or 0,
// pyflakes failed.
if ($e->getError() !== 1 || $e->getStderr() !== '') {
throw $e;
} else {
$stdout = $e->getStdout();
}
}
$lines = explode("\n", $stdout);
$messages = array();
foreach ($lines as $line) {
$matches = null;
if (!preg_match('/^(.*?):(\d+): (.*)$/', $line, $matches)) {
continue;
}
foreach ($matches as $key => $match) {
$matches[$key] = trim($match);
}
$severity = ArcanistLintSeverity::SEVERITY_WARNING;
$description = $matches[3];
- if (preg_match('/(^undefined|^duplicate|before assignment$)/', $description)) {
+
+ $error_regexp = '/(^undefined|^duplicate|before assignment$)/';
+ if (preg_match($error_regexp, $description)) {
$severity = ArcanistLintSeverity::SEVERITY_ERROR;
}
$message = new ArcanistLintMessage();
$message->setPath($path);
$message->setLine($matches[2]);
$message->setCode($this->getLinterName());
$message->setDescription($description);
$message->setSeverity($severity);
$this->addLintMessage($message);
}
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 8, 06:26 (1 d, 13 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1034116
Default Alt Text
(17 KB)

Event Timeline