1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-09-19 16:38:51 +02:00

Some documentation.

Summary:

Test Plan:

Reviewers:

CC:
This commit is contained in:
epriestley 2011-02-19 11:36:08 -08:00
parent b50acb5129
commit 5099b005cf
74 changed files with 451 additions and 15 deletions

View file

@ -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"
}
}

View file

@ -30,6 +30,8 @@ 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);

View file

@ -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) {

View file

@ -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',

View file

@ -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) {

View file

@ -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(

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Represents a parsed commit message.
*
* @group differential
*/
class ArcanistDifferentialCommitMessage {
private $rawCorpus;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Thrown when a commit message isn't parseable.
*
* @group differential
*/
class ArcanistDifferentialCommitMessageParserException extends Exception {
}

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Reference to a Differential revision.
*
* @group differential
*/
class ArcanistDifferentialRevisionRef {
protected $id;

View file

@ -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 =

View 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.

View file

@ -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 =

View file

@ -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

View file

@ -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 {
}

View file

@ -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 {
}

View file

@ -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 {
}

View file

@ -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 {
}

View file

@ -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 {
}

View file

@ -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.');

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Manages lint execution.
*
* @group lint
*/
abstract class ArcanistLintEngine {
protected $workingCopy;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Lint engine which enforces libphutil rules.
*
* @group linter
*/
class PhutilLintEngine extends ArcanistLintEngine {
public function buildLinters() {

View file

@ -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();

View file

@ -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';

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Test cases for @{class:ArcanistApacheLicenseLinter}.
*
* @group testcase
*/
class ArcanistApacheLicenseLinterTestCase extends ArcanistLinterTestCase {
public function testApacheLicenseLint() {

View file

@ -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();

View file

@ -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) {

View file

@ -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;

View file

@ -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 {

View file

@ -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;

View file

@ -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) {

View file

@ -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;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Enforces basic text file rules.
*
* @group linter
*/
class ArcanistTextLinter extends ArcanistLinter {
const LINT_DOS_NEWLINE = 1;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Test cases for @{class:ArcanistTextLinter}.
*
* @group testcase
*/
class ArcanistTextLinterTestCase extends ArcanistLinterTestCase {
public function testTextLint() {

View file

@ -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();

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Tests for @{class:ArcanistXHPASTLinter}.
*
* @group testcase
*/
class ArcanistXHPASTLinterTestCase extends ArcanistLinterTestCase {
public function testXHPASTLint() {

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Message emitted by a linter, like an error or warning.
*
* @group lint
*/
class ArcanistLintMessage {
protected $path;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Applies lint patches to the working copy.
*
* @group lint
*/
final class ArcanistLintPatcher {
private $dirtyUntil = 0;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Shows lint messages to the user.
*
* @group lint
*/
class ArcanistLintRenderer {
private $summaryMode;

View file

@ -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;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Describes the severity of an @{class:ArcanistLintMessage}.
*
* @group lint
*/
class ArcanistLintSeverity {
const SEVERITY_ADVICE = 'advice';

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Converts changesets between different formats.
*
* @group diff
*/
class ArcanistBundle {
private $changes;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Parses diffs from a working copy.
*
* @group diff
*/
class ArcanistDiffParser {
protected $api;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Test cases for @{class:ArcanistDiffParser}.
*
* @group testcase
*/
class ArcanistDiffParserTestCase extends ArcanistPhutilTestCase {
public function testParser() {

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Represents a change to an individual path.
*
* @group diff
*/
class ArcanistDiffChange {
protected $metadata = array();

View file

@ -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;

View file

@ -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 {

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Lists dependencies and requirements for a module.
*
* @group module
*/
class PhutilModuleRequirements {
protected $builtins = array(

View file

@ -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;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Interfaces with Git working copies.
*
* @group workingcopy
*/
class ArcanistGitAPI extends ArcanistRepositoryAPI {
private $status;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Interfaces with Subversion working copies.
*
* @group workingcopy
*/
class ArcanistSubversionAPI extends ArcanistRepositoryAPI {
protected $svnStatus;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Manages unit test execution.
*
* @group unit
*/
abstract class ArcanistBaseUnitTestEngine {
private $workingCopy;

View file

@ -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() {

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Very meta test for @{class:PhutilUnitTestEngine}.
*
* @group testcase
*/
class PhutilUnitTestEngineTestCase extends ArcanistPhutilTestCase {
public function testPass() {

View file

@ -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;

View file

@ -16,4 +16,9 @@
* limitations under the License.
*/
/**
* Thrown to prematurely end test execution.
*
* @group unitrun
*/
class ArcanistPhutilTestTerminatedException extends Exception {}

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Represents the outcome of running a unit test.
*
* @group unit
*/
class ArcanistUnitTestResult {
const RESULT_PASS = 'pass';

View file

@ -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() {

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Implements a runnable command, like "arc diff" or "arc help".
*
* @group workflow
*/
class ArcanistBaseWorkflow {
private $conduit;

View file

@ -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() {

View file

@ -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() {

View file

@ -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;

View file

@ -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';

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Installable as a git pre-receive hook.
*
* @group workflow
*/
class ArcanistGitHookPreReceiveWorkflow extends ArcanistBaseWorkflow {
public function getCommandHelp() {

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Seduces the reader with majestic prose.
*
* @group workflow
*/
class ArcanistHelpWorkflow extends ArcanistBaseWorkflow {
public function getCommandHelp() {

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Runs lint rules on changes.
*
* @group workflow
*/
class ArcanistLintWorkflow extends ArcanistBaseWorkflow {
const RESULT_OKAY = 0;

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Lists open revisions in Differential.
*
* @group workflow
*/
class ArcanistListWorkflow extends ArcanistBaseWorkflow {
public function getCommandHelp() {

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Explicitly marks Differential revisions as "Committed".
*
* @group workflow
*/
class ArcanistMarkCommittedWorkflow extends ArcanistBaseWorkflow {
public function getCommandHelp() {

View file

@ -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';

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Powers shell-completion scripts.
*
* @group workflow
*/
class ArcanistShellCompleteWorkflow extends ArcanistBaseWorkflow {
public function getCommandHelp() {

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Installable as an SVN "pre-commit" hook.
*
* @group workflow
*/
class ArcanistSvnHookPreCommitWorkflow extends ArcanistBaseWorkflow {
public function getCommandHelp() {

View file

@ -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;

View file

@ -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');

View file

@ -16,6 +16,11 @@
* limitations under the License.
*/
/**
* Interfaces with basic information about the working copy.
*
* @group workingcopy
*/
class ArcanistWorkingCopyIdentity {
protected $projectConfig;