@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
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Record new commits in the push log

Summary:
Ref T4195. Like the previous diffs, these both create a useful log and give us an object to hand off to Herald.

Surface this information in Diffusion, too, and clean things up a little bit.

Test Plan: {F87565}

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T4195

Differential Revision: https://secure.phabricator.com/D7718

+144 -40
+73 -21
src/applications/diffusion/controller/DiffusionCommitController.php
··· 403 403 array $audit_requests) { 404 404 405 405 assert_instances_of($parents, 'PhabricatorRepositoryCommit'); 406 - $user = $this->getRequest()->getUser(); 406 + $viewer = $this->getRequest()->getUser(); 407 407 $commit_phid = $commit->getPHID(); 408 + $drequest = $this->getDiffusionRequest(); 409 + $repository = $drequest->getRepository(); 408 410 409 411 $edge_query = id(new PhabricatorEdgeQuery()) 410 412 ->withSourcePHIDs(array($commit_phid)) ··· 440 442 } 441 443 } 442 444 445 + // NOTE: We should never normally have more than a single push log, but 446 + // it can occur naturally if a commit is pushed, then the branch it was 447 + // on is deleted, then the commit is pushed again (or through other similar 448 + // chains of events). This should be rare, but does not indicate a bug 449 + // or data issue. 450 + 451 + // NOTE: We never query push logs in SVN because the commiter is always 452 + // the pusher and the commit time is always the push time; the push log 453 + // is redundant and we save a query by skipping it. 454 + 455 + $push_logs = array(); 456 + if ($repository->isHosted() && !$repository->isSVN()) { 457 + $push_logs = id(new PhabricatorRepositoryPushLogQuery()) 458 + ->setViewer($viewer) 459 + ->withRepositoryPHIDs(array($repository->getPHID())) 460 + ->withNewRefs(array($commit->getCommitIdentifier())) 461 + ->withRefTypes(array(PhabricatorRepositoryPushLog::REFTYPE_COMMIT)) 462 + ->execute(); 463 + foreach ($push_logs as $log) { 464 + $phids[] = $log->getPusherPHID(); 465 + } 466 + } 467 + 443 468 $handles = array(); 444 469 if ($phids) { 445 470 $handles = $this->loadViewerHandles($phids); ··· 494 519 } 495 520 } 496 521 497 - $props['Committed'] = phabricator_datetime($commit->getEpoch(), $user); 522 + if (!$repository->isSVN()) { 523 + $authored_info = id(new PHUIStatusItemView()); 524 + // TODO: In Git, a distinct authorship date is available. When present, 525 + // we should show it here. 498 526 499 - $author_phid = $data->getCommitDetail('authorPHID'); 500 - if ($data->getCommitDetail('authorPHID')) { 501 - $props['Author'] = $handles[$author_phid]->renderLink(); 502 - } else { 503 - $props['Author'] = $data->getAuthorName(); 527 + $author_phid = $data->getCommitDetail('authorPHID'); 528 + $author_name = $data->getAuthorName(); 529 + if ($author_phid) { 530 + $authored_info->setTarget($handles[$author_phid]->renderLink()); 531 + } else if (strlen($author_name)) { 532 + $authored_info->setTarget($author_name); 533 + } 534 + 535 + $props['Authored'] = id(new PHUIStatusListView()) 536 + ->addItem($authored_info); 537 + } 538 + 539 + $committed_info = id(new PHUIStatusItemView()) 540 + ->setNote(phabricator_datetime($commit->getEpoch(), $viewer)); 541 + 542 + $committer_phid = $data->getCommitDetail('committerPHID'); 543 + $committer_name = $data->getCommitDetail('committer'); 544 + if ($committer_phid) { 545 + $committed_info->setTarget($handles[$committer_phid]->renderLink()); 546 + } else if (strlen($committer_name)) { 547 + $committed_info->setTarget($committer_name); 548 + } else if ($author_phid) { 549 + $committed_info->setTarget($handles[$author_phid]->renderLink()); 550 + } else if (strlen($author_name)) { 551 + $committed_info->setTarget($author_name); 552 + } 553 + 554 + $props['Comitted'] = id(new PHUIStatusListView()) 555 + ->addItem($committed_info); 556 + 557 + if ($push_logs) { 558 + $pushed_list = new PHUIStatusListView(); 559 + 560 + foreach ($push_logs as $push_log) { 561 + $pushed_item = id(new PHUIStatusItemView()) 562 + ->setTarget($handles[$push_log->getPusherPHID()]->renderLink()) 563 + ->setNote(phabricator_datetime($push_log->getEpoch(), $viewer)); 564 + $pushed_list->addItem($pushed_item); 565 + } 566 + 567 + $props['Pushed'] = $pushed_list; 504 568 } 505 569 506 570 $reviewer_phid = $data->getCommitDetail('reviewerPHID'); ··· 508 572 $props['Reviewer'] = $handles[$reviewer_phid]->renderLink(); 509 573 } 510 574 511 - $committer = $data->getCommitDetail('committer'); 512 - if ($committer) { 513 - $committer_phid = $data->getCommitDetail('committerPHID'); 514 - if ($data->getCommitDetail('committerPHID')) { 515 - $props['Committer'] = $handles[$committer_phid]->renderLink(); 516 - } else { 517 - $props['Committer'] = $committer; 518 - } 519 - } 520 - 521 575 if ($revision_phid) { 522 576 $props['Differential Revision'] = $handles[$revision_phid]->renderLink(); 523 577 } ··· 530 584 $props['Parents'] = phutil_implode_html(" \xC2\xB7 ", $parent_links); 531 585 } 532 586 533 - $request = $this->getDiffusionRequest(); 534 - 535 587 $props['Branches'] = phutil_tag( 536 588 'span', 537 589 array( ··· 545 597 ), 546 598 pht('Unknown')); 547 599 548 - $callsign = $request->getRepository()->getCallsign(); 600 + $callsign = $repository->getCallsign(); 549 601 $root = '/diffusion/'.$callsign.'/commit/'.$commit->getCommitIdentifier(); 550 602 Javelin::initBehavior( 551 603 'diffusion-commit-branches', ··· 554 606 $root.'/tags/' => 'commit-tags', 555 607 )); 556 608 557 - $refs = $this->buildRefs($request); 609 + $refs = $this->buildRefs($drequest); 558 610 if ($refs) { 559 611 $props['References'] = $refs; 560 612 }
+44 -19
src/applications/diffusion/engine/DiffusionCommitHookEngine.php
··· 18 18 private $subversionRepository; 19 19 private $remoteAddress; 20 20 private $remoteProtocol; 21 + private $transactionKey; 21 22 22 23 public function setRemoteProtocol($remote_protocol) { 23 24 $this->remoteProtocol = $remote_protocol; ··· 37 38 return $this->remoteAddress; 38 39 } 39 40 41 + private function getRemoteAddressForLog() { 42 + // If whatever we have here isn't a valid IPv4 address, just store `null`. 43 + // Older versions of PHP return `-1` on failure instead of `false`. 44 + $remote_address = $this->getRemoteAddress(); 45 + $remote_address = max(0, ip2long($remote_address)); 46 + $remote_address = nonempty($remote_address, null); 47 + return $remote_address; 48 + } 49 + 50 + private function getTransactionKey() { 51 + if (!$this->transactionKey) { 52 + $entropy = Filesystem::readRandomBytes(64); 53 + $this->transactionKey = PhabricatorHash::digestForIndex($entropy); 54 + } 55 + return $this->transactionKey; 56 + } 57 + 40 58 public function setSubversionTransactionInfo($transaction, $repository) { 41 59 $this->subversionTransaction = $transaction; 42 60 $this->subversionRepository = $repository; ··· 89 107 return $err; 90 108 } 91 109 110 + private function newPushLog() { 111 + return PhabricatorRepositoryPushLog::initializeNewLog($this->getViewer()) 112 + ->setRepositoryPHID($this->getRepository()->getPHID()) 113 + ->setEpoch(time()) 114 + ->setRemoteAddress($this->getRemoteAddressForLog()) 115 + ->setRemoteProtocol($this->getRemoteProtocol()) 116 + ->setTransactionKey($this->getTransactionKey()) 117 + ->setRejectCode(PhabricatorRepositoryPushLog::REJECT_ACCEPT) 118 + ->setRejectDetails(null); 119 + } 120 + 121 + 92 122 /** 93 123 * @task git 94 124 */ ··· 106 136 // TODO: Now, do content checks. 107 137 108 138 // TODO: Generalize this; just getting some data in the database for now. 109 - $transaction_key = PhabricatorHash::digestForIndex( 110 - Filesystem::readRandomBytes(64)); 111 - 112 - // If whatever we have here isn't a valid IPv4 address, just store `null`. 113 - // Older versions of PHP return `-1` on failure instead of `false`. 114 - $remote_address = $this->getRemoteAddress(); 115 - $remote_address = max(0, ip2long($remote_address)); 116 - $remote_address = nonempty($remote_address, null); 117 - 118 - $remote_protocol = $this->getRemoteProtocol(); 119 139 120 140 $logs = array(); 121 141 foreach ($updates as $update) { 122 - $log = PhabricatorRepositoryPushLog::initializeNewLog($this->getViewer()) 123 - ->setRepositoryPHID($this->getRepository()->getPHID()) 124 - ->setEpoch(time()) 125 - ->setRemoteAddress($remote_address) 126 - ->setRemoteProtocol($remote_protocol) 127 - ->setTransactionKey($transaction_key) 142 + $log = $this->newPushLog() 128 143 ->setRefType($update['type']) 129 144 ->setRefNameHash(PhabricatorHash::digestForIndex($update['ref'])) 130 145 ->setRefNameRaw($update['ref']) 131 146 ->setRefNameEncoding(phutil_is_utf8($update['ref']) ? 'utf8' : null) 132 147 ->setRefOld($update['old']) 133 148 ->setRefNew($update['new']) 134 - ->setMergeBase(idx($update, 'merge-base')) 135 - ->setRejectCode(PhabricatorRepositoryPushLog::REJECT_ACCEPT) 136 - ->setRejectDetails(null); 149 + ->setMergeBase(idx($update, 'merge-base')); 137 150 138 151 $flags = 0; 139 152 if ($update['operation'] == 'create') { ··· 148 161 } 149 162 150 163 $log->setChangeFlags($flags); 164 + $logs[] = $log; 165 + } 166 + 167 + // Now, build logs for all the commits. 168 + // TODO: Generalize this, too. 169 + $commits = array_mergev(ipull($updates, 'commits')); 170 + $commits = array_unique($commits); 171 + foreach ($commits as $commit) { 172 + $log = $this->newPushLog() 173 + ->setRefType(PhabricatorRepositoryPushLog::REFTYPE_COMMIT) 174 + ->setRefNew($commit) 175 + ->setChangeFlags(PhabricatorRepositoryPushLog::CHANGEFLAG_ADD); 151 176 $logs[] = $log; 152 177 } 153 178
+26
src/applications/repository/query/PhabricatorRepositoryPushLogQuery.php
··· 6 6 private $ids; 7 7 private $repositoryPHIDs; 8 8 private $pusherPHIDs; 9 + private $refTypes; 10 + private $newRefs; 9 11 10 12 public function withIDs(array $ids) { 11 13 $this->ids = $ids; ··· 19 21 20 22 public function withPusherPHIDs(array $pusher_phids) { 21 23 $this->pusherPHIDs = $pusher_phids; 24 + return $this; 25 + } 26 + 27 + public function withRefTypes(array $ref_types) { 28 + $this->refTypes = $ref_types; 29 + return $this; 30 + } 31 + 32 + public function withNewRefs(array $new_refs) { 33 + $this->newRefs = $new_refs; 22 34 return $this; 23 35 } 24 36 ··· 84 96 $conn_r, 85 97 'pusherPHID in (%Ls)', 86 98 $this->pusherPHIDs); 99 + } 100 + 101 + if ($this->refTypes) { 102 + $where[] = qsprintf( 103 + $conn_r, 104 + 'refType IN (%Ls)', 105 + $this->refTypes); 106 + } 107 + 108 + if ($this->newRefs) { 109 + $where[] = qsprintf( 110 + $conn_r, 111 + 'refNew IN (%Ls)', 112 + $this->newRefs); 87 113 } 88 114 89 115 $where[] = $this->buildPagingClause($conn_r);
+1
src/view/phui/PHUIStatusListView.php
··· 6 6 7 7 public function addItem(PHUIStatusItemView $item) { 8 8 $this->items[] = $item; 9 + return $this; 9 10 } 10 11 11 12 protected function canAppendChild() {