1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-25 16:22:42 +01:00

Move Git-specific "arc land" parsing of "--onto" and "--remote" into GitLandEngine

Summary: Ref T13434. Move some git-engine-specific handling of "arc land" arguments into the Git engine. This prepares to handle Perforce workflows.

Test Plan: Will "arc land" this change.

Maniphest Tasks: T13434

Differential Revision: https://secure.phabricator.com/D20867
This commit is contained in:
epriestley 2019-10-26 12:09:56 -07:00
parent da6d4f85ee
commit 9c7bbb760a
3 changed files with 149 additions and 122 deletions

View file

@ -9,6 +9,14 @@ final class ArcanistGitLandEngine
private $mergedRef; private $mergedRef;
private $restoreWhenDestroyed; private $restoreWhenDestroyed;
public function parseArguments() {
$onto = $this->getEngineOnto();
$this->setTargetOnto($onto);
$remote = $this->getEngineRemote();
$this->setTargetRemote($remote);
}
public function execute() { public function execute() {
$this->verifySourceAndTargetExist(); $this->verifySourceAndTargetExist();
$this->fetchTarget(); $this->fetchTarget();
@ -615,4 +623,114 @@ final class ArcanistGitLandEngine
return !$err; return !$err;
} }
private function getEngineOnto() {
$source_ref = $this->getSourceRef();
$onto = $this->getOntoArgument();
if ($onto !== null) {
$this->writeInfo(
pht('TARGET'),
pht(
'Landing onto "%s", selected with the "--onto" flag.',
$onto));
return $onto;
}
$api = $this->getRepositoryAPI();
$path = $api->getPathToUpstream($source_ref);
if ($path->getLength()) {
$cycle = $path->getCycle();
if ($cycle) {
$this->writeWarn(
pht('LOCAL CYCLE'),
pht(
'Local branch tracks an upstream, but following it leads to a '.
'local cycle; ignoring branch upstream.'));
echo tsprintf(
"\n %s\n\n",
implode(' -> ', $cycle));
} else {
if ($path->isConnectedToRemote()) {
$onto = $path->getRemoteBranchName();
$this->writeInfo(
pht('TARGET'),
pht(
'Landing onto "%s", selected by following tracking branches '.
'upstream to the closest remote.',
$onto));
return $onto;
} else {
$this->writeInfo(
pht('NO PATH TO UPSTREAM'),
pht(
'Local branch tracks an upstream, but there is no path '.
'to a remote; ignoring branch upstream.'));
}
}
}
$workflow = $this->getWorkflow();
$config_key = 'arc.land.onto.default';
$onto = $workflow->getConfigFromAnySource($config_key);
if ($onto !== null) {
$this->writeInfo(
pht('TARGET'),
pht(
'Landing onto "%s", selected by "%s" configuration.',
$onto,
$config_key));
return $onto;
}
$onto = 'master';
$this->writeInfo(
pht('TARGET'),
pht(
'Landing onto "%s", the default target under git.',
$onto));
return $onto;
}
private function getEngineRemote() {
$source_ref = $this->getSourceRef();
$remote = $this->getRemoteArgument();
if ($remote !== null) {
$this->writeInfo(
pht('REMOTE'),
pht(
'Using remote "%s", selected with the "--remote" flag.',
$remote));
return $remote;
}
$api = $this->getRepositoryAPI();
$path = $api->getPathToUpstream($source_ref);
$remote = $path->getRemoteRemoteName();
if ($remote !== null) {
$this->writeInfo(
pht('REMOTE'),
pht(
'Using remote "%s", selected by following tracking branches '.
'upstream to the closest remote.',
$remote));
return $remote;
}
$remote = 'origin';
$this->writeInfo(
pht('REMOTE'),
pht(
'Using remote "%s", the default remote under git.',
$remote));
return $remote;
}
} }

View file

@ -13,6 +13,8 @@ abstract class ArcanistLandEngine extends Phobject {
private $shouldSquash; private $shouldSquash;
private $shouldDeleteRemote; private $shouldDeleteRemote;
private $shouldPreview; private $shouldPreview;
private $remoteArgument;
private $ontoArgument;
// TODO: This is really grotesque. // TODO: This is really grotesque.
private $buildMessageCallback; private $buildMessageCallback;
@ -117,6 +119,25 @@ abstract class ArcanistLandEngine extends Phobject {
return $this->commitMessageFile; return $this->commitMessageFile;
} }
final public function setRemoteArgument($remote_argument) {
$this->remoteArgument = $remote_argument;
return $this;
}
final public function getRemoteArgument() {
return $this->remoteArgument;
}
final public function setOntoArgument($onto_argument) {
$this->ontoArgument = $onto_argument;
return $this;
}
final public function getOntoArgument() {
return $this->ontoArgument;
}
abstract public function parseArguments();
abstract public function execute(); abstract public function execute();
abstract protected function getLandingCommits(); abstract protected function getLandingCommits();

