mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-14 19:02:40 +01:00
(stable) Promote 2015 Week 34
This commit is contained in:
commit
0d2b7fde78
13 changed files with 127 additions and 18 deletions
|
@ -54,6 +54,7 @@ phutil_register_library_map(array(
|
|||
'ArcanistCommentStyleXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistCommentStyleXHPASTLinterRule.php',
|
||||
'ArcanistCommitWorkflow' => 'workflow/ArcanistCommitWorkflow.php',
|
||||
'ArcanistCompilerLintRenderer' => 'lint/renderer/ArcanistCompilerLintRenderer.php',
|
||||
'ArcanistComposerLinter' => 'lint/linter/ArcanistComposerLinter.php',
|
||||
'ArcanistComprehensiveLintEngine' => 'lint/engine/ArcanistComprehensiveLintEngine.php',
|
||||
'ArcanistConcatenationOperatorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistConcatenationOperatorXHPASTLinterRule.php',
|
||||
'ArcanistConfiguration' => 'configuration/ArcanistConfiguration.php',
|
||||
|
@ -337,6 +338,7 @@ phutil_register_library_map(array(
|
|||
'ArcanistCommentStyleXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistCommitWorkflow' => 'ArcanistWorkflow',
|
||||
'ArcanistCompilerLintRenderer' => 'ArcanistLintRenderer',
|
||||
'ArcanistComposerLinter' => 'ArcanistLinter',
|
||||
'ArcanistComprehensiveLintEngine' => 'ArcanistLintEngine',
|
||||
'ArcanistConcatenationOperatorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistConfiguration' => 'Phobject',
|
||||
|
|
|
@ -471,6 +471,8 @@ abstract class ArcanistLintEngine extends Phobject {
|
|||
}
|
||||
|
||||
private function executeLinters(array $runnable) {
|
||||
assert_instances_of($runnable, 'ArcanistLinter');
|
||||
|
||||
$all_paths = $this->getPaths();
|
||||
$path_chunks = array_chunk($all_paths, 32, $preserve_keys = true);
|
||||
|
||||
|
|
55
src/lint/linter/ArcanistComposerLinter.php
Normal file
55
src/lint/linter/ArcanistComposerLinter.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
|
||||
final class ArcanistComposerLinter extends ArcanistLinter {
|
||||
|
||||
const LINT_OUT_OF_DATE = 1;
|
||||
|
||||
public function getInfoName() {
|
||||
return pht('Composer');
|
||||
}
|
||||
|
||||
public function getInfoDescription() {
|
||||
return pht('A linter for Composer related files.');
|
||||
}
|
||||
|
||||
public function getLinterName() {
|
||||
return 'COMPOSER';
|
||||
}
|
||||
|
||||
public function getLinterConfigurationName() {
|
||||
return 'composer';
|
||||
}
|
||||
|
||||
public function getLintNameMap() {
|
||||
return array(
|
||||
self::LINT_OUT_OF_DATE => pht('Lock file out-of-date'),
|
||||
);
|
||||
}
|
||||
|
||||
public function lintPath($path) {
|
||||
switch (basename($path)) {
|
||||
case 'composer.json':
|
||||
$this->lintComposerJson($path);
|
||||
break;
|
||||
case 'composer.lock':
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function lintComposerJson($path) {
|
||||
$composer_hash = md5(Filesystem::readFile(dirname($path).'/composer.json'));
|
||||
$composer_lock = phutil_json_decode(
|
||||
Filesystem::readFile(dirname($path).'/composer.lock'));
|
||||
|
||||
if ($composer_hash !== $composer_lock['hash']) {
|
||||
$this->raiseLintAtPath(
|
||||
self::LINT_OUT_OF_DATE,
|
||||
pht(
|
||||
"The '%s' file seems to be out-of-date. ".
|
||||
"You probably need to run `%s`.",
|
||||
'composer.lock',
|
||||
'composer update'));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -22,9 +22,14 @@ final class ArcanistInlineHTMLXHPASTLinterRule
|
|||
continue;
|
||||
}
|
||||
|
||||
if (preg_match('/^\s*$/', $html->getValue())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->raiseLintAtToken(
|
||||
$html,
|
||||
pht('PHP files must only contain PHP code.'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ final class ArcanistPyLintLinter extends ArcanistExternalLinter {
|
|||
$options = array();
|
||||
|
||||
$options[] = '--reports=no';
|
||||
$options[] = '--msg-template="{line}|{column}|{msg_id}|{symbol}|{msg}"';
|
||||
$options[] = '--msg-template={line}|{column}|{msg_id}|{symbol}|{msg}';
|
||||
|
||||
// Specify an `--rcfile`, either absolute or relative to the project root.
|
||||
// Stupidly, the command line args above are overridden by rcfile, so be
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
array ( 1, 2, 3 );
|
||||
list ( $x, $y ) = array();
|
||||
[ 1, 2 , 3 ];
|
||||
~~~~~~~~~~
|
||||
warning:3:6
|
||||
warning:3:8
|
||||
|
@ -9,8 +10,11 @@ warning:3:16
|
|||
warning:4:5
|
||||
warning:4:7
|
||||
warning:4:14
|
||||
warning:5:2
|
||||
warning:5:11
|
||||
~~~~~~~~~~
|
||||
<?php
|
||||
|
||||
array(1, 2, 3);
|
||||
list($x, $y) = array();
|
||||
[1, 2 , 3];
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
|
||||
This shouldn't fatal the parser.
|
||||
~~~~~~~~~~
|
||||
disabled:2:1
|
||||
|
|
|
@ -3,6 +3,7 @@ garbage garbage
|
|||
|
||||
?>
|
||||
~~~~~~~~~~
|
||||
disabled:1:1
|
||||
error:1:1
|
||||
~~~~~~~~~~
|
||||
garbage garbage
|
||||
|
|
|
@ -179,6 +179,12 @@ function some_func($x, $y) {
|
|||
echo $z;
|
||||
};
|
||||
}
|
||||
|
||||
function some_func($x, $y) {
|
||||
$func = function ($z) use ($x) {
|
||||
echo "$x/$y/$z";
|
||||
};
|
||||
}
|
||||
~~~~~~~~~~
|
||||
warning:9:3
|
||||
error:28:3
|
||||
|
@ -201,3 +207,4 @@ error:150:9
|
|||
error:164:9
|
||||
error:171:5
|
||||
error:178:10
|
||||
error:185:14
|
||||
|
|
|
@ -24,6 +24,11 @@ final class ArcanistCallParenthesesXHPASTLinterRule
|
|||
foreach ($nodes as $node) {
|
||||
switch ($node->getTypeName()) {
|
||||
case 'n_ARRAY_LITERAL':
|
||||
if (head($node->getTokens())->getTypeName() == '[') {
|
||||
// Short array syntax.
|
||||
continue 2;
|
||||
}
|
||||
|
||||
$params = $node->getChildOfType(0, 'n_ARRAY_VALUE_LIST');
|
||||
break;
|
||||
|
||||
|
@ -44,6 +49,7 @@ final class ArcanistCallParenthesesXHPASTLinterRule
|
|||
$tokens = $params->getTokens();
|
||||
$first = head($tokens);
|
||||
|
||||
|
||||
$leading = $first->getNonsemanticTokensBefore();
|
||||
$leading_text = implode('', mpull($leading, 'getValue'));
|
||||
if (preg_match('/^\s+$/', $leading_text)) {
|
||||
|
|
|
@ -29,12 +29,6 @@ final class ArcanistParenthesesSpacingXHPASTLinterRule
|
|||
|
||||
$token_o = array_shift($tokens);
|
||||
$token_c = array_pop($tokens);
|
||||
if ($token_o->getTypeName() !== '(') {
|
||||
throw new Exception(pht('Expected open parentheses.'));
|
||||
}
|
||||
if ($token_c->getTypeName() !== ')') {
|
||||
throw new Exception(pht('Expected close parentheses.'));
|
||||
}
|
||||
|
||||
$nonsem_o = $token_o->getNonsemanticTokensAfter();
|
||||
$nonsem_c = $token_c->getNonsemanticTokensBefore();
|
||||
|
|
|
@ -68,6 +68,7 @@ final class ArcanistUndeclaredVariableXHPASTLinterRule
|
|||
) + array_fill_keys($this->getSuperGlobalNames(), 0);
|
||||
$declaration_tokens = array();
|
||||
$exclude_tokens = array();
|
||||
$exclude_strings = array();
|
||||
$vars = array();
|
||||
|
||||
// First up, find all the different kinds of declarations, as explained
|
||||
|
@ -175,6 +176,16 @@ final class ArcanistUndeclaredVariableXHPASTLinterRule
|
|||
foreach ($func_decl->selectDescendantsOfType('n_VARIABLE') as $var) {
|
||||
$exclude_tokens[$var->getID()] = true;
|
||||
}
|
||||
|
||||
foreach (array('n_STRING_SCALAR', 'n_HEREDOC') as $type) {
|
||||
foreach ($func_decl->selectDescendantsOfType($type) as $string) {
|
||||
$exclude_strings[$string->getID()] = array();
|
||||
|
||||
foreach ($string->getStringVariables() as $offset => $var) {
|
||||
$exclude_strings[$string->getID()][$var] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now we have every declaration except foreach(), handled below. Build
|
||||
|
@ -316,6 +327,10 @@ final class ArcanistUndeclaredVariableXHPASTLinterRule
|
|||
foreach (array('n_STRING_SCALAR', 'n_HEREDOC') as $type) {
|
||||
foreach ($body->selectDescendantsOfType($type) as $string) {
|
||||
foreach ($string->getStringVariables() as $offset => $var) {
|
||||
if (isset($exclude_strings[$string->getID()][$var])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$all[$string->getOffset() + $offset - 1] = '$'.$var;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -492,17 +492,34 @@ EOTEXT
|
|||
'arc amend',
|
||||
'--revision <id>'));
|
||||
} else if (count($revisions) > 1) {
|
||||
switch ($this->branchType) {
|
||||
case self::REFTYPE_BOOKMARK:
|
||||
$message = pht(
|
||||
"There are multiple revisions on feature %s '%s' which are not ".
|
||||
"present on '%s':\n\n".
|
||||
"There are multiple revisions on feature bookmark '%s' which are ".
|
||||
"not present on '%s':\n\n".
|
||||
"%s\n".
|
||||
"Separate these revisions onto different %s, or use --revision <id>' ".
|
||||
"to use the commit message from <id> and land them all.",
|
||||
$this->branchType,
|
||||
'Separate these revisions onto different bookmarks, or use '.
|
||||
'--revision <id> to use the commit message from <id> '.
|
||||
'and land them all.',
|
||||
$this->branch,
|
||||
$this->onto,
|
||||
$this->renderRevisionList($revisions),
|
||||
$this->branchType.'s');
|
||||
$this->renderRevisionList($revisions));
|
||||
break;
|
||||
case self::REFTYPE_BRANCH:
|
||||
default:
|
||||
$message = pht(
|
||||
"There are multiple revisions on feature branch '%s' which are ".
|
||||
"not present on '%s':\n\n".
|
||||
"%s\n".
|
||||
'Separate these revisions onto different branches, or use '.
|
||||
'--revision <id> to use the commit message from <id> '.
|
||||
'and land them all.',
|
||||
$this->branch,
|
||||
$this->onto,
|
||||
$this->renderRevisionList($revisions));
|
||||
break;
|
||||
}
|
||||
|
||||
throw new ArcanistUsageException($message);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue