mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-21 22:32:41 +01:00
Remove "arc feature", "arc branch", "arc bookmark", and significant chunks of obsolete marker code
Summary: Ref T13546. Moves away from the older workflows in favor of "arc branches", "arc bookmarks", and "arc work". Test Plan: Grepped for affected symbols, didn't find any callers. Maniphest Tasks: T13546 Differential Revision: https://secure.phabricator.com/D21337
This commit is contained in:
parent
3d64140ff3
commit
b003cf9310
10 changed files with 12 additions and 581 deletions
|
@ -49,12 +49,10 @@ phutil_register_library_map(array(
|
|||
'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBlacklistedFunctionXHPASTLinterRule.php',
|
||||
'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase.php',
|
||||
'ArcanistBlindlyTrustHTTPEngineExtension' => 'configuration/ArcanistBlindlyTrustHTTPEngineExtension.php',
|
||||
'ArcanistBookmarkWorkflow' => 'workflow/ArcanistBookmarkWorkflow.php',
|
||||
'ArcanistBookmarksWorkflow' => 'workflow/ArcanistBookmarksWorkflow.php',
|
||||
'ArcanistBoolConfigOption' => 'config/option/ArcanistBoolConfigOption.php',
|
||||
'ArcanistBraceFormattingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistBraceFormattingXHPASTLinterRule.php',
|
||||
'ArcanistBraceFormattingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistBraceFormattingXHPASTLinterRuleTestCase.php',
|
||||
'ArcanistBranchWorkflow' => 'workflow/ArcanistBranchWorkflow.php',
|
||||
'ArcanistBranchesWorkflow' => 'workflow/ArcanistBranchesWorkflow.php',
|
||||
'ArcanistBrowseCommitHardpointQuery' => 'browse/query/ArcanistBrowseCommitHardpointQuery.php',
|
||||
'ArcanistBrowseCommitURIHardpointQuery' => 'browse/query/ArcanistBrowseCommitURIHardpointQuery.php',
|
||||
|
@ -194,8 +192,6 @@ phutil_register_library_map(array(
|
|||
'ArcanistExternalLinterTestCase' => 'lint/linter/__tests__/ArcanistExternalLinterTestCase.php',
|
||||
'ArcanistExtractUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistExtractUseXHPASTLinterRule.php',
|
||||
'ArcanistExtractUseXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistExtractUseXHPASTLinterRuleTestCase.php',
|
||||
'ArcanistFeatureBaseWorkflow' => 'workflow/ArcanistFeatureBaseWorkflow.php',
|
||||
'ArcanistFeatureWorkflow' => 'workflow/ArcanistFeatureWorkflow.php',
|
||||
'ArcanistFileConfigurationSource' => 'config/source/ArcanistFileConfigurationSource.php',
|
||||
'ArcanistFileDataRef' => 'upload/ArcanistFileDataRef.php',
|
||||
'ArcanistFileRef' => 'ref/file/ArcanistFileRef.php',
|
||||
|
@ -1068,12 +1064,10 @@ phutil_register_library_map(array(
|
|||
'ArcanistBlacklistedFunctionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistBlacklistedFunctionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||
'ArcanistBlindlyTrustHTTPEngineExtension' => 'PhutilHTTPEngineExtension',
|
||||
'ArcanistBookmarkWorkflow' => 'ArcanistFeatureBaseWorkflow',
|
||||
'ArcanistBookmarksWorkflow' => 'ArcanistMarkersWorkflow',
|
||||
'ArcanistBoolConfigOption' => 'ArcanistSingleSourceConfigOption',
|
||||
'ArcanistBraceFormattingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistBraceFormattingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||
'ArcanistBranchWorkflow' => 'ArcanistFeatureBaseWorkflow',
|
||||
'ArcanistBranchesWorkflow' => 'ArcanistMarkersWorkflow',
|
||||
'ArcanistBrowseCommitHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
|
||||
'ArcanistBrowseCommitURIHardpointQuery' => 'ArcanistBrowseURIHardpointQuery',
|
||||
|
@ -1224,8 +1218,6 @@ phutil_register_library_map(array(
|
|||
'ArcanistExternalLinterTestCase' => 'ArcanistLinterTestCase',
|
||||
'ArcanistExtractUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistExtractUseXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||
'ArcanistFeatureBaseWorkflow' => 'ArcanistArcWorkflow',
|
||||
'ArcanistFeatureWorkflow' => 'ArcanistFeatureBaseWorkflow',
|
||||
'ArcanistFileConfigurationSource' => 'ArcanistFilesystemConfigurationSource',
|
||||
'ArcanistFileDataRef' => 'Phobject',
|
||||
'ArcanistFileRef' => array(
|
||||
|
|
|
@ -22,14 +22,6 @@ final class ArcanistArcConfigurationEngineExtension
|
|||
'default' => array(),
|
||||
'example' => '["/var/arc/customlib/src"]',
|
||||
),
|
||||
|
||||
'arc.feature.start.default' => array(
|
||||
'type' => 'string',
|
||||
'help' => pht(
|
||||
'The name of the default branch to create the new feature branch '.
|
||||
'off of.'),
|
||||
'example' => '"develop"',
|
||||
),
|
||||
'editor' => array(
|
||||
'type' => 'string',
|
||||
'help' => pht(
|
||||
|
|
|
@ -65,13 +65,6 @@ final class ArcanistSettings extends Phobject {
|
|||
'engine is specified by the current project.'),
|
||||
'example' => '"ExampleUnitTestEngine"',
|
||||
),
|
||||
'arc.feature.start.default' => array(
|
||||
'type' => 'string',
|
||||
'help' => pht(
|
||||
'The name of the default branch to create the new feature branch '.
|
||||
'off of.'),
|
||||
'example' => '"develop"',
|
||||
),
|
||||
'arc.land.onto.default' => array(
|
||||
'type' => 'string',
|
||||
'help' => pht(
|
||||
|
|
|
@ -597,16 +597,16 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
|||
|
||||
public function getCanonicalRevisionName($string) {
|
||||
$match = null;
|
||||
|
||||
if (preg_match('/@([0-9]+)$/', $string, $match)) {
|
||||
$stdout = $this->getHashFromFromSVNRevisionNumber($match[1]);
|
||||
} else {
|
||||
list($stdout) = $this->execxLocal(
|
||||
phutil_is_windows()
|
||||
? 'show -s --format=%C %s --'
|
||||
: 'show -s --format=%s %s --',
|
||||
'show -s --format=%s %s --',
|
||||
'%H',
|
||||
$string);
|
||||
}
|
||||
|
||||
return rtrim($stdout);
|
||||
}
|
||||
|
||||
|
@ -1056,7 +1056,7 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
|||
*
|
||||
* @return list<dict<string, string>> Dictionary of branch information.
|
||||
*/
|
||||
public function getAllBranches() {
|
||||
private function getAllBranches() {
|
||||
$field_list = array(
|
||||
'%(refname)',
|
||||
'%(objectname)',
|
||||
|
@ -1102,26 +1102,6 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
|||
return $result;
|
||||
}
|
||||
|
||||
public function getAllBranchRefs() {
|
||||
$branches = $this->getAllBranches();
|
||||
|
||||
$refs = array();
|
||||
foreach ($branches as $branch) {
|
||||
$commit_ref = $this->newCommitRef()
|
||||
->setCommitHash($branch['hash'])
|
||||
->setTreeHash($branch['tree'])
|
||||
->setCommitEpoch($branch['epoch'])
|
||||
->attachMessage($branch['text']);
|
||||
|
||||
$refs[] = $this->newMarkerRef()
|
||||
->setName($branch['name'])
|
||||
->setIsActive($branch['current'])
|
||||
->attachCommitRef($commit_ref);
|
||||
}
|
||||
|
||||
return $refs;
|
||||
}
|
||||
|
||||
public function getBaseCommitRef() {
|
||||
$base_commit = $this->getBaseCommit();
|
||||
|
||||
|
@ -1783,5 +1763,4 @@ final class ArcanistGitAPI extends ArcanistRepositoryAPI {
|
|||
return new ArcanistGitRepositoryMarkerQuery();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -49,12 +49,6 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
|||
}
|
||||
|
||||
public function getCanonicalRevisionName($string) {
|
||||
$match = null;
|
||||
if ($this->isHgSubversionRepo() &&
|
||||
preg_match('/@([0-9]+)$/', $string, $match)) {
|
||||
$string = hgsprintf('svnrev(%s)', $match[1]);
|
||||
}
|
||||
|
||||
list($stdout) = $this->execxLocal(
|
||||
'log -l 1 --template %s -r %s --',
|
||||
'{node}',
|
||||
|
@ -63,32 +57,6 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
|||
return $stdout;
|
||||
}
|
||||
|
||||
public function getHashFromFromSVNRevisionNumber($revision_id) {
|
||||
$matches = array();
|
||||
$string = hgsprintf('svnrev(%s)', $revision_id);
|
||||
list($stdout) = $this->execxLocal(
|
||||
'log -l 1 --template %s -r %s --',
|
||||
'{node}',
|
||||
$string);
|
||||
if (!$stdout) {
|
||||
throw new ArcanistUsageException(
|
||||
pht('Cannot find the HG equivalent of %s given.', $revision_id));
|
||||
}
|
||||
return $stdout;
|
||||
}
|
||||
|
||||
|
||||
public function getSVNRevisionNumberFromHash($hash) {
|
||||
$matches = array();
|
||||
list($stdout) = $this->execxLocal(
|
||||
'log -r %s --template {svnrev}', $hash);
|
||||
if (!$stdout) {
|
||||
throw new ArcanistUsageException(
|
||||
pht('Cannot find the SVN equivalent of %s given.', $hash));
|
||||
}
|
||||
return $stdout;
|
||||
}
|
||||
|
||||
public function getSourceControlPath() {
|
||||
return '/';
|
||||
}
|
||||
|
@ -505,53 +473,6 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function getAllBranches() {
|
||||
// TODO: This is wrong, and returns bookmarks.
|
||||
|
||||
list($branch_info) = $this->execxLocal('bookmarks');
|
||||
if (trim($branch_info) == 'no bookmarks set') {
|
||||
return array();
|
||||
}
|
||||
|
||||
$matches = null;
|
||||
preg_match_all(
|
||||
'/^\s*(\*?)\s*(.+)\s(\S+)$/m',
|
||||
$branch_info,
|
||||
$matches,
|
||||
PREG_SET_ORDER);
|
||||
|
||||
$return = array();
|
||||
foreach ($matches as $match) {
|
||||
list(, $current, $name, $hash) = $match;
|
||||
|
||||
list($id, $hash) = explode(':', $hash);
|
||||
|
||||
$return[] = array(
|
||||
'current' => (bool)$current,
|
||||
'name' => rtrim($name),
|
||||
'hash' => $hash,
|
||||
);
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
public function getAllBranchRefs() {
|
||||
$branches = $this->getAllBranches();
|
||||
|
||||
$refs = array();
|
||||
foreach ($branches as $branch) {
|
||||
$commit_ref = $this->newCommitRef()
|
||||
->setCommitHash($branch['hash']);
|
||||
|
||||
$refs[] = $this->newMarkerRef()
|
||||
->setBranchName($branch['name'])
|
||||
->setIsCurrentBranch($branch['current'])
|
||||
->attachCommitRef($commit_ref);
|
||||
}
|
||||
|
||||
return $refs;
|
||||
}
|
||||
|
||||
public function getBaseCommitRef() {
|
||||
$base_commit = $this->getBaseCommit();
|
||||
|
||||
|
@ -937,10 +858,6 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
|||
|
||||
}
|
||||
|
||||
public function isHgSubversionRepo() {
|
||||
return file_exists($this->getPath('.hg/svn/rev_map'));
|
||||
}
|
||||
|
||||
public function getSubversionInfo() {
|
||||
$info = array();
|
||||
$base_path = null;
|
||||
|
@ -972,133 +889,16 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
|
|||
}
|
||||
|
||||
public function getActiveBookmark() {
|
||||
$bookmarks = $this->getBookmarks();
|
||||
foreach ($bookmarks as $bookmark) {
|
||||
if ($bookmark['is_active']) {
|
||||
return $bookmark['name'];
|
||||
}
|
||||
$bookmark = $this->newMarkerRefQuery()
|
||||
->withMarkerTypes(ArcanistMarkerRef::TYPE_BOOKMARK)
|
||||
->withIsActive(true)
|
||||
->executeOne();
|
||||
|
||||
if (!$bookmark) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isBookmark($name) {
|
||||
$bookmarks = $this->getBookmarks();
|
||||
foreach ($bookmarks as $bookmark) {
|
||||
if ($bookmark['name'] === $name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isBranch($name) {
|
||||
$branches = $this->getBranches();
|
||||
foreach ($branches as $branch) {
|
||||
if ($branch['name'] === $name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getBranches() {
|
||||
list($stdout) = $this->execxLocal('--debug branches');
|
||||
$lines = ArcanistMercurialParser::parseMercurialBranches($stdout);
|
||||
|
||||
$branches = array();
|
||||
foreach ($lines as $name => $spec) {
|
||||
$branches[] = array(
|
||||
'name' => $name,
|
||||
'revision' => $spec['rev'],
|
||||
);
|
||||
}
|
||||
|
||||
return $branches;
|
||||
}
|
||||
|
||||
public function getBookmarks() {
|
||||
$bookmarks = array();
|
||||
|
||||
list($raw_output) = $this->execxLocal('bookmarks');
|
||||
$raw_output = trim($raw_output);
|
||||
if ($raw_output !== 'no bookmarks set') {
|
||||
foreach (explode("\n", $raw_output) as $line) {
|
||||
// example line: * mybook 2:6b274d49be97
|
||||
list($name, $revision) = $this->splitBranchOrBookmarkLine($line);
|
||||
|
||||
$is_active = false;
|
||||
if ('*' === $name[0]) {
|
||||
$is_active = true;
|
||||
$name = substr($name, 2);
|
||||
}
|
||||
|
||||
$bookmarks[] = array(
|
||||
'is_active' => $is_active,
|
||||
'name' => $name,
|
||||
'revision' => $revision,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $bookmarks;
|
||||
}
|
||||
|
||||
public function getBookmarkCommitHash($name) {
|
||||
// TODO: Cache this.
|
||||
|
||||
$bookmarks = $this->getBookmarks($name);
|
||||
$bookmarks = ipull($bookmarks, null, 'name');
|
||||
|
||||
foreach ($bookmarks as $bookmark) {
|
||||
if ($bookmark['name'] === $name) {
|
||||
return $bookmark['revision'];
|
||||
}
|
||||
}
|
||||
|
||||
throw new Exception(pht('No bookmark "%s".', $name));
|
||||
}
|
||||
|
||||
public function getBranchCommitHash($name) {
|
||||
// TODO: Cache this.
|
||||
// TODO: This won't work when there are multiple branch heads with the
|
||||
// same name.
|
||||
|
||||
$branches = $this->getBranches($name);
|
||||
|
||||
$heads = array();
|
||||
foreach ($branches as $branch) {
|
||||
if ($branch['name'] === $name) {
|
||||
$heads[] = $branch;
|
||||
}
|
||||
}
|
||||
|
||||
if (count($heads) === 1) {
|
||||
return idx(head($heads), 'revision');
|
||||
}
|
||||
|
||||
if (!$heads) {
|
||||
throw new Exception(pht('No branch "%s".', $name));
|
||||
}
|
||||
|
||||
throw new Exception(pht('Too many branch heads for "%s".', $name));
|
||||
}
|
||||
|
||||
private function splitBranchOrBookmarkLine($line) {
|
||||
// branches and bookmarks are printed in the format:
|
||||
// default 0:a5ead76cdf85 (inactive)
|
||||
// * mybook 2:6b274d49be97
|
||||
// this code divides the name half from the revision half
|
||||
// it does not parse the * and (inactive) bits
|
||||
$colon_index = strrpos($line, ':');
|
||||
$before_colon = substr($line, 0, $colon_index);
|
||||
$start_rev_index = strrpos($before_colon, ' ');
|
||||
$name = substr($line, 0, $start_rev_index);
|
||||
$rev = substr($line, $start_rev_index);
|
||||
|
||||
return array(trim($name), trim($rev));
|
||||
return $bookmark->getName();
|
||||
}
|
||||
|
||||
public function getRemoteURI() {
|
||||
|
|
|
@ -369,15 +369,6 @@ abstract class ArcanistRepositoryAPI extends Phobject {
|
|||
throw new ArcanistCapabilityNotSupportedException($this);
|
||||
}
|
||||
|
||||
public function getAllBranches() {
|
||||
// TODO: Implement for Mercurial/SVN and make abstract.
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getAllBranchRefs() {
|
||||
throw new ArcanistCapabilityNotSupportedException($this);
|
||||
}
|
||||
|
||||
public function getBaseCommitRef() {
|
||||
throw new ArcanistCapabilityNotSupportedException($this);
|
||||
}
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class ArcanistBookmarkWorkflow
|
||||
extends ArcanistFeatureBaseWorkflow {
|
||||
|
||||
public function getWorkflowName() {
|
||||
return 'bookmark';
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class ArcanistBranchWorkflow
|
||||
extends ArcanistFeatureBaseWorkflow {
|
||||
|
||||
public function getWorkflowName() {
|
||||
return 'branch';
|
||||
}
|
||||
|
||||
}
|
|
@ -1,286 +0,0 @@
|
|||
<?php
|
||||
|
||||
abstract class ArcanistFeatureBaseWorkflow
|
||||
extends ArcanistArcWorkflow {
|
||||
|
||||
private $branches;
|
||||
|
||||
public function getWorkflowArguments() {
|
||||
return array(
|
||||
$this->newWorkflowArgument('view-all')
|
||||
->setHelp(pht('Include closed and abandoned revisions.')),
|
||||
$this->newWorkflowArgument('by-status')
|
||||
->setParameter('status')
|
||||
->setHelp(pht('Sort branches by status instead of time.')),
|
||||
$this->newWorkflowArgument('output')
|
||||
->setParameter('format')
|
||||
->setHelp(
|
||||
pht(
|
||||
'With "json", show features in machine-readable JSON format.')),
|
||||
$this->newWorkflowArgument('branch')
|
||||
->setWildcard(true),
|
||||
);
|
||||
}
|
||||
|
||||
public function getWorkflowInformation() {
|
||||
return $this->newWorkflowInformation()
|
||||
->setSynopsis(pht('Wrapper on "git branch" or "hg bookmark".'))
|
||||
->addExample(pht('**%s** [__options__]', $this->getWorkflowName()))
|
||||
->addExample(pht('**%s** __name__ [__start__]', $this->getWorkflowName()))
|
||||
->setHelp(
|
||||
pht(<<<EOHELP
|
||||
A wrapper on 'git branch' or 'hg bookmark'.
|
||||
|
||||
Without __name__, it lists the available branches and their revision status.
|
||||
|
||||
With __name__, it creates or checks out a branch. If the branch __name__
|
||||
doesn't exist and is in format D123 then the branch of revision D123 is
|
||||
checked out. Use __start__ to specify where the new branch will start. Use
|
||||
'arc.feature.start.default' to set the default feature start location.
|
||||
EOHELP
|
||||
));
|
||||
}
|
||||
|
||||
public function runWorkflow() {
|
||||
$repository_api = $this->getRepositoryAPI();
|
||||
if (!$repository_api) {
|
||||
throw new PhutilArgumentUsageException(
|
||||
pht(
|
||||
'This command must be run in a Git or Mercurial working copy.'));
|
||||
}
|
||||
|
||||
$names = $this->getArgument('branch');
|
||||
if ($names) {
|
||||
if (count($names) > 2) {
|
||||
throw new ArcanistUsageException(pht('Specify only one branch.'));
|
||||
}
|
||||
return $this->checkoutBranch($names);
|
||||
}
|
||||
|
||||
// TODO: Everything in this whole workflow that says "branch" means
|
||||
// "bookmark" in Mercurial.
|
||||
|
||||
$branches = $repository_api->getAllBranchRefs();
|
||||
if (!$branches) {
|
||||
throw new ArcanistUsageException(
|
||||
pht('No branches in this working copy.'));
|
||||
}
|
||||
|
||||
$states = array();
|
||||
foreach ($branches as $branch_key => $branch) {
|
||||
$state_ref = id(new ArcanistWorkingCopyStateRef())
|
||||
->setCommitRef($branch->getCommitRef());
|
||||
|
||||
$states[] = array(
|
||||
'branch' => $branch,
|
||||
'state' => $state_ref,
|
||||
);
|
||||
}
|
||||
|
||||
$this->loadHardpoints(
|
||||
ipull($states, 'state'),
|
||||
ArcanistWorkingCopyStateRef::HARDPOINT_REVISIONREFS);
|
||||
|
||||
$this->printBranches($states);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private function checkoutBranch(array $names) {
|
||||
$api = $this->getRepositoryAPI();
|
||||
|
||||
if ($api instanceof ArcanistMercurialAPI) {
|
||||
$command = 'update %s';
|
||||
} else {
|
||||
$command = 'checkout %s';
|
||||
}
|
||||
|
||||
$err = 1;
|
||||
|
||||
$name = $names[0];
|
||||
if (isset($names[1])) {
|
||||
$start = $names[1];
|
||||
} else {
|
||||
$start = $this->getConfigFromAnySource('arc.feature.start.default');
|
||||
}
|
||||
|
||||
$branches = $api->getAllBranches();
|
||||
if (in_array($name, ipull($branches, 'name'))) {
|
||||
list($err, $stdout, $stderr) = $api->execManualLocal($command, $name);
|
||||
}
|
||||
|
||||
if ($err) {
|
||||
$match = null;
|
||||
if (preg_match('/^D(\d+)$/', $name, $match)) {
|
||||
$diff = $this->getConduitEngine()->resolveCall(
|
||||
'differential.querydiffs',
|
||||
array(
|
||||
'revisionIDs' => array($match[1]),
|
||||
));
|
||||
$diff = head($diff);
|
||||
|
||||
if ($diff['branch'] != '') {
|
||||
$name = $diff['branch'];
|
||||
list($err, $stdout, $stderr) = $api->execManualLocal(
|
||||
$command,
|
||||
$name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($err) {
|
||||
if ($api instanceof ArcanistMercurialAPI) {
|
||||
$rev = '';
|
||||
if ($start) {
|
||||
$rev = csprintf('-r %s', $start);
|
||||
}
|
||||
|
||||
$exec = $api->execManualLocal('bookmark %C %s', $rev, $name);
|
||||
|
||||
if (!$exec[0] && $start) {
|
||||
$api->execxLocal('update %s', $name);
|
||||
}
|
||||
} else {
|
||||
$startarg = $start ? csprintf('%s', $start) : '';
|
||||
$exec = $api->execManualLocal(
|
||||
'checkout --track -b %s %C',
|
||||
$name,
|
||||
$startarg);
|
||||
}
|
||||
|
||||
list($err, $stdout, $stderr) = $exec;
|
||||
}
|
||||
|
||||
echo $stdout;
|
||||
fprintf(STDERR, '%s', $stderr);
|
||||
return $err;
|
||||
}
|
||||
|
||||
private function printBranches(array $states) {
|
||||
static $color_map = array(
|
||||
'Closed' => 'cyan',
|
||||
'Needs Review' => 'magenta',
|
||||
'Needs Revision' => 'red',
|
||||
'Accepted' => 'green',
|
||||
'No Revision' => 'blue',
|
||||
'Abandoned' => 'default',
|
||||
);
|
||||
|
||||
static $ssort_map = array(
|
||||
'Closed' => 1,
|
||||
'No Revision' => 2,
|
||||
'Needs Review' => 3,
|
||||
'Needs Revision' => 4,
|
||||
'Accepted' => 5,
|
||||
);
|
||||
|
||||
$out = array();
|
||||
foreach ($states as $objects) {
|
||||
$state = $objects['state'];
|
||||
$branch = $objects['branch'];
|
||||
|
||||
$revision = null;
|
||||
if ($state->hasAmbiguousRevisionRefs()) {
|
||||
$status = pht('Ambiguous Revision');
|
||||
} else {
|
||||
$revision = $state->getRevisionRef();
|
||||
if ($revision) {
|
||||
$status = $revision->getStatusDisplayName();
|
||||
} else {
|
||||
$status = pht('No Revision');
|
||||
}
|
||||
}
|
||||
|
||||
if (!$this->getArgument('view-all') && !$branch->getIsActive()) {
|
||||
if ($status == 'Closed' || $status == 'Abandoned') {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$commit = $branch->getCommitRef();
|
||||
$epoch = $commit->getCommitEpoch();
|
||||
|
||||
$color = idx($color_map, $status, 'default');
|
||||
|
||||
$epoch_vector = id(new PhutilSortVector())
|
||||
->addInt($epoch);
|
||||
|
||||
$status_vector = id(new PhutilSortVector())
|
||||
->addInt(idx($ssort_map, $status, 0))
|
||||
->addInt($epoch);
|
||||
|
||||
if ($revision) {
|
||||
$desc = $revision->getFullName();
|
||||
} else {
|
||||
$desc = $commit->getSummary();
|
||||
}
|
||||
|
||||
$out[] = array(
|
||||
'name' => $branch->getName(),
|
||||
'current' => $branch->getIsActive(),
|
||||
'status' => $status,
|
||||
'desc' => $desc,
|
||||
'revision' => $revision ? $revision->getID() : null,
|
||||
'color' => $color,
|
||||
'epoch' => $epoch,
|
||||
|
||||
'esort' => $epoch_vector,
|
||||
'ssort' => $status_vector,
|
||||
);
|
||||
}
|
||||
|
||||
if (!$out) {
|
||||
// All of the revisions are closed or abandoned.
|
||||
return;
|
||||
}
|
||||
|
||||
$len_name = max(array_map('strlen', ipull($out, 'name'))) + 2;
|
||||
$len_status = max(array_map('strlen', ipull($out, 'status'))) + 2;
|
||||
|
||||
// Sort the list in natural order first. When we apply a stable sort to
|
||||
// the list below, branches which were last updated at the same time will
|
||||
// retain this ordering. This allows "feature1", "feature2", etc., to
|
||||
// display in the correct order if they were touched at the same second,
|
||||
// which is common when "arc land" performs a cascading rebase.
|
||||
|
||||
$name_map = ipull($out, 'name');
|
||||
natcasesort($name_map);
|
||||
$out = array_select_keys($out, array_keys($name_map));
|
||||
|
||||
if ($this->getArgument('by-status')) {
|
||||
$vectors = ipull($out, 'ssort');
|
||||
} else {
|
||||
$vectors = ipull($out, 'esort');
|
||||
}
|
||||
|
||||
$vectors = msortv($vectors, 'getSelf');
|
||||
$out = array_select_keys($out, array_keys($vectors));
|
||||
|
||||
if ($this->getArgument('output') == 'json') {
|
||||
foreach ($out as &$feature) {
|
||||
unset($feature['color'], $feature['ssort'], $feature['esort']);
|
||||
}
|
||||
echo json_encode(ipull($out, null, 'name'))."\n";
|
||||
} else {
|
||||
$table = id(new PhutilConsoleTable())
|
||||
->setShowHeader(false)
|
||||
->addColumn('current', array('title' => ''))
|
||||
->addColumn('name', array('title' => pht('Name')))
|
||||
->addColumn('status', array('title' => pht('Status')))
|
||||
->addColumn('descr', array('title' => pht('Description')));
|
||||
|
||||
foreach ($out as $line) {
|
||||
$table->addRow(array(
|
||||
'current' => $line['current'] ? '*' : '',
|
||||
'name' => tsprintf('**%s**', $line['name']),
|
||||
'status' => tsprintf(
|
||||
"<fg:{$line['color']}>%s</fg>", $line['status']),
|
||||
'descr' => $line['desc'],
|
||||
));
|
||||
}
|
||||
|
||||
$table->draw();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class ArcanistFeatureWorkflow
|
||||
extends ArcanistFeatureBaseWorkflow {
|
||||
|
||||
public function getWorkflowName() {
|
||||
return 'feature';
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue