Page MenuHomePhabricator

D9983.id24026.diff
No OneTemporary

D9983.id24026.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -16,8 +16,6 @@
'ArcanistBackoutWorkflow' => 'workflow/ArcanistBackoutWorkflow.php',
'ArcanistBaseCommitParser' => 'parser/ArcanistBaseCommitParser.php',
'ArcanistBaseCommitParserTestCase' => 'parser/__tests__/ArcanistBaseCommitParserTestCase.php',
- 'ArcanistBaseTestResultParser' => 'unit/engine/ArcanistBaseTestResultParser.php',
- 'ArcanistBaseUnitTestEngine' => 'unit/engine/ArcanistBaseUnitTestEngine.php',
'ArcanistBaseWorkflow' => 'workflow/ArcanistBaseWorkflow.php',
'ArcanistBaseXHPASTLinter' => 'lint/linter/ArcanistBaseXHPASTLinter.php',
'ArcanistBookmarkWorkflow' => 'workflow/ArcanistBookmarkWorkflow.php',
@@ -168,6 +166,7 @@
'ArcanistSvnHookPreCommitWorkflow' => 'workflow/ArcanistSvnHookPreCommitWorkflow.php',
'ArcanistTasksWorkflow' => 'workflow/ArcanistTasksWorkflow.php',
'ArcanistTestCase' => 'infrastructure/testing/ArcanistTestCase.php',
+ 'ArcanistTestResultParser' => 'unit/engine/ArcanistTestResultParser.php',
'ArcanistTextLinter' => 'lint/linter/ArcanistTextLinter.php',
'ArcanistTextLinterTestCase' => 'lint/linter/__tests__/ArcanistTextLinterTestCase.php',
'ArcanistTimeWorkflow' => 'workflow/ArcanistTimeWorkflow.php',
@@ -175,6 +174,7 @@
'ArcanistUncommittedChangesException' => 'exception/usage/ArcanistUncommittedChangesException.php',
'ArcanistUnitConsoleRenderer' => 'unit/renderer/ArcanistUnitConsoleRenderer.php',
'ArcanistUnitRenderer' => 'unit/renderer/ArcanistUnitRenderer.php',
+ 'ArcanistUnitTestEngine' => 'unit/engine/ArcanistUnitTestEngine.php',
'ArcanistUnitTestResult' => 'unit/ArcanistUnitTestResult.php',
'ArcanistUnitWorkflow' => 'workflow/ArcanistUnitWorkflow.php',
'ArcanistUpgradeWorkflow' => 'workflow/ArcanistUpgradeWorkflow.php',
@@ -183,6 +183,7 @@
'ArcanistUserAbortException' => 'exception/usage/ArcanistUserAbortException.php',
'ArcanistVersionWorkflow' => 'workflow/ArcanistVersionWorkflow.php',
'ArcanistWhichWorkflow' => 'workflow/ArcanistWhichWorkflow.php',
+ 'ArcanistWorkflow' => 'workflow/ArcanistWorkflow.php',
'ArcanistWorkingCopyIdentity' => 'workingcopyidentity/ArcanistWorkingCopyIdentity.php',
'ArcanistXHPASTLintNamingHook' => 'lint/linter/xhpast/ArcanistXHPASTLintNamingHook.php',
'ArcanistXHPASTLintNamingHookTestCase' => 'lint/linter/xhpast/__tests__/ArcanistXHPASTLintNamingHookTestCase.php',
@@ -210,69 +211,69 @@
),
'function' => array(),
'xmap' => array(
- 'ArcanistAliasWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistAmendWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistAnoidWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistAliasWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistAmendWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistAnoidWorkflow' => 'ArcanistWorkflow',
'ArcanistArcanistLinterTestCase' => 'ArcanistLinterTestCase',
- 'ArcanistBackoutWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistBackoutWorkflow' => 'ArcanistWorkflow',
'ArcanistBaseCommitParserTestCase' => 'ArcanistTestCase',
- 'ArcanistBaseWorkflow' => 'Phobject',
+ 'ArcanistBaseWorkflow' => 'ArcanistWorkflow',
'ArcanistBaseXHPASTLinter' => 'ArcanistFutureLinter',
'ArcanistBookmarkWorkflow' => 'ArcanistFeatureWorkflow',
'ArcanistBranchWorkflow' => 'ArcanistFeatureWorkflow',
'ArcanistBritishTestCase' => 'ArcanistTestCase',
- 'ArcanistBrowseWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistBrowseWorkflow' => 'ArcanistWorkflow',
'ArcanistBundleTestCase' => 'ArcanistTestCase',
'ArcanistCSSLintLinter' => 'ArcanistExternalLinter',
'ArcanistCSSLintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistCSharpLinter' => 'ArcanistLinter',
- 'ArcanistCallConduitWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistCallConduitWorkflow' => 'ArcanistWorkflow',
'ArcanistCapabilityNotSupportedException' => 'Exception',
'ArcanistChmodLinter' => 'ArcanistLinter',
'ArcanistChooseInvalidRevisionException' => 'Exception',
'ArcanistChooseNoRevisionsException' => 'Exception',
- 'ArcanistCloseRevisionWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistCloseWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistCloseRevisionWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistCloseWorkflow' => 'ArcanistWorkflow',
'ArcanistClosureLinter' => 'ArcanistExternalLinter',
'ArcanistClosureLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistCoffeeLintLinter' => 'ArcanistExternalLinter',
'ArcanistCoffeeLintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistCommentRemoverTestCase' => 'ArcanistTestCase',
- 'ArcanistCommitWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistCommitWorkflow' => 'ArcanistWorkflow',
'ArcanistConduitLinter' => 'ArcanistLinter',
'ArcanistConfigurationDrivenLintEngine' => 'ArcanistLintEngine',
- 'ArcanistCoverWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistCoverWorkflow' => 'ArcanistWorkflow',
'ArcanistCppcheckLinter' => 'ArcanistExternalLinter',
'ArcanistCppcheckLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistCpplintLinter' => 'ArcanistExternalLinter',
'ArcanistCpplintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistDiffParserTestCase' => 'ArcanistTestCase',
'ArcanistDiffUtilsTestCase' => 'ArcanistTestCase',
- 'ArcanistDiffWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistDiffWorkflow' => 'ArcanistWorkflow',
'ArcanistDifferentialCommitMessageParserException' => 'Exception',
'ArcanistDifferentialDependencyGraph' => 'AbstractDirectedGraph',
- 'ArcanistDownloadWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistDownloadWorkflow' => 'ArcanistWorkflow',
'ArcanistEventType' => 'PhutilEventType',
- 'ArcanistExportWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistExportWorkflow' => 'ArcanistWorkflow',
'ArcanistExternalLinter' => 'ArcanistFutureLinter',
- 'ArcanistFeatureWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistFeatureWorkflow' => 'ArcanistWorkflow',
'ArcanistFilenameLinter' => 'ArcanistLinter',
- 'ArcanistFlagWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistFlagWorkflow' => 'ArcanistWorkflow',
'ArcanistFlake8Linter' => 'ArcanistExternalLinter',
'ArcanistFlake8LinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistFutureLinter' => 'ArcanistLinter',
'ArcanistGeneratedLinter' => 'ArcanistLinter',
- 'ArcanistGetConfigWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistGetConfigWorkflow' => 'ArcanistWorkflow',
'ArcanistGitAPI' => 'ArcanistRepositoryAPI',
- 'ArcanistGitHookPreReceiveWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistGitHookPreReceiveWorkflow' => 'ArcanistWorkflow',
'ArcanistGoLintLinter' => 'ArcanistExternalLinter',
'ArcanistGoLintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
- 'ArcanistHelpWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistHelpWorkflow' => 'ArcanistWorkflow',
'ArcanistHgClientChannel' => 'PhutilProtocolChannel',
'ArcanistHgServerChannel' => 'PhutilProtocolChannel',
'ArcanistInfrastructureTestCase' => 'ArcanistTestCase',
- 'ArcanistInlinesWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistInstallCertificateWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistInlinesWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistInstallCertificateWorkflow' => 'ArcanistWorkflow',
'ArcanistJSHintLinter' => 'ArcanistExternalLinter',
'ArcanistJSHintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistJSONLintLinter' => 'ArcanistExternalLinter',
@@ -281,20 +282,20 @@
'ArcanistJSONLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistJscsLinter' => 'ArcanistExternalLinter',
'ArcanistJscsLinterTestCase' => 'ArcanistArcanistLinterTestCase',
- 'ArcanistLandWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistLandWorkflow' => 'ArcanistWorkflow',
'ArcanistLesscLinter' => 'ArcanistExternalLinter',
'ArcanistLesscLinterTestCase' => 'ArcanistArcanistLinterTestCase',
- 'ArcanistLiberateWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistLiberateWorkflow' => 'ArcanistWorkflow',
'ArcanistLintCheckstyleXMLRenderer' => 'ArcanistLintRenderer',
'ArcanistLintConsoleRenderer' => 'ArcanistLintRenderer',
'ArcanistLintJSONRenderer' => 'ArcanistLintRenderer',
'ArcanistLintLikeCompilerRenderer' => 'ArcanistLintRenderer',
'ArcanistLintNoneRenderer' => 'ArcanistLintRenderer',
'ArcanistLintSummaryRenderer' => 'ArcanistLintRenderer',
- 'ArcanistLintWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistLintWorkflow' => 'ArcanistWorkflow',
'ArcanistLinterTestCase' => 'ArcanistPhutilTestCase',
- 'ArcanistLintersWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistListWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistLintersWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistListWorkflow' => 'ArcanistWorkflow',
'ArcanistMercurialAPI' => 'ArcanistRepositoryAPI',
'ArcanistMercurialParserTestCase' => 'ArcanistTestCase',
'ArcanistMergeConflictLinter' => 'ArcanistLinter',
@@ -306,10 +307,10 @@
'ArcanistPEP8Linter' => 'ArcanistExternalLinter',
'ArcanistPEP8LinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistPHPCSLinterTestCase' => 'ArcanistArcanistLinterTestCase',
- 'ArcanistPasteWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistPatchWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistPasteWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistPatchWorkflow' => 'ArcanistWorkflow',
'ArcanistPhpcsLinter' => 'ArcanistExternalLinter',
- 'ArcanistPhrequentWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistPhrequentWorkflow' => 'ArcanistWorkflow',
'ArcanistPhutilLibraryLinter' => 'ArcanistLinter',
'ArcanistPhutilTestCaseTestCase' => 'ArcanistPhutilTestCase',
'ArcanistPhutilTestSkippedException' => 'Exception',
@@ -324,12 +325,12 @@
'ArcanistPyLintLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistRepositoryAPIMiscTestCase' => 'ArcanistTestCase',
'ArcanistRepositoryAPIStateTestCase' => 'ArcanistTestCase',
- 'ArcanistRevertWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistRevertWorkflow' => 'ArcanistWorkflow',
'ArcanistRubyLinter' => 'ArcanistExternalLinter',
'ArcanistRubyLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistScriptAndRegexLinter' => 'ArcanistLinter',
- 'ArcanistSetConfigWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistShellCompleteWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistSetConfigWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistShellCompleteWorkflow' => 'ArcanistWorkflow',
'ArcanistSingleLintEngine' => 'ArcanistLintEngine',
'ArcanistSpellingLinter' => 'ArcanistLinter',
'ArcanistSpellingLinterTestCase' => 'ArcanistArcanistLinterTestCase',
@@ -337,22 +338,23 @@
'ArcanistStopWorkflow' => 'ArcanistPhrequentWorkflow',
'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI',
'ArcanistSubversionHookAPI' => 'ArcanistHookAPI',
- 'ArcanistSvnHookPreCommitWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistTasksWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistSvnHookPreCommitWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistTasksWorkflow' => 'ArcanistWorkflow',
'ArcanistTestCase' => 'ArcanistPhutilTestCase',
'ArcanistTextLinter' => 'ArcanistLinter',
'ArcanistTextLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'ArcanistTimeWorkflow' => 'ArcanistPhrequentWorkflow',
- 'ArcanistTodoWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistTodoWorkflow' => 'ArcanistWorkflow',
'ArcanistUncommittedChangesException' => 'ArcanistUsageException',
'ArcanistUnitConsoleRenderer' => 'ArcanistUnitRenderer',
- 'ArcanistUnitWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistUpgradeWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistUploadWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistUnitWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistUpgradeWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistUploadWorkflow' => 'ArcanistWorkflow',
'ArcanistUsageException' => 'Exception',
'ArcanistUserAbortException' => 'ArcanistUsageException',
- 'ArcanistVersionWorkflow' => 'ArcanistBaseWorkflow',
- 'ArcanistWhichWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistVersionWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistWhichWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistWorkflow' => 'Phobject',
'ArcanistXHPASTLintNamingHookTestCase' => 'ArcanistTestCase',
'ArcanistXHPASTLintTestSwitchHook' => 'ArcanistXHPASTLintSwitchHook',
'ArcanistXHPASTLinter' => 'ArcanistBaseXHPASTLinter',
@@ -361,17 +363,17 @@
'ArcanistXMLLinterTestCase' => 'ArcanistArcanistLinterTestCase',
'CSharpToolsTestEngine' => 'XUnitTestEngine',
'ComprehensiveLintEngine' => 'ArcanistLintEngine',
- 'GoTestResultParser' => 'ArcanistBaseTestResultParser',
+ 'GoTestResultParser' => 'ArcanistTestResultParser',
'GoTestResultParserTestCase' => 'ArcanistTestCase',
- 'NoseTestEngine' => 'ArcanistBaseUnitTestEngine',
+ 'NoseTestEngine' => 'ArcanistUnitTestEngine',
'PHPUnitTestEngineTestCase' => 'ArcanistTestCase',
- 'PhpunitResultParser' => 'ArcanistBaseTestResultParser',
- 'PhpunitTestEngine' => 'ArcanistBaseUnitTestEngine',
- 'PhutilUnitTestEngine' => 'ArcanistBaseUnitTestEngine',
+ 'PhpunitResultParser' => 'ArcanistTestResultParser',
+ 'PhpunitTestEngine' => 'ArcanistUnitTestEngine',
+ 'PhutilUnitTestEngine' => 'ArcanistUnitTestEngine',
'PhutilUnitTestEngineTestCase' => 'ArcanistTestCase',
- 'PytestTestEngine' => 'ArcanistBaseUnitTestEngine',
+ 'PytestTestEngine' => 'ArcanistUnitTestEngine',
'UnitTestableArcanistLintEngine' => 'ArcanistLintEngine',
- 'XUnitTestEngine' => 'ArcanistBaseUnitTestEngine',
+ 'XUnitTestEngine' => 'ArcanistUnitTestEngine',
'XUnitTestResultParserTestCase' => 'ArcanistTestCase',
),
));
diff --git a/src/configuration/ArcanistConfiguration.php b/src/configuration/ArcanistConfiguration.php
--- a/src/configuration/ArcanistConfiguration.php
+++ b/src/configuration/ArcanistConfiguration.php
@@ -38,7 +38,7 @@
$workflows_by_name = array();
$workflows_by_class_name = id(new PhutilSymbolLoader())
- ->setAncestorClass('ArcanistBaseWorkflow')
+ ->setAncestorClass('ArcanistWorkflow')
->loadObjects();
foreach ($workflows_by_class_name as $class => $workflow) {
$name = $workflow->getWorkflowName();
@@ -60,14 +60,11 @@
return (bool)$this->buildWorkflow($workflow);
}
- public function willRunWorkflow($command, ArcanistBaseWorkflow $workflow) {
+ public function willRunWorkflow($command, ArcanistWorkflow $workflow) {
// This is a hook.
}
- public function didRunWorkflow(
- $command,
- ArcanistBaseWorkflow $workflow,
- $err) {
+ public function didRunWorkflow($command, ArcanistWorkflow $workflow, $err) {
// This is a hook.
}
diff --git a/src/unit/engine/ArcanistBaseTestResultParser.php b/src/unit/engine/ArcanistTestResultParser.php
rename from src/unit/engine/ArcanistBaseTestResultParser.php
rename to src/unit/engine/ArcanistTestResultParser.php
--- a/src/unit/engine/ArcanistBaseTestResultParser.php
+++ b/src/unit/engine/ArcanistTestResultParser.php
@@ -1,9 +1,9 @@
<?php
/**
- * Abstract Base class for test result parsers.
+ * Abstract base class for test result parsers.
*/
-abstract class ArcanistBaseTestResultParser {
+abstract class ArcanistTestResultParser {
protected $enableCoverage;
protected $projectRoot;
@@ -36,13 +36,12 @@
}
/**
- * Parse test results from provided input and return an array
- * of ArcanistUnitTestResult
+ * Parse test results from provided input and return an array of
+ * @{class:ArcanistUnitTestResult}.
*
- * @param string $path Path to test
- * @param string $test_results String containing test results
- *
- * @return array ArcanistUnitTestResult
+ * @param string Path to test.
+ * @param string String containing test results.
+ * @return array
*/
abstract public function parseTestResults($path, $test_results);
diff --git a/src/unit/engine/ArcanistBaseUnitTestEngine.php b/src/unit/engine/ArcanistUnitTestEngine.php
rename from src/unit/engine/ArcanistBaseUnitTestEngine.php
rename to src/unit/engine/ArcanistUnitTestEngine.php
--- a/src/unit/engine/ArcanistBaseUnitTestEngine.php
+++ b/src/unit/engine/ArcanistUnitTestEngine.php
@@ -3,7 +3,7 @@
/**
* Manages unit test execution.
*/
-abstract class ArcanistBaseUnitTestEngine {
+abstract class ArcanistUnitTestEngine {
private $workingCopy;
private $paths;
diff --git a/src/unit/engine/GoTestResultParser.php b/src/unit/engine/GoTestResultParser.php
--- a/src/unit/engine/GoTestResultParser.php
+++ b/src/unit/engine/GoTestResultParser.php
@@ -5,7 +5,7 @@
*
* (To generate test output, run something like: `go test -v`)
*/
-final class GoTestResultParser extends ArcanistBaseTestResultParser {
+final class GoTestResultParser extends ArcanistTestResultParser {
/**
* Parse test results from Go test report
diff --git a/src/unit/engine/NoseTestEngine.php b/src/unit/engine/NoseTestEngine.php
--- a/src/unit/engine/NoseTestEngine.php
+++ b/src/unit/engine/NoseTestEngine.php
@@ -5,7 +5,7 @@
*
* Requires nose 1.1.3 for code coverage.
*/
-final class NoseTestEngine extends ArcanistBaseUnitTestEngine {
+final class NoseTestEngine extends ArcanistUnitTestEngine {
public function run() {
$paths = $this->getPaths();
diff --git a/src/unit/engine/PhpunitResultParser.php b/src/unit/engine/PhpunitResultParser.php
--- a/src/unit/engine/PhpunitResultParser.php
+++ b/src/unit/engine/PhpunitResultParser.php
@@ -6,7 +6,7 @@
* For an example on how to integrate with your test engine, see
* @{class:PhpunitTestEngine}.
*/
-final class PhpunitResultParser extends ArcanistBaseTestResultParser {
+final class PhpunitResultParser extends ArcanistTestResultParser {
/**
* Parse test results from phpunit json report
diff --git a/src/unit/engine/PhpunitTestEngine.php b/src/unit/engine/PhpunitTestEngine.php
--- a/src/unit/engine/PhpunitTestEngine.php
+++ b/src/unit/engine/PhpunitTestEngine.php
@@ -3,7 +3,7 @@
/**
* PHPUnit wrapper.
*/
-final class PhpunitTestEngine extends ArcanistBaseUnitTestEngine {
+final class PhpunitTestEngine extends ArcanistUnitTestEngine {
private $configFile;
private $phpunitBinary = 'phpunit';
diff --git a/src/unit/engine/PhutilUnitTestEngine.php b/src/unit/engine/PhutilUnitTestEngine.php
--- a/src/unit/engine/PhutilUnitTestEngine.php
+++ b/src/unit/engine/PhutilUnitTestEngine.php
@@ -3,7 +3,7 @@
/**
* Very basic unit test engine which runs libphutil tests.
*/
-final class PhutilUnitTestEngine extends ArcanistBaseUnitTestEngine {
+final class PhutilUnitTestEngine extends ArcanistUnitTestEngine {
protected function supportsRunAllTests() {
return true;
diff --git a/src/unit/engine/PytestTestEngine.php b/src/unit/engine/PytestTestEngine.php
--- a/src/unit/engine/PytestTestEngine.php
+++ b/src/unit/engine/PytestTestEngine.php
@@ -3,7 +3,7 @@
/**
* Very basic 'py.test' unit test engine wrapper.
*/
-final class PytestTestEngine extends ArcanistBaseUnitTestEngine {
+final class PytestTestEngine extends ArcanistUnitTestEngine {
public function run() {
$working_copy = $this->getWorkingCopy();
diff --git a/src/unit/engine/XUnitTestEngine.php b/src/unit/engine/XUnitTestEngine.php
--- a/src/unit/engine/XUnitTestEngine.php
+++ b/src/unit/engine/XUnitTestEngine.php
@@ -9,7 +9,7 @@
*
* @concrete-extensible
*/
-class XUnitTestEngine extends ArcanistBaseUnitTestEngine {
+class XUnitTestEngine extends ArcanistUnitTestEngine {
protected $runtimeEngine;
protected $buildEngine;
diff --git a/src/workflow/ArcanistAliasWorkflow.php b/src/workflow/ArcanistAliasWorkflow.php
--- a/src/workflow/ArcanistAliasWorkflow.php
+++ b/src/workflow/ArcanistAliasWorkflow.php
@@ -3,7 +3,7 @@
/**
* Manages aliases for commands with options.
*/
-final class ArcanistAliasWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistAliasWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'alias';
diff --git a/src/workflow/ArcanistAmendWorkflow.php b/src/workflow/ArcanistAmendWorkflow.php
--- a/src/workflow/ArcanistAmendWorkflow.php
+++ b/src/workflow/ArcanistAmendWorkflow.php
@@ -3,7 +3,7 @@
/**
* Synchronizes commit messages from Differential.
*/
-final class ArcanistAmendWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistAmendWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'amend';
diff --git a/src/workflow/ArcanistAnoidWorkflow.php b/src/workflow/ArcanistAnoidWorkflow.php
--- a/src/workflow/ArcanistAnoidWorkflow.php
+++ b/src/workflow/ArcanistAnoidWorkflow.php
@@ -1,6 +1,6 @@
<?php
-final class ArcanistAnoidWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistAnoidWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'anoid';
diff --git a/src/workflow/ArcanistBackoutWorkflow.php b/src/workflow/ArcanistBackoutWorkflow.php
--- a/src/workflow/ArcanistBackoutWorkflow.php
+++ b/src/workflow/ArcanistBackoutWorkflow.php
@@ -3,7 +3,7 @@
/**
* Runs git revert and assigns a high priority task to original author.
*/
-final class ArcanistBackoutWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistBackoutWorkflow extends ArcanistWorkflow {
private $console;
private $conduit;
diff --git a/src/workflow/ArcanistBaseWorkflow.php b/src/workflow/ArcanistBaseWorkflow.php
--- a/src/workflow/ArcanistBaseWorkflow.php
+++ b/src/workflow/ArcanistBaseWorkflow.php
@@ -1,1791 +1,7 @@
<?php
/**
- * Implements a runnable command, like "arc diff" or "arc help".
- *
- * = Managing Conduit =
- *
- * Workflows have the builtin ability to open a Conduit connection to a
- * Phabricator installation, so methods can be invoked over the API. Workflows
- * may either not need this (e.g., "help"), or may need a Conduit but not
- * authentication (e.g., calling only public APIs), or may need a Conduit and
- * authentication (e.g., "arc diff").
- *
- * To specify that you need an //unauthenticated// conduit, override
- * @{method:requiresConduit} to return ##true##. To specify that you need an
- * //authenticated// conduit, override @{method:requiresAuthentication} to
- * return ##true##. You can also manually invoke @{method:establishConduit}
- * and/or @{method:authenticateConduit} later in a workflow to upgrade it.
- * Once a conduit is open, you can access the client by calling
- * @{method:getConduit}, which allows you to invoke methods. You can get
- * verified information about the user identity by calling @{method:getUserPHID}
- * or @{method:getUserName} after authentication occurs.
- *
- * = Scratch Files =
- *
- * Arcanist workflows can read and write 'scratch files', which are temporary
- * files stored in the project that persist across commands. They can be useful
- * if you want to save some state, or keep a copy of a long message the user
- * entered if something goes wrong.
- *
- *
- * @task conduit Conduit
- * @task scratch Scratch Files
- * @task phabrep Phabricator Repositories
- *
- * @stable
+ * NOTE: Do not extend from this class, extend from @{class:ArcanistWorkflow}
+ * instead.
*/
-abstract class ArcanistBaseWorkflow extends Phobject {
-
- const COMMIT_DISABLE = 0;
- const COMMIT_ALLOW = 1;
- const COMMIT_ENABLE = 2;
-
- const AUTO_COMMIT_TITLE = 'Automatic commit by arc';
-
- private $commitMode = self::COMMIT_DISABLE;
-
- private $conduit;
- private $conduitURI;
- private $conduitCredentials;
- private $conduitAuthenticated;
- private $forcedConduitVersion;
- private $conduitTimeout;
-
- private $userPHID;
- private $userName;
- private $repositoryAPI;
- private $configurationManager;
- private $workingCopy;
- private $arguments;
- private $passedArguments;
- private $command;
-
- private $stashed;
- private $shouldAmend;
-
- private $projectInfo;
- private $repositoryInfo;
- private $repositoryReasons;
-
- private $arcanistConfiguration;
- private $parentWorkflow;
- private $workingDirectory;
- private $repositoryVersion;
-
- private $changeCache = array();
-
-
- public function __construct() {}
-
-
- abstract public function run();
-
- /**
- * Finalizes any cleanup operations that need to occur regardless of
- * whether the command succeeded or failed.
- */
- public function finalize() {
- $this->finalizeWorkingCopy();
- }
-
- /**
- * Return the command used to invoke this workflow from the command like,
- * e.g. "help" for @{class:ArcanistHelpWorkflow}.
- *
- * @return string The command a user types to invoke this workflow.
- */
- abstract public function getWorkflowName();
-
- /**
- * Return console formatted string with all command synopses.
- *
- * @return string 6-space indented list of available command synopses.
- */
- abstract public function getCommandSynopses();
-
- /**
- * Return console formatted string with command help printed in `arc help`.
- *
- * @return string 10-space indented help to use the command.
- */
- abstract public function getCommandHelp();
-
-
-/* -( Conduit )------------------------------------------------------------ */
-
-
- /**
- * Set the URI which the workflow will open a conduit connection to when
- * @{method:establishConduit} is called. Arcanist makes an effort to set
- * this by default for all workflows (by reading ##.arcconfig## and/or the
- * value of ##--conduit-uri##) even if they don't need Conduit, so a workflow
- * can generally upgrade into a conduit workflow later by just calling
- * @{method:establishConduit}.
- *
- * You generally should not need to call this method unless you are
- * specifically overriding the default URI. It is normally sufficient to
- * just invoke @{method:establishConduit}.
- *
- * NOTE: You can not call this after a conduit has been established.
- *
- * @param string The URI to open a conduit to when @{method:establishConduit}
- * is called.
- * @return this
- * @task conduit
- */
- final public function setConduitURI($conduit_uri) {
- if ($this->conduit) {
- throw new Exception(
- 'You can not change the Conduit URI after a conduit is already open.');
- }
- $this->conduitURI = $conduit_uri;
- return $this;
- }
-
- /**
- * Returns the URI the conduit connection within the workflow uses.
- *
- * @return string
- * @task conduit
- */
- final public function getConduitURI() {
- return $this->conduitURI;
- }
-
- /**
- * Open a conduit channel to the server which was previously configured by
- * calling @{method:setConduitURI}. Arcanist will do this automatically if
- * the workflow returns ##true## from @{method:requiresConduit}, or you can
- * later upgrade a workflow and build a conduit by invoking it manually.
- *
- * You must establish a conduit before you can make conduit calls.
- *
- * NOTE: You must call @{method:setConduitURI} before you can call this
- * method.
- *
- * @return this
- * @task conduit
- */
- final public function establishConduit() {
- if ($this->conduit) {
- return $this;
- }
-
- if (!$this->conduitURI) {
- throw new Exception(
- 'You must specify a Conduit URI with setConduitURI() before you can '.
- 'establish a conduit.');
- }
-
- $this->conduit = new ConduitClient($this->conduitURI);
-
- if ($this->conduitTimeout) {
- $this->conduit->setTimeout($this->conduitTimeout);
- }
-
- $user = $this->getConfigFromAnySource('http.basicauth.user');
- $pass = $this->getConfigFromAnySource('http.basicauth.pass');
- if ($user !== null && $pass !== null) {
- $this->conduit->setBasicAuthCredentials($user, $pass);
- }
-
- return $this;
- }
-
- final public function getConfigFromAnySource($key) {
- return $this->configurationManager->getConfigFromAnySource($key);
- }
-
-
- /**
- * Set credentials which will be used to authenticate against Conduit. These
- * credentials can then be used to establish an authenticated connection to
- * conduit by calling @{method:authenticateConduit}. Arcanist sets some
- * defaults for all workflows regardless of whether or not they return true
- * from @{method:requireAuthentication}, based on the ##~/.arcrc## and
- * ##.arcconf## files if they are present. Thus, you can generally upgrade a
- * workflow which does not require authentication into an authenticated
- * workflow by later invoking @{method:requireAuthentication}. You should not
- * normally need to call this method unless you are specifically overriding
- * the defaults.
- *
- * NOTE: You can not call this method after calling
- * @{method:authenticateConduit}.
- *
- * @param dict A credential dictionary, see @{method:authenticateConduit}.
- * @return this
- * @task conduit
- */
- final public function setConduitCredentials(array $credentials) {
- if ($this->isConduitAuthenticated()) {
- throw new Exception(
- 'You may not set new credentials after authenticating conduit.');
- }
-
- $this->conduitCredentials = $credentials;
- return $this;
- }
-
-
- /**
- * Force arc to identify with a specific Conduit version during the
- * protocol handshake. This is primarily useful for development (especially
- * for sending diffs which bump the client Conduit version), since the client
- * still actually speaks the builtin version of the protocol.
- *
- * Controlled by the --conduit-version flag.
- *
- * @param int Version the client should pretend to be.
- * @return this
- * @task conduit
- */
- final public function forceConduitVersion($version) {
- $this->forcedConduitVersion = $version;
- return $this;
- }
-
-
- /**
- * Get the protocol version the client should identify with.
- *
- * @return int Version the client should claim to be.
- * @task conduit
- */
- final public function getConduitVersion() {
- return nonempty($this->forcedConduitVersion, 6);
- }
-
-
- /**
- * Override the default timeout for Conduit.
- *
- * Controlled by the --conduit-timeout flag.
- *
- * @param float Timeout, in seconds.
- * @return this
- * @task conduit
- */
- final public function setConduitTimeout($timeout) {
- $this->conduitTimeout = $timeout;
- if ($this->conduit) {
- $this->conduit->setConduitTimeout($timeout);
- }
- return $this;
- }
-
-
- /**
- * Open and authenticate a conduit connection to a Phabricator server using
- * provided credentials. Normally, Arcanist does this for you automatically
- * when you return true from @{method:requiresAuthentication}, but you can
- * also upgrade an existing workflow to one with an authenticated conduit
- * by invoking this method manually.
- *
- * You must authenticate the conduit before you can make authenticated conduit
- * calls (almost all calls require authentication).
- *
- * This method uses credentials provided via @{method:setConduitCredentials}
- * to authenticate to the server:
- *
- * - ##user## (required) The username to authenticate with.
- * - ##certificate## (required) The Conduit certificate to use.
- * - ##description## (optional) Description of the invoking command.
- *
- * Successful authentication allows you to call @{method:getUserPHID} and
- * @{method:getUserName}, as well as use the client you access with
- * @{method:getConduit} to make authenticated calls.
- *
- * NOTE: You must call @{method:setConduitURI} and
- * @{method:setConduitCredentials} before you invoke this method.
- *
- * @return this
- * @task conduit
- */
- final public function authenticateConduit() {
- if ($this->isConduitAuthenticated()) {
- return $this;
- }
-
- $this->establishConduit();
- $credentials = $this->conduitCredentials;
-
- try {
- if (!$credentials) {
- throw new Exception(
- 'Set conduit credentials with setConduitCredentials() before '.
- 'authenticating conduit!');
- }
-
- if (empty($credentials['user'])) {
- throw new ConduitClientException(
- 'ERR-INVALID-USER',
- 'Empty user in credentials.');
- }
- if (empty($credentials['certificate'])) {
- throw new ConduitClientException(
- 'ERR-NO-CERTIFICATE',
- 'Empty certificate in credentials.');
- }
-
- $description = idx($credentials, 'description', '');
- $user = $credentials['user'];
- $certificate = $credentials['certificate'];
-
- $connection = $this->getConduit()->callMethodSynchronous(
- 'conduit.connect',
- array(
- 'client' => 'arc',
- 'clientVersion' => $this->getConduitVersion(),
- 'clientDescription' => php_uname('n').':'.$description,
- 'user' => $user,
- 'certificate' => $certificate,
- 'host' => $this->conduitURI,
- ));
- } catch (ConduitClientException $ex) {
- if ($ex->getErrorCode() == 'ERR-NO-CERTIFICATE' ||
- $ex->getErrorCode() == 'ERR-INVALID-USER') {
- $conduit_uri = $this->conduitURI;
- $message =
- "\n".
- phutil_console_format(
- 'YOU NEED TO __INSTALL A CERTIFICATE__ TO LOGIN TO PHABRICATOR').
- "\n\n".
- phutil_console_format(
- ' To do this, run: **arc install-certificate**').
- "\n\n".
- "The server '{$conduit_uri}' rejected your request:".
- "\n".
- $ex->getMessage();
- throw new ArcanistUsageException($message);
- } else if ($ex->getErrorCode() == 'NEW-ARC-VERSION') {
-
- // Cleverly disguise this as being AWESOME!!!
-
- echo phutil_console_format("**New Version Available!**\n\n");
- echo phutil_console_wrap($ex->getMessage());
- echo "\n\n";
- echo "In most cases, arc can be upgraded automatically.\n";
-
- $ok = phutil_console_confirm(
- 'Upgrade arc now?',
- $default_no = false);
- if (!$ok) {
- throw $ex;
- }
-
- $root = dirname(phutil_get_library_root('arcanist'));
-
- chdir($root);
- $err = phutil_passthru('%s upgrade', $root.'/bin/arc');
- if (!$err) {
- echo "\nTry running your arc command again.\n";
- }
- exit(1);
- } else {
- throw $ex;
- }
- }
-
- $this->userName = $user;
- $this->userPHID = $connection['userPHID'];
-
- $this->conduitAuthenticated = true;
-
- return $this;
- }
-
- /**
- * @return bool True if conduit is authenticated, false otherwise.
- * @task conduit
- */
- final protected function isConduitAuthenticated() {
- return (bool)$this->conduitAuthenticated;
- }
-
-
- /**
- * Override this to return true if your workflow requires a conduit channel.
- * Arc will build the channel for you before your workflow executes. This
- * implies that you only need an unauthenticated channel; if you need
- * authentication, override @{method:requiresAuthentication}.
- *
- * @return bool True if arc should build a conduit channel before running
- * the workflow.
- * @task conduit
- */
- public function requiresConduit() {
- return false;
- }
-
-
- /**
- * Override this to return true if your workflow requires an authenticated
- * conduit channel. This implies that it requires a conduit. Arc will build
- * and authenticate the channel for you before the workflow executes.
- *
- * @return bool True if arc should build an authenticated conduit channel
- * before running the workflow.
- * @task conduit
- */
- public function requiresAuthentication() {
- return false;
- }
-
-
- /**
- * Returns the PHID for the user once they've authenticated via Conduit.
- *
- * @return phid Authenticated user PHID.
- * @task conduit
- */
- final public function getUserPHID() {
- if (!$this->userPHID) {
- $workflow = get_class($this);
- throw new Exception(
- "This workflow ('{$workflow}') requires authentication, override ".
- "requiresAuthentication() to return true.");
- }
- return $this->userPHID;
- }
-
- /**
- * Return the username for the user once they've authenticated via Conduit.
- *
- * @return string Authenticated username.
- * @task conduit
- */
- final public function getUserName() {
- return $this->userName;
- }
-
-
- /**
- * Get the established @{class@libphutil:ConduitClient} in order to make
- * Conduit method calls. Before the client is available it must be connected,
- * either implicitly by making @{method:requireConduit} or
- * @{method:requireAuthentication} return true, or explicitly by calling
- * @{method:establishConduit} or @{method:authenticateConduit}.
- *
- * @return @{class@libphutil:ConduitClient} Live conduit client.
- * @task conduit
- */
- final public function getConduit() {
- if (!$this->conduit) {
- $workflow = get_class($this);
- throw new Exception(
- "This workflow ('{$workflow}') requires a Conduit, override ".
- "requiresConduit() to return true.");
- }
- return $this->conduit;
- }
-
-
- final public function setArcanistConfiguration(
- ArcanistConfiguration $arcanist_configuration) {
-
- $this->arcanistConfiguration = $arcanist_configuration;
- return $this;
- }
-
- final public function getArcanistConfiguration() {
- return $this->arcanistConfiguration;
- }
-
- final public function setConfigurationManager(
- ArcanistConfigurationManager $arcanist_configuration_manager) {
-
- $this->configurationManager = $arcanist_configuration_manager;
- return $this;
- }
-
- final public function getConfigurationManager() {
- return $this->configurationManager;
- }
-
- public function requiresWorkingCopy() {
- return false;
- }
-
- public function desiresWorkingCopy() {
- return false;
- }
-
- public function requiresRepositoryAPI() {
- return false;
- }
-
- public function desiresRepositoryAPI() {
- return false;
- }
-
- final public function setCommand($command) {
- $this->command = $command;
- return $this;
- }
-
- final public function getCommand() {
- return $this->command;
- }
-
- public function getArguments() {
- return array();
- }
-
- final public function setWorkingDirectory($working_directory) {
- $this->workingDirectory = $working_directory;
- return $this;
- }
-
- final public function getWorkingDirectory() {
- return $this->workingDirectory;
- }
-
- final private function setParentWorkflow($parent_workflow) {
- $this->parentWorkflow = $parent_workflow;
- return $this;
- }
-
- final protected function getParentWorkflow() {
- return $this->parentWorkflow;
- }
-
- final public function buildChildWorkflow($command, array $argv) {
- $arc_config = $this->getArcanistConfiguration();
- $workflow = $arc_config->buildWorkflow($command);
- $workflow->setParentWorkflow($this);
- $workflow->setCommand($command);
- $workflow->setConfigurationManager($this->getConfigurationManager());
-
- if ($this->repositoryAPI) {
- $workflow->setRepositoryAPI($this->repositoryAPI);
- }
-
- if ($this->userPHID) {
- $workflow->userPHID = $this->getUserPHID();
- $workflow->userName = $this->getUserName();
- }
-
- if ($this->conduit) {
- $workflow->conduit = $this->conduit;
- }
-
- if ($this->workingCopy) {
- $workflow->setWorkingCopy($this->workingCopy);
- }
-
- $workflow->setArcanistConfiguration($arc_config);
-
- $workflow->parseArguments(array_values($argv));
-
- return $workflow;
- }
-
- final public function getArgument($key, $default = null) {
- return idx($this->arguments, $key, $default);
- }
-
- final public function getPassedArguments() {
- return $this->passedArguments;
- }
-
- final public function getCompleteArgumentSpecification() {
- $spec = $this->getArguments();
- $arc_config = $this->getArcanistConfiguration();
- $command = $this->getCommand();
- $spec += $arc_config->getCustomArgumentsForCommand($command);
-
- return $spec;
- }
-
- final public function parseArguments(array $args) {
- $this->passedArguments = $args;
-
- $spec = $this->getCompleteArgumentSpecification();
-
- $dict = array();
-
- $more_key = null;
- if (!empty($spec['*'])) {
- $more_key = $spec['*'];
- unset($spec['*']);
- $dict[$more_key] = array();
- }
-
- $short_to_long_map = array();
- foreach ($spec as $long => $options) {
- if (!empty($options['short'])) {
- $short_to_long_map[$options['short']] = $long;
- }
- }
-
- foreach ($spec as $long => $options) {
- if (!empty($options['repeat'])) {
- $dict[$long] = array();
- }
- }
-
- $more = array();
- for ($ii = 0; $ii < count($args); $ii++) {
- $arg = $args[$ii];
- $arg_name = null;
- $arg_key = null;
- if ($arg == '--') {
- $more = array_merge(
- $more,
- array_slice($args, $ii + 1));
- break;
- } else if (!strncmp($arg, '--', 2)) {
- $arg_key = substr($arg, 2);
- if (!array_key_exists($arg_key, $spec)) {
- $corrected = ArcanistConfiguration::correctArgumentSpelling(
- $arg_key,
- array_keys($spec));
- if (count($corrected) == 1) {
- PhutilConsole::getConsole()->writeErr(
- pht(
- "(Assuming '%s' is the British spelling of '%s'.)",
- '--'.$arg_key,
- '--'.head($corrected))."\n");
- $arg_key = head($corrected);
- } else {
- throw new ArcanistUsageException(pht(
- "Unknown argument '%s'. Try 'arc help'.",
- $arg_key));
- }
- }
- } else if (!strncmp($arg, '-', 1)) {
- $arg_key = substr($arg, 1);
- if (empty($short_to_long_map[$arg_key])) {
- throw new ArcanistUsageException(pht(
- "Unknown argument '%s'. Try 'arc help'.",
- $arg_key));
- }
- $arg_key = $short_to_long_map[$arg_key];
- } else {
- $more[] = $arg;
- continue;
- }
-
- $options = $spec[$arg_key];
- if (empty($options['param'])) {
- $dict[$arg_key] = true;
- } else {
- if ($ii == count($args) - 1) {
- throw new ArcanistUsageException(pht(
- "Option '%s' requires a parameter.",
- $arg));
- }
- if (!empty($options['repeat'])) {
- $dict[$arg_key][] = $args[$ii + 1];
- } else {
- $dict[$arg_key] = $args[$ii + 1];
- }
- $ii++;
- }
- }
-
- if ($more) {
- if ($more_key) {
- $dict[$more_key] = $more;
- } else {
- $example = reset($more);
- throw new ArcanistUsageException(pht(
- "Unrecognized argument '%s'. Try 'arc help'.",
- $example));
- }
- }
-
- foreach ($dict as $key => $value) {
- if (empty($spec[$key]['conflicts'])) {
- continue;
- }
- foreach ($spec[$key]['conflicts'] as $conflict => $more) {
- if (isset($dict[$conflict])) {
- if ($more) {
- $more = ': '.$more;
- } else {
- $more = '.';
- }
- // TODO: We'll always display these as long-form, when the user might
- // have typed them as short form.
- throw new ArcanistUsageException(
- "Arguments '--{$key}' and '--{$conflict}' are mutually exclusive".
- $more);
- }
- }
- }
-
- $this->arguments = $dict;
-
- $this->didParseArguments();
-
- return $this;
- }
-
- protected function didParseArguments() {
- // Override this to customize workflow argument behavior.
- }
-
- final public function getWorkingCopy() {
- $working_copy = $this->getConfigurationManager()->getWorkingCopyIdentity();
- if (!$working_copy) {
- $workflow = get_class($this);
- throw new Exception(
- "This workflow ('{$workflow}') requires a working copy, override ".
- "requiresWorkingCopy() to return true.");
- }
- return $working_copy;
- }
-
- final public function setWorkingCopy(
- ArcanistWorkingCopyIdentity $working_copy) {
- $this->workingCopy = $working_copy;
- return $this;
- }
-
- final public function setRepositoryAPI($api) {
- $this->repositoryAPI = $api;
- return $this;
- }
-
- final public function hasRepositoryAPI() {
- try {
- return (bool)$this->getRepositoryAPI();
- } catch (Exception $ex) {
- return false;
- }
- }
-
- final public function getRepositoryAPI() {
- if (!$this->repositoryAPI) {
- $workflow = get_class($this);
- throw new Exception(
- "This workflow ('{$workflow}') requires a Repository API, override ".
- "requiresRepositoryAPI() to return true.");
- }
- return $this->repositoryAPI;
- }
-
- final protected function shouldRequireCleanUntrackedFiles() {
- return empty($this->arguments['allow-untracked']);
- }
-
- final public function setCommitMode($mode) {
- $this->commitMode = $mode;
- return $this;
- }
-
- final public function finalizeWorkingCopy() {
- if ($this->stashed) {
- $api = $this->getRepositoryAPI();
- $api->unstashChanges();
- echo pht('Restored stashed changes to the working directory.')."\n";
- }
- }
-
- final public function requireCleanWorkingCopy() {
- $api = $this->getRepositoryAPI();
-
- $must_commit = array();
-
- $working_copy_desc = phutil_console_format(
- " Working copy: __%s__\n\n",
- $api->getPath());
-
- $untracked = $api->getUntrackedChanges();
- if ($this->shouldRequireCleanUntrackedFiles()) {
-
- if (!empty($untracked)) {
- echo "You have untracked files in this working copy.\n\n".
- $working_copy_desc.
- " Untracked files in working copy:\n".
- " ".implode("\n ", $untracked)."\n\n";
-
- if ($api instanceof ArcanistGitAPI) {
- echo phutil_console_wrap(
- "Since you don't have '.gitignore' rules for these files and have ".
- "not listed them in '.git/info/exclude', you may have forgotten ".
- "to 'git add' them to your commit.\n");
- } else if ($api instanceof ArcanistSubversionAPI) {
- echo phutil_console_wrap(
- "Since you don't have 'svn:ignore' rules for these files, you may ".
- "have forgotten to 'svn add' them.\n");
- } else if ($api instanceof ArcanistMercurialAPI) {
- echo phutil_console_wrap(
- "Since you don't have '.hgignore' rules for these files, you ".
- "may have forgotten to 'hg add' them to your commit.\n");
- }
-
- if ($this->askForAdd($untracked)) {
- $api->addToCommit($untracked);
- $must_commit += array_flip($untracked);
- } else if ($this->commitMode == self::COMMIT_DISABLE) {
- $prompt = $this->getAskForAddPrompt($untracked);
- if (phutil_console_confirm($prompt)) {
- throw new ArcanistUsageException(pht(
- "Add these files and then run 'arc %s' again.",
- $this->getWorkflowName()));
- }
- }
-
- }
- }
-
- // NOTE: this is a subversion-only concept.
- $incomplete = $api->getIncompleteChanges();
- if ($incomplete) {
- throw new ArcanistUsageException(
- "You have incompletely checked out directories in this working copy. ".
- "Fix them before proceeding.\n\n".
- $working_copy_desc.
- " Incomplete directories in working copy:\n".
- " ".implode("\n ", $incomplete)."\n\n".
- "You can fix these paths by running 'svn update' on them.");
- }
-
- $conflicts = $api->getMergeConflicts();
- if ($conflicts) {
- throw new ArcanistUsageException(
- "You have merge conflicts in this working copy. Resolve merge ".
- "conflicts before proceeding.\n\n".
- $working_copy_desc.
- " Conflicts in working copy:\n".
- " ".implode("\n ", $conflicts)."\n");
- }
-
- $missing = $api->getMissingChanges();
- if ($missing) {
- throw new ArcanistUsageException(
- pht(
- "You have missing files in this working copy. Revert or formally ".
- "remove them (with `svn rm`) before proceeding.\n\n".
- "%s".
- " Missing files in working copy:\n%s\n",
- $working_copy_desc,
- " ".implode("\n ", $missing)));
- }
-
- $unstaged = $api->getUnstagedChanges();
- if ($unstaged) {
- echo "You have unstaged changes in this working copy.\n\n".
- $working_copy_desc.
- " Unstaged changes in working copy:\n".
- " ".implode("\n ", $unstaged)."\n";
- if ($this->askForAdd($unstaged)) {
- $api->addToCommit($unstaged);
- $must_commit += array_flip($unstaged);
- } else {
- $permit_autostash = $this->getConfigFromAnySource(
- 'arc.autostash',
- false);
- if ($permit_autostash && $api->canStashChanges()) {
- echo "Stashing uncommitted changes. (You can restore them with ".
- "`git stash pop`.)\n";
- $api->stashChanges();
- $this->stashed = true;
- } else {
- throw new ArcanistUsageException(
- 'Stage and commit (or revert) them before proceeding.');
- }
- }
- }
-
- $uncommitted = $api->getUncommittedChanges();
- foreach ($uncommitted as $key => $path) {
- if (array_key_exists($path, $must_commit)) {
- unset($uncommitted[$key]);
- }
- }
- if ($uncommitted) {
- echo "You have uncommitted changes in this working copy.\n\n".
- $working_copy_desc.
- " Uncommitted changes in working copy:\n".
- " ".implode("\n ", $uncommitted)."\n";
- if ($this->askForAdd($uncommitted)) {
- $must_commit += array_flip($uncommitted);
- } else {
- throw new ArcanistUncommittedChangesException(
- 'Commit (or revert) them before proceeding.');
- }
- }
-
- if ($must_commit) {
- if ($this->getShouldAmend()) {
- $commit = head($api->getLocalCommitInformation());
- $api->amendCommit($commit['message']);
- } else if ($api->supportsLocalCommits()) {
- $commit_message = phutil_console_prompt('Enter commit message:');
- if ($commit_message == '') {
- $commit_message = self::AUTO_COMMIT_TITLE;
- }
- $api->doCommit($commit_message);
- }
- }
- }
-
- private function getShouldAmend() {
- if ($this->shouldAmend === null) {
- $this->shouldAmend = $this->calculateShouldAmend();
- }
- return $this->shouldAmend;
- }
-
- private function calculateShouldAmend() {
- $api = $this->getRepositoryAPI();
-
- if ($this->isHistoryImmutable() || !$api->supportsAmend()) {
- return false;
- }
-
- $commits = $api->getLocalCommitInformation();
- if (!$commits) {
- return false;
- }
-
- $commit = reset($commits);
- $message = ArcanistDifferentialCommitMessage::newFromRawCorpus(
- $commit['message']);
-
- if ($message->getGitSVNBaseRevision()) {
- return false;
- }
-
- if ($api->getAuthor() != $commit['author']) {
- return false;
- }
-
- if ($message->getRevisionID() && $this->getArgument('create')) {
- return false;
- }
-
- // TODO: Check commits since tracking branch. If empty then return false.
-
- $repository = $this->loadProjectRepository();
- if ($repository) {
- $callsign = $repository['callsign'];
- $known_commits = $this->getConduit()->callMethodSynchronous(
- 'diffusion.getcommits',
- array('commits' => array('r'.$callsign.$commit['commit'])));
- if (ifilter($known_commits, 'error', $negate = true)) {
- return false;
- }
- }
-
- if (!$message->getRevisionID()) {
- return true;
- }
-
- $in_working_copy = $api->loadWorkingCopyDifferentialRevisions(
- $this->getConduit(),
- array(
- 'authors' => array($this->getUserPHID()),
- 'status' => 'status-open',
- ));
- if ($in_working_copy) {
- return true;
- }
-
- return false;
- }
-
- private function askForAdd(array $files) {
- if ($this->commitMode == self::COMMIT_DISABLE) {
- return false;
- }
- if ($this->commitMode == self::COMMIT_ENABLE) {
- return true;
- }
- $prompt = $this->getAskForAddPrompt($files);
- return phutil_console_confirm($prompt);
- }
-
- private function getAskForAddPrompt(array $files) {
- if ($this->getShouldAmend()) {
- $prompt = pht(
- 'Do you want to amend these files to the commit?',
- count($files));
- } else {
- $prompt = pht(
- 'Do you want to add these files to the commit?',
- count($files));
- }
- return $prompt;
- }
-
- final protected function loadDiffBundleFromConduit(
- ConduitClient $conduit,
- $diff_id) {
-
- return $this->loadBundleFromConduit(
- $conduit,
- array(
- 'diff_id' => $diff_id,
- ));
- }
-
- final protected function loadRevisionBundleFromConduit(
- ConduitClient $conduit,
- $revision_id) {
-
- return $this->loadBundleFromConduit(
- $conduit,
- array(
- 'revision_id' => $revision_id,
- ));
- }
-
- final private function loadBundleFromConduit(
- ConduitClient $conduit,
- $params) {
-
- $future = $conduit->callMethod('differential.getdiff', $params);
- $diff = $future->resolve();
-
- $changes = array();
- foreach ($diff['changes'] as $changedict) {
- $changes[] = ArcanistDiffChange::newFromDictionary($changedict);
- }
- $bundle = ArcanistBundle::newFromChanges($changes);
- $bundle->setConduit($conduit);
- // since the conduit method has changes, assume that these fields
- // could be unset
- $bundle->setProjectID(idx($diff, 'projectName'));
- $bundle->setBaseRevision(idx($diff, 'sourceControlBaseRevision'));
- $bundle->setRevisionID(idx($diff, 'revisionID'));
- $bundle->setAuthorName(idx($diff, 'authorName'));
- $bundle->setAuthorEmail(idx($diff, 'authorEmail'));
- return $bundle;
- }
-
- /**
- * Return a list of lines changed by the current diff, or ##null## if the
- * change list is meaningless (for example, because the path is a directory
- * or binary file).
- *
- * @param string Path within the repository.
- * @param string Change selection mode (see ArcanistDiffHunk).
- * @return list|null List of changed line numbers, or null to indicate that
- * the path is not a line-oriented text file.
- */
- final protected function getChangedLines($path, $mode) {
- $repository_api = $this->getRepositoryAPI();
- $full_path = $repository_api->getPath($path);
- if (is_dir($full_path)) {
- return null;
- }
-
- if (!file_exists($full_path)) {
- return null;
- }
-
- $change = $this->getChange($path);
-
- if ($change->getFileType() !== ArcanistDiffChangeType::FILE_TEXT) {
- return null;
- }
-
- $lines = $change->getChangedLines($mode);
- return array_keys($lines);
- }
-
- final protected function getChange($path) {
- $repository_api = $this->getRepositoryAPI();
-
- // TODO: Very gross
- $is_git = ($repository_api instanceof ArcanistGitAPI);
- $is_hg = ($repository_api instanceof ArcanistMercurialAPI);
- $is_svn = ($repository_api instanceof ArcanistSubversionAPI);
-
- if ($is_svn) {
- // NOTE: In SVN, we don't currently support a "get all local changes"
- // operation, so special case it.
- if (empty($this->changeCache[$path])) {
- $diff = $repository_api->getRawDiffText($path);
- $parser = $this->newDiffParser();
- $changes = $parser->parseDiff($diff);
- if (count($changes) != 1) {
- throw new Exception('Expected exactly one change.');
- }
- $this->changeCache[$path] = reset($changes);
- }
- } else if ($is_git || $is_hg) {
- if (empty($this->changeCache)) {
- $changes = $repository_api->getAllLocalChanges();
- foreach ($changes as $change) {
- $this->changeCache[$change->getCurrentPath()] = $change;
- }
- }
- } else {
- throw new Exception('Missing VCS support.');
- }
-
- if (empty($this->changeCache[$path])) {
- if ($is_git || $is_hg) {
- // This can legitimately occur under git/hg if you make a change,
- // "git/hg commit" it, and then revert the change in the working copy
- // and run "arc lint".
- $change = new ArcanistDiffChange();
- $change->setCurrentPath($path);
- return $change;
- } else {
- throw new Exception(
- "Trying to get change for unchanged path '{$path}'!");
- }
- }
-
- return $this->changeCache[$path];
- }
-
- final public function willRunWorkflow() {
- $spec = $this->getCompleteArgumentSpecification();
- foreach ($this->arguments as $arg => $value) {
- if (empty($spec[$arg])) {
- continue;
- }
- $options = $spec[$arg];
- if (!empty($options['supports'])) {
- $system_name = $this->getRepositoryAPI()->getSourceControlSystemName();
- if (!in_array($system_name, $options['supports'])) {
- $extended_info = null;
- if (!empty($options['nosupport'][$system_name])) {
- $extended_info = ' '.$options['nosupport'][$system_name];
- }
- throw new ArcanistUsageException(
- "Option '--{$arg}' is not supported under {$system_name}.".
- $extended_info);
- }
- }
- }
- }
-
- final protected function normalizeRevisionID($revision_id) {
- return preg_replace('/^D/i', '', $revision_id);
- }
-
- protected function shouldShellComplete() {
- return true;
- }
-
- protected function getShellCompletions(array $argv) {
- return array();
- }
-
- protected function getSupportedRevisionControlSystems() {
- return array('any');
- }
-
- final protected function getPassthruArgumentsAsMap($command) {
- $map = array();
- foreach ($this->getCompleteArgumentSpecification() as $key => $spec) {
- if (!empty($spec['passthru'][$command])) {
- if (isset($this->arguments[$key])) {
- $map[$key] = $this->arguments[$key];
- }
- }
- }
- return $map;
- }
-
- final protected function getPassthruArgumentsAsArgv($command) {
- $spec = $this->getCompleteArgumentSpecification();
- $map = $this->getPassthruArgumentsAsMap($command);
- $argv = array();
- foreach ($map as $key => $value) {
- $argv[] = '--'.$key;
- if (!empty($spec[$key]['param'])) {
- $argv[] = $value;
- }
- }
- return $argv;
- }
-
- /**
- * Write a message to stderr so that '--json' flags or stdout which is meant
- * to be piped somewhere aren't disrupted.
- *
- * @param string Message to write to stderr.
- * @return void
- */
- final protected function writeStatusMessage($msg) {
- fwrite(STDERR, $msg);
- }
-
- final protected function isHistoryImmutable() {
- $repository_api = $this->getRepositoryAPI();
-
- $config = $this->getConfigFromAnySource('history.immutable');
- if ($config !== null) {
- return $config;
- }
-
- return $repository_api->isHistoryDefaultImmutable();
- }
-
- /**
- * Workflows like 'lint' and 'unit' operate on a list of working copy paths.
- * The user can either specify the paths explicitly ("a.js b.php"), or by
- * specifying a revision ("--rev a3f10f1f") to select all paths modified
- * since that revision, or by omitting both and letting arc choose the
- * default relative revision.
- *
- * This method takes the user's selections and returns the paths that the
- * workflow should act upon.
- *
- * @param list List of explicitly provided paths.
- * @param string|null Revision name, if provided.
- * @param mask Mask of ArcanistRepositoryAPI flags to exclude.
- * Defaults to ArcanistRepositoryAPI::FLAG_UNTRACKED.
- * @return list List of paths the workflow should act on.
- */
- final protected function selectPathsForWorkflow(
- array $paths,
- $rev,
- $omit_mask = null) {
-
- if ($omit_mask === null) {
- $omit_mask = ArcanistRepositoryAPI::FLAG_UNTRACKED;
- }
-
- if ($paths) {
- $working_copy = $this->getWorkingCopy();
- foreach ($paths as $key => $path) {
- $full_path = Filesystem::resolvePath($path);
- if (!Filesystem::pathExists($full_path)) {
- throw new ArcanistUsageException("Path '{$path}' does not exist!");
- }
- $relative_path = Filesystem::readablePath(
- $full_path,
- $working_copy->getProjectRoot());
- $paths[$key] = $relative_path;
- }
- } else {
- $repository_api = $this->getRepositoryAPI();
-
- if ($rev) {
- $this->parseBaseCommitArgument(array($rev));
- }
-
- $paths = $repository_api->getWorkingCopyStatus();
- foreach ($paths as $path => $flags) {
- if ($flags & $omit_mask) {
- unset($paths[$path]);
- }
- }
- $paths = array_keys($paths);
- }
-
- return array_values($paths);
- }
-
- final protected function renderRevisionList(array $revisions) {
- $list = array();
- foreach ($revisions as $revision) {
- $list[] = ' - D'.$revision['id'].': '.$revision['title']."\n";
- }
- return implode('', $list);
- }
-
-
-/* -( Scratch Files )------------------------------------------------------ */
-
-
- /**
- * Try to read a scratch file, if it exists and is readable.
- *
- * @param string Scratch file name.
- * @return mixed String for file contents, or false for failure.
- * @task scratch
- */
- final protected function readScratchFile($path) {
- if (!$this->repositoryAPI) {
- return false;
- }
- return $this->getRepositoryAPI()->readScratchFile($path);
- }
-
-
- /**
- * Try to read a scratch JSON file, if it exists and is readable.
- *
- * @param string Scratch file name.
- * @return array Empty array for failure.
- * @task scratch
- */
- final protected function readScratchJSONFile($path) {
- $file = $this->readScratchFile($path);
- if (!$file) {
- return array();
- }
- return json_decode($file, true);
- }
-
-
- /**
- * Try to write a scratch file, if there's somewhere to put it and we can
- * write there.
- *
- * @param string Scratch file name to write.
- * @param string Data to write.
- * @return bool True on success, false on failure.
- * @task scratch
- */
- final protected function writeScratchFile($path, $data) {
- if (!$this->repositoryAPI) {
- return false;
- }
- return $this->getRepositoryAPI()->writeScratchFile($path, $data);
- }
-
-
- /**
- * Try to write a scratch JSON file, if there's somewhere to put it and we can
- * write there.
- *
- * @param string Scratch file name to write.
- * @param array Data to write.
- * @return bool True on success, false on failure.
- * @task scratch
- */
- final protected function writeScratchJSONFile($path, array $data) {
- return $this->writeScratchFile($path, json_encode($data));
- }
-
-
- /**
- * Try to remove a scratch file.
- *
- * @param string Scratch file name to remove.
- * @return bool True if the file was removed successfully.
- * @task scratch
- */
- final protected function removeScratchFile($path) {
- if (!$this->repositoryAPI) {
- return false;
- }
- return $this->getRepositoryAPI()->removeScratchFile($path);
- }
-
-
- /**
- * Get a human-readable description of the scratch file location.
- *
- * @param string Scratch file name.
- * @return mixed String, or false on failure.
- * @task scratch
- */
- final protected function getReadableScratchFilePath($path) {
- if (!$this->repositoryAPI) {
- return false;
- }
- return $this->getRepositoryAPI()->getReadableScratchFilePath($path);
- }
-
-
- /**
- * Get the path to a scratch file, if possible.
- *
- * @param string Scratch file name.
- * @return mixed File path, or false on failure.
- * @task scratch
- */
- final protected function getScratchFilePath($path) {
- if (!$this->repositoryAPI) {
- return false;
- }
- return $this->getRepositoryAPI()->getScratchFilePath($path);
- }
-
- final protected function getRepositoryEncoding() {
- $default = 'UTF-8';
- return nonempty(idx($this->getProjectInfo(), 'encoding'), $default);
- }
-
- final protected function getProjectInfo() {
- if ($this->projectInfo === null) {
- $project_id = $this->getWorkingCopy()->getProjectID();
- if (!$project_id) {
- $this->projectInfo = array();
- } else {
- try {
- $this->projectInfo = $this->getConduit()->callMethodSynchronous(
- 'arcanist.projectinfo',
- array(
- 'name' => $project_id,
- ));
- } catch (ConduitClientException $ex) {
- if ($ex->getErrorCode() != 'ERR-BAD-ARCANIST-PROJECT') {
- throw $ex;
- }
-
- // TODO: Implement a proper query method that doesn't throw on
- // project not found. We just swallow this because some pathways,
- // like Git with uncommitted changes in a repository with a new
- // project ID, may attempt to access project information before
- // the project is created. See T2153.
- return array();
- }
- }
- }
-
- return $this->projectInfo;
- }
-
- final protected function loadProjectRepository() {
- $project = $this->getProjectInfo();
- if (isset($project['repository'])) {
- return $project['repository'];
- }
- // NOTE: The rest of the code is here for backwards compatibility.
-
- $repository_phid = idx($project, 'repositoryPHID');
- if (!$repository_phid) {
- return array();
- }
-
- $repositories = $this->getConduit()->callMethodSynchronous(
- 'repository.query',
- array());
- $repositories = ipull($repositories, null, 'phid');
-
- return idx($repositories, $repository_phid, array());
- }
-
- final protected function newInteractiveEditor($text) {
- $editor = new PhutilInteractiveEditor($text);
-
- $preferred = $this->getConfigFromAnySource('editor');
- if ($preferred) {
- $editor->setPreferredEditor($preferred);
- }
-
- return $editor;
- }
-
- final protected function newDiffParser() {
- $parser = new ArcanistDiffParser();
- if ($this->repositoryAPI) {
- $parser->setRepositoryAPI($this->getRepositoryAPI());
- }
- $parser->setWriteDiffOnFailure(true);
- return $parser;
- }
-
- final protected function resolveCall(ConduitFuture $method, $timeout = null) {
- try {
- return $method->resolve($timeout);
- } catch (ConduitClientException $ex) {
- if ($ex->getErrorCode() == 'ERR-CONDUIT-CALL') {
- echo phutil_console_wrap(
- "This feature requires a newer version of Phabricator. Please ".
- "update it using these instructions: ".
- "http://www.phabricator.com/docs/phabricator/article/".
- "Installation_Guide.html#updating-phabricator\n\n");
- }
- throw $ex;
- }
- }
-
- final protected function dispatchEvent($type, array $data) {
- $data += array(
- 'workflow' => $this,
- );
-
- $event = new PhutilEvent($type, $data);
- PhutilEventEngine::dispatchEvent($event);
-
- return $event;
- }
-
- final public function parseBaseCommitArgument(array $argv) {
- if (!count($argv)) {
- return;
- }
-
- $api = $this->getRepositoryAPI();
- if (!$api->supportsCommitRanges()) {
- throw new ArcanistUsageException(
- 'This version control system does not support commit ranges.');
- }
-
- if (count($argv) > 1) {
- throw new ArcanistUsageException(
- 'Specify exactly one base commit. The end of the commit range is '.
- 'always the working copy state.');
- }
-
- $api->setBaseCommit(head($argv));
-
- return $this;
- }
-
- final protected function getRepositoryVersion() {
- if (!$this->repositoryVersion) {
- $api = $this->getRepositoryAPI();
- $commit = $api->getSourceControlBaseRevision();
- $versions = array('' => $commit);
- foreach ($api->getChangedFiles($commit) as $path => $mask) {
- $versions[$path] = (Filesystem::pathExists($path)
- ? md5_file($path)
- : '');
- }
- $this->repositoryVersion = md5(json_encode($versions));
- }
- return $this->repositoryVersion;
- }
-
-
-/* -( Phabricator Repositories )------------------------------------------- */
-
-
- /**
- * Get the PHID of the Phabricator repository this working copy corresponds
- * to. Returns `null` if no repository can be identified.
- *
- * @return phid|null Repository PHID, or null if no repository can be
- * identified.
- *
- * @task phabrep
- */
- final protected function getRepositoryPHID() {
- return idx($this->getRepositoryInformation(), 'phid');
- }
-
-
- /**
- * Get the callsign of the Phabricator repository this working copy
- * corresponds to. Returns `null` if no repository can be identified.
- *
- * @return string|null Repository callsign, or null if no repository can be
- * identified.
- *
- * @task phabrep
- */
- final protected function getRepositoryCallsign() {
- return idx($this->getRepositoryInformation(), 'callsign');
- }
-
-
- /**
- * Get the URI of the Phabricator repository this working copy
- * corresponds to. Returns `null` if no repository can be identified.
- *
- * @return string|null Repository URI, or null if no repository can be
- * identified.
- *
- * @task phabrep
- */
- final protected function getRepositoryURI() {
- return idx($this->getRepositoryInformation(), 'uri');
- }
-
-
- /**
- * Get human-readable reasoning explaining how `arc` evaluated which
- * Phabricator repository corresponds to this working copy. Used by
- * `arc which` to explain the process to users.
- *
- * @return list<string> Human-readable explanation of the repository
- * association process.
- *
- * @task phabrep
- */
- final protected function getRepositoryReasons() {
- $this->getRepositoryInformation();
- return $this->repositoryReasons;
- }
-
-
- /**
- * @task phabrep
- */
- private function getRepositoryInformation() {
- if ($this->repositoryInfo === null) {
- list($info, $reasons) = $this->loadRepositoryInformation();
- $this->repositoryInfo = nonempty($info, array());
- $this->repositoryReasons = $reasons;
- }
-
- return $this->repositoryInfo;
- }
-
-
- /**
- * @task phabrep
- */
- private function loadRepositoryInformation() {
- list($query, $reasons) = $this->getRepositoryQuery();
- if (!$query) {
- return array(null, $reasons);
- }
-
- try {
- $results = $this->getConduit()->callMethodSynchronous(
- 'repository.query',
- $query);
- } catch (ConduitClientException $ex) {
- if ($ex->getErrorCode() == 'ERR-CONDUIT-CALL') {
- $reasons[] = pht(
- 'This version of Arcanist is more recent than the version of '.
- 'Phabricator you are connecting to: the Phabricator install is '.
- 'out of date and does not have support for identifying '.
- 'repositories by callsign or URI. Update Phabricator to enable '.
- 'these features.');
- return array(null, $reasons);
- }
- throw $ex;
- }
-
- $result = null;
- if (!$results) {
- $reasons[] = pht(
- 'No repositories matched the query. Check that your configuration '.
- 'is correct, or use "repository.callsign" to select a repository '.
- 'explicitly.');
- } else if (count($results) > 1) {
- $reasons[] = pht(
- 'Multiple repostories (%s) matched the query. You can use the '.
- '"repository.callsign" configuration to select the one you want.',
- implode(', ', ipull($results, 'callsign')));
- } else {
- $result = head($results);
- $reasons[] = pht('Found a unique matching repository.');
- }
-
- return array($result, $reasons);
- }
-
-
- /**
- * @task phabrep
- */
- private function getRepositoryQuery() {
- $reasons = array();
-
- $callsign = $this->getConfigFromAnySource('repository.callsign');
- if ($callsign) {
- $query = array(
- 'callsigns' => array($callsign),
- );
- $reasons[] = pht(
- 'Configuration value "repository.callsign" is set to "%s".',
- $callsign);
- return array($query, $reasons);
- } else {
- $reasons[] = pht(
- 'Configuration value "repository.callsign" is empty.');
- }
-
- $project_info = $this->getProjectInfo();
- $project_name = $this->getWorkingCopy()->getProjectID();
- if ($this->getProjectInfo()) {
- if (!empty($project_info['repository']['callsign'])) {
- $callsign = $project_info['repository']['callsign'];
- $query = array(
- 'callsigns' => array($callsign),
- );
- $reasons[] = pht(
- 'Configuration value "project.name" is set to "%s"; this project '.
- 'is associated with the "%s" repository.',
- $project_name,
- $callsign);
- return array($query, $reasons);
- } else {
- $reasons[] = pht(
- 'Configuration value "project.name" is set to "%s", but this '.
- 'project is not associated with a repository.',
- $project_name);
- }
- } else if (strlen($project_name)) {
- $reasons[] = pht(
- 'Configuration value "project.name" is set to "%s", but that '.
- 'project does not exist.',
- $project_name);
- } else {
- $reasons[] = pht(
- 'Configuration value "project.name" is empty.');
- }
-
- $uuid = $this->getRepositoryAPI()->getRepositoryUUID();
- if ($uuid !== null) {
- $query = array(
- 'uuids' => array($uuid),
- );
- $reasons[] = pht(
- 'The UUID for this working copy is "%s".',
- $uuid);
- return array($query, $reasons);
- } else {
- $reasons[] = pht(
- 'This repository has no VCS UUID (this is normal for git/hg).');
- }
-
- $remote_uri = $this->getRepositoryAPI()->getRemoteURI();
- if ($remote_uri !== null) {
- $query = array(
- 'remoteURIs' => array($remote_uri),
- );
- $reasons[] = pht(
- 'The remote URI for this working copy is "%s".',
- $remote_uri);
- return array($query, $reasons);
- } else {
- $reasons[] = pht(
- 'Unable to determine the remote URI for this repository.');
- }
-
- return array(null, $reasons);
- }
-
-
- /**
- * Build a new lint engine for the current working copy.
- *
- * Optionally, you can pass an explicit engine class name to build an engine
- * of a particular class. Normally this is used to implement an `--engine`
- * flag from the CLI.
- *
- * @param string Optional explicit engine class name.
- * @return ArcanistLintEngine Constructed engine.
- */
- protected function newLintEngine($engine_class = null) {
- $working_copy = $this->getWorkingCopy();
- $config = $this->getConfigurationManager();
-
- if (!$engine_class) {
- $engine_class = $config->getConfigFromAnySource('lint.engine');
- }
-
- if (!$engine_class) {
- if (Filesystem::pathExists($working_copy->getProjectPath('.arclint'))) {
- $engine_class = 'ArcanistConfigurationDrivenLintEngine';
- }
- }
-
- if (!$engine_class) {
- throw new ArcanistNoEngineException(
- pht(
- "No lint engine is configured for this project. ".
- "Create an '.arclint' file, or configure an advanced engine ".
- "with 'lint.engine' in '.arcconfig'."));
- }
-
- $base_class = 'ArcanistLintEngine';
- if (!class_exists($engine_class) ||
- !is_subclass_of($engine_class, $base_class)) {
- throw new ArcanistUsageException(
- pht(
- 'Configured lint engine "%s" is not a subclass of "%s", but must '.
- 'be.',
- $engine_class,
- $base_class));
- }
-
- $engine = newv($engine_class, array())
- ->setWorkingCopy($working_copy)
- ->setConfigurationManager($config);
-
- return $engine;
- }
-
-}
+abstract class ArcanistBaseWorkflow extends ArcanistWorkflow {}
diff --git a/src/workflow/ArcanistBrowseWorkflow.php b/src/workflow/ArcanistBrowseWorkflow.php
--- a/src/workflow/ArcanistBrowseWorkflow.php
+++ b/src/workflow/ArcanistBrowseWorkflow.php
@@ -3,7 +3,7 @@
/**
* Browse files in the Diffusion web interface.
*/
-final class ArcanistBrowseWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistBrowseWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'browse';
diff --git a/src/workflow/ArcanistCallConduitWorkflow.php b/src/workflow/ArcanistCallConduitWorkflow.php
--- a/src/workflow/ArcanistCallConduitWorkflow.php
+++ b/src/workflow/ArcanistCallConduitWorkflow.php
@@ -3,7 +3,7 @@
/**
* Provides command-line access to the Conduit API.
*/
-final class ArcanistCallConduitWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistCallConduitWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'call-conduit';
diff --git a/src/workflow/ArcanistCloseRevisionWorkflow.php b/src/workflow/ArcanistCloseRevisionWorkflow.php
--- a/src/workflow/ArcanistCloseRevisionWorkflow.php
+++ b/src/workflow/ArcanistCloseRevisionWorkflow.php
@@ -3,7 +3,7 @@
/**
* Explicitly closes Differential revisions.
*/
-final class ArcanistCloseRevisionWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistCloseRevisionWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'close-revision';
diff --git a/src/workflow/ArcanistCloseWorkflow.php b/src/workflow/ArcanistCloseWorkflow.php
--- a/src/workflow/ArcanistCloseWorkflow.php
+++ b/src/workflow/ArcanistCloseWorkflow.php
@@ -3,7 +3,7 @@
/**
* Close a task.
*/
-final class ArcanistCloseWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistCloseWorkflow extends ArcanistWorkflow {
private $tasks;
private $statusOptions;
diff --git a/src/workflow/ArcanistCommitWorkflow.php b/src/workflow/ArcanistCommitWorkflow.php
--- a/src/workflow/ArcanistCommitWorkflow.php
+++ b/src/workflow/ArcanistCommitWorkflow.php
@@ -3,7 +3,7 @@
/**
* Executes "svn commit" once a revision has been "Accepted".
*/
-final class ArcanistCommitWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistCommitWorkflow extends ArcanistWorkflow {
private $revisionID;
diff --git a/src/workflow/ArcanistCoverWorkflow.php b/src/workflow/ArcanistCoverWorkflow.php
--- a/src/workflow/ArcanistCoverWorkflow.php
+++ b/src/workflow/ArcanistCoverWorkflow.php
@@ -3,7 +3,7 @@
/**
* Covers your professional reputation by blaming changes to locate reviewers.
*/
-final class ArcanistCoverWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistCoverWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'cover';
diff --git a/src/workflow/ArcanistDiffWorkflow.php b/src/workflow/ArcanistDiffWorkflow.php
--- a/src/workflow/ArcanistDiffWorkflow.php
+++ b/src/workflow/ArcanistDiffWorkflow.php
@@ -8,7 +8,7 @@
* @task diffspec Diff Specification
* @task diffprop Diff Properties
*/
-final class ArcanistDiffWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistDiffWorkflow extends ArcanistWorkflow {
private $console;
private $hasWarnedExternals = false;
diff --git a/src/workflow/ArcanistDownloadWorkflow.php b/src/workflow/ArcanistDownloadWorkflow.php
--- a/src/workflow/ArcanistDownloadWorkflow.php
+++ b/src/workflow/ArcanistDownloadWorkflow.php
@@ -3,7 +3,7 @@
/**
* Download a file from Phabricator.
*/
-final class ArcanistDownloadWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistDownloadWorkflow extends ArcanistWorkflow {
private $id;
private $saveAs;
diff --git a/src/workflow/ArcanistExportWorkflow.php b/src/workflow/ArcanistExportWorkflow.php
--- a/src/workflow/ArcanistExportWorkflow.php
+++ b/src/workflow/ArcanistExportWorkflow.php
@@ -3,7 +3,7 @@
/**
* Exports changes from Differential or the working copy to a file.
*/
-final class ArcanistExportWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistExportWorkflow extends ArcanistWorkflow {
const SOURCE_LOCAL = 'local';
const SOURCE_DIFF = 'diff';
diff --git a/src/workflow/ArcanistFeatureWorkflow.php b/src/workflow/ArcanistFeatureWorkflow.php
--- a/src/workflow/ArcanistFeatureWorkflow.php
+++ b/src/workflow/ArcanistFeatureWorkflow.php
@@ -5,7 +5,7 @@
*
* @concrete-extensible
*/
-class ArcanistFeatureWorkflow extends ArcanistBaseWorkflow {
+class ArcanistFeatureWorkflow extends ArcanistWorkflow {
private $branches;
diff --git a/src/workflow/ArcanistFlagWorkflow.php b/src/workflow/ArcanistFlagWorkflow.php
--- a/src/workflow/ArcanistFlagWorkflow.php
+++ b/src/workflow/ArcanistFlagWorkflow.php
@@ -1,6 +1,6 @@
<?php
-final class ArcanistFlagWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistFlagWorkflow extends ArcanistWorkflow {
private static $colorMap = array(
0 => 'red', // Red
diff --git a/src/workflow/ArcanistGetConfigWorkflow.php b/src/workflow/ArcanistGetConfigWorkflow.php
--- a/src/workflow/ArcanistGetConfigWorkflow.php
+++ b/src/workflow/ArcanistGetConfigWorkflow.php
@@ -3,7 +3,7 @@
/**
* Read configuration settings.
*/
-final class ArcanistGetConfigWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistGetConfigWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'get-config';
diff --git a/src/workflow/ArcanistGitHookPreReceiveWorkflow.php b/src/workflow/ArcanistGitHookPreReceiveWorkflow.php
--- a/src/workflow/ArcanistGitHookPreReceiveWorkflow.php
+++ b/src/workflow/ArcanistGitHookPreReceiveWorkflow.php
@@ -3,7 +3,7 @@
/**
* Installable as a git pre-receive hook.
*/
-final class ArcanistGitHookPreReceiveWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistGitHookPreReceiveWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'git-hook-pre-receive';
diff --git a/src/workflow/ArcanistHelpWorkflow.php b/src/workflow/ArcanistHelpWorkflow.php
--- a/src/workflow/ArcanistHelpWorkflow.php
+++ b/src/workflow/ArcanistHelpWorkflow.php
@@ -3,7 +3,7 @@
/**
* Seduces the reader with majestic prose.
*/
-final class ArcanistHelpWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistHelpWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'help';
diff --git a/src/workflow/ArcanistInlinesWorkflow.php b/src/workflow/ArcanistInlinesWorkflow.php
--- a/src/workflow/ArcanistInlinesWorkflow.php
+++ b/src/workflow/ArcanistInlinesWorkflow.php
@@ -1,6 +1,6 @@
<?php
-final class ArcanistInlinesWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistInlinesWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'inlines';
diff --git a/src/workflow/ArcanistInstallCertificateWorkflow.php b/src/workflow/ArcanistInstallCertificateWorkflow.php
--- a/src/workflow/ArcanistInstallCertificateWorkflow.php
+++ b/src/workflow/ArcanistInstallCertificateWorkflow.php
@@ -3,7 +3,7 @@
/**
* Installs arcanist certificates.
*/
-final class ArcanistInstallCertificateWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistInstallCertificateWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'install-certificate';
diff --git a/src/workflow/ArcanistLandWorkflow.php b/src/workflow/ArcanistLandWorkflow.php
--- a/src/workflow/ArcanistLandWorkflow.php
+++ b/src/workflow/ArcanistLandWorkflow.php
@@ -3,7 +3,7 @@
/**
* Lands a branch by rebasing, merging and amending it.
*/
-final class ArcanistLandWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistLandWorkflow extends ArcanistWorkflow {
private $isGit;
private $isGitSvn;
diff --git a/src/workflow/ArcanistLiberateWorkflow.php b/src/workflow/ArcanistLiberateWorkflow.php
--- a/src/workflow/ArcanistLiberateWorkflow.php
+++ b/src/workflow/ArcanistLiberateWorkflow.php
@@ -9,7 +9,7 @@
* definition it had when it first loaded. This is normally fine, but
* problematic in this case because `arc liberate` modifies library definitions.
*/
-final class ArcanistLiberateWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistLiberateWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'liberate';
diff --git a/src/workflow/ArcanistLintWorkflow.php b/src/workflow/ArcanistLintWorkflow.php
--- a/src/workflow/ArcanistLintWorkflow.php
+++ b/src/workflow/ArcanistLintWorkflow.php
@@ -3,7 +3,7 @@
/**
* Runs lint rules on changes.
*/
-final class ArcanistLintWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistLintWorkflow extends ArcanistWorkflow {
const RESULT_OKAY = 0;
const RESULT_WARNINGS = 1;
diff --git a/src/workflow/ArcanistLintersWorkflow.php b/src/workflow/ArcanistLintersWorkflow.php
--- a/src/workflow/ArcanistLintersWorkflow.php
+++ b/src/workflow/ArcanistLintersWorkflow.php
@@ -3,7 +3,7 @@
/**
* List available linters.
*/
-final class ArcanistLintersWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistLintersWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'linters';
diff --git a/src/workflow/ArcanistListWorkflow.php b/src/workflow/ArcanistListWorkflow.php
--- a/src/workflow/ArcanistListWorkflow.php
+++ b/src/workflow/ArcanistListWorkflow.php
@@ -3,7 +3,7 @@
/**
* Lists open revisions in Differential.
*/
-final class ArcanistListWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistListWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'list';
diff --git a/src/workflow/ArcanistPasteWorkflow.php b/src/workflow/ArcanistPasteWorkflow.php
--- a/src/workflow/ArcanistPasteWorkflow.php
+++ b/src/workflow/ArcanistPasteWorkflow.php
@@ -3,7 +3,7 @@
/**
* Upload a chunk of text to the Paste application, or download one.
*/
-final class ArcanistPasteWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistPasteWorkflow extends ArcanistWorkflow {
private $id;
private $language;
diff --git a/src/workflow/ArcanistPatchWorkflow.php b/src/workflow/ArcanistPatchWorkflow.php
--- a/src/workflow/ArcanistPatchWorkflow.php
+++ b/src/workflow/ArcanistPatchWorkflow.php
@@ -3,7 +3,7 @@
/**
* Applies changes from Differential or a file to the working copy.
*/
-final class ArcanistPatchWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistPatchWorkflow extends ArcanistWorkflow {
const SOURCE_BUNDLE = 'bundle';
const SOURCE_PATCH = 'patch';
diff --git a/src/workflow/ArcanistPhrequentWorkflow.php b/src/workflow/ArcanistPhrequentWorkflow.php
--- a/src/workflow/ArcanistPhrequentWorkflow.php
+++ b/src/workflow/ArcanistPhrequentWorkflow.php
@@ -3,7 +3,7 @@
/**
* Base workflow for Phrequent workflows
*/
-abstract class ArcanistPhrequentWorkflow extends ArcanistBaseWorkflow {
+abstract class ArcanistPhrequentWorkflow extends ArcanistWorkflow {
protected function printCurrentTracking() {
$conduit = $this->getConduit();
diff --git a/src/workflow/ArcanistRevertWorkflow.php b/src/workflow/ArcanistRevertWorkflow.php
--- a/src/workflow/ArcanistRevertWorkflow.php
+++ b/src/workflow/ArcanistRevertWorkflow.php
@@ -3,7 +3,7 @@
/**
* Redirects to `arc backout` workflow.
*/
-final class ArcanistRevertWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistRevertWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'revert';
diff --git a/src/workflow/ArcanistSetConfigWorkflow.php b/src/workflow/ArcanistSetConfigWorkflow.php
--- a/src/workflow/ArcanistSetConfigWorkflow.php
+++ b/src/workflow/ArcanistSetConfigWorkflow.php
@@ -3,7 +3,7 @@
/**
* Write configuration settings.
*/
-final class ArcanistSetConfigWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistSetConfigWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'set-config';
diff --git a/src/workflow/ArcanistShellCompleteWorkflow.php b/src/workflow/ArcanistShellCompleteWorkflow.php
--- a/src/workflow/ArcanistShellCompleteWorkflow.php
+++ b/src/workflow/ArcanistShellCompleteWorkflow.php
@@ -3,7 +3,7 @@
/**
* Powers shell-completion scripts.
*/
-final class ArcanistShellCompleteWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistShellCompleteWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'shell-complete';
diff --git a/src/workflow/ArcanistSvnHookPreCommitWorkflow.php b/src/workflow/ArcanistSvnHookPreCommitWorkflow.php
--- a/src/workflow/ArcanistSvnHookPreCommitWorkflow.php
+++ b/src/workflow/ArcanistSvnHookPreCommitWorkflow.php
@@ -3,7 +3,7 @@
/**
* Installable as an SVN "pre-commit" hook.
*/
-final class ArcanistSvnHookPreCommitWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistSvnHookPreCommitWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'svn-hook-pre-commit';
diff --git a/src/workflow/ArcanistTasksWorkflow.php b/src/workflow/ArcanistTasksWorkflow.php
--- a/src/workflow/ArcanistTasksWorkflow.php
+++ b/src/workflow/ArcanistTasksWorkflow.php
@@ -3,7 +3,7 @@
/**
* Displays User Tasks.
*/
-final class ArcanistTasksWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistTasksWorkflow extends ArcanistWorkflow {
private $tasks;
diff --git a/src/workflow/ArcanistTodoWorkflow.php b/src/workflow/ArcanistTodoWorkflow.php
--- a/src/workflow/ArcanistTodoWorkflow.php
+++ b/src/workflow/ArcanistTodoWorkflow.php
@@ -3,7 +3,7 @@
/**
* Quickly create a task.
*/
-final class ArcanistTodoWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistTodoWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'todo';
diff --git a/src/workflow/ArcanistUnitWorkflow.php b/src/workflow/ArcanistUnitWorkflow.php
--- a/src/workflow/ArcanistUnitWorkflow.php
+++ b/src/workflow/ArcanistUnitWorkflow.php
@@ -3,7 +3,7 @@
/**
* Runs unit tests which cover your changes.
*/
-final class ArcanistUnitWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistUnitWorkflow extends ArcanistWorkflow {
const RESULT_OKAY = 0;
const RESULT_UNSOUND = 1;
@@ -133,10 +133,10 @@
$paths = $this->selectPathsForWorkflow($paths, $rev);
if (!class_exists($engine_class) ||
- !is_subclass_of($engine_class, 'ArcanistBaseUnitTestEngine')) {
+ !is_subclass_of($engine_class, 'ArcanistUnitTestEngine')) {
throw new ArcanistUsageException(
"Configured unit test engine '{$engine_class}' is not a subclass of ".
- "'ArcanistBaseUnitTestEngine'.");
+ "'ArcanistUnitTestEngine'.");
}
$this->engine = newv($engine_class, array());
diff --git a/src/workflow/ArcanistUpgradeWorkflow.php b/src/workflow/ArcanistUpgradeWorkflow.php
--- a/src/workflow/ArcanistUpgradeWorkflow.php
+++ b/src/workflow/ArcanistUpgradeWorkflow.php
@@ -3,7 +3,7 @@
/**
* Upgrade arcanist itself.
*/
-final class ArcanistUpgradeWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistUpgradeWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'upgrade';
diff --git a/src/workflow/ArcanistUploadWorkflow.php b/src/workflow/ArcanistUploadWorkflow.php
--- a/src/workflow/ArcanistUploadWorkflow.php
+++ b/src/workflow/ArcanistUploadWorkflow.php
@@ -3,7 +3,7 @@
/**
* Upload a file to Phabricator.
*/
-final class ArcanistUploadWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistUploadWorkflow extends ArcanistWorkflow {
private $paths;
private $json;
diff --git a/src/workflow/ArcanistVersionWorkflow.php b/src/workflow/ArcanistVersionWorkflow.php
--- a/src/workflow/ArcanistVersionWorkflow.php
+++ b/src/workflow/ArcanistVersionWorkflow.php
@@ -3,7 +3,7 @@
/**
* Display the current version of Arcanist.
*/
-final class ArcanistVersionWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistVersionWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'version';
diff --git a/src/workflow/ArcanistWhichWorkflow.php b/src/workflow/ArcanistWhichWorkflow.php
--- a/src/workflow/ArcanistWhichWorkflow.php
+++ b/src/workflow/ArcanistWhichWorkflow.php
@@ -3,7 +3,7 @@
/**
* Show which revision or revisions are in the working copy.
*/
-final class ArcanistWhichWorkflow extends ArcanistBaseWorkflow {
+final class ArcanistWhichWorkflow extends ArcanistWorkflow {
public function getWorkflowName() {
return 'which';
diff --git a/src/workflow/ArcanistBaseWorkflow.php b/src/workflow/ArcanistWorkflow.php
copy from src/workflow/ArcanistBaseWorkflow.php
copy to src/workflow/ArcanistWorkflow.php
--- a/src/workflow/ArcanistBaseWorkflow.php
+++ b/src/workflow/ArcanistWorkflow.php
@@ -35,7 +35,7 @@
*
* @stable
*/
-abstract class ArcanistBaseWorkflow extends Phobject {
+abstract class ArcanistWorkflow extends Phobject {
const COMMIT_DISABLE = 0;
const COMMIT_ALLOW = 1;
@@ -86,6 +86,13 @@
* whether the command succeeded or failed.
*/
public function finalize() {
+ // TODO: Remove this once ArcanistBaseWorkflow is gone.
+ if ($this instanceof ArcanistBaseWorkflow) {
+ phutil_deprecated(
+ __CLASS__,
+ 'You should extend from `ArcanistWorkflow` instead.');
+ }
+
$this->finalizeWorkingCopy();
}

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 6, 1:48 AM (1 d, 6 h ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/7b/rs/wbff4sjdnmgu4opy
Default Alt Text
D9983.id24026.diff (92 KB)

Event Timeline