1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-02-02 09:58:24 +01:00

Add a "bin/audit synchronize" command

Summary: Ref T10978. This is just a maintenance convenience script. It can fix up overall commit state after you `bin/audit delete` stuff or nuke a bunch of stuff from the database, as I did on `secure.phabricator.com`.

Test Plan: Ran `bin/audit synchronize`, and `bin/audit update-owners`.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10978

Differential Revision: https://secure.phabricator.com/D17271
This commit is contained in:
epriestley 2017-01-31 08:52:38 -08:00
parent 49b03c0353
commit aca0f642a3
5 changed files with 192 additions and 68 deletions

View file

@ -1887,6 +1887,7 @@ phutil_register_library_map(array(
'PhabricatorAuditManagementWorkflow' => 'applications/audit/management/PhabricatorAuditManagementWorkflow.php',
'PhabricatorAuditReplyHandler' => 'applications/audit/mail/PhabricatorAuditReplyHandler.php',
'PhabricatorAuditStatusConstants' => 'applications/audit/constants/PhabricatorAuditStatusConstants.php',
'PhabricatorAuditSynchronizeManagementWorkflow' => 'applications/audit/management/PhabricatorAuditSynchronizeManagementWorkflow.php',
'PhabricatorAuditTransaction' => 'applications/audit/storage/PhabricatorAuditTransaction.php',
'PhabricatorAuditTransactionComment' => 'applications/audit/storage/PhabricatorAuditTransactionComment.php',
'PhabricatorAuditTransactionQuery' => 'applications/audit/query/PhabricatorAuditTransactionQuery.php',
@ -6783,6 +6784,7 @@ phutil_register_library_map(array(
'PhabricatorAuditManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorAuditReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
'PhabricatorAuditStatusConstants' => 'Phobject',
'PhabricatorAuditSynchronizeManagementWorkflow' => 'PhabricatorAuditManagementWorkflow',
'PhabricatorAuditTransaction' => 'PhabricatorModularTransaction',
'PhabricatorAuditTransactionComment' => 'PhabricatorApplicationTransactionComment',
'PhabricatorAuditTransactionQuery' => 'PhabricatorApplicationTransactionQuery',

View file

@ -1,4 +1,90 @@
<?php
abstract class PhabricatorAuditManagementWorkflow
extends PhabricatorManagementWorkflow {}
extends PhabricatorManagementWorkflow {
protected function getCommitConstraintArguments() {
return array(
array(
'name' => 'all',
'help' => pht('Update all commits in all repositories.'),
),
array(
'name' => 'objects',
'wildcard' => true,
'help' => pht('Update named commits and repositories.'),
),
);
}
protected function loadCommitsWithConstraints(PhutilArgumentParser $args) {
$viewer = $this->getViewer();
$all = $args->getArg('all');
$names = $args->getArg('objects');
if (!$names && !$all) {
throw new PhutilArgumentUsageException(
pht(
'Specify "--all" to affect everything, or a list of specific '.
'commits or repositories to affect.'));
} else if ($names && $all) {
throw new PhutilArgumentUsageException(
pht(
'Specify either a list of objects to affect or "--all", but not '.
'both.'));
}
if ($all) {
$objects = new LiskMigrationIterator(new PhabricatorRepository());
} else {
$query = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->withNames($names);
$query->execute();
$objects = array();
$results = $query->getNamedResults();
foreach ($names as $name) {
if (!isset($results[$name])) {
throw new PhutilArgumentUsageException(
pht(
'Object "%s" is not a valid object.',
$name));
}
$object = $results[$name];
if (!($object instanceof PhabricatorRepository) &&
!($object instanceof PhabricatorRepositoryCommit)) {
throw new PhutilArgumentUsageException(
pht(
'Object "%s" is not a valid repository or commit.',
$name));
}
$objects[] = $object;
}
}
return $objects;
}
protected function loadCommitsForConstraintObject($object) {
$viewer = $this->getViewer();
if ($object instanceof PhabricatorRepository) {
$commits = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withRepository($object)
->execute();
} else {
$commits = array($object);
}
return $commits;
}
}

View file

@ -0,0 +1,58 @@
<?php
final class PhabricatorAuditSynchronizeManagementWorkflow
extends PhabricatorAuditManagementWorkflow {
protected function didConstruct() {
$this
->setName('synchronize')
->setExamples('**synchronize** ...')
->setSynopsis(pht('Update audit status for commits.'))
->setArguments(
array_merge(
$this->getCommitConstraintArguments(),
array()));
}
public function execute(PhutilArgumentParser $args) {
$viewer = $this->getViewer();
$objects = $this->loadCommitsWithConstraints($args);
foreach ($objects as $object) {
$commits = $this->loadCommitsForConstraintObject($object);
foreach ($commits as $commit) {
$commit = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withPHIDs(array($commit->getPHID()))
->needAuditRequests(true)
->executeOne();
if (!$commit) {
continue;
}
$old_status = $commit->getAuditStatus();
$commit->updateAuditStatus($commit->getAudits());
$new_status = $commit->getAuditStatus();
if ($old_status == $new_status) {
echo tsprintf(
"%s\n",
pht(
'No changes for "%s".',
$commit->getDisplayName()));
} else {
echo tsprintf(
"%s\n",
pht(
'Updated "%s": "%s" -> "%s".',
$commit->getDisplayName(),
PhabricatorAuditCommitStatusConstants::getStatusName(
$old_status),
PhabricatorAuditCommitStatusConstants::getStatusName(
$new_status)));
}
}
}
}
}

View file

@ -9,79 +9,17 @@ final class PhabricatorAuditUpdateOwnersManagementWorkflow
->setExamples('**update-owners** ...')
->setSynopsis(pht('Update package relationships for commits.'))
->setArguments(
array(
array(
'name' => 'all',
'help' => pht('Update all commits in all repositories.'),
),
array(
'name' => 'objects',
'wildcard' => true,
'help' => pht('Update named commits and repositories.'),
),
));
array_merge(
$this->getCommitConstraintArguments(),
array()));
}
public function execute(PhutilArgumentParser $args) {
$viewer = $this->getViewer();
$all = $args->getArg('all');
$names = $args->getArg('objects');
if (!$names && !$all) {
throw new PhutilArgumentUsageException(
pht(
'Specify "--all" to update everything, or a list of specific '.
'commits or repositories to update.'));
} else if ($names && $all) {
throw new PhutilArgumentUsageException(
pht(
'Specify either a list of objects to update or "--all", but not '.
'both.'));
}
if ($all) {
$objects = new LiskMigrationIterator(new PhabricatorRepository());
} else {
$query = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->withNames($names);
$query->execute();
$objects = array();
$results = $query->getNamedResults();
foreach ($names as $name) {
if (!isset($results[$name])) {
throw new PhutilArgumentUsageException(
pht(
'Object "%s" is not a valid object.',
$name));
}
$object = $results[$name];
if (!($object instanceof PhabricatorRepository) &&
!($object instanceof PhabricatorRepositoryCommit)) {
throw new PhutilArgumentUsageException(
pht(
'Object "%s" is not a valid repository or commit.',
$name));
}
$objects[] = $object;
}
}
$objects = $this->loadCommitsWithConstraints($args);
foreach ($objects as $object) {
if ($object instanceof PhabricatorRepository) {
$commits = id(new DiffusionCommitQuery())
->setViewer($viewer)
->withRepository($object)
->execute();
} else {
$commits = array($object);
}
$commits = $this->loadCommitsForConstraintObject($object);
foreach ($commits as $commit) {
$repository = $commit->getRepository();

View file

@ -156,6 +156,46 @@ Audit Tips
- Press "?" to view keyboard shortcuts.
Audit Maintenance
=================
The `bin/audit` command allows you to perform several maintenance operations.
Get more information about a command by running:
```
phabricator/ $ ./bin/audit help <command>
```
Supported operations are:
**Delete Audits**: Delete audits that match certain parameters with
`bin/audit delete`.
You can use this command to forcibly delete requests which may have triggered
incorrectly (for example, because a package or Herald rule was configured in an
overbroad way).
After deleting audits, you may want to run `bin/audit synchronize` to
synchronize audit state.
**Synchronize Audit State**: Synchronize the audit state of commits to the
current open audit requests with `bin/audit synchronize`.
Normally, overall audit state is automatically kept up to date as changes are
made to an audit. However, if you delete audits or manually update the database
to make changes to audit request state, the state of corresponding commits may
no longer be correct.
This command will update commits so their overall audit state reflects the
cumulative state of their actual audit requests.
**Update Owners Package Membership**: Update which Owners packages commits
belong to with `bin/audit update-owners`.
Normally, commits are automatically associated with packages when they are
imported. You can use this command to manually rebuild this association if
you run into problems with it.
Next Steps
==========