Something went wrong. Try again.
@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
Something went wrong. Try again.
4.3 kB · 144 lines
PHP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145<?php
final class DiffusionLowLevelCommitFieldsQuery extends DiffusionLowLevelQuery {
private $ref; private $revisionMatchData = array( 'usedURI' => null, 'foundURI' => null, 'validDomain' => null, 'matchHashType' => null, 'matchHashValue' => null, );
public function withCommitRef(DiffusionCommitRef $ref) { $this->ref = $ref; return $this; }
public function getRevisionMatchData() { return $this->revisionMatchData; }
private function setRevisionMatchData($key, $value) { $this->revisionMatchData[$key] = $value; return $this; }
protected function executeQuery() { $ref = $this->ref; $message = $ref->getMessage(); $hashes = $ref->getHashes();
$params = array( 'corpus' => $message, 'partial' => true, );
$result = id(new ConduitCall('differential.parsecommitmessage', $params)) ->setUser(PhabricatorUser::getOmnipotentUser()) ->execute(); $fields = $result['fields'];
$revision_id = idx($fields, 'revisionID'); if ($revision_id) { $this->setRevisionMatchData('usedURI', true); } else { $this->setRevisionMatchData('usedURI', false); } $revision_id_info = $result['revisionIDFieldInfo']; $this->setRevisionMatchData('foundURI', $revision_id_info['value']); $this->setRevisionMatchData( 'validDomain', $revision_id_info['validDomain']);
// If there is no "Differential Revision:" field in the message, try to // identify the revision by doing a hash lookup.
if (!$revision_id && $hashes) { $hash_list = array(); foreach ($hashes as $hash) { $hash_list[] = array($hash->getHashType(), $hash->getHashValue()); } $revisions = id(new DifferentialRevisionQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->needHashes(true) ->withCommitHashes($hash_list) ->execute();
if ($revisions) { $revision = $this->pickBestRevision($revisions);
$fields['revisionID'] = $revision->getID(); $revision_hashes = $revision->getHashes();
$revision_hashes = DiffusionCommitHash::convertArrayToObjects( $revision_hashes); $revision_hashes = mpull($revision_hashes, null, 'getHashType');
// sort the hashes in the order the mighty // @{class:ArcanstDifferentialRevisionHash} does; probably unnecessary // but should future proof things nicely. $revision_hashes = array_select_keys( $revision_hashes, ArcanistDifferentialRevisionHash::getTypes());
foreach ($hashes as $hash) { $revision_hash = idx($revision_hashes, $hash->getHashType()); if (!$revision_hash) { continue; } if ($revision_hash->getHashValue() == $hash->getHashValue()) { $this->setRevisionMatchData( 'matchHashType', $hash->getHashType()); $this->setRevisionMatchData( 'matchHashValue', $hash->getHashValue()); break; } } } }
return $fields; }
/** * When querying for revisions by hash, more than one revision may be found. * This function identifies the "best" revision from such a set. Typically, * there is only one revision found. Otherwise, we try to pick an accepted * revision first, followed by an open revision, and otherwise we go with a * closed or abandoned revision as a last resort. * * @param array<DifferentialRevision> $revisions */ private function pickBestRevision(array $revisions) { assert_instances_of($revisions, DifferentialRevision::class);
// If we have more than one revision of a given status, choose the most // recently updated one. $revisions = msort($revisions, 'getDateModified'); $revisions = array_reverse($revisions);
// Try to find an accepted revision first. foreach ($revisions as $revision) { if ($revision->isAccepted()) { return $revision; } }
// Try to find an open revision. foreach ($revisions as $revision) { if (!$revision->isClosed()) { return $revision; } }
// Settle for whatever's left. return head($revisions); }
}