Differential D20467 Diff 48843 src/applications/repository/worker/PhabricatorRepositoryCommitPublishWorker.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/repository/worker/PhabricatorRepositoryCommitPublishWorker.php
- This file was moved from src/applications/repository/worker/PhabricatorRepositoryCommitOwnersWorker.php.
<?php | <?php | ||||
final class PhabricatorRepositoryCommitOwnersWorker | final class PhabricatorRepositoryCommitPublishWorker | ||||
extends PhabricatorRepositoryCommitParserWorker { | extends PhabricatorRepositoryCommitParserWorker { | ||||
protected function getImportStepFlag() { | protected function getImportStepFlag() { | ||||
return PhabricatorRepositoryCommit::IMPORTED_OWNERS; | return PhabricatorRepositoryCommit::IMPORTED_PUBLISH; | ||||
} | |||||
public function getRequiredLeaseTime() { | |||||
// Herald rules may take a long time to process. | |||||
return phutil_units('4 hours in seconds'); | |||||
amckinley: I can see that this comes from `PhabricatorRepositoryCommitHeraldWorker`, but maybe it's a good… | |||||
} | } | ||||
protected function parseCommit( | protected function parseCommit( | ||||
PhabricatorRepository $repository, | PhabricatorRepository $repository, | ||||
PhabricatorRepositoryCommit $commit) { | PhabricatorRepositoryCommit $commit) { | ||||
if (!$this->shouldSkipImportStep()) { | if (!$this->shouldSkipImportStep()) { | ||||
$this->triggerOwnerAudits($repository, $commit); | $this->publishCommit($repository, $commit); | ||||
$commit->writeImportStatusFlag($this->getImportStepFlag()); | $commit->writeImportStatusFlag($this->getImportStepFlag()); | ||||
} | } | ||||
if ($this->shouldQueueFollowupTasks()) { | // This is the last task in the sequence, so we don't need to queue any | ||||
$this->queueTask( | // followup workers. | ||||
'PhabricatorRepositoryCommitHeraldWorker', | |||||
array( | |||||
'commitID' => $commit->getID(), | |||||
)); | |||||
} | |||||
} | } | ||||
private function triggerOwnerAudits( | private function publishCommit( | ||||
PhabricatorRepository $repository, | PhabricatorRepository $repository, | ||||
PhabricatorRepositoryCommit $commit) { | PhabricatorRepositoryCommit $commit) { | ||||
$viewer = PhabricatorUser::getOmnipotentUser(); | $viewer = PhabricatorUser::getOmnipotentUser(); | ||||
$publisher = $repository->newPublisher(); | $publisher = $repository->newPublisher(); | ||||
if (!$publisher->shouldPublishCommit($commit)) { | if (!$publisher->shouldPublishCommit($commit)) { | ||||
return; | return; | ||||
} | } | ||||
$commit_phid = $commit->getPHID(); | |||||
// Reload the commit to get the commit data, identities, and any | |||||
// outstanding audit requests. | |||||
$commit = id(new DiffusionCommitQuery()) | |||||
->setViewer($viewer) | |||||
->withPHIDs(array($commit_phid)) | |||||
->needCommitData(true) | |||||
->needIdentities(true) | |||||
->needAuditRequests(true) | |||||
->executeOne(); | |||||
if (!$commit) { | |||||
throw new PhabricatorWorkerPermanentFailureException( | |||||
pht( | |||||
'Failed to reload commit "%s".', | |||||
$commit_phid)); | |||||
} | |||||
$xactions = array( | |||||
$this->newAuditTransactions($commit), | |||||
$this->newPublishTransactions($commit), | |||||
); | |||||
$xactions = array_mergev($xactions); | |||||
$acting_phid = $this->getPublishAsPHID($commit); | |||||
$content_source = $this->newContentSource(); | |||||
$editor = $commit->getApplicationTransactionEditor() | |||||
->setActor($viewer) | |||||
->setActingAsPHID($acting_phid) | |||||
->setContinueOnNoEffect(true) | |||||
->setContinueOnMissingFields(true) | |||||
->setContentSource($content_source); | |||||
try { | |||||
$raw_patch = $this->loadRawPatchText($repository, $commit); | |||||
} catch (Exception $ex) { | |||||
$raw_patch = pht('Unable to generate patch: %s', $ex->getMessage()); | |||||
} | |||||
$editor->setRawPatch($raw_patch); | |||||
$editor->applyTransactions($commit, $xactions); | |||||
} | |||||
private function getPublishAsPHID(PhabricatorRepositoryCommit $commit) { | |||||
if ($commit->hasCommitterIdentity()) { | |||||
return $commit->getCommitterIdentity()->getIdentityDisplayPHID(); | |||||
} | |||||
if ($commit->hasAuthorIdentity()) { | |||||
return $commit->getAuthorIdentity()->getIdentityDisplayPHID(); | |||||
} | |||||
return id(new PhabricatorDiffusionApplication())->getPHID(); | |||||
} | |||||
private function newPublishTransactions(PhabricatorRepositoryCommit $commit) { | |||||
$data = $commit->getCommitData(); | |||||
$xactions = array(); | |||||
$xactions[] = $commit->getApplicationTransactionTemplate() | |||||
->setTransactionType(PhabricatorAuditTransaction::TYPE_COMMIT) | |||||
->setDateCreated($commit->getEpoch()) | |||||
->setNewValue( | |||||
array( | |||||
'description' => $data->getCommitMessage(), | |||||
'summary' => $data->getSummary(), | |||||
'authorName' => $data->getAuthorName(), | |||||
'authorPHID' => $commit->getAuthorPHID(), | |||||
'committerName' => $data->getCommitDetail('committer'), | |||||
'committerPHID' => $data->getCommitDetail('committerPHID'), | |||||
)); | |||||
return $xactions; | |||||
} | |||||
private function newAuditTransactions(PhabricatorRepositoryCommit $commit) { | |||||
$viewer = PhabricatorUser::getOmnipotentUser(); | |||||
$repository = $commit->getRepository(); | |||||
$affected_paths = PhabricatorOwnerPathQuery::loadAffectedPaths( | $affected_paths = PhabricatorOwnerPathQuery::loadAffectedPaths( | ||||
$repository, | $repository, | ||||
$commit, | $commit, | ||||
PhabricatorUser::getOmnipotentUser()); | PhabricatorUser::getOmnipotentUser()); | ||||
$affected_packages = PhabricatorOwnersPackage::loadAffectedPackages( | $affected_packages = PhabricatorOwnersPackage::loadAffectedPackages( | ||||
$repository, | $repository, | ||||
$affected_paths); | $affected_paths); | ||||
$commit->writeOwnersEdges(mpull($affected_packages, 'getPHID')); | $commit->writeOwnersEdges(mpull($affected_packages, 'getPHID')); | ||||
if (!$affected_packages) { | if (!$affected_packages) { | ||||
return; | return array(); | ||||
} | |||||
$commit = id(new DiffusionCommitQuery()) | |||||
->setViewer($viewer) | |||||
->withPHIDs(array($commit->getPHID())) | |||||
->needCommitData(true) | |||||
->needAuditRequests(true) | |||||
->executeOne(); | |||||
if (!$commit) { | |||||
return; | |||||
} | } | ||||
$data = $commit->getCommitData(); | $data = $commit->getCommitData(); | ||||
$author_phid = $data->getCommitDetail('authorPHID'); | $author_phid = $data->getCommitDetail('authorPHID'); | ||||
$revision_id = $data->getCommitDetail('differential.revisionID'); | $revision_id = $data->getCommitDetail('differential.revisionID'); | ||||
if ($revision_id) { | if ($revision_id) { | ||||
$revision = id(new DifferentialRevisionQuery()) | $revision = id(new DifferentialRevisionQuery()) | ||||
Show All 25 Lines | foreach ($affected_packages as $package) { | ||||
continue; | continue; | ||||
} | } | ||||
$auditor_phids[] = $package->getPHID(); | $auditor_phids[] = $package->getPHID(); | ||||
} | } | ||||
// If none of the packages are triggering audits, we're all done. | // If none of the packages are triggering audits, we're all done. | ||||
if (!$auditor_phids) { | if (!$auditor_phids) { | ||||
return; | return array(); | ||||
} | } | ||||
$audit_type = DiffusionCommitAuditorsTransaction::TRANSACTIONTYPE; | $audit_type = DiffusionCommitAuditorsTransaction::TRANSACTIONTYPE; | ||||
$owners_phid = id(new PhabricatorOwnersApplication()) | |||||
->getPHID(); | |||||
$content_source = $this->newContentSource(); | |||||
$xactions = array(); | $xactions = array(); | ||||
$xactions[] = $commit->getApplicationTransactionTemplate() | $xactions[] = $commit->getApplicationTransactionTemplate() | ||||
->setTransactionType($audit_type) | ->setTransactionType($audit_type) | ||||
->setNewValue( | ->setNewValue( | ||||
array( | array( | ||||
'+' => array_fuse($auditor_phids), | '+' => array_fuse($auditor_phids), | ||||
)); | )); | ||||
$editor = $commit->getApplicationTransactionEditor() | return $xactions; | ||||
->setActor($viewer) | |||||
->setActingAsPHID($owners_phid) | |||||
->setContinueOnNoEffect(true) | |||||
->setContinueOnMissingFields(true) | |||||
->setContentSource($content_source); | |||||
$editor->applyTransactions($commit, $xactions); | |||||
} | } | ||||
private function shouldTriggerAudit( | private function shouldTriggerAudit( | ||||
PhabricatorRepositoryCommit $commit, | PhabricatorRepositoryCommit $commit, | ||||
PhabricatorOwnersPackage $package, | PhabricatorOwnersPackage $package, | ||||
$author_phid, | $author_phid, | ||||
$revision) { | $revision) { | ||||
▲ Show 20 Lines • Show All 112 Lines • ▼ Show 20 Lines | private function isOwnerInvolved( | ||||
if ($found_accept) { | if ($found_accept) { | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
private function loadRawPatchText( | |||||
PhabricatorRepository $repository, | |||||
PhabricatorRepositoryCommit $commit) { | |||||
$viewer = PhabricatorUser::getOmnipotentUser(); | |||||
$identifier = $commit->getCommitIdentifier(); | |||||
$drequest = DiffusionRequest::newFromDictionary( | |||||
array( | |||||
'user' => $viewer, | |||||
'repository' => $repository, | |||||
)); | |||||
$time_key = 'metamta.diffusion.time-limit'; | |||||
$byte_key = 'metamta.diffusion.byte-limit'; | |||||
$time_limit = PhabricatorEnv::getEnvConfig($time_key); | |||||
$byte_limit = PhabricatorEnv::getEnvConfig($byte_key); | |||||
$diff_info = DiffusionQuery::callConduitWithDiffusionRequest( | |||||
$viewer, | |||||
$drequest, | |||||
'diffusion.rawdiffquery', | |||||
array( | |||||
'commit' => $identifier, | |||||
'linesOfContext' => 3, | |||||
'timeout' => $time_limit, | |||||
'byteLimit' => $byte_limit, | |||||
)); | |||||
if ($diff_info['tooSlow']) { | |||||
throw new Exception( | |||||
pht( | |||||
'Patch generation took longer than configured limit ("%s") of '. | |||||
'%s second(s).', | |||||
$time_key, | |||||
new PhutilNumber($time_limit))); | |||||
} | |||||
if ($diff_info['tooHuge']) { | |||||
$pretty_limit = phutil_format_bytes($byte_limit); | |||||
throw new Exception( | |||||
pht( | |||||
'Patch size exceeds configured byte size limit ("%s") of %s.', | |||||
$byte_key, | |||||
$pretty_limit)); | |||||
} | |||||
$file_phid = $diff_info['filePHID']; | |||||
$file = id(new PhabricatorFileQuery()) | |||||
->setViewer($viewer) | |||||
->withPHIDs(array($file_phid)) | |||||
->executeOne(); | |||||
if (!$file) { | |||||
throw new Exception( | |||||
pht( | |||||
'Failed to load file ("%s") returned by "%s".', | |||||
$file_phid, | |||||
'diffusion.rawdiffquery')); | |||||
} | |||||
return $file->loadFileData(); | |||||
} | |||||
} | } |
I can see that this comes from PhabricatorRepositoryCommitHeraldWorker, but maybe it's a good reason to separate these workers?