mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-26 00:32:41 +01:00
Merge branch 'master' of github.com:facebook/arcanist
This commit is contained in:
commit
8dc45eac97
17 changed files with 134 additions and 14 deletions
|
@ -32,12 +32,17 @@ phutil_require_module('arcanist', 'repository/api/base');
|
||||||
|
|
||||||
$config_trace_mode = false;
|
$config_trace_mode = false;
|
||||||
$args = array_slice($argv, 1);
|
$args = array_slice($argv, 1);
|
||||||
|
$load = array();
|
||||||
|
$matches = null;
|
||||||
foreach ($args as $key => $arg) {
|
foreach ($args as $key => $arg) {
|
||||||
if ($arg == '--') {
|
if ($arg == '--') {
|
||||||
break;
|
break;
|
||||||
} else if ($arg == '--trace') {
|
} else if ($arg == '--trace') {
|
||||||
unset($args[$key]);
|
unset($args[$key]);
|
||||||
$config_trace_mode = true;
|
$config_trace_mode = true;
|
||||||
|
} else if (preg_match('/^--load-phutil-library=(.*)$/', $arg, $matches)) {
|
||||||
|
unset($args[$key]);
|
||||||
|
$load['?'] = $matches[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +59,11 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
$working_copy = ArcanistWorkingCopyIdentity::newFromPath($_SERVER['PWD']);
|
$working_copy = ArcanistWorkingCopyIdentity::newFromPath($_SERVER['PWD']);
|
||||||
|
if ($load) {
|
||||||
|
$libs = $load;
|
||||||
|
} else {
|
||||||
$libs = $working_copy->getConfig('phutil_libraries');
|
$libs = $working_copy->getConfig('phutil_libraries');
|
||||||
|
}
|
||||||
if ($libs) {
|
if ($libs) {
|
||||||
foreach ($libs as $name => $location) {
|
foreach ($libs as $name => $location) {
|
||||||
if ($config_trace_mode) {
|
if ($config_trace_mode) {
|
||||||
|
|
|
@ -59,6 +59,7 @@ phutil_register_library_map(array(
|
||||||
'ArcanistSubversionAPI' => 'repository/api/subversion',
|
'ArcanistSubversionAPI' => 'repository/api/subversion',
|
||||||
'ArcanistSvnHookPreCommitWorkflow' => 'workflow/svn-hook-pre-commit',
|
'ArcanistSvnHookPreCommitWorkflow' => 'workflow/svn-hook-pre-commit',
|
||||||
'ArcanistTextLinter' => 'lint/linter/text',
|
'ArcanistTextLinter' => 'lint/linter/text',
|
||||||
|
'ArcanistTextLinterTestCase' => 'lint/linter/text/__tests__',
|
||||||
'ArcanistUnitTestResult' => 'unit/result',
|
'ArcanistUnitTestResult' => 'unit/result',
|
||||||
'ArcanistUnitWorkflow' => 'workflow/unit',
|
'ArcanistUnitWorkflow' => 'workflow/unit',
|
||||||
'ArcanistUsageException' => 'exception/usage',
|
'ArcanistUsageException' => 'exception/usage',
|
||||||
|
@ -104,6 +105,7 @@ phutil_register_library_map(array(
|
||||||
'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI',
|
'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI',
|
||||||
'ArcanistSvnHookPreCommitWorkflow' => 'ArcanistBaseWorkflow',
|
'ArcanistSvnHookPreCommitWorkflow' => 'ArcanistBaseWorkflow',
|
||||||
'ArcanistTextLinter' => 'ArcanistLinter',
|
'ArcanistTextLinter' => 'ArcanistLinter',
|
||||||
|
'ArcanistTextLinterTestCase' => 'ArcanistLinterTestCase',
|
||||||
'ArcanistUnitWorkflow' => 'ArcanistBaseWorkflow',
|
'ArcanistUnitWorkflow' => 'ArcanistBaseWorkflow',
|
||||||
'ArcanistUserAbortException' => 'ArcanistUsageException',
|
'ArcanistUserAbortException' => 'ArcanistUsageException',
|
||||||
'ArcanistXHPASTLinter' => 'ArcanistLinter',
|
'ArcanistXHPASTLinter' => 'ArcanistLinter',
|
||||||
|
|
|
@ -30,8 +30,9 @@ class ArcanistDifferentialCommitMessage {
|
||||||
$obj = new ArcanistDifferentialCommitMessage();
|
$obj = new ArcanistDifferentialCommitMessage();
|
||||||
$obj->rawCorpus = $corpus;
|
$obj->rawCorpus = $corpus;
|
||||||
|
|
||||||
|
// TODO: Remove "Diffcamp" backward compatibility.
|
||||||
$match = null;
|
$match = null;
|
||||||
if (preg_match('/^Differential Revision:\s*D?(\d+)/m', $corpus, $match)) {
|
if (preg_match('/^(?:Differential|DiffCamp) Revision:\s*D?(\d+)/im', $corpus, $match)) {
|
||||||
$obj->revisionID = (int)$match[1];
|
$obj->revisionID = (int)$match[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,11 @@ class ArcanistApacheLicenseLinterTestCase extends ArcanistLinterTestCase {
|
||||||
|
|
||||||
public function testApacheLicenseLint() {
|
public function testApacheLicenseLint() {
|
||||||
$linter = new ArcanistApacheLicenseLinter();
|
$linter = new ArcanistApacheLicenseLinter();
|
||||||
return $this->executeTestsInDirectory(dirname(__FILE__).'/data/', $linter);
|
$working_copy = ArcanistWorkingCopyIdentity::newFromPath(__FILE__);
|
||||||
|
return $this->executeTestsInDirectory(
|
||||||
|
dirname(__FILE__).'/data/',
|
||||||
|
$linter,
|
||||||
|
$working_copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
phutil_require_module('arcanist', 'lint/linter/apachelicense');
|
phutil_require_module('arcanist', 'lint/linter/apachelicense');
|
||||||
phutil_require_module('arcanist', 'lint/linter/base/test');
|
phutil_require_module('arcanist', 'lint/linter/base/test');
|
||||||
|
phutil_require_module('arcanist', 'workingcopyidentity');
|
||||||
|
|
||||||
|
|
||||||
phutil_require_source('ArcanistApacheLicenseLinterTestCase.php');
|
phutil_require_source('ArcanistApacheLicenseLinterTestCase.php');
|
||||||
|
|
|
@ -18,17 +18,15 @@
|
||||||
|
|
||||||
abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
|
abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
|
||||||
|
|
||||||
public function executeTestsInDirectory($root, $linter) {
|
public function executeTestsInDirectory($root, $linter, $working_copy) {
|
||||||
foreach (Filesystem::listDirectory($root, $hidden = false) as $file) {
|
foreach (Filesystem::listDirectory($root, $hidden = false) as $file) {
|
||||||
$this->lintFile($root.$file, $linter);
|
$this->lintFile($root.$file, $linter, $working_copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function lintFile($file, $linter) {
|
private function lintFile($file, $linter, $working_copy) {
|
||||||
$linter = clone $linter;
|
$linter = clone $linter;
|
||||||
|
|
||||||
$working_copy = ArcanistWorkingCopyIdentity::newFromPath(__FILE__);
|
|
||||||
|
|
||||||
$contents = Filesystem::readFile($file);
|
$contents = Filesystem::readFile($file);
|
||||||
$contents = explode("~~~~~~~~~~\n", $contents);
|
$contents = explode("~~~~~~~~~~\n", $contents);
|
||||||
if (count($contents) < 2) {
|
if (count($contents) < 2) {
|
||||||
|
@ -77,8 +75,7 @@ abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
|
||||||
$engine->setWorkingCopy($working_copy);
|
$engine->setWorkingCopy($working_copy);
|
||||||
$engine->setPaths(array($path));
|
$engine->setPaths(array($path));
|
||||||
|
|
||||||
// TODO: restore this
|
$engine->setCommitHookMode(idx($config, 'hook', false));
|
||||||
// $engine->setCommitHookMode(idx($config, 'hook', false));
|
|
||||||
|
|
||||||
$linter->addPath($path);
|
$linter->addPath($path);
|
||||||
$linter->addData($path, $data);
|
$linter->addData($path, $data);
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
phutil_require_module('arcanist', 'lint/engine/test');
|
phutil_require_module('arcanist', 'lint/engine/test');
|
||||||
phutil_require_module('arcanist', 'lint/patcher');
|
phutil_require_module('arcanist', 'lint/patcher');
|
||||||
phutil_require_module('arcanist', 'unit/engine/phutil/testcase');
|
phutil_require_module('arcanist', 'unit/engine/phutil/testcase');
|
||||||
phutil_require_module('arcanist', 'workingcopyidentity');
|
|
||||||
|
|
||||||
phutil_require_module('phutil', 'filesystem');
|
phutil_require_module('phutil', 'filesystem');
|
||||||
phutil_require_module('phutil', 'utils');
|
phutil_require_module('phutil', 'utils');
|
||||||
|
|
|
@ -24,6 +24,7 @@ class ArcanistTextLinter extends ArcanistLinter {
|
||||||
const LINT_EOF_NEWLINE = 4;
|
const LINT_EOF_NEWLINE = 4;
|
||||||
const LINT_BAD_CHARSET = 5;
|
const LINT_BAD_CHARSET = 5;
|
||||||
const LINT_TRAILING_WHITESPACE = 6;
|
const LINT_TRAILING_WHITESPACE = 6;
|
||||||
|
const LINT_NO_COMMIT = 7;
|
||||||
|
|
||||||
private $maxLineLength = 80;
|
private $maxLineLength = 80;
|
||||||
|
|
||||||
|
@ -54,6 +55,7 @@ class ArcanistTextLinter extends ArcanistLinter {
|
||||||
self::LINT_EOF_NEWLINE => 'File Does Not End in Newline',
|
self::LINT_EOF_NEWLINE => 'File Does Not End in Newline',
|
||||||
self::LINT_BAD_CHARSET => 'Bad Charset',
|
self::LINT_BAD_CHARSET => 'Bad Charset',
|
||||||
self::LINT_TRAILING_WHITESPACE => 'Trailing Whitespace',
|
self::LINT_TRAILING_WHITESPACE => 'Trailing Whitespace',
|
||||||
|
self::LINT_NO_COMMIT => 'Explicit @no'.'commit',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +76,10 @@ class ArcanistTextLinter extends ArcanistLinter {
|
||||||
$this->lintLineLength($path);
|
$this->lintLineLength($path);
|
||||||
$this->lintEOFNewline($path);
|
$this->lintEOFNewline($path);
|
||||||
$this->lintTrailingWhitespace($path);
|
$this->lintTrailingWhitespace($path);
|
||||||
|
|
||||||
|
if ($this->getEngine()->getCommitHookMode()) {
|
||||||
|
$this->lintNoCommit($path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function lintNewlines($path) {
|
protected function lintNewlines($path) {
|
||||||
|
@ -181,4 +187,21 @@ class ArcanistTextLinter extends ArcanistLinter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function lintNoCommit($path) {
|
||||||
|
$data = $this->getData($path);
|
||||||
|
|
||||||
|
$deadly = '@no'.'commit';
|
||||||
|
|
||||||
|
$offset = strpos($data, $deadly);
|
||||||
|
if ($offset !== false) {
|
||||||
|
$this->raiseLintAtOffset(
|
||||||
|
$offset,
|
||||||
|
self::LINT_NO_COMMIT,
|
||||||
|
'This file is explicitly marked as "'.$deadly.'", which blocks '.
|
||||||
|
'commits.',
|
||||||
|
$deadly);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2011 Facebook, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class ArcanistTextLinterTestCase extends ArcanistLinterTestCase {
|
||||||
|
|
||||||
|
public function testTextLint() {
|
||||||
|
$linter = new ArcanistTextLinter();
|
||||||
|
$working_copy = ArcanistWorkingCopyIdentity::newFromPath(__FILE__);
|
||||||
|
return $this->executeTestsInDirectory(
|
||||||
|
dirname(__FILE__).'/data/',
|
||||||
|
$linter,
|
||||||
|
$working_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
14
src/lint/linter/text/__tests__/__init__.php
Normal file
14
src/lint/linter/text/__tests__/__init__.php
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is automatically generated. Lint this module to rebuild it.
|
||||||
|
* @generated
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_module('arcanist', 'lint/linter/base/test');
|
||||||
|
phutil_require_module('arcanist', 'lint/linter/text');
|
||||||
|
phutil_require_module('arcanist', 'workingcopyidentity');
|
||||||
|
|
||||||
|
|
||||||
|
phutil_require_source('ArcanistTextLinterTestCase.php');
|
|
@ -0,0 +1,8 @@
|
||||||
|
@nocommit
|
||||||
|
~~~~~~~~~~
|
||||||
|
error:1:1
|
||||||
|
~~~~~~~~~~
|
||||||
|
~~~~~~~~~~
|
||||||
|
{
|
||||||
|
"hook" : true
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
@nocommit
|
||||||
|
~~~~~~~~~~
|
|
@ -20,7 +20,11 @@ class ArcanistXHPASTLinterTestCase extends ArcanistLinterTestCase {
|
||||||
|
|
||||||
public function testXHPASTLint() {
|
public function testXHPASTLint() {
|
||||||
$linter = new ArcanistXHPASTLinter();
|
$linter = new ArcanistXHPASTLinter();
|
||||||
return $this->executeTestsInDirectory(dirname(__FILE__).'/data/', $linter);
|
$working_copy = ArcanistWorkingCopyIdentity::newFromPath(__FILE__);
|
||||||
|
return $this->executeTestsInDirectory(
|
||||||
|
dirname(__FILE__).'/data/',
|
||||||
|
$linter,
|
||||||
|
$working_copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
phutil_require_module('arcanist', 'lint/linter/base/test');
|
phutil_require_module('arcanist', 'lint/linter/base/test');
|
||||||
phutil_require_module('arcanist', 'lint/linter/xhpast');
|
phutil_require_module('arcanist', 'lint/linter/xhpast');
|
||||||
|
phutil_require_module('arcanist', 'workingcopyidentity');
|
||||||
|
|
||||||
|
|
||||||
phutil_require_source('ArcanistXHPASTLinterTestCase.php');
|
phutil_require_source('ArcanistXHPASTLinterTestCase.php');
|
||||||
|
|
|
@ -124,6 +124,10 @@ EOTEXT
|
||||||
array($revision_id));
|
array($revision_id));
|
||||||
$mark_workflow->run();
|
$mark_workflow->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
echo phutil_console_wrap(
|
||||||
|
"You may now push this commit upstream, as appropriate (e.g. with ".
|
||||||
|
"'git push', or 'git svn dcommit', or by printing and faxing it).\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -123,6 +123,7 @@ EOTEXT
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
$output = array();
|
$output = array();
|
||||||
foreach ($arguments as $argument => $spec) {
|
foreach ($arguments as $argument => $spec) {
|
||||||
if ($argument == '*') {
|
if ($argument == '*') {
|
||||||
|
@ -136,7 +137,22 @@ EOTEXT
|
||||||
$output[] = '--'.$argument;
|
$output[] = '--'.$argument;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$cur = idx($argv, $pos, '');
|
||||||
|
$any_match = false;
|
||||||
|
foreach ($output as $possible) {
|
||||||
|
if (!strncmp($possible, $cur, strlen($cur))) {
|
||||||
|
$any_match = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$any_match && isset($arguments['*'])) {
|
||||||
|
// TODO: the '*' specifier should probably have more details about
|
||||||
|
// whether or not it is a list of files. Since it almost always is in
|
||||||
|
// practice, assume FILE for now.
|
||||||
|
echo "FILE\n";
|
||||||
|
} else {
|
||||||
echo implode(' ', $output)."\n";
|
echo implode(' ', $output)."\n";
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,11 @@ EOTEXT
|
||||||
|
|
||||||
public function getArguments() {
|
public function getArguments() {
|
||||||
return array(
|
return array(
|
||||||
|
'engine' => array(
|
||||||
|
'param' => 'classname',
|
||||||
|
'help' =>
|
||||||
|
"Override configured unit engine for this project."
|
||||||
|
),
|
||||||
'*' => 'paths',
|
'*' => 'paths',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue