Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F19280259
D10705.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
32 KB
Referenced Files
None
Subscribers
None
D10705.diff
View Options
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,37 @@
final class PhabricatorAuditEditor
extends PhabricatorApplicationTransactionEditor {
+ const MAX_FILES_SHOWN_IN_EMAIL = 1000;
+
+ private $auditReasonMap = array();
+ private $heraldEmailPHIDs = array();
+ 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('Added by '.$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 +48,8 @@
$types[] = PhabricatorTransactions::TYPE_COMMENT;
$types[] = PhabricatorTransactions::TYPE_EDGE;
+ $types[] = PhabricatorAuditTransaction::TYPE_COMMIT;
+
// TODO: These will get modernized eventually, but that can happen one
// at a time later on.
$types[] = PhabricatorAuditActionConstants::ACTION;
@@ -44,6 +77,7 @@
switch ($xaction->getTransactionType()) {
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
+ case PhabricatorAuditTransaction::TYPE_COMMIT:
return null;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
// TODO: For now, just record the added PHIDs. Eventually, turn these
@@ -62,6 +96,7 @@
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
case PhabricatorAuditActionConstants::ADD_AUDITORS:
+ case PhabricatorAuditTransaction::TYPE_COMMIT:
return $xaction->getNewValue();
}
@@ -79,6 +114,7 @@
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
case PhabricatorAuditActionConstants::ADD_AUDITORS:
+ case PhabricatorAuditTransaction::TYPE_COMMIT:
return;
}
@@ -95,6 +131,7 @@
case PhabricatorTransactions::TYPE_EDGE:
case PhabricatorAuditActionConstants::ACTION:
case PhabricatorAuditActionConstants::INLINE:
+ case PhabricatorAuditTransaction::TYPE_COMMIT:
return;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
$new = $xaction->getNewValue();
@@ -123,10 +160,7 @@
->setCommitPHID($object->getPHID())
->setAuditorPHID($phid)
->setAuditStatus($audit_requested)
- ->setAuditReasons(
- array(
- 'Added by '.$actor->getUsername(),
- ))
+ ->setAuditReasons($this->getAuditReasons($phid))
->save();
}
@@ -165,8 +199,12 @@
$actor_is_author = ($object->getAuthorPHID()) &&
($actor_phid == $object->getAuthorPHID());
+ $import_status_flag = null;
foreach ($xactions as $xaction) {
switch ($xaction->getTransactionType()) {
+ case PhabricatorAuditTransaction::TYPE_COMMIT:
+ $import_status_flag = PhabricatorRepositoryCommit::IMPORTED_HERALD;
+ break;
case PhabricatorAuditActionConstants::ACTION:
$new = $xaction->getNewValue();
switch ($new) {
@@ -265,9 +303,66 @@
$object->updateAuditStatus($requests);
$object->save();
+ if ($import_status_flag) {
+ $object->writeImportStatusFlag($import_status_flag);
+ }
+
return $xactions;
}
+ protected function expandTransaction(
+ PhabricatorLiskDAO $object,
+ PhabricatorApplicationTransaction $xaction) {
+
+ $xactions = parent::expandTransaction($object, $xaction);
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorAuditTransaction::TYPE_COMMIT:
+ $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(array_fuse($phids));
+ }
+
protected function sortTransactions(array $xactions) {
$xactions = parent::sortTransactions($xactions);
@@ -386,13 +481,23 @@
$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);
+
+ return $template;
}
protected function getMailTo(PhabricatorLiskDAO $object) {
$phids = array();
+ if ($this->heraldEmailPHIDs) {
+ $phids = $this->heraldEmailPHIDs;
+ }
+
if ($object->getAuthorPHID()) {
$phids[] = $object->getAuthorPHID();
}
@@ -414,12 +519,17 @@
$body = parent::buildMailBody($object, $xactions);
$type_inline = PhabricatorAuditActionConstants::INLINE;
+ $type_push = PhabricatorAuditTransaction::TYPE_COMMIT;
+ $is_commit = false;
$inlines = array();
foreach ($xactions as $xaction) {
if ($xaction->getTransactionType() == $type_inline) {
$inlines[] = $xaction;
}
+ if ($xaction->getTransactionType() == $type_push) {
+ $is_commit = true;
+ }
}
if ($inlines) {
@@ -428,6 +538,14 @@
$this->renderInlineCommentsForMail($object, $inlines));
}
+ if ($is_commit) {
+ $data = $object->getCommitData();
+ $body->addTextSection(pht('AFFECTED FILES'), $this->affectedFiles);
+ $this->inlinePatch(
+ $body,
+ $object);
+ }
+
// Reload the commit to pull commit data.
$commit = id(new DiffusionCommitQuery())
->setViewer($this->requireActor())
@@ -440,7 +558,7 @@
$author_phid = $commit->getAuthorPHID();
if ($author_phid) {
- $user_phids[$commit->getAuthorPHID()][] = pht('Author');
+ $user_phids[$author_phid][] = pht('Author');
}
$committer_phid = $data->getCommitDetail('committerPHID');
@@ -448,6 +566,13 @@
$user_phids[$committer_phid][] = pht('Committer');
}
+ // we loaded this in applyFinalEffects
+ $audit_requests = $object->getAudits();
+ $auditor_phids = mpull($audit_requests, 'getAuditorPHID');
+ foreach ($auditor_phids as $auditor_phid) {
+ $user_phids[$auditor_phid][] = pht('Auditor');
+ }
+
// TODO: It would be nice to show pusher here too, but that information
// is a little tricky to get at right now.
@@ -481,6 +606,68 @@
return $body;
}
+ private function attachPatch(
+ PhabricatorMetaMTAMail $template,
+ PhabricatorRepositoryCommit $commit) {
+
+ if (!$this->getRawPatch()) {
+ return;
+ }
+
+ $attach_key = 'metamta.diffusion.attach-patches';
+ $attach_patches = PhabricatorEnv::getEnvConfig($attach_key);
+ if (!$attach_patches) {
+ return;
+ }
+
+ $repository = $commit->getRepository();
+ $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,
+ PhabricatorRepositoryCommit $commit) {
+
+ if (!$this->getRawPatch()) {
+ return;
+ }
+
+ $inline_key = 'metamta.diffusion.inline-patches';
+ $inline_patches = PhabricatorEnv::getEnvConfig($inline_key);
+ if (!$inline_patches) {
+ return;
+ }
+
+ $repository = $commit->getRepository();
+ $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,91 @@
return $this->isCommitMostlyImported($object);
}
+ protected function shouldApplyHeraldRules(
+ PhabricatorLiskDAO $object,
+ array $xactions) {
+
+ foreach ($xactions as $xaction) {
+ switch ($xaction->getTransactionType()) {
+ case PhabricatorAuditTransaction::TYPE_COMMIT:
+ $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_fuse(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());
+
+ $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_COMMIT = 'audit:commit';
+
public function getApplicationName() {
return 'audit';
}
@@ -15,12 +17,35 @@
return new PhabricatorAuditTransactionComment();
}
+ public function getRemarkupBlocks() {
+ $blocks = parent::getRemarkupBlocks();
+
+ switch ($this->getTransactionType()) {
+ case self::TYPE_COMMIT:
+ $data = $this->getNewValue();
+ $blocks[] = $data['description'];
+ break;
+ }
+
+ return $blocks;
+ }
+
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
$type = $this->getTransactionType();
switch ($type) {
+ case self::TYPE_COMMIT:
+ $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 +84,8 @@
break;
case PhabricatorAuditActionConstants::ADD_AUDITORS:
return pht('Added Auditors');
+ case self::TYPE_COMMIT:
+ return pht('Committed');
}
return parent::getActionName();
@@ -104,10 +131,47 @@
}
switch ($type) {
+ case self::TYPE_COMMIT:
+ $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 +267,40 @@
}
switch ($type) {
+ case self::TYPE_COMMIT:
+ $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 +363,15 @@
return parent::getTitleForFeed($story);
}
+ public function getBodyForFeed(PhabricatorFeedStory $story) {
+ switch ($this->getTransactionType()) {
+ case self::TYPE_COMMIT:
+ $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 +395,9 @@
switch ($this->getTransactionType()) {
case PhabricatorAuditActionConstants::INLINE:
return null;
+ case self::TYPE_COMMIT:
+ $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,34 +13,14 @@
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());
+ // Reload the commit to pull commit data and audit requests.
+ $commit = id(new DiffusionCommitQuery())
+ ->setViewer(PhabricatorUser::getOmnipotentUser())
+ ->withIDs(array($commit->getID()))
+ ->needCommitData(true)
+ ->needAuditRequests(true)
+ ->executeOne();
+ $data = $commit->getCommitData();
if (!$data) {
throw new PhabricatorWorkerPermanentFailureException(
@@ -50,402 +29,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);
- $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_COMMIT)
+ ->setDateCreated($commit->getEpoch())
+ ->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
Details
Attached
Mime Type
text/plain
Expires
Wed, Dec 24, 3:06 AM (16 h, 36 m)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/km/rg/br43ylp2zamdf3yo
Default Alt Text
D10705.diff (32 KB)
Attached To
Mode
D10705: Move audit to application transactions
Attached
Detach File
Event Timeline
Log In to Comment