1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 00:32:42 +01:00

Add workflow to create repository identities

Summary:
Depends on D19443. Creates a workflow for populating the new identity table by iterating over commits, either one repo at a time or all at once. Locally caches identities to avoid fetching them `inf` times. An actual migration that invokes this workflow will come in another revision that won't land until at least next week.

Performance is ~2k commits in 4.9s on my local machine.

Test Plan: Ran locally a few times with a few different states of the `repository_identity` table.

Reviewers: epriestley

Reviewed By: epriestley

Subscribers: jcox, Korvin, PHID-OPKG-gm6ozazyms6q6i22gyam

Differential Revision: https://secure.phabricator.com/D19446
This commit is contained in:
Austin McKinley 2018-05-10 18:41:19 -07:00
parent fe5fde5910
commit 2f6784ee1c
3 changed files with 104 additions and 1 deletions

View file

@ -4118,6 +4118,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryManagementMovePathsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementMovePathsWorkflow.php',
'PhabricatorRepositoryManagementParentsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementParentsWorkflow.php',
'PhabricatorRepositoryManagementPullWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementPullWorkflow.php',
'PhabricatorRepositoryManagementRebuildIdentitiesWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementRebuildIdentitiesWorkflow.php',
'PhabricatorRepositoryManagementRefsWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementRefsWorkflow.php',
'PhabricatorRepositoryManagementReparseWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementReparseWorkflow.php',
'PhabricatorRepositoryManagementThawWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementThawWorkflow.php',
@ -10031,6 +10032,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryManagementMovePathsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementParentsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementPullWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementRebuildIdentitiesWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementRefsWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementReparseWorkflow' => 'PhabricatorRepositoryManagementWorkflow',
'PhabricatorRepositoryManagementThawWorkflow' => 'PhabricatorRepositoryManagementWorkflow',

View file

@ -0,0 +1,101 @@
<?php
final class PhabricatorRepositoryManagementRebuildIdentitiesWorkflow
extends PhabricatorRepositoryManagementWorkflow {
protected function didConstruct() {
$this
->setName('rebuild-identities')
->setExamples(
'**rebuild-identities** [__options__] __repository__')
->setSynopsis(pht('Rebuild repository identities from commits.'))
->setArguments(
array(
array(
'name' => 'repositories',
'wildcard' => true,
),
array(
'name' => 'all',
'help' => pht('Rebuild identities across all repositories.'),
),
));
}
public function execute(PhutilArgumentParser $args) {
$console = PhutilConsole::getConsole();
$all = $args->getArg('all');
$repositories = $args->getArg('repositories');
if ($all xor empty($repositories)) {
throw new PhutilArgumentUsageException(
pht('Specify --all or a list of repositories, but not both.'));
}
$query = id(new DiffusionCommitQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->needCommitData(true);
if ($repositories) {
$repos = $this->loadRepositories($args, 'repositories');
$query->withRepositoryIDs(mpull($repos, 'getID'));
}
$iterator = new PhabricatorQueryIterator($query);
foreach ($iterator as $commit) {
$data = $commit->getCommitData();
$author_name = $data->getAuthorName();
$author_identity = $this->getIdentityForCommit(
$commit, $author_name);
$commit->setAuthorIdentityPHID($author_identity->getPHID());
$data->setCommitDetail(
'authorIdentityPHID', $author_identity->getPHID());
$committer_name = $data->getCommitDetail('committer', null);
if ($committer_name) {
$committer_identity = $this->getIdentityForCommit(
$commit, $committer_name);
$commit->setCommitterIdentityPHID($committer_identity->getPHID());
$data->setCommitDetail(
'committerIdentityPHID', $committer_identity->getPHID());
}
$commit->save();
$data->save();
}
}
private function getIdentityForCommit(
PhabricatorRepositoryCommit $commit, $identity_name) {
static $seen = array();
$identity_key = PhabricatorHash::digestForIndex($identity_name);
if (empty($seen[$identity_key])) {
try {
$user_phid = id(new DiffusionResolveUserQuery())
->withCommit($commit)
->withName($identity_name)
->execute();
$identity = id(new PhabricatorRepositoryIdentity())
->setAuthorPHID($commit->getPHID())
->setIdentityName($identity_name)
->setAutomaticGuessedUserPHID($user_phid)
->save();
} catch (AphrontDuplicateKeyQueryException $ex) {
// Somehow this identity already exists?
$identity = id(new PhabricatorRepositoryIdentityQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withIdentityNames(array($identity_name))
->executeOne();
}
$seen[$identity_key] = $identity;
}
return $seen[$identity_key];
}
}

View file

@ -6,7 +6,7 @@ final class PhabricatorRepositoryManagementReparseWorkflow
protected function didConstruct() {
$this
->setName('reparse')
->setExamples('**reparse** [options] __repository__')
->setExamples('**reparse** [options] __commit__')
->setSynopsis(
pht(
'**reparse** __what__ __which_parts__ [--trace] [--force]'."\n\n".