Page MenuHomePhabricator

D10705.id25703.diff
No OneTemporary

D10705.id25703.diff

diff --git a/src/applications/audit/editor/PhabricatorAuditEditor.php b/src/applications/audit/editor/PhabricatorAuditEditor.php
--- a/src/applications/audit/editor/PhabricatorAuditEditor.php
+++ b/src/applications/audit/editor/PhabricatorAuditEditor.php
@@ -3,6 +3,38 @@
final class PhabricatorAuditEditor
extends PhabricatorApplicationTransactionEditor {
+ const MAX_FILES_SHOWN_IN_EMAIL = 1000;
+
+ private $auditReasonMap = array();
+ private $heraldEmailPHIDs = array();
+ private $differentialRevision;
+ private $affectedFiles;
+ private $rawPatch;
+
+ public function addAuditReason($phid, $reason) {
+ if (!isset($this->auditReasonMap[$phid])) {
+ $this->auditReasonMap[$phid] = array();
+ }
+ $this->auditReasonMap[$phid][] = $reason;
+ return $this;
+ }
+
+ private function getAuditReasons($phid) {
+ if (isset($this->auditReasonMap[$phid])) {
+ return $this->auditReasonMap[$phid];
+ }
+ return array(pht('Added by %s.', $this->getActor()->getUsername()));
+ }
+
+ public function setRawPatch($patch) {
+ $this->rawPatch = $patch;
+ return $this;
+ }
+
+ public function getRawPatch() {
+ return $this->rawPatch;
+ }
+
public function getEditorApplicationClass() {
return 'PhabricatorAuditApplication';
}
@@ -17,6 +49,8 @@
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_EDGE;
+ $types[] = PhabricatorAuditTransaction::TYPE_PUSH;
+
// TODO: These will get modernized eventually, but that can happen one
// at a time later on.
$types[] = PhabricatorAuditActionConstants::ACTION;
@@ -44,6 +78,7 @@
switch ($xaction->getTransactionType()) {
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
+ case PhabricatorAuditTransaction::TYPE_PUSH:
return null;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
// TODO: For now, just record the added PHIDs. Eventually, turn these
@@ -62,6 +97,7 @@
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
case PhabricatorAuditActionConstants::ADD_AUDITORS:
+ case PhabricatorAuditTransaction::TYPE_PUSH:
return $xaction->getNewValue();
}
@@ -80,6 +116,10 @@
case PhabricatorAuditActionConstants::INLINE:
case PhabricatorAuditActionConstants::ADD_AUDITORS:
return;
+ case PhabricatorAuditTransaction::TYPE_PUSH:
+ $object->writeImportStatusFlag(
+ PhabricatorRepositoryCommit::IMPORTED_HERALD);
+ return;
}
return parent::applyCustomInternalTransaction($object, $xaction);
@@ -95,6 +135,7 @@
case PhabricatorTransactions::TYPE_EDGE:
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
+ case PhabricatorAuditTransaction::TYPE_PUSH:
return;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
$new = $xaction->getNewValue();
@@ -123,10 +164,7 @@
->setCommitPHID($object->getPHID())
->setAuditorPHID($phid)
->setAuditStatus($audit_requested)
- ->setAuditReasons(
- array(
- 'Added by '.$actor->getUsername(),
- ))
+ ->setAuditReasons($this->getAuditReasons($phid))
->save();
}
@@ -268,6 +306,59 @@
return $xactions;
}
+ protected function expandTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ $xactions = parent::expandTransaction($object, $xaction);
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorAuditTransaction::TYPE_PUSH:
+ $request = $this->createAuditRequestTransactionFromCommitMessage(
+ $object);
+ if ($request) {
+ $xactions[] = $request;
+ }
+ break;
+ default:
+ break;
+ }
+ return $xactions;
+ }
+
+ private function createAuditRequestTransactionFromCommitMessage(
+ PhabricatorRepositoryCommit $commit) {
+
+ $data = $commit->getCommitData();
+ $message = $data->getCommitMessage();
+
+ $matches = null;
+ if (!preg_match('/^Auditors:\s*(.*)$/im', $message, $matches)) {
+ return array();
+ }
+
+ $phids = id(new PhabricatorObjectListQuery())
+ ->setViewer($this->getActor())
+ ->setAllowPartialResults(true)
+ ->setAllowedTypes(
+ array(
+ PhabricatorPeopleUserPHIDType::TYPECONST,
+ PhabricatorProjectProjectPHIDType::TYPECONST,
+ ))
+ ->setObjectList($matches[1])
+ ->execute();
+
+ if (!$phids) {
+ return array();
+ }
+
+ foreach ($phids as $phid) {
+ $this->addAuditReason($phid, 'Requested by Author');
+ }
+ return id(new PhabricatorAuditTransaction())
+ ->setTransactionType(PhabricatorAuditActionConstants::ADD_AUDITORS)
+ ->setNewValue($phids);
+ }
+
protected function sortTransactions(array $xactions) {
$xactions = parent::sortTransactions($xactions);
@@ -386,13 +477,24 @@
$subject = "{$name}: {$summary}";
$thread_topic = "Commit {$monogram}{$identifier}";
- return id(new PhabricatorMetaMTAMail())
+ $template = id(new PhabricatorMetaMTAMail())
->setSubject($subject)
->addHeader('Thread-Topic', $thread_topic);
+
+ $this->attachPatch(
+ $template,
+ $object->getRepository(),
+ $object);
+
+ return $template;
}
protected function getMailTo(PhabricatorLiskDAO $object) {
$phids = array();
+ if ($this->heraldEmailPHIDs) {
+ $phids = $this->heraldEmailPHIDs;
+ }
+
if ($object->getAuthorPHID()) {
$phids[] = $object->getAuthorPHID();
}
@@ -414,12 +516,17 @@
$body = parent::buildMailBody($object, $xactions);
$type_inline = PhabricatorAuditActionConstants::INLINE;
+ $type_push = PhabricatorAuditTransaction::TYPE_PUSH;
+ $is_push = false;
$inlines = array();
foreach ($xactions as $xaction) {
if ($xaction->getTransactionType() == $type_inline) {
$inlines[] = $xaction;
}
+ if ($xaction->getTransactionType() == $type_push) {
+ $is_push = true;
+ }
}
if ($inlines) {
@@ -428,6 +535,24 @@
$this->renderInlineCommentsForMail($object, $inlines));
}
+ if ($is_push) {
+ $data = $object->getCommitData();
+ $description = $data->getCommitMessage();
+ $body->addRawSection($description);
+ if ($this->differentialRevision) {
+ $differential = PhabricatorEnv::getProductionURI(
+ '/D'.$this->differentialRevision->getID());
+ } else {
+ $differential = pht('No revision.');
+ }
+ $body->addTextSection(pht('DIFFERENTIAL REVISION'), $differential);
+ $body->addTextSection(pht('AFFECTED FILES'), $this->affectedFiles);
+ $this->inlinePatch(
+ $body,
+ $object->getRepository(),
+ $object);
+ }
+
// Reload the commit to pull commit data.
$commit = id(new DiffusionCommitQuery())
->setViewer($this->requireActor())
@@ -481,6 +606,68 @@
return $body;
}
+ private function attachPatch(
+ PhabricatorMetaMTAMail $template,
+ PhabricatorRepository $repository,
+ PhabricatorRepositoryCommit $commit) {
+
+ if (!$this->getRawPatch()) {
+ return;
+ }
+
+ $attach_key = 'metamta.diffusion.attach-patches';
+ $attach_patches = PhabricatorEnv::getEnvConfig($attach_key);
+ if (!$attach_patches) {
+ return;
+ }
+
+ $encoding = $repository->getDetail('encoding', 'UTF-8');
+
+ $raw_patch = $this->getRawPatch();
+ $commit_name = $repository->formatCommitName(
+ $commit->getCommitIdentifier());
+
+ $template->addAttachment(
+ new PhabricatorMetaMTAAttachment(
+ $raw_patch,
+ $commit_name.'.patch',
+ 'text/x-patch; charset='.$encoding));
+ }
+
+ private function inlinePatch(
+ PhabricatorMetaMTAMailBody $body,
+ PhabricatorRepository $repository,
+ PhabricatorRepositoryCommit $commit) {
+
+ if (!$this->getRawPatch()) {
+ return;
+ }
+
+ $inline_key = 'metamta.diffusion.inline-patches';
+ $inline_patches = PhabricatorEnv::getEnvConfig($inline_key);
+ if (!$inline_patches) {
+ return;
+ }
+
+ $raw_patch = $this->getRawPatch();
+ $result = null;
+ $len = substr_count($raw_patch, "\n");
+ if ($len <= $inline_patches) {
+ // We send email as utf8, so we need to convert the text to utf8 if
+ // we can.
+ $encoding = $repository->getDetail('encoding', 'UTF-8');
+ if ($encoding) {
+ $raw_patch = phutil_utf8_convert($raw_patch, 'UTF-8', $encoding);
+ }
+ $result = phutil_utf8ize($raw_patch);
+ }
+
+ if ($result) {
+ $result = "PATCH\n\n{$result}\n";
+ }
+ $body->addRawSection($result);
+ }
+
private function renderInlineCommentsForMail(
PhabricatorLiskDAO $object,
array $inline_xactions) {
@@ -521,6 +708,93 @@
return $this->isCommitMostlyImported($object);
}
+ protected function shouldApplyHeraldRules(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ foreach ($xactions as $xaction) {
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorAuditTransaction::TYPE_PUSH:
+ $repository = $object->getRepository();
+ if ($repository->isImporting()) {
+ return false;
+ }
+ if ($repository->getDetail('herald-disabled')) {
+ return false;
+ }
+ return true;
+ default:
+ break;
+ }
+ }
+ return parent::shouldApplyHeraldRules($object, $xactions);
+ }
+
+ protected function buildHeraldAdapter(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ return id(new HeraldCommitAdapter())
+ ->setCommit($object);
+ }
+
+ protected function didApplyHeraldRules(
+ PhabricatorLiskDAO $object,
+ HeraldAdapter $adapter,
+ HeraldTranscript $transcript) {
+
+ $xactions = array();
+
+ $audit_phids = $adapter->getAuditMap();
+ foreach ($audit_phids as $phid => $rule_ids) {
+ foreach ($rule_ids as $rule_id) {
+ $this->addAuditReason(
+ $phid,
+ pht(
+ '%s Triggered Audit',
+ "H{$rule_id}"));
+ }
+ }
+ if ($audit_phids) {
+ $xactions[] = id(new PhabricatorAuditTransaction())
+ ->setTransactionType(PhabricatorAuditActionConstants::ADD_AUDITORS)
+ ->setNewValue(array_keys($audit_phids));
+ }
+
+ $cc_phids = $adapter->getAddCCMap();
+ $add_ccs = array('+' => array());
+ foreach ($cc_phids as $phid => $rule_ids) {
+ $add_ccs['+'][$phid] = $phid;
+ }
+ $xactions[] = id(new PhabricatorAuditTransaction())
+ ->setTransactionType(PhabricatorTransactions::TYPE_SUBSCRIBERS)
+ ->setNewValue($add_ccs);
+
+ $this->heraldEmailPHIDs = $adapter->getEmailPHIDs();
+
+ HarbormasterBuildable::applyBuildPlans(
+ $object->getPHID(),
+ $object->getRepository()->getPHID(),
+ $adapter->getBuildPlans());
+
+ $this->differentialRevision = $adapter->loadDifferentialRevision();
+
+ $limit = self::MAX_FILES_SHOWN_IN_EMAIL;
+ $files = $adapter->loadAffectedPaths();
+ sort($files);
+ if (count($files) > $limit) {
+ array_splice($files, $limit);
+ $files[] = pht(
+ '(This commit affected more than %d files. Only %d are shown here '.
+ 'and additional ones are truncated.)',
+ $limit,
+ $limit);
+ }
+ $this->affectedFiles = implode("\n", $files);
+
+ return $xactions;
+ }
+
private function isCommitMostlyImported(PhabricatorLiskDAO $object) {
$has_message = PhabricatorRepositoryCommit::IMPORTED_MESSAGE;
$has_changes = PhabricatorRepositoryCommit::IMPORTED_CHANGE;
diff --git a/src/applications/audit/storage/PhabricatorAuditTransaction.php b/src/applications/audit/storage/PhabricatorAuditTransaction.php
--- a/src/applications/audit/storage/PhabricatorAuditTransaction.php
+++ b/src/applications/audit/storage/PhabricatorAuditTransaction.php
@@ -3,6 +3,8 @@
final class PhabricatorAuditTransaction
extends PhabricatorApplicationTransaction {
+ const TYPE_PUSH = 'audit:push';
+
public function getApplicationName() {
return 'audit';
}
@@ -21,6 +23,16 @@
$type = $this->getTransactionType();
switch ($type) {
+ case self::TYPE_PUSH:
+ $phids[] = $this->getObjectPHID();
+ $data = $this->getNewValue();
+ if ($data['authorPHID']) {
+ $phids[] = $data['authorPHID'];
+ }
+ if ($data['committerPHID']) {
+ $phids[] = $data['committerPHID'];
+ }
+ break;
case PhabricatorAuditActionConstants::ADD_CCS:
case PhabricatorAuditActionConstants::ADD_AUDITORS:
$old = $this->getOldValue();
@@ -59,6 +71,8 @@
break;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
return pht('Added Auditors');
+ case self::TYPE_PUSH:
+ return pht('Pushed');
}
return parent::getActionName();
@@ -104,10 +118,47 @@
}
switch ($type) {
+ case self::TYPE_PUSH:
+ $author = null;
+ if ($new['authorPHID']) {
+ $author = $this->renderHandleLink($new['authorPHID']);
+ } else {
+ $author = $new['authorName'];
+ }
+
+ $committer = null;
+ if ($new['committerPHID']) {
+ $committer = $this->renderHandleLink($new['committerPHID']);
+ } else if ($new['committerName']) {
+ $committer = $new['committerName'];
+ }
+
+ $commit = $this->renderHandleLink($this->getObjectPHID());
+
+ if (!$committer) {
+ $committer = $author;
+ $author = null;
+ }
+
+ if ($author) {
+ $title = pht(
+ '%s committed %s (authored by %s).',
+ $committer,
+ $commit,
+ $author);
+ } else {
+ $title = pht(
+ '%s committed %s.',
+ $committer,
+ $commit);
+ }
+ return $title;
+
case PhabricatorAuditActionConstants::INLINE:
return pht(
'%s added inline comments.',
$author_handle);
+
case PhabricatorAuditActionConstants::ADD_CCS:
if ($add && $rem) {
return pht(
@@ -203,6 +254,40 @@
}
switch ($type) {
+ case self::TYPE_PUSH:
+ $author = null;
+ if ($new['authorPHID']) {
+ $author = $this->renderHandleLink($new['authorPHID']);
+ } else {
+ $author = $new['authorName'];
+ }
+
+ $committer = null;
+ if ($new['committerPHID']) {
+ $committer = $this->renderHandleLink($new['committerPHID']);
+ } else if ($new['committerName']) {
+ $committer = $new['committerName'];
+ }
+
+ if (!$committer) {
+ $committer = $author;
+ $author = null;
+ }
+
+ if ($author) {
+ $title = pht(
+ '%s committed %s (authored by %s).',
+ $committer,
+ $object_handle,
+ $author);
+ } else {
+ $title = pht(
+ '%s committed %s.',
+ $committer,
+ $object_handle);
+ }
+ return $title;
+
case PhabricatorAuditActionConstants::INLINE:
return pht(
'%s added inline comments to %s.',
@@ -265,6 +350,15 @@
return parent::getTitleForFeed($story);
}
+ public function getBodyForFeed(PhabricatorFeedStory $story) {
+ switch ($this->getTransactionType()) {
+ case self::TYPE_PUSH:
+ $data = $this->getNewValue();
+ return $story->renderSummary($data['summary']);
+ }
+ return parent::getBodyForFeed($story);
+ }
+
// TODO: These two mail methods can likely be abstracted by introducing a
// formal concept of "inline comment" transactions.
@@ -288,6 +382,9 @@
switch ($this->getTransactionType()) {
case PhabricatorAuditActionConstants::INLINE:
return null;
+ case self::TYPE_PUSH:
+ $data = $this->getNewValue();
+ return $data['description'];
}
return parent::getBodyForMail();
diff --git a/src/applications/feed/story/PhabricatorFeedStory.php b/src/applications/feed/story/PhabricatorFeedStory.php
--- a/src/applications/feed/story/PhabricatorFeedStory.php
+++ b/src/applications/feed/story/PhabricatorFeedStory.php
@@ -387,7 +387,7 @@
}
}
- final protected function renderSummary($text, $len = 128) {
+ final public function renderSummary($text, $len = 128) {
if ($len) {
$text = id(new PhutilUTF8StringTruncator())
->setMaximumGlyphs($len)
diff --git a/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php b/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php
--- a/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php
+++ b/src/applications/repository/worker/PhabricatorRepositoryCommitHeraldWorker.php
@@ -3,7 +3,6 @@
final class PhabricatorRepositoryCommitHeraldWorker
extends PhabricatorRepositoryCommitParserWorker {
- const MAX_FILES_SHOWN_IN_EMAIL = 1000;
public function getRequiredLeaseTime() {
// Herald rules may take a long time to process.
@@ -14,31 +13,6 @@
PhabricatorRepository $repository,
PhabricatorRepositoryCommit $commit) {
- $result = $this->applyHeraldRules($repository, $commit);
-
- $commit->writeImportStatusFlag(
- PhabricatorRepositoryCommit::IMPORTED_HERALD);
-
- return $result;
- }
-
- private function applyHeraldRules(
- PhabricatorRepository $repository,
- PhabricatorRepositoryCommit $commit) {
-
- $commit->attachRepository($repository);
-
- // Don't take any actions on an importing repository. Principally, this
- // avoids generating thousands of audits or emails when you import an
- // established repository on an existing install.
- if ($repository->isImporting()) {
- return;
- }
-
- if ($repository->getDetail('herald-disabled')) {
- return;
- }
-
$data = id(new PhabricatorRepositoryCommitData())->loadOneWhere(
'commitID = %d',
$commit->getID());
@@ -50,402 +24,44 @@
'or no longer exists.'));
}
- $adapter = id(new HeraldCommitAdapter())
- ->setCommit($commit);
-
- $rules = id(new HeraldRuleQuery())
- ->setViewer(PhabricatorUser::getOmnipotentUser())
- ->withContentTypes(array($adapter->getAdapterContentType()))
- ->withDisabled(false)
- ->needConditionsAndActions(true)
- ->needAppliedToPHIDs(array($adapter->getPHID()))
- ->needValidateAuthors(true)
- ->execute();
-
- $engine = new HeraldEngine();
-
- $effects = $engine->applyRules($rules, $adapter);
- $engine->applyEffects($effects, $adapter, $rules);
- $xscript = $engine->getTranscript();
-
- $audit_phids = $adapter->getAuditMap();
- $cc_phids = $adapter->getAddCCMap();
- if ($audit_phids || $cc_phids) {
- $this->createAudits($commit, $audit_phids, $cc_phids, $rules);
- }
-
- HarbormasterBuildable::applyBuildPlans(
- $commit->getPHID(),
- $repository->getPHID(),
- $adapter->getBuildPlans());
-
- $explicit_auditors = $this->createAuditsFromCommitMessage($commit, $data);
-
- $this->publishFeedStory($repository, $commit, $data);
-
- $herald_targets = $adapter->getEmailPHIDs();
-
- $email_phids = array_unique(
- array_merge(
- $explicit_auditors,
- array_keys($cc_phids),
- $herald_targets));
- if (!$email_phids) {
- return;
- }
-
- $revision = $adapter->loadDifferentialRevision();
- if ($revision) {
- $name = $revision->getTitle();
- } else {
- $name = $data->getSummary();
- }
-
- $author_phid = $data->getCommitDetail('authorPHID');
- $reviewer_phid = $data->getCommitDetail('reviewerPHID');
-
- $phids = array_filter(
- array(
- $author_phid,
- $reviewer_phid,
- $commit->getPHID(),
- ));
-
- $handles = id(new PhabricatorHandleQuery())
- ->setViewer(PhabricatorUser::getOmnipotentUser())
- ->withPHIDs($phids)
- ->execute();
-
- $commit_handle = $handles[$commit->getPHID()];
- $commit_name = $commit_handle->getName();
-
- if ($author_phid) {
- $author_name = $handles[$author_phid]->getName();
- } else {
- $author_name = $data->getAuthorName();
- }
-
- if ($reviewer_phid) {
- $reviewer_name = $handles[$reviewer_phid]->getName();
- } else {
- $reviewer_name = null;
- }
-
- $who = implode(', ', array_filter(array($author_name, $reviewer_name)));
-
- $description = $data->getCommitMessage();
-
- $commit_uri = PhabricatorEnv::getProductionURI($commit_handle->getURI());
- $differential = $revision
- ? PhabricatorEnv::getProductionURI('/D'.$revision->getID())
- : 'No revision.';
-
- $limit = self::MAX_FILES_SHOWN_IN_EMAIL;
- $files = $adapter->loadAffectedPaths();
- sort($files);
- if (count($files) > $limit) {
- array_splice($files, $limit);
- $files[] = '(This commit affected more than '.$limit.' files. '.
- 'Only '.$limit.' are shown here and additional ones are truncated.)';
- }
- $files = implode("\n", $files);
-
- $xscript_id = $xscript->getID();
-
- $why_uri = '/herald/transcript/'.$xscript_id.'/';
-
- $reply_handler = PhabricatorAuditCommentEditor::newReplyHandlerForCommit(
- $commit);
-
- $template = new PhabricatorMetaMTAMail();
-
- $inline_patch_text = $this->buildPatch($template, $repository, $commit);
-
- $body = new PhabricatorMetaMTAMailBody();
- $body->addRawSection($description);
- $body->addTextSection(pht('DETAILS'), $commit_uri);
-
- // TODO: This should be integrated properly once we move to
- // ApplicationTransactions.
- $field_list = PhabricatorCustomField::getObjectFields(
- $commit,
- PhabricatorCustomField::ROLE_APPLICATIONTRANSACTIONS);
- $field_list
- ->setViewer(PhabricatorUser::getOmnipotentUser())
- ->readFieldsFromStorage($commit);
- foreach ($field_list->getFields() as $field) {
- try {
- $field->buildApplicationTransactionMailBody(
- new DifferentialTransaction(), // Bogus object to satisfy typehint.
- $body);
- } catch (Exception $ex) {
- // Log the exception and continue.
- phlog($ex);
- }
- }
-
- $body->addTextSection(pht('DIFFERENTIAL REVISION'), $differential);
- $body->addTextSection(pht('AFFECTED FILES'), $files);
- $body->addReplySection($reply_handler->getReplyHandlerInstructions());
- $body->addHeraldSection($why_uri);
- $body->addRawSection($inline_patch_text);
- $body = $body->render();
-
- $prefix = PhabricatorEnv::getEnvConfig('metamta.diffusion.subject-prefix');
-
- $threading = PhabricatorAuditCommentEditor::getMailThreading(
- $repository,
- $commit);
- list($thread_id, $thread_topic) = $threading;
-
- $template->setRelatedPHID($commit->getPHID());
- $template->setSubject("{$commit_name}: {$name}");
- $template->setSubjectPrefix($prefix);
- $template->setVarySubjectPrefix('[Commit]');
- $template->setBody($body);
- $template->setThreadID($thread_id, $is_new = true);
- $template->addHeader('Thread-Topic', $thread_topic);
- $template->setIsBulk(true);
-
- $template->addHeader('X-Herald-Rules', $xscript->getXHeraldRulesHeader());
- if ($author_phid) {
- $template->setFrom($author_phid);
- }
-
- // TODO: We should verify that each recipient can actually see the
- // commit before sending them email (T603).
+ $commit->attachRepository($repository);
+ $commit->attachCommitData($data);
- $mails = $reply_handler->multiplexMail(
- $template,
- id(new PhabricatorHandleQuery())
- ->setViewer(PhabricatorUser::getOmnipotentUser())
- ->withPHIDs($email_phids)
- ->execute(),
+ $content_source = PhabricatorContentSource::newForSource(
+ PhabricatorContentSource::SOURCE_DAEMON,
array());
- foreach ($mails as $mail) {
- $mail->saveAndSend();
- }
- }
-
- private function createAudits(
- PhabricatorRepositoryCommit $commit,
- array $map,
- array $ccmap,
- array $rules) {
- assert_instances_of($rules, 'HeraldRule');
-
- $requests = id(new PhabricatorRepositoryAuditRequest())->loadAllWhere(
- 'commitPHID = %s',
- $commit->getPHID());
- $requests = mpull($requests, null, 'getAuditorPHID');
-
- $rules = mpull($rules, null, 'getID');
-
- $maps = array(
- PhabricatorAuditStatusConstants::AUDIT_REQUIRED => $map,
- );
-
- foreach ($maps as $status => $map) {
- foreach ($map as $phid => $rule_ids) {
- $request = idx($requests, $phid);
- if ($request) {
- continue;
- }
- $reasons = array();
- foreach ($rule_ids as $id) {
- $rule_name = '?';
- if ($rules[$id]) {
- $rule_name = $rules[$id]->getName();
- }
- if ($status == PhabricatorAuditStatusConstants::AUDIT_REQUIRED) {
- $reasons[] = pht(
- '%s Triggered Audit',
- "H{$id} {$rule_name}");
- } else {
- $reasons[] = pht(
- '%s Triggered CC',
- "H{$id} {$rule_name}");
- }
- }
-
- $request = new PhabricatorRepositoryAuditRequest();
- $request->setCommitPHID($commit->getPHID());
- $request->setAuditorPHID($phid);
- $request->setAuditStatus($status);
- $request->setAuditReasons($reasons);
- $request->save();
- }
- }
-
- $commit->updateAuditStatus($requests);
- $commit->save();
-
- if ($ccmap) {
- id(new PhabricatorSubscriptionsEditor())
- ->setActor(PhabricatorUser::getOmnipotentUser())
- ->setObject($commit)
- ->subscribeExplicit(array_keys($ccmap))
- ->save();
- }
- }
-
-
- /**
- * Find audit requests in the "Auditors" field if it is present and trigger
- * explicit audit requests.
- */
- private function createAuditsFromCommitMessage(
- PhabricatorRepositoryCommit $commit,
- PhabricatorRepositoryCommitData $data) {
-
- $message = $data->getCommitMessage();
-
- $matches = null;
- if (!preg_match('/^Auditors:\s*(.*)$/im', $message, $matches)) {
- return array();
- }
-
- $phids = id(new PhabricatorObjectListQuery())
- ->setViewer(PhabricatorUser::getOmnipotentUser())
- ->setAllowPartialResults(true)
- ->setAllowedTypes(
- array(
- PhabricatorPeopleUserPHIDType::TYPECONST,
- PhabricatorProjectProjectPHIDType::TYPECONST,
- ))
- ->setObjectList($matches[1])
- ->execute();
-
- if (!$phids) {
- return array();
- }
-
- $requests = id(new PhabricatorRepositoryAuditRequest())->loadAllWhere(
- 'commitPHID = %s',
- $commit->getPHID());
- $requests = mpull($requests, null, 'getAuditorPHID');
-
- foreach ($phids as $phid) {
- if (isset($requests[$phid])) {
- continue;
- }
-
- $request = new PhabricatorRepositoryAuditRequest();
- $request->setCommitPHID($commit->getPHID());
- $request->setAuditorPHID($phid);
- $request->setAuditStatus(
- PhabricatorAuditStatusConstants::AUDIT_REQUESTED);
- $request->setAuditReasons(
- array(
- 'Requested by Author',
- ));
- $request->save();
-
- $requests[$phid] = $request;
- }
-
- $commit->updateAuditStatus($requests);
- $commit->save();
-
- return $phids;
- }
-
- private function publishFeedStory(
- PhabricatorRepository $repository,
- PhabricatorRepositoryCommit $commit,
- PhabricatorRepositoryCommitData $data) {
-
- if (time() > $commit->getEpoch() + (24 * 60 * 60)) {
- // Don't publish stories that are more than 24 hours old, to avoid
- // ridiculous levels of feed spam if a repository is imported without
- // disabling feed publishing.
- return;
- }
-
- $author_phid = $commit->getAuthorPHID();
$committer_phid = $data->getCommitDetail('committerPHID');
-
- $publisher = new PhabricatorFeedStoryPublisher();
- $publisher->setStoryType(PhabricatorFeedStoryTypeConstants::STORY_COMMIT);
- $publisher->setStoryData(
- array(
- 'commitPHID' => $commit->getPHID(),
+ $author_phid = $data->getCommitDetail('authorPHID');
+ $acting_as_phid = nonempty(
+ $committer_phid,
+ $author_phid,
+ id(new PhabricatorDiffusionApplication())->getPHID());
+
+ $editor = id(new PhabricatorAuditEditor())
+ ->setActor(PhabricatorUser::getOmnipotentUser())
+ ->setActingAsPHID($acting_as_phid)
+ ->setContentSource($content_source);
+
+ $xactions = array();
+ $xactions[] = id(new PhabricatorAuditTransaction())
+ ->setTransactionType(PhabricatorAuditTransaction::TYPE_PUSH)
+ ->setNewValue(array(
+ 'description' => $data->getCommitMessage(),
'summary' => $data->getSummary(),
'authorName' => $data->getAuthorName(),
- 'authorPHID' => $author_phid,
+ 'authorPHID' => $commit->getAuthorPHID(),
'committerName' => $data->getCommitDetail('committer'),
- 'committerPHID' => $committer_phid,
+ 'committerPHID' => $data->getCommitDetail('committerPHID'),
));
- $publisher->setStoryTime($commit->getEpoch());
- $publisher->setRelatedPHIDs(
- array_filter(
- array(
- $author_phid,
- $committer_phid,
- )));
- if ($author_phid) {
- $publisher->setStoryAuthorPHID($author_phid);
- }
- $publisher->publish();
- }
-
- private function buildPatch(
- PhabricatorMetaMTAMail $template,
- PhabricatorRepository $repository,
- PhabricatorRepositoryCommit $commit) {
-
- $attach_key = 'metamta.diffusion.attach-patches';
- $inline_key = 'metamta.diffusion.inline-patches';
-
- $attach_patches = PhabricatorEnv::getEnvConfig($attach_key);
- $inline_patches = PhabricatorEnv::getEnvConfig($inline_key);
-
- if (!$attach_patches && !$inline_patches) {
- return;
- }
-
- $encoding = $repository->getDetail('encoding', 'UTF-8');
-
- $result = null;
- $patch_error = null;
-
try {
$raw_patch = $this->loadRawPatchText($repository, $commit);
- if ($attach_patches) {
- $commit_name = $repository->formatCommitName(
- $commit->getCommitIdentifier());
-
- $template->addAttachment(
- new PhabricatorMetaMTAAttachment(
- $raw_patch,
- $commit_name.'.patch',
- 'text/x-patch; charset='.$encoding));
- }
} catch (Exception $ex) {
phlog($ex);
- $patch_error = 'Unable to generate: '.$ex->getMessage();
- }
-
- if ($patch_error) {
- $result = $patch_error;
- } else if ($inline_patches) {
- $len = substr_count($raw_patch, "\n");
- if ($len <= $inline_patches) {
- // We send email as utf8, so we need to convert the text to utf8 if
- // we can.
- if ($encoding) {
- $raw_patch = phutil_utf8_convert($raw_patch, 'UTF-8', $encoding);
- }
- $result = phutil_utf8ize($raw_patch);
- }
+ $raw_patch = pht('Unable to generate patch: %s', $ex->getMessage());
}
-
- if ($result) {
- $result = "PATCH\n\n{$result}\n";
- }
-
- return $result;
+ $editor->setRawPatch($raw_patch);
+ return $editor->applyTransactions($commit, $xactions);
}
private function loadRawPatchText(

File Metadata

Mime Type
text/plain
Expires
Sun, Jun 9, 6:05 AM (2 w, 5 d ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/sf/fz/aljd5xmq7znf5vli
Default Alt Text
D10705.id25703.diff (31 KB)

Event Timeline