View file

@ -224,23 +224,28 @@ EOTEXT
} }
if ($engine) { if ($engine) {
$this->readEngineArguments();
$this->requireCleanWorkingCopy();
$should_hold = $this->getArgument('hold'); $should_hold = $this->getArgument('hold');
$remote_arg = $this->getArgument('remote');
$onto_arg = $this->getArgument('onto');
$engine $engine
->setWorkflow($this) ->setWorkflow($this)
->setRepositoryAPI($this->getRepositoryAPI()) ->setRepositoryAPI($this->getRepositoryAPI())
->setSourceRef($this->branch) ->setSourceRef($this->branch)
->setTargetRemote($this->remote)
->setTargetOnto($this->onto)
->setShouldHold($should_hold) ->setShouldHold($should_hold)
->setShouldKeep($this->keepBranch) ->setShouldKeep($this->keepBranch)
->setShouldSquash($this->useSquash) ->setShouldSquash($this->useSquash)
->setShouldPreview($this->preview) ->setShouldPreview($this->preview)
->setRemoteArgument($remote_arg)
->setOntoArgument($onto_arg)
->setBuildMessageCallback(array($this, 'buildEngineMessage')); ->setBuildMessageCallback(array($this, 'buildEngineMessage'));
// The goal here is to raise errors with flags early (which is cheap),
// before we test if the working copy is clean (which can be slow). This
// could probably be structured more cleanly.
$engine->parseArguments();
$this->requireCleanWorkingCopy();
$engine->execute(); $engine->execute();
if (!$should_hold && !$this->preview) { if (!$should_hold && !$this->preview) {
@ -337,123 +342,6 @@ EOTEXT
return $refspec; return $refspec;
} }
private function readEngineArguments() {
// NOTE: This is hard-coded for Git right now.
// TODO: Clean this up and move it into LandEngines.
$onto = $this->getEngineOnto();
$remote = $this->getEngineRemote();
// This just overwrites work we did earlier, but it has to be up in this
// class for now because other parts of the workflow still depend on it.
$this->onto = $onto;
$this->remote = $remote;
$this->ontoRemoteBranch = $this->remote.'/'.$onto;
}
private function getEngineOnto() {
$onto = $this->getArgument('onto');
if ($onto !== null) {
$this->writeInfo(
pht('TARGET'),
pht(
'Landing onto "%s", selected by the --onto flag.',
$onto));
return $onto;
}
$api = $this->getRepositoryAPI();
$path = $api->getPathToUpstream($this->branch);
if ($path->getLength()) {
$cycle = $path->getCycle();
if ($cycle) {
$this->writeWarn(
pht('LOCAL CYCLE'),
pht(
'Local branch tracks an upstream, but following it leads to a '.
'local cycle; ignoring branch upstream.'));
echo tsprintf(
"\n %s\n\n",
implode(' -> ', $cycle));
} else {
if ($path->isConnectedToRemote()) {
$onto = $path->getRemoteBranchName();
$this->writeInfo(
pht('TARGET'),
pht(
'Landing onto "%s", selected by following tracking branches '.
'upstream to the closest remote.',
$onto));
return $onto;
} else {
$this->writeInfo(
pht('NO PATH TO UPSTREAM'),
pht(
'Local branch tracks an upstream, but there is no path '.
'to a remote; ignoring branch upstream.'));
}
}
}
$config_key = 'arc.land.onto.default';
$onto = $this->getConfigFromAnySource($config_key);
if ($onto !== null) {
$this->writeInfo(
pht('TARGET'),
pht(
'Landing onto "%s", selected by "%s" configuration.',
$onto,
$config_key));
return $onto;
}
$onto = 'master';
$this->writeInfo(
pht('TARGET'),
pht(
'Landing onto "%s", the default target under git.',
$onto));
return $onto;
}
private function getEngineRemote() {
$remote = $this->getArgument('remote');
if ($remote !== null) {
$this->writeInfo(
pht('REMOTE'),
pht(
'Using remote "%s", selected by the --remote flag.',
$remote));
return $remote;
}
$api = $this->getRepositoryAPI();
$path = $api->getPathToUpstream($this->branch);
$remote = $path->getRemoteRemoteName();
if ($remote !== null) {
$this->writeInfo(
pht('REMOTE'),
pht(
'Using remote "%s", selected by following tracking branches '.
'upstream to the closest remote.',
$remote));
return $remote;
}
$remote = 'origin';
$this->writeInfo(
pht('REMOTE'),
pht(
'Using remote "%s", the default remote under git.',
$remote));
return $remote;
}
private function readArguments() { private function readArguments() {
$repository_api = $this->getRepositoryAPI(); $repository_api = $this->getRepositoryAPI();
$this->isGit = $repository_api instanceof ArcanistGitAPI; $this->isGit = $repository_api instanceof ArcanistGitAPI;