1
0
Fork 0
mirror of https://we.phorge.it/source/arcanist.git synced 2024-11-26 08:42:40 +01:00
phorge-arcanist/src/workflow/ArcanistUpgradeWorkflow.php
epriestley 0b3cd39230 Update the "WorkingCopy" API and create a fallback "Filesystem" working copy
Summary:
Ref T11968.

  - Allow "WorkingCopy" objects to maintain an API object and update callers ("get...()" instead of "new...()").
  - Always generate a WorkingCopy object and a RepositoryAPI object.

Currently, code has to look like this:

```
$working_copy = ...
if ($working_copy) {
  $repository_api = ...
  if ($repository_api [instanceof ... ]) {
```

This is clunky. There's also no reason some "arc" commands can't run outside a VCS working directory without special-casing how they interact with the filesystem.

Conceptually, model the filesystem as a trivial VCS (which stores exactly one commit, always amends onto it, and discards history). Provide a trivial WorkingCopy and API for it.

(This change isn't terribly interesting on its own, but chips away at landing the new Hardpoint infrastructure.)

Test Plan: Ran `arc version`, `arc upgrade`.

Maniphest Tasks: T11968

Differential Revision: https://secure.phabricator.com/D21070
2020-04-08 09:22:43 -07:00

133 lines
3.7 KiB
PHP

<?php
final class ArcanistUpgradeWorkflow
extends ArcanistArcWorkflow {
public function getWorkflowName() {
return 'upgrade';
}
public function getWorkflowInformation() {
$help = pht(<<<EOTEXT
Upgrade Arcanist to the latest version.
EOTEXT
);
return $this->newWorkflowInformation()
->setSynopsis(pht('Upgrade Arcanist to the latest version.'))
->addExample(pht('**upgrade**'))
->setHelp($help);
}
public function getWorkflowArguments() {
return array();
}
public function runWorkflow() {
$log = $this->getLogEngine();
$roots = array(
'arcanist' => dirname(phutil_get_library_root('arcanist')),
);
$supported_branches = array(
'master',
'stable',
);
$supported_branches = array_fuse($supported_branches);
foreach ($roots as $library => $root) {
$log->writeStatus(
pht('PREPARING'),
pht(
'Preparing to upgrade "%s"...',
$library));
$working_copy = ArcanistWorkingCopy::newFromWorkingDirectory($root);
$repository_api = $working_copy->getRepositoryAPI();
$is_git = ($repository_api instanceof ArcanistGitAPI);
if (!$is_git) {
throw new PhutilArgumentUsageException(
pht(
'The "arc upgrade" workflow uses "git pull" to upgrade '.
'Arcanist, but the "arcanist/" directory (in "%s") is not a Git '.
'working copy. You must leave "arcanist/" as a Git '.
'working copy to use "arc upgrade".',
$root));
}
// NOTE: Don't use requireCleanWorkingCopy() here because it tries to
// amend changes and generally move the workflow forward. We just want to
// abort if there are local changes and make the user sort things out.
$uncommitted = $repository_api->getUncommittedStatus();
if ($uncommitted) {
$message = pht(
'You have uncommitted changes in the working copy ("%s") for this '.
'library ("%s"):',
$root,
$library);
$list = id(new PhutilConsoleList())
->setWrap(false)
->addItems(array_keys($uncommitted));
id(new PhutilConsoleBlock())
->addParagraph($message)
->addList($list)
->addParagraph(
pht(
'Discard these changes before running "arc upgrade".'))
->draw();
throw new PhutilArgumentUsageException(
pht('"arc upgrade" can only upgrade clean working copies.'));
}
$branch_name = $repository_api->getBranchName();
if (!isset($supported_branches[$branch_name])) {
throw new PhutilArgumentUsageException(
pht(
'Library "%s" (in "%s") is on branch "%s", but this branch is '.
'not supported for automatic upgrades. Supported branches are: '.
'%s.',
$library,
$root,
$branch_name,
implode(', ', array_keys($supported_branches))));
}
$log->writeStatus(
pht('UPGRADING'),
pht(
'Upgrading "%s" (on branch "%s").',
$library,
$branch_name));
$command = csprintf(
'git pull --rebase origin -- %R',
$branch_name);
$future = (new PhutilExecPassthru($command))
->setCWD($root);
try {
$this->newCommand($future)
->execute();
} catch (Exception $ex) {
// If we failed, try to go back to the old state, then throw the
// original exception.
exec_manual('git rebase --abort');
throw $ex;
}
}
$log->writeSuccess(
pht('UPGRADED'),
pht('Your copy of Arcanist is now up to date.'));
return 0;
}
}