1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-28 09:42:40 +01:00

Use MarkerRefs to resolve landing symbols in Mercurial

Summary: Ref T13546. Update the Mercurial code which finds default targets and maps symbols to targets under "arc land" to use the new MarkerRef workflow.

Test Plan: Ran "arc land" with (and without) various arguments in Mercurial, saw them resolve in a seemingly sensible way.

Maniphest Tasks: T13546

Differential Revision: https://secure.phabricator.com/D21335
This commit is contained in:
epriestley 2020-06-08 11:30:28 -07:00
parent 599ba0f999
commit 5abf0b96c8
5 changed files with 111 additions and 32 deletions

View file

@ -7,9 +7,19 @@ final class ArcanistMercurialLandEngine
$api = $this->getRepositoryAPI();
$log = $this->getLogEngine();
$bookmark = $api->getActiveBookmark();
if ($bookmark !== null) {
$markers = $api->newMarkerRefQuery()
->withIsActive(true)
->execute();
$bookmark = null;
foreach ($markers as $marker) {
if ($marker->isBookmark()) {
$bookmark = $marker->getName();
break;
}
}
if ($bookmark !== null) {
$log->writeStatus(
pht('SOURCE'),
pht(
@ -19,51 +29,97 @@ final class ArcanistMercurialLandEngine
return array($bookmark);
}
$branch = $api->getBranchName();
if ($branch !== null) {
$branch = null;
foreach ($markers as $marker) {
if ($marker->isBranch()) {
$branch = $marker->getName();
break;
}
}
if ($branch !== null) {
$log->writeStatus(
pht('SOURCE'),
pht(
'Landing the current branch, "%s".',
'Landing the active branch, "%s".',
$branch));
return array($branch);
}
throw new Exception(pht('TODO: Operate on raw revision.'));
$commit = $api->getCanonicalRevisionName('.');
$log->writeStatus(
pht('SOURCE'),
pht(
'Landing the active commit, "%s".',
$this->getDisplayHash($commit)));
return array($commit);
}
protected function resolveSymbols(array $symbols) {
assert_instances_of($symbols, 'ArcanistLandSymbol');
$api = $this->getRepositoryAPI();
foreach ($symbols as $symbol) {
$marker_types = array(
ArcanistMarkerRef::TYPE_BOOKMARK,
ArcanistMarkerRef::TYPE_BRANCH,
);
$unresolved = $symbols;
foreach ($marker_types as $marker_type) {
$markers = $api->newMarkerRefQuery()
->withMarkerTypes(array($marker_type))
->execute();
$markers = mgroup($markers, 'getName');
foreach ($unresolved as $key => $symbol) {
$raw_symbol = $symbol->getSymbol();
if ($api->isBookmark($raw_symbol)) {
$hash = $api->getBookmarkCommitHash($raw_symbol);
$symbol->setCommit($hash);
// TODO: Set that this is a bookmark?
continue;
}
if ($api->isBranch($raw_symbol)) {
$hash = $api->getBranchCommitHash($raw_symbol);
$symbol->setCommit($hash);
// TODO: Set that this is a branch?
$named_markers = idx($markers, $raw_symbol);
if (!$named_markers) {
continue;
}
if (count($named_markers) > 1) {
throw new PhutilArgumentUsageException(
pht(
'Symbol "%s" is not a bookmark or branch name.',
'Symbol "%s" is ambiguous: it matches multiple markers '.
'(of type "%s"). Use an unambiguous identifier.',
$raw_symbol,
$marker_type));
}
$marker = head($named_markers);
$symbol->setCommit($marker->getCommitHash());
unset($unresolved[$key]);
}
}
foreach ($unresolved as $symbol) {
$raw_symbol = $symbol->getSymbol();
// TODO: This doesn't have accurate error behavior if the user provides
// a revset like "x::y".
try {
$commit = $api->getCanonicalRevisionName($raw_symbol);
} catch (CommandException $ex) {
$commit = null;
}
if ($commit === null) {
throw new PhutilArgumentUsageException(
pht(
'Symbol "%s" does not identify a bookmark, branch, or commit.',
$raw_symbol));
}
$symbol->setCommit($commit);
}
}
protected function selectOntoRemote(array $symbols) {

View file

@ -59,6 +59,7 @@ final class ArcanistMercurialAPI extends ArcanistRepositoryAPI {
'log -l 1 --template %s -r %s --',
'{node}',
$string);
return $stdout;
}

View file

@ -109,6 +109,14 @@ final class ArcanistMarkerRef
return $this->isActive;
}
public function isBookmark() {
return ($this->getMarkerType() === self::TYPE_BOOKMARK);
}
public function isBranch() {
return ($this->getMarkerType() === self::TYPE_BRANCH);
}
public function attachCommitRef(ArcanistCommitRef $ref) {
return $this->attachHardpoint(self::HARDPOINT_COMMITREF, $ref);
}

View file

@ -4,7 +4,8 @@ abstract class ArcanistRepositoryMarkerQuery
extends Phobject {
private $repositoryAPI;
private $types;
private $isActive;
private $markerTypes;
private $commitHashes;
private $ancestorCommitHashes;
@ -17,15 +18,20 @@ abstract class ArcanistRepositoryMarkerQuery
return $this->repositoryAPI;
}
final public function withTypes(array $types) {
$this->types = array_fuse($types);
final public function withMarkerTypes(array $types) {
$this->markerTypes = array_fuse($types);
return $this;
}
final public function withIsActive($active) {
$this->isActive = $active;
return $this;
}
final public function execute() {
$markers = $this->newRefMarkers();
$types = $this->types;
$types = $this->markerTypes;
if ($types !== null) {
foreach ($markers as $key => $marker) {
if (!isset($types[$marker->getMarkerType()])) {
@ -34,6 +40,14 @@ abstract class ArcanistRepositoryMarkerQuery
}
}
if ($this->isActive !== null) {
foreach ($markers as $key => $marker) {
if ($marker->getIsActive() !== $this->isActive) {
unset($markers[$key]);
}
}
}
return $this->sortMarkers($markers);
}
@ -53,11 +67,11 @@ abstract class ArcanistRepositoryMarkerQuery
}
final protected function shouldQueryMarkerType($marker_type) {
if ($this->types === null) {
if ($this->markerTypes === null) {
return true;
}
return isset($this->types[$marker_type]);
return isset($this->markerTypes[$marker_type]);
}
}

View file

@ -11,7 +11,7 @@ abstract class ArcanistMarkersWorkflow
$marker_type = $this->getWorkflowMarkerType();
$markers = $api->newMarkerRefQuery()
->withTypes(array($marker_type))
->withMarkerTypes(array($marker_type))
->execute();
$states = array();