mirror of
https://we.phorge.it/source/phorge.git
synced 2025-02-03 02:18:24 +01:00
Add options to include patches inline or attached for Diffusion commit emails
Summary: See D818 for an older attempt at this. Support code has matured to the point where the patch is pretty straightforward. @tido, this was a long-standing request from Aditya back in the day. Test Plan: Used `reparse.php --herald` to send myself a bunch of emails with various patch configurations. Confirmed that limits are respected, reasonable errors arise when they're violated, etc. (Timeout is a little funky but that's out of scope here, I think.) Reviewers: btrahan Reviewed By: btrahan CC: tido, aran Maniphest Tasks: T456 Differential Revision: https://secure.phabricator.com/D2967
This commit is contained in:
parent
2b690372de
commit
9574b91e55
2 changed files with 119 additions and 2 deletions
|
@ -396,6 +396,26 @@ return array(
|
||||||
// affects Diffusion.
|
// affects Diffusion.
|
||||||
'metamta.diffusion.reply-handler' => 'PhabricatorAuditReplyHandler',
|
'metamta.diffusion.reply-handler' => 'PhabricatorAuditReplyHandler',
|
||||||
|
|
||||||
|
// Set this to true if you want patches to be attached to commit notifications
|
||||||
|
// from Diffusion. This won't work with SendGrid.
|
||||||
|
'metamta.diffusion.attach-patches' => false,
|
||||||
|
|
||||||
|
// To include patches in Diffusion email bodies, set this to a positive
|
||||||
|
// integer. Patches will be inlined if they are at most that many lines.
|
||||||
|
// By default, patches are not inlined.
|
||||||
|
'metamta.diffusion.inline-patches' => 0,
|
||||||
|
|
||||||
|
// If you've enabled attached patches or inline patches for commit emails, you
|
||||||
|
// can establish a hard byte limit on their size. You should generally set
|
||||||
|
// reasonable byte and time limits (defaults are 1MB and 60 seconds) to avoid
|
||||||
|
// sending ridiculously enormous email for changes like "importing an external
|
||||||
|
// library" or "accidentally committed this full-length movie as text".
|
||||||
|
'metamta.diffusion.byte-limit' => 1024 * 1024,
|
||||||
|
|
||||||
|
// If you've enabled attached patches or inline patches for commit emails, you
|
||||||
|
// can establish a hard time limit on generating them.
|
||||||
|
'metamta.diffusion.time-limit' => 60,
|
||||||
|
|
||||||
// Prefix prepended to mail sent by Package.
|
// Prefix prepended to mail sent by Package.
|
||||||
'metamta.package.subject-prefix' => '[Package]',
|
'metamta.package.subject-prefix' => '[Package]',
|
||||||
|
|
||||||
|
|
|
@ -130,6 +130,9 @@ final class PhabricatorRepositoryCommitHeraldWorker
|
||||||
" ".$reply_instructions."\n";
|
" ".$reply_instructions."\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$template = new PhabricatorMetaMTAMail();
|
||||||
|
|
||||||
|
$inline_patch_text = $this->buildPatch($template, $repository, $commit);
|
||||||
|
|
||||||
$body = <<<EOBODY
|
$body = <<<EOBODY
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
|
@ -149,7 +152,7 @@ MANAGE HERALD COMMIT RULES
|
||||||
|
|
||||||
WHY DID I GET THIS EMAIL?
|
WHY DID I GET THIS EMAIL?
|
||||||
{$why_uri}
|
{$why_uri}
|
||||||
|
{$inline_patch_text}
|
||||||
EOBODY;
|
EOBODY;
|
||||||
|
|
||||||
$prefix = PhabricatorEnv::getEnvConfig('metamta.diffusion.subject-prefix');
|
$prefix = PhabricatorEnv::getEnvConfig('metamta.diffusion.subject-prefix');
|
||||||
|
@ -159,7 +162,6 @@ EOBODY;
|
||||||
$commit);
|
$commit);
|
||||||
list($thread_id, $thread_topic) = $threading;
|
list($thread_id, $thread_topic) = $threading;
|
||||||
|
|
||||||
$template = new PhabricatorMetaMTAMail();
|
|
||||||
$template->setRelatedPHID($commit->getPHID());
|
$template->setRelatedPHID($commit->getPHID());
|
||||||
$template->setSubject("{$commit_name}: {$name}");
|
$template->setSubject("{$commit_name}: {$name}");
|
||||||
$template->setSubjectPrefix($prefix);
|
$template->setSubjectPrefix($prefix);
|
||||||
|
@ -314,4 +316,99 @@ EOBODY;
|
||||||
$publisher->publish();
|
$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 (strtolower($encoding) != 'utf-8' &&
|
||||||
|
function_exists('mb_convert_encoding')) {
|
||||||
|
$raw_patch = mb_convert_encoding($raw_patch, 'utf-8', $encoding);
|
||||||
|
}
|
||||||
|
$result = phutil_utf8ize($raw_patch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result) {
|
||||||
|
$result = "\nPATCH\n\n{$result}\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function loadRawPatchText(
|
||||||
|
PhabricatorRepository $repository,
|
||||||
|
PhabricatorRepositoryCommit $commit) {
|
||||||
|
|
||||||
|
$drequest = DiffusionRequest::newFromDictionary(
|
||||||
|
array(
|
||||||
|
'repository' => $repository,
|
||||||
|
'commit' => $commit->getCommitIdentifier(),
|
||||||
|
));
|
||||||
|
|
||||||
|
$raw_query = DiffusionRawDiffQuery::newFromDiffusionRequest($drequest);
|
||||||
|
$raw_query->setLinesOfContext(3);
|
||||||
|
|
||||||
|
$time_key = 'metamta.diffusion.time-limit';
|
||||||
|
$byte_key = 'metamta.diffusion.byte-limit';
|
||||||
|
$time_limit = PhabricatorEnv::getEnvConfig($time_key);
|
||||||
|
$byte_limit = PhabricatorEnv::getEnvConfig($byte_key);
|
||||||
|
|
||||||
|
if ($time_limit) {
|
||||||
|
$raw_query->setTimeout($time_limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
$raw_diff = $raw_query->loadRawDiff();
|
||||||
|
|
||||||
|
$size = strlen($raw_diff);
|
||||||
|
if ($byte_limit && $size > $byte_limit) {
|
||||||
|
$pretty_size = phabricator_format_bytes($size);
|
||||||
|
$pretty_limit = phabricator_format_bytes($byte_limit);
|
||||||
|
throw new Exception(
|
||||||
|
"Patch size of {$pretty_size} exceeds configured byte size limit of ".
|
||||||
|
"{$pretty_limit}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return $raw_diff;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue