mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-21 22:32:41 +01:00
Merge branch 'master' of github.com:facebook/arcanist
This commit is contained in:
commit
ed53f98e9e
74 changed files with 532 additions and 22 deletions
|
@ -3,7 +3,17 @@
|
|||
"src_base" : "https://github.com/facebook/arcanist/blob/master",
|
||||
"groups" : {
|
||||
"intro" : "Introduction",
|
||||
"config" : "Setup & Configuration"
|
||||
"config" : "Setup & Configuration",
|
||||
"workflow" : "Workflows",
|
||||
"lint" : "Lint Integration",
|
||||
"linter" : "Linters",
|
||||
"unit" : "Unit Test Integration",
|
||||
"unitrun" : "Unit Test Runners",
|
||||
"diff" : "Diff and Changeset APIs",
|
||||
"differential" : "Differential Integration",
|
||||
"workingcopy" : "Working Copy APIs",
|
||||
"module" : "Phutil Module System",
|
||||
"testcase" : "Test Cases"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,10 @@ phutil_require_module('arcanist', 'configuration');
|
|||
phutil_require_module('arcanist', 'workingcopyidentity');
|
||||
phutil_require_module('arcanist', 'repository/api/base');
|
||||
|
||||
ini_set('memory_limit', -1);
|
||||
|
||||
$config_trace_mode = false;
|
||||
$force_conduit = null;
|
||||
$args = array_slice($argv, 1);
|
||||
$load = array();
|
||||
$matches = null;
|
||||
|
@ -46,6 +49,9 @@ foreach ($args as $key => $arg) {
|
|||
} else if (preg_match('/^--load-phutil-library=(.*)$/', $arg, $matches)) {
|
||||
unset($args[$key]);
|
||||
$load['?'] = $matches[1];
|
||||
} else if (preg_match('/^--conduit-uri=(.*)$/', $arg, $matches)) {
|
||||
unset($args[$key]);
|
||||
$force_conduit = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,7 +141,12 @@ try {
|
|||
|
||||
$set_guid = false;
|
||||
if ($need_conduit) {
|
||||
$conduit_uri = $working_copy->getConduitURI();
|
||||
|
||||
if ($force_conduit) {
|
||||
$conduit_uri = $force_conduit;
|
||||
} else {
|
||||
$conduit_uri = $working_copy->getConduitURI();
|
||||
}
|
||||
if (!$conduit_uri) {
|
||||
throw new ArcanistUsageException(
|
||||
"No Conduit URI is specified in the .arcconfig file for this project. ".
|
||||
|
|
|
@ -53,7 +53,7 @@ phutil_require_module('phutil', 'parser/xhpast/api/tree');
|
|||
|
||||
phutil_require_module('arcanist', 'lint/linter/phutilmodule');
|
||||
phutil_require_module('arcanist', 'lint/message');
|
||||
phutil_require_module('arcanist', 'staticanalysis/parsers/phutilmodule');
|
||||
phutil_require_module('arcanist', 'parser/phutilmodule');
|
||||
|
||||
|
||||
$data = array();
|
||||
|
@ -114,7 +114,7 @@ foreach (Futures($futures) as $file => $future) {
|
|||
}
|
||||
$requirements->addSourceDependency($name, $value);
|
||||
} else if ($call_name == 'phutil_require_module') {
|
||||
analyze_require_module($call, $requirements);
|
||||
analyze_phutil_require_module($call, $requirements);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -146,7 +146,7 @@ foreach (Futures($futures) as $file => $future) {
|
|||
|
||||
$call_name = $name->getConcreteString();
|
||||
if ($call_name == 'phutil_require_module') {
|
||||
analyze_require_module($call, $requirements);
|
||||
analyze_phutil_require_module($call, $requirements);
|
||||
} else if ($call_name == 'call_user_func' ||
|
||||
$call_name == 'call_user_func_array') {
|
||||
$params = $call->getChildByIndex(1)->getChildren();
|
||||
|
@ -307,7 +307,12 @@ if (!$has_init && $has_files) {
|
|||
|
||||
echo json_encode($requirements->toDictionary());
|
||||
|
||||
function analyze_require_module(
|
||||
/**
|
||||
* Parses meaning from calls to phutil_require_module() in __init__.php files.
|
||||
*
|
||||
* @group module
|
||||
*/
|
||||
function analyze_phutil_require_module(
|
||||
XHPASTNode $call,
|
||||
PhutilModuleRequirements $requirements) {
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ phutil_register_library_map(array(
|
|||
'ArcanistXHPASTLinter' => 'lint/linter/xhpast',
|
||||
'ArcanistXHPASTLinterTestCase' => 'lint/linter/xhpast/__tests__',
|
||||
'PhutilLintEngine' => 'lint/engine/phutil',
|
||||
'PhutilModuleRequirements' => 'staticanalysis/parsers/phutilmodule',
|
||||
'PhutilModuleRequirements' => 'parser/phutilmodule',
|
||||
'PhutilUnitTestEngine' => 'unit/engine/phutil',
|
||||
'PhutilUnitTestEngineTestCase' => 'unit/engine/phutil/__tests__',
|
||||
'UnitTestableArcanistLintEngine' => 'lint/engine/test',
|
||||
|
|
|
@ -16,6 +16,28 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Runtime workflow configuration. In Arcanist, commands you type like
|
||||
* "arc diff" or "arc lint" are called "workflows". This class allows you to add
|
||||
* new workflows (and extend existing workflows) by subclassing it and then
|
||||
* pointing to your subclass in your project configuration.
|
||||
*
|
||||
* For instructions on how to extend this class and customize Arcanist in your
|
||||
* project, see @{article:Building New Configuration Classes}.
|
||||
*
|
||||
* When specified as the **arcanist_configuration** class in your project's
|
||||
* ##.arcconfig##, your subclass will be instantiated (instead of this class)
|
||||
* and be able to handle all the method calls. In particular, you can:
|
||||
*
|
||||
* - create, replace, or disable workflows by overriding buildWorkflow()
|
||||
* and buildAllWorkflows();
|
||||
* - add additional steps before or after workflows run by overriding
|
||||
* willRunWorkflow() or didRunWorkflow(); and
|
||||
* - add new flags to existing workflows by overriding
|
||||
* getCustomArgumentsForCommand().
|
||||
*
|
||||
* @group config
|
||||
*/
|
||||
class ArcanistConfiguration {
|
||||
|
||||
public function buildWorkflow($command) {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dumping ground for diff- and diff-algorithm-related miscellany.
|
||||
*
|
||||
* @group diff
|
||||
*/
|
||||
final class ArcanistDiffUtils {
|
||||
|
||||
public static function renderDifferences(
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a parsed commit message.
|
||||
*
|
||||
* @group differential
|
||||
*/
|
||||
class ArcanistDifferentialCommitMessage {
|
||||
|
||||
private $rawCorpus;
|
||||
|
@ -75,6 +80,11 @@ class ArcanistDifferentialCommitMessage {
|
|||
return null;
|
||||
}
|
||||
|
||||
public function setFieldValue($key, $value) {
|
||||
$this->fields[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getFields() {
|
||||
return $this->fields;
|
||||
}
|
||||
|
@ -91,4 +101,11 @@ class ArcanistDifferentialCommitMessage {
|
|||
return $this->gitSVNUUID;
|
||||
}
|
||||
|
||||
public function getChecksum() {
|
||||
$fields = array_filter($this->fields);
|
||||
ksort($fields);
|
||||
$fields = json_encode($fields);
|
||||
return md5($fields);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown when a commit message isn't parseable.
|
||||
*
|
||||
* @group differential
|
||||
*/
|
||||
class ArcanistDifferentialCommitMessageParserException extends Exception {
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Reference to a Differential revision.
|
||||
*
|
||||
* @group differential
|
||||
*/
|
||||
class ArcanistDifferentialRevisionRef {
|
||||
|
||||
protected $id;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
@title Setting Up .arcconfig
|
||||
@group config
|
||||
|
||||
This document describes how to configure Arcanist projects with ##.arcconfig##
|
||||
files.
|
||||
Explains how to configure Arcanist projects with ##.arcconfig## files.
|
||||
|
||||
= .arcconfig Basics =
|
||||
|
||||
|
|
83
src/docs/building_new_configuration_classes.diviner
Normal file
83
src/docs/building_new_configuration_classes.diviner
Normal file
|
@ -0,0 +1,83 @@
|
|||
@title Building New Configuration Classes
|
||||
@group config
|
||||
|
||||
Explains how to build new classes to control how Arcanist behaves.
|
||||
|
||||
= Overview =
|
||||
|
||||
Arcanist has some basic configuration options available in the ##.arcconfig##
|
||||
file (see @{article:Setting Up .arcconfig}), but it can't handle everything. If
|
||||
you want to customize Arcanist at a deeper level, you need to build new classes.
|
||||
For instance:
|
||||
|
||||
- if you want to configure linters, or add new linters, you need to create a
|
||||
new class which extends @{class:ArcanistLintEngine}.
|
||||
- if you want to integrate with a unit testing framework, you need to create a
|
||||
new class which extends @{class:ArcanistBaseUnitTestEngine}.
|
||||
- if you you want to change how workflows behave, or add new workflows, you
|
||||
need to create a new class which extends @{class:ArcanistConfiguration}.
|
||||
|
||||
Arcanist works through a sort of dependency-injection approach. For example,
|
||||
Arcanist does not run lint rules by default, but you can set **lint_engine**
|
||||
in your ##.arcconfig## to the name of a class which extends
|
||||
@{class:ArcanistLintEngine}. When running from inside your project, Arcanist
|
||||
will load this class and call methods on it in order to run lint. To make this
|
||||
work, you need to do three things:
|
||||
|
||||
- actually write the class;
|
||||
- add the library where the class exists to your ##.arcconfig##;
|
||||
- add the class name to your ##.arcconfig## as the **lint_engine**,
|
||||
**unit_engine**, or **arcanist_configuration**.
|
||||
|
||||
= Write the Class =
|
||||
|
||||
(TODO)
|
||||
|
||||
= Load the Class =
|
||||
|
||||
To make the class loadable, you need to put the path to it in your
|
||||
##.arcconfig##, under **phutil_libraries**:
|
||||
|
||||
{
|
||||
// ...
|
||||
"phutil_libraries" : {
|
||||
// ...
|
||||
"my-library" : "/path/to/my/library",
|
||||
// ...
|
||||
}
|
||||
// ...
|
||||
}
|
||||
|
||||
You can either specify an absolute path, or a path relative to the project root.
|
||||
When you run ##arc --trace##, you should see a message to the effect that it has
|
||||
loaded your library.
|
||||
|
||||
For debugging or testing, you can also run Arcanist with the
|
||||
##--load-phutil-library## flag:
|
||||
|
||||
arc --load-phutil-library=/path/to/library <command>
|
||||
|
||||
You can specify this flag more than once to load several libraries. Note that
|
||||
if you use this flag, Arcanist will ignore any libraries listed in
|
||||
##.arcconfig##.
|
||||
|
||||
= Use the Class =
|
||||
|
||||
This step is easy: just edit ##.arcconfig## to specify your class name as
|
||||
the appropriate configuration value.
|
||||
|
||||
{
|
||||
// ...
|
||||
"lint_engine" : "MyCustomArcanistLintEngine",
|
||||
// ...
|
||||
}
|
||||
|
||||
Now, when you run Arcanist in your project, it will invoke your class when
|
||||
appropriate.
|
||||
|
||||
For lint and unit tests, you can also use the ##--engine## flag override the
|
||||
default engine:
|
||||
|
||||
arc lint --engine MyCustomArcanistLintEngine
|
||||
|
||||
This is mostly useful for debugging and testing.
|
|
@ -1,10 +1,10 @@
|
|||
@title Arcanist Overview
|
||||
@group intro
|
||||
|
||||
This document provides an overview of Arcanist, a code workflow tool. Arcanist
|
||||
(commonly, "arc") is the command-line frontend to Differential.
|
||||
Overview of Arcanist, a code workflow tool.
|
||||
|
||||
A detailed command reference is available by running ##arc help##.
|
||||
Arcanist (commonly, "arc") is the command-line frontend to Differential. A
|
||||
detailed command reference is available by running ##arc help##.
|
||||
|
||||
= Overview =
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
@title Installing Arcanist SVN Hooks
|
||||
@group config
|
||||
|
||||
Describes how to set up Arcanist as an SVN pre-commit hook.
|
||||
|
||||
= Installing Arcanist SVN Hooks =
|
||||
|
||||
You can install Arcanist as an SVN pre-commit hook, to reject commits which
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown when the user chooses an invalid revision when prompted by a workflow.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistChooseInvalidRevisionException extends Exception {
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown when there are no valid revisions to choose from, in a workflow which
|
||||
* prompts the user to choose a revision.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistChooseNoRevisionsException extends Exception {
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown when there is a problem with how a user is invoking a command, rather
|
||||
* than a technical problem.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistUsageException extends Exception {
|
||||
|
||||
}
|
||||
|
|
|
@ -16,5 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown when lint or unit tests have no effect, i.e. no paths are affected
|
||||
* by any linter or no unit tests provide coverage.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistNoEffectException extends ArcanistUsageException {
|
||||
}
|
||||
|
|
|
@ -16,5 +16,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown when no engine is configured for linting or running unit tests.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistNoEngineException extends ArcanistUsageException {
|
||||
}
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown when the user chooses not to continue when warned that they're about
|
||||
* to do something dangerous.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistUserAbortException extends ArcanistUsageException {
|
||||
public function __construct() {
|
||||
parent::__construct('User aborted the workflow.');
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages lint execution.
|
||||
*
|
||||
* @group lint
|
||||
*/
|
||||
abstract class ArcanistLintEngine {
|
||||
|
||||
protected $workingCopy;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lint engine which enforces libphutil rules.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
class PhutilLintEngine extends ArcanistLintEngine {
|
||||
|
||||
public function buildLinters() {
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lint engine for use in constructing test cases. See
|
||||
* @{class:ArcanistLinterTestCase}.
|
||||
*
|
||||
* @group testcase
|
||||
*/
|
||||
final class UnitTestableArcanistLintEngine extends ArcanistLintEngine {
|
||||
|
||||
protected $linters = array();
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds the Apache license to source files.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
class ArcanistApacheLicenseLinter extends ArcanistLicenseLinter {
|
||||
public function getLinterName() {
|
||||
return 'APACHELICENSE';
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test cases for @{class:ArcanistApacheLicenseLinter}.
|
||||
*
|
||||
* @group testcase
|
||||
*/
|
||||
class ArcanistApacheLicenseLinterTestCase extends ArcanistLinterTestCase {
|
||||
|
||||
public function testApacheLicenseLint() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements lint rules, like syntax checks for a specific language.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
abstract class ArcanistLinter {
|
||||
|
||||
protected $paths = array();
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Facilitiates implementation of test cases for @{class:ArcanistLinter}s.
|
||||
*
|
||||
* @group testcase
|
||||
*/
|
||||
abstract class ArcanistLinterTestCase extends ArcanistPhutilTestCase {
|
||||
|
||||
public function executeTestsInDirectory($root, $linter, $working_copy) {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Stifles creativity in choosing imaginative file names.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
class ArcanistFilenameLinter extends ArcanistLinter {
|
||||
|
||||
const LINT_BAD_FILENAME = 1;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This linter just stops the lint process when a file is marked as generated
|
||||
* code.
|
||||
* Stops other linters from running on generated code.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
class ArcanistGeneratedLinter extends ArcanistLinter {
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Adds a license or copyright header to source files.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
abstract class ArcanistLicenseLinter extends ArcanistLinter {
|
||||
const LINT_NO_LICENSE_HEADER = 1;
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Uses "pep8.py" to enforce PEP8 rules for Python.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
class ArcanistPEP8Linter extends ArcanistLinter {
|
||||
|
||||
public function willLintPaths(array $paths) {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Applies rules for modules in Phutil libraries.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
class ArcanistPhutilModuleLinter extends ArcanistLinter {
|
||||
|
||||
const LINT_UNDECLARED_CLASS = 1;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enforces basic text file rules.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
class ArcanistTextLinter extends ArcanistLinter {
|
||||
|
||||
const LINT_DOS_NEWLINE = 1;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test cases for @{class:ArcanistTextLinter}.
|
||||
*
|
||||
* @group testcase
|
||||
*/
|
||||
class ArcanistTextLinterTestCase extends ArcanistLinterTestCase {
|
||||
|
||||
public function testTextLint() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Uses XHPAST to apply lint rules to PHP or PHP+XHP.
|
||||
*
|
||||
* @group linter
|
||||
*/
|
||||
class ArcanistXHPASTLinter extends ArcanistLinter {
|
||||
|
||||
private $trees = array();
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests for @{class:ArcanistXHPASTLinter}.
|
||||
*
|
||||
* @group testcase
|
||||
*/
|
||||
class ArcanistXHPASTLinterTestCase extends ArcanistLinterTestCase {
|
||||
|
||||
public function testXHPASTLint() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Message emitted by a linter, like an error or warning.
|
||||
*
|
||||
* @group lint
|
||||
*/
|
||||
class ArcanistLintMessage {
|
||||
|
||||
protected $path;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Applies lint patches to the working copy.
|
||||
*
|
||||
* @group lint
|
||||
*/
|
||||
final class ArcanistLintPatcher {
|
||||
|
||||
private $dirtyUntil = 0;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Shows lint messages to the user.
|
||||
*
|
||||
* @group lint
|
||||
*/
|
||||
class ArcanistLintRenderer {
|
||||
|
||||
private $summaryMode;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A group of @{class:ArcanistLintMessage}s that apply to a file.
|
||||
*
|
||||
* @group lint
|
||||
*/
|
||||
final class ArcanistLintResult {
|
||||
|
||||
protected $path;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Describes the severity of an @{class:ArcanistLintMessage}.
|
||||
*
|
||||
* @group lint
|
||||
*/
|
||||
class ArcanistLintSeverity {
|
||||
|
||||
const SEVERITY_ADVICE = 'advice';
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Converts changesets between different formats.
|
||||
*
|
||||
* @group diff
|
||||
*/
|
||||
class ArcanistBundle {
|
||||
|
||||
private $changes;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Parses diffs from a working copy.
|
||||
*
|
||||
* @group diff
|
||||
*/
|
||||
class ArcanistDiffParser {
|
||||
|
||||
protected $api;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Test cases for @{class:ArcanistDiffParser}.
|
||||
*
|
||||
* @group testcase
|
||||
*/
|
||||
class ArcanistDiffParserTestCase extends ArcanistPhutilTestCase {
|
||||
|
||||
public function testParser() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a change to an individual path.
|
||||
*
|
||||
* @group diff
|
||||
*/
|
||||
class ArcanistDiffChange {
|
||||
|
||||
protected $metadata = array();
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Defines constants for file types and operations in changesets.
|
||||
*
|
||||
* @group diff
|
||||
*/
|
||||
class ArcanistDiffChangeType {
|
||||
const TYPE_ADD = 1;
|
||||
const TYPE_CHANGE = 2;
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
*/
|
||||
|
||||
/**
|
||||
* A hunk is a contiguous set of added and removed lines in a diff. This is
|
||||
* the parsed representation thereof.
|
||||
* Represents a contiguous set of added and removed lines in a diff.
|
||||
*
|
||||
* @group diff
|
||||
*/
|
||||
class ArcanistDiffHunk {
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lists dependencies and requirements for a module.
|
||||
*
|
||||
* @group module
|
||||
*/
|
||||
class PhutilModuleRequirements {
|
||||
|
||||
protected $builtins = array(
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interfaces with the VCS in the working copy.
|
||||
*
|
||||
* @group workingcopy
|
||||
*/
|
||||
abstract class ArcanistRepositoryAPI {
|
||||
|
||||
const FLAG_MODIFIED = 1;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interfaces with Git working copies.
|
||||
*
|
||||
* @group workingcopy
|
||||
*/
|
||||
class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
||||
|
||||
private $status;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interfaces with Subversion working copies.
|
||||
*
|
||||
* @group workingcopy
|
||||
*/
|
||||
class ArcanistSubversionAPI extends ArcanistRepositoryAPI {
|
||||
|
||||
protected $svnStatus;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Manages unit test execution.
|
||||
*
|
||||
* @group unit
|
||||
*/
|
||||
abstract class ArcanistBaseUnitTestEngine {
|
||||
|
||||
private $workingCopy;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Very basic unit test engine which runs libphutil tests.
|
||||
*
|
||||
* @group unitrun
|
||||
*/
|
||||
class PhutilUnitTestEngine extends ArcanistBaseUnitTestEngine {
|
||||
|
||||
public function run() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Very meta test for @{class:PhutilUnitTestEngine}.
|
||||
*
|
||||
* @group testcase
|
||||
*/
|
||||
class PhutilUnitTestEngineTestCase extends ArcanistPhutilTestCase {
|
||||
|
||||
public function testPass() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Base test case for the very simple libphutil test framework.
|
||||
*
|
||||
* @group unitrun
|
||||
*/
|
||||
abstract class ArcanistPhutilTestCase {
|
||||
|
||||
private $runningTest;
|
||||
|
|
|
@ -16,4 +16,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Thrown to prematurely end test execution.
|
||||
*
|
||||
* @group unitrun
|
||||
*/
|
||||
class ArcanistPhutilTestTerminatedException extends Exception {}
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the outcome of running a unit test.
|
||||
*
|
||||
* @group unit
|
||||
*/
|
||||
class ArcanistUnitTestResult {
|
||||
|
||||
const RESULT_PASS = 'pass';
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Updates git commit messages after a revision is "Accepted".
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistAmendWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements a runnable command, like "arc diff" or "arc help".
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistBaseWorkflow {
|
||||
|
||||
private $conduit;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Executes "svn commit" once a revision has been "Accepted".
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistCommitWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Covers your professional reputation by blaming changes to locate reviewers.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistCoverWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sends changes from your working copy to Differential for code review.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistDiffWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
private $hasWarnedExternals = false;
|
||||
|
@ -323,6 +328,50 @@ EOTEXT
|
|||
);
|
||||
|
||||
if ($message->getRevisionID()) {
|
||||
// TODO: This is silly -- we're getting a text corpus from the server
|
||||
// and then sending it right back to be parsed. This should be a
|
||||
// single call.
|
||||
$remote_corpus = $conduit->callMethodSynchronous(
|
||||
'differential.getcommitmessage',
|
||||
array(
|
||||
'revision_id' => $message->getRevisionID(),
|
||||
));
|
||||
$remote_message = ArcanistDifferentialCommitMessage::newFromRawCorpus(
|
||||
$remote_corpus);
|
||||
$remote_message->pullDataFromConduit($conduit);
|
||||
|
||||
// TODO: We should throw here if you deleted the 'testPlan'.
|
||||
|
||||
$sync = array('title', 'summary', 'testPlan');
|
||||
foreach ($sync as $field) {
|
||||
$local = $message->getFieldValue($field);
|
||||
$remote_message->setFieldValue($field, $local);
|
||||
}
|
||||
|
||||
$should_edit = $this->getArgument('edit');
|
||||
if (!$should_edit) {
|
||||
$local_sum = $message->getChecksum();
|
||||
$remote_sum = $remote_message->getChecksum();
|
||||
if ($local_sum != $remote_sum) {
|
||||
$prompt =
|
||||
"You have made local changes to your commit message. Arcanist ".
|
||||
"ignores most local changes. Instead, use the '--edit' flag to ".
|
||||
"edit revision information. Edit revision information now?";
|
||||
$should_edit = phutil_console_confirm(
|
||||
$prompt,
|
||||
$default_no = false);
|
||||
}
|
||||
}
|
||||
|
||||
if ($should_edit) {
|
||||
// TODO: lol. But we need differential.unparsecommitmessage or
|
||||
// something.
|
||||
throw new ArcanistUsageException(
|
||||
'--edit is not supported yet. Edit revisions from the web '.
|
||||
'UI.');
|
||||
}
|
||||
|
||||
$revision['fields'] = $remote_message->getFields();
|
||||
|
||||
$update_message = $this->getUpdateMessage();
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Exports changes from Differential or the working copy to a file.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
final class ArcanistExportWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
const SOURCE_LOCAL = 'local';
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Installable as a git pre-receive hook.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistGitHookPreReceiveWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Seduces the reader with majestic prose.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistHelpWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
|
@ -157,6 +162,14 @@ EOTEXT
|
|||
__--no-ansi__
|
||||
Output in plain ASCII text only, without color or style.
|
||||
|
||||
__--load-phutil-library=/path/to/library__
|
||||
Ignore libraries listed in .arcconfig and explicitly load specified
|
||||
libraries instead. Mostly useful for Arcanist development.
|
||||
|
||||
__--conduit-uri=...__
|
||||
Ignore configured Conduit URI and use an explicit one instead. Mostly
|
||||
useful for Arcanist development.
|
||||
|
||||
|
||||
EOTEXT
|
||||
);
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Runs lint rules on changes.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistLintWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
const RESULT_OKAY = 0;
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lists open revisions in Differential.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistListWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Explicitly marks Differential revisions as "Committed".
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistMarkCommittedWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
|
@ -26,7 +31,7 @@ class ArcanistMarkCommittedWorkflow extends ArcanistBaseWorkflow {
|
|||
to do this; arc commit (svn), arc amend (git) or commit hooks in the
|
||||
master remote repository should do it for you. However, if these
|
||||
mechanisms have failed for some reason you can use this command to
|
||||
manually change a revision status from "accepted" to "committed".
|
||||
manually change a revision status from "Accepted" to "Committed".
|
||||
EOTEXT
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Applies changes from Differential or a file to the working copy.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
final class ArcanistPatchWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
const SOURCE_BUNDLE = 'bundle';
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Powers shell-completion scripts.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistShellCompleteWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
|
@ -24,7 +29,6 @@ class ArcanistShellCompleteWorkflow extends ArcanistBaseWorkflow {
|
|||
Supports: bash, etc.
|
||||
Implements shell completion. To use shell completion, source the
|
||||
appropriate script from 'resources/shell/' in your .shellrc.
|
||||
|
||||
EOTEXT
|
||||
);
|
||||
}
|
||||
|
@ -123,7 +127,7 @@ EOTEXT
|
|||
}
|
||||
return 0;
|
||||
} else {
|
||||
|
||||
|
||||
$output = array();
|
||||
foreach ($arguments as $argument => $spec) {
|
||||
if ($argument == '*') {
|
||||
|
@ -136,7 +140,7 @@ EOTEXT
|
|||
}
|
||||
$output[] = '--'.$argument;
|
||||
}
|
||||
|
||||
|
||||
$cur = idx($argv, $pos, '');
|
||||
$any_match = false;
|
||||
foreach ($output as $possible) {
|
||||
|
@ -144,7 +148,7 @@ EOTEXT
|
|||
$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
|
||||
|
|
|
@ -16,13 +16,20 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Installable as an SVN "pre-commit" hook.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistSvnHookPreCommitWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
public function getCommandHelp() {
|
||||
return phutil_console_format(<<<EOTEXT
|
||||
**svn-hook-pre-commit** __repository__ __transaction__
|
||||
Supports: svn
|
||||
You can install this as an SVN pre-commit hook.
|
||||
You can install this as an SVN pre-commit hook. For more information,
|
||||
see the article "Installing Arcanist SVN Hooks" in the Arcanist
|
||||
documentation.
|
||||
EOTEXT
|
||||
);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Runs unit tests which cover your changes.
|
||||
*
|
||||
* @group workflow
|
||||
*/
|
||||
class ArcanistUnitWorkflow extends ArcanistBaseWorkflow {
|
||||
|
||||
const RESULT_OKAY = 0;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
|
||||
phutil_require_module('arcanist', 'exception/usage/noengine');
|
||||
phutil_require_module('arcanist', 'repository/api/base');
|
||||
phutil_require_module('arcanist', 'unit/result');
|
||||
phutil_require_module('arcanist', 'workflow/base');
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interfaces with basic information about the working copy.
|
||||
*
|
||||
* @group workingcopy
|
||||
*/
|
||||
class ArcanistWorkingCopyIdentity {
|
||||
|
||||
protected $projectConfig;
|
||||
|
|
Loading…
Reference in a new issue