mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-08 21:08:29 +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:
parent
49b03c0353
commit
aca0f642a3
5 changed files with 192 additions and 68 deletions
|
@ -1887,6 +1887,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuditManagementWorkflow' => 'applications/audit/management/PhabricatorAuditManagementWorkflow.php',
|
'PhabricatorAuditManagementWorkflow' => 'applications/audit/management/PhabricatorAuditManagementWorkflow.php',
|
||||||
'PhabricatorAuditReplyHandler' => 'applications/audit/mail/PhabricatorAuditReplyHandler.php',
|
'PhabricatorAuditReplyHandler' => 'applications/audit/mail/PhabricatorAuditReplyHandler.php',
|
||||||
'PhabricatorAuditStatusConstants' => 'applications/audit/constants/PhabricatorAuditStatusConstants.php',
|
'PhabricatorAuditStatusConstants' => 'applications/audit/constants/PhabricatorAuditStatusConstants.php',
|
||||||
|
'PhabricatorAuditSynchronizeManagementWorkflow' => 'applications/audit/management/PhabricatorAuditSynchronizeManagementWorkflow.php',
|
||||||
'PhabricatorAuditTransaction' => 'applications/audit/storage/PhabricatorAuditTransaction.php',
|
'PhabricatorAuditTransaction' => 'applications/audit/storage/PhabricatorAuditTransaction.php',
|
||||||
'PhabricatorAuditTransactionComment' => 'applications/audit/storage/PhabricatorAuditTransactionComment.php',
|
'PhabricatorAuditTransactionComment' => 'applications/audit/storage/PhabricatorAuditTransactionComment.php',
|
||||||
'PhabricatorAuditTransactionQuery' => 'applications/audit/query/PhabricatorAuditTransactionQuery.php',
|
'PhabricatorAuditTransactionQuery' => 'applications/audit/query/PhabricatorAuditTransactionQuery.php',
|
||||||
|
@ -6783,6 +6784,7 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorAuditManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
'PhabricatorAuditManagementWorkflow' => 'PhabricatorManagementWorkflow',
|
||||||
'PhabricatorAuditReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
'PhabricatorAuditReplyHandler' => 'PhabricatorApplicationTransactionReplyHandler',
|
||||||
'PhabricatorAuditStatusConstants' => 'Phobject',
|
'PhabricatorAuditStatusConstants' => 'Phobject',
|
||||||
|
'PhabricatorAuditSynchronizeManagementWorkflow' => 'PhabricatorAuditManagementWorkflow',
|
||||||
'PhabricatorAuditTransaction' => 'PhabricatorModularTransaction',
|
'PhabricatorAuditTransaction' => 'PhabricatorModularTransaction',
|
||||||
'PhabricatorAuditTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
'PhabricatorAuditTransactionComment' => 'PhabricatorApplicationTransactionComment',
|
||||||
'PhabricatorAuditTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
'PhabricatorAuditTransactionQuery' => 'PhabricatorApplicationTransactionQuery',
|
||||||
|
|
|
@ -1,4 +1,90 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
abstract class PhabricatorAuditManagementWorkflow
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,79 +9,17 @@ final class PhabricatorAuditUpdateOwnersManagementWorkflow
|
||||||
->setExamples('**update-owners** ...')
|
->setExamples('**update-owners** ...')
|
||||||
->setSynopsis(pht('Update package relationships for commits.'))
|
->setSynopsis(pht('Update package relationships for commits.'))
|
||||||
->setArguments(
|
->setArguments(
|
||||||
array(
|
array_merge(
|
||||||
array(
|
$this->getCommitConstraintArguments(),
|
||||||
'name' => 'all',
|
array()));
|
||||||
'help' => pht('Update all commits in all repositories.'),
|
|
||||||
),
|
|
||||||
array(
|
|
||||||
'name' => 'objects',
|
|
||||||
'wildcard' => true,
|
|
||||||
'help' => pht('Update named commits and repositories.'),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function execute(PhutilArgumentParser $args) {
|
public function execute(PhutilArgumentParser $args) {
|
||||||
$viewer = $this->getViewer();
|
$viewer = $this->getViewer();
|
||||||
|
$objects = $this->loadCommitsWithConstraints($args);
|
||||||
$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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($objects as $object) {
|
foreach ($objects as $object) {
|
||||||
if ($object instanceof PhabricatorRepository) {
|
$commits = $this->loadCommitsForConstraintObject($object);
|
||||||
$commits = id(new DiffusionCommitQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withRepository($object)
|
|
||||||
->execute();
|
|
||||||
} else {
|
|
||||||
$commits = array($object);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($commits as $commit) {
|
foreach ($commits as $commit) {
|
||||||
$repository = $commit->getRepository();
|
$repository = $commit->getRepository();
|
||||||
|
|
|
@ -156,6 +156,46 @@ Audit Tips
|
||||||
- Press "?" to view keyboard shortcuts.
|
- 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
|
Next Steps
|
||||||
==========
|
==========
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue