The branch PHP_POST_RECEIVE on karma.git has been updated via 99a863d4846676c53e15031cdc217c264aa082f8 (commit) via 91e9caf26371fc75f01faa4a1e7f0a9729313c4e (commit) via 8965fe78b0a0e1a1fca87677183472a8eb0ae8e9 (commit) via 57727b422a5df298c6db0ba73d2aa4eab3b76fb8 (commit) via b8e2e76374106a75687c430597ac8a352c7e514e (commit) from 30a1031bfb19338e8eb5cfabc72c7352d6f38a18 (commit)
http://git.php.net/?p=karma.git;a=log;h=99a863d4846676c53e15031cdc217c264aa082f8;hp=30a1031bfb19338e8eb5cfabc72c7352d6f38a18 Summary of changes: hooks/post-receive | 48 +----- hooks/{post-receive => post-receive.mail} | 6 +- lib/Git/PostReceiveHook.php | 271 +++++++++++++++++++---------- 3 files changed, 180 insertions(+), 145 deletions(-) copy hooks/{post-receive => post-receive.mail} (88%) -- Log ---------------------------------------- commit 99a863d4846676c53e15031cdc217c264aa082f8 Author: Alexander Moskaliov <ir...@php.net> Date: Wed Mar 14 17:25:37 2012 +0400 separate post-recive script diff --git a/hooks/post-receive b/hooks/post-receive index cc37b0b..6121887 100755 --- a/hooks/post-receive +++ b/hooks/post-receive @@ -1,44 +1,3 @@ -#!/usr/bin/env php -<?php -namespace Karma; - -// STATUS: not worked -// TODO: add license -// TODO: refactor -// TODO: documentation -// TODO: run post-receive.mirror - - -// /git/users.db - -error_reporting(E_ALL | E_STRICT); -date_default_timezone_set('UTC'); -putenv("PATH=/opt/bin:/usr/local/bin:/usr/bin:/bin"); -putenv("LC_ALL=en_US.UTF-8"); -mb_internal_encoding("UTF-8"); - -const REPOSITORY_PATH = '/git/repositories'; - -set_include_path('/git/checkout/karma/lib' . - PATH_SEPARATOR . - get_include_path()); - -include 'Mail.php'; -include 'Git.php'; -include 'Git/ReceiveHook.php'; -include 'Git/PostReceiveHook.php'; - - -$recipients = exec('git config hooks.mailinglist'); -$emailPrefix = exec('git config hooks.emailprefix') ?: '[git]'; - -$user = null; -if (getenv('REMOTE_USER')) { - $user = getenv('REMOTE_USER'); -} else if (getenv('SSH_CONNECTION') && getenv('GL_USER')) { - /* gitolite user */ - $user = getenv('GL_USER'); -} - -$hook = new \Git\PostReceiveHook(getenv('GL_REPO_BASE_ABS') ?: REPOSITORY_PATH, $user, $recipients, $emailPrefix); -$hook->process(); \ No newline at end of file +#!/bin/sh +[ -f 'hooks/post-receive.mail' ] && hooks/post-receive.mail +[ -f 'hooks/post-receive.mirror' ] && hooks/post-receive.mirror diff --git a/hooks/post-receive b/hooks/post-receive.mail similarity index 95% copy from hooks/post-receive copy to hooks/post-receive.mail index cc37b0b..af9bcd5 100755 --- a/hooks/post-receive +++ b/hooks/post-receive.mail @@ -6,7 +6,6 @@ namespace Karma; // TODO: add license // TODO: refactor // TODO: documentation -// TODO: run post-receive.mirror // /git/users.db commit 91e9caf26371fc75f01faa4a1e7f0a9729313c4e Author: Alexander Moskaliov <ir...@php.net> Date: Wed Mar 14 16:57:04 2012 +0400 add bugs info in commit mail diff --git a/lib/Git/PostReceiveHook.php b/lib/Git/PostReceiveHook.php index a635ab0..a9b0180 100644 --- a/lib/Git/PostReceiveHook.php +++ b/lib/Git/PostReceiveHook.php @@ -401,6 +401,23 @@ class PostReceiveHook extends ReceiveHook return $this->commitsData[$revision]; } + private function getBugs($log) + { + $bugUrlPrefixes = [ + 'pear' => 'http://pear.php.net/bugs/', + 'pecl' => 'https://bugs.php.net/', + 'php' => 'https://bugs.php.net/', + '' => 'https://bugs.php.net/' + ]; + $bugs = []; + if (preg_match_all('/(?:(pecl|pear|php)\s*)?(?:bug|#)[\s#:]*([0-9]+)/iuX', $log, $matchedBugs, PREG_SET_ORDER)) { + foreach($matchedBugs as $bug) { + $bugs[] = $bugUrlPrefixes[$bug[1]] . $bug[2]; + } + } + return $bugs; + } + /** * Send mail about commit. * Subject: [git] [commit] %PROJECT%: %PATHS% @@ -455,6 +472,10 @@ class PostReceiveHook extends ReceiveHook $message .= "\nLog:\n" . $info['log'] . "\n"; + if ($bugs = $this->getBugs($info['log'])) { + $message .= "\nBugs:\n" . implode("\n", $bugs) . "\n"; + } + if (strlen($pathsString) < 8192) { // inline changed paths commit 8965fe78b0a0e1a1fca87677183472a8eb0ae8e9 Author: Alexander Moskaliov <ir...@php.net> Date: Wed Mar 14 16:33:44 2012 +0400 add push user fullname from users.db diff --git a/hooks/post-receive b/hooks/post-receive index 12884a4..cc37b0b 100755 --- a/hooks/post-receive +++ b/hooks/post-receive @@ -4,11 +4,10 @@ namespace Karma; // STATUS: not worked // TODO: add license -// TODO: refactor with lib/Git +// TODO: refactor // TODO: documentation -// TODO: refactor for PHP 5.4 -// TODO: reformat mails -// TODO: check mail length +// TODO: run post-receive.mirror + // /git/users.db diff --git a/lib/Git/PostReceiveHook.php b/lib/Git/PostReceiveHook.php index d4991e9..a635ab0 100644 --- a/lib/Git/PostReceiveHook.php +++ b/lib/Git/PostReceiveHook.php @@ -3,8 +3,10 @@ namespace Git; class PostReceiveHook extends ReceiveHook { + const USERS_DB_FILE = '/git/users.db'; private $pushAuthor = ''; + private $pushAuthorName = ''; private $mailingList = ''; private $emailPrefix = ''; @@ -26,12 +28,27 @@ class PostReceiveHook extends ReceiveHook parent::__construct($basePath); $this->pushAuthor = $pushAuthor; + $this->pushAuthorName = $this->getUserName($pushAuthor); $this->mailingList = $mailingList; $this->emailPrefix = $emailPrefix; $this->allBranches = $this->getAllBranches(); } + public function getUserName($user) + { + $usersDB = file(__DIR__ . '/users.db'); + foreach ($usersDB as $userline) { + list ($username, $fullname, $email) = explode(":", trim($userline)); + if ($username === $user) { + return $fullname; + } + } + return ''; + } + + + /** * */ @@ -176,7 +193,7 @@ class PostReceiveHook extends ReceiveHook $mail->setMessage($message); - $mail->setFrom($this->pushAuthor . '@php.net', $this->pushAuthor); + $mail->setFrom($this->pushAuthor . '@php.net', $this->pushAuthorName); $mail->addTo($this->mailingList); $mail->send(); @@ -283,7 +300,7 @@ class PostReceiveHook extends ReceiveHook $mail->setMessage($message); - $mail->setFrom($this->pushAuthor . '@php.net', $this->pushAuthor); + $mail->setFrom($this->pushAuthor . '@php.net', $this->pushAuthorName); $mail->addTo($this->mailingList); $mail->send(); @@ -476,7 +493,7 @@ class PostReceiveHook extends ReceiveHook $mail->setMessage($message); - $mail->setFrom($this->pushAuthor . '@php.net', $this->pushAuthor); + $mail->setFrom($this->pushAuthor . '@php.net', $this->pushAuthorName); $mail->addTo($this->mailingList); $mail->send(); commit 57727b422a5df298c6db0ba73d2aa4eab3b76fb8 Author: Alexander Moskaliov <ir...@php.net> Date: Wed Mar 14 16:18:13 2012 +0400 add commit sort by date diff --git a/lib/Git/PostReceiveHook.php b/lib/Git/PostReceiveHook.php index e1eb76b..d4991e9 100644 --- a/lib/Git/PostReceiveHook.php +++ b/lib/Git/PostReceiveHook.php @@ -61,6 +61,15 @@ class PostReceiveHook extends ReceiveHook } } + // sort revisions by commit time + usort($this->revisions, function($a, $b){ + if ($a['time'] == $b['time']) { + return 0; + } + return ($a['time'] < $b['time']) ? -1 : 1; + }); + + //send mails per commit foreach ($this->revisions as $revision => $branches) { // check if it commit was already in other branches if (!$this->isRevExistsInBranches($revision, array_diff($this->allBranches, $branches))) { @@ -181,7 +190,6 @@ class PostReceiveHook extends ReceiveHook */ private function cacheRevisions($branchName, array $revisions) { - //TODO: add mail order from older commit to newer foreach ($revisions as $revision) { $this->revisions[$revision][$branchName] = $branchName; @@ -369,7 +377,8 @@ class PostReceiveHook extends ReceiveHook 'committer_email' => $raw[6], // %ce 'committer_date' => $raw[7], // %cD 'subject' => $raw[8], // %s - 'log' => $raw[9] // %B + 'log' => $raw[9], // %B + 'time' => strtotime($raw[7]) ]; } return $this->commitsData[$revision]; commit b8e2e76374106a75687c430597ac8a352c7e514e Author: Alexander Moskaliov <ir...@php.net> Date: Wed Mar 14 16:10:01 2012 +0400 reformat mail for branch diff --git a/lib/Git/PostReceiveHook.php b/lib/Git/PostReceiveHook.php index 04c37f2..e1eb76b 100644 --- a/lib/Git/PostReceiveHook.php +++ b/lib/Git/PostReceiveHook.php @@ -8,9 +8,10 @@ class PostReceiveHook extends ReceiveHook private $mailingList = ''; private $emailPrefix = ''; - private $newBranches = []; + private $alreadyExistsBranches = []; private $updatedBranches = []; private $revisions = []; + private $commitsData = []; private $allBranches = []; @@ -38,16 +39,18 @@ class PostReceiveHook extends ReceiveHook { $this->hookInput(); - //cache list of new and updated branches + //cache list of old and updated branches + $newBranches = []; foreach ($this->refs as $ref) { if ($ref['reftype'] == self::REF_BRANCH){ if ($ref['changetype'] == self::TYPE_UPDATED) { $this->updatedBranches[] = $ref['refname']; } elseif ($ref['changetype'] == self::TYPE_CREATED) { - $this->newBranches[] = $ref['refname']; + $newBranches[] = $ref['refname']; } } } + $this->alreadyExistsBranches = array_diff($this->allBranches, $newBranches); //send mails per ref push foreach ($this->refs as $ref) { @@ -69,12 +72,12 @@ class PostReceiveHook extends ReceiveHook /** * Send mail about branch. - * Subject: [git] [branch] %STATUS% branch %BRANCH_NAME% in %PROJECT% + * Subject: [git] [branch] %PROJECT%: %STATUS% branch %BRANCH_NAME% * Body: * Branch %BRANCH_NAME% in %PROJECT% was %STATUS% * Date: Thu, 08 Mar 2012 12:39:48 +0000(current mail date) * - * Link: http://git.php.net/?p=%PROJECT_PATH%;a=shortlog;h=refs/heads/%BRANCH_NAME% + * Link: http://git.php.net/?p=%PROJECT_PATH%;a=log;h=%SHA_NEW%;hp=%SHA_OLD% * * --part1-- * Log: @@ -84,17 +87,7 @@ class PostReceiveHook extends ReceiveHook * Author: %USER% Thu, 08 Mar 2012 12:39:48 +0000 * Committer: %USER% Thu, 08 Mar 2012 12:39:48 +0000 * Link: http://git.php.net/?p=%PROJECT_PATH%;a=commitdiff;h=%SHA% - * Shortlog: %SHORT_MESSAGE% - * --/per commit-- - * - * --/part1-- - * - * (if part1 exceeded maximum size) - * --part1-- - * Commits: - * - * --per commit-- - * Commit: %SHA% + * Shortlog: %COMMIT_SUBJECT% * --/per commit-- * * --/part1-- @@ -106,58 +99,79 @@ class PostReceiveHook extends ReceiveHook */ private function sendBranchMail($name, $changeType, $oldrev, $newrev) { - // FIXME: work in progress + $status = [self::TYPE_UPDATED => 'Update', self::TYPE_CREATED => 'Create', => self::TYPE_DELETED => 'Delete']; + $shortname = str_replace('refs/heads/', '', $name); + + // forced push if ($changeType == self::TYPE_UPDATED) { - $title = "Branch " . $name . " was updated"; - } elseif ($changeType == self::TYPE_CREATED) { - $title = "Branch " . $name . " was created"; + $replacedRevisions = $this->getRevisions(escapeshellarg($newrev . '..' . $oldrev)) ?: false; } else { - $title = "Branch " . $name . " was deleted"; + $replacedRevisions = false; } - $message = $title . "\n\n"; - if ($changeType != self::TYPE_DELETED) { - if ($changeType == self::TYPE_UPDATED) { - // check if push was with --force option - if ($replacedRevisions = $this->getRevisions(escapeshellarg($newrev . '..' . $oldrev))) { - $message .= "Discarded revisions: \n" . implode("\n", $replacedRevisions) . "\n"; - } + $revisions = $this->getBranchRevisions($name, $changeType, $oldrev, $newrev); - // git rev-list old..new - $revisions = $this->getRevisions(escapeshellarg($oldrev . '..' . $newrev)); + if (count($revisions)) { + + $logString = ''; + + foreach ($revisions as $revision) { + $commitInfo = $this->getCommitInfo($revision); + $logString .= 'Commit: ' . $revision . "\n"; + $logString .= 'Author: ' . $commitInfo['author'] . '(' . $commitInfo['author_email'] . ') ' . $commitInfo['author_date'] . "\n"; + $logString .= 'Committer: ' . $commitInfo['committer'] . '(' . $commitInfo['committer_email'] . ') ' . $commitInfo['committer_date'] . "\n"; + $logString .= "Link: http://git.php.net/?p=" . $this->getRepositoryName() . ".git;a=commitdiff;h=" . $revision . "\n"; + $logString .= "Shortlog:\n" . $commitInfo['subject'] . "\n"; - } else { - // for new branch we write log about new commits only - $revisions = $this->getRevisions( - escapeshellarg($newrev) . ' --not ' . implode(' ', $this->escapeArrayShellArgs(array_diff($this->allBranches, $this->newBranches))) - ); - - foreach ($this->updatedBranches as $refname) { - if ($this->isRevExistsInBranches($this->refs[$refname]['old'], [$name])) { - $this->cacheRevisions($name, $this->getRevisions(escapeshellarg($this->refs[$refname]['old'] . '..' . $newrev))); - } } } + } - $this->cacheRevisions($name, $revisions); - if (count($revisions)) { - $message .= "--------LOG--------\n"; - foreach ($revisions as $revision) { - $diff = \Git::gitExec( - 'diff-tree --stat --pretty=medium -c %s', - escapeshellarg($revision) - ); - $message .= $diff."\n\n"; + + $mail = new \Mail(); + $mail->setSubject($this->emailPrefix . '[branch] ' . $this->getRepositoryName() . ': ' . $status[$changeType] . ' branch ' . $shortname); + + $message = 'Branch ' . $shortname . ' in ' . $this->getRepositoryName() . ' was ' . $status[$changeType] . 'd' . "\n"; + $message .= 'Date: ' . date('r') . "\n"; + + $message .= "\n"; + $message .= "Link: http://git.php.net/?p=" . $this->getRepositoryName() . ".git;a=log;h=" . $newrev . ";hp=" . $oldrev . "\n"; + $message .= "\n"; + + // forced push + if ($replacedRevisions) { + $message .= "Discarded revisions: \n" . implode("\n", $replacedRevisions) . "\n\n"; + } + + if ($changeType != self::TYPE_DELETED) { + + if (strlen($logString) < 8192) { + // inline log + $message .= "Log:\n" . $logString . "\n"; + } else { + // log attach + $logFile = 'log_' . $oldrev . '_' . $newrev . '.txt'; + $mail->addTextFile($logFile, $logString); + if ((strlen($message) + $mail->getFileLength($logFile)) > 262144) { + // changed paths attach exceeded max size + $mail->dropFile($logFile); + $message .= 'Log: <changed paths exceeded maximum size>'; } } } - $this->mail($this->emailPrefix . '[push] ' . $title , $message); + $mail->setMessage($message); + + $mail->setFrom($this->pushAuthor . '@php.net', $this->pushAuthor); + $mail->addTo($this->mailingList); + + $mail->send(); + } @@ -202,22 +216,22 @@ class PostReceiveHook extends ReceiveHook * --/part1-- * * @param $name string - * @param $changetype int + * @param $changeType int * @param $oldrev string * @param $newrev string */ - private function sendTagMail($name, $changetype, $oldrev, $newrev) + private function sendTagMail($name, $changeType, $oldrev, $newrev) { $status = [self::TYPE_UPDATED => 'Update', self::TYPE_CREATED => 'Create', => self::TYPE_DELETED => 'Delete']; $shortname = str_replace('refs/tags/', '', $name); $mail = new \Mail(); - $mail->setSubject($this->emailPrefix . '[tag] ' . $this->getRepositoryName() . ': ' . $status[$changetype] . ' tag ' . $shortname; + $mail->setSubject($this->emailPrefix . '[tag] ' . $this->getRepositoryName() . ': ' . $status[$changeType] . ' tag ' . $shortname; - $message = 'Tag ' . $shortname . ' in ' . $this->getRepositoryName() . ' was ' . $status[$changetype] . 'd' . - (($changetype == self::TYPE_DELETED) ? ' from ' . $oldrev : '' ) . "\n"; + $message = 'Tag ' . $shortname . ' in ' . $this->getRepositoryName() . ' was ' . $status[$changeType] . 'd' . + (($changeType != self::TYPE_CREATED) ? ' from ' . $oldrev : '' ) . "\n"; - if ($changetype != self::TYPE_DELETED) { + if ($changeType != self::TYPE_DELETED) { $info = $this->getTagInfo($name); $targetInfo = $this->getCommitInfo($info['target']); $targetPaths = $this->getChangedPaths(escapeshellarg($info['target'])); @@ -233,7 +247,7 @@ class PostReceiveHook extends ReceiveHook } $message .= "\n"; - $message .= "Link: http://git.php.net/?p=" . $this->getRepositoryName() . ".git;;a=tag;h=" . $info['revision'] . "\n"; + $message .= "Link: http://git.php.net/?p=" . $this->getRepositoryName() . ".git;a=tag;h=" . $info['revision'] . "\n"; $message .= "\n"; $message .= 'Target: ' . $info['target'] . "\n"; @@ -274,27 +288,53 @@ class PostReceiveHook extends ReceiveHook private function getTagInfo($tag) { $temp = \Git::gitExec("for-each-ref --format=\"%%(objecttype)\n%%(*objectname)\n%%(taggername)\n%%(taggeremail)\n%%(taggerdate)\n%%(*objectname)\n%%(contents)\" %s", escapeshellarg($tag)); - $temp = explode("\n", $temp, 6); + $temp = explode("\n", $temp, 6); //6 elements separated by \n, last element - log message if ($temp[0] == 'tag') { $info = [ - 'annotated' => true, - 'revision' => $temp[1], - 'tagger' => $temp[2], - 'tagger_email' => $temp[3], - 'tagger_date' => $temp[4], - 'target' => $temp[5], - 'log' => $temp[6] + 'annotated' => true, + 'revision' => $temp[1], + 'tagger' => $temp[2], + 'tagger_email' => $temp[3], + 'tagger_date' => $temp[4], + 'target' => $temp[5], + 'log' => $temp[6] ]; } else { $info = [ - 'annotated' => false, - 'revision' => $temp[1], - 'target' => $temp[1] + 'annotated' => false, + 'revision' => $temp[1], + 'target' => $temp[1] ]; } return $info; } + + + private function getBranchRevisions($name, $changeType, $oldrev, $newrev) + { + if ($changeType == self::TYPE_UPDATED) { + // git rev-list old..new + $revisions = $this->getRevisions(escapeshellarg($oldrev . '..' . $newrev)); + } else { + // for new branch we write log about new commits only + $revisions = $this->getRevisions( + escapeshellarg($newrev) . ' --not ' . implode(' ', $this->escapeArrayShellArgs($this->alreadyExistsBranches)) + ); + + foreach ($this->updatedBranches as $refname) { + if ($this->isRevExistsInBranches($this->refs[$refname]['old'], [$name])) { + $this->cacheRevisions($name, $this->getRevisions(escapeshellarg($this->refs[$refname]['old'] . '..' . $newrev))); + } + } + } + + $this->cacheRevisions($name, $revisions); + + return $revisions; + } + + /** * Get list of revisions for $revRange * @@ -317,23 +357,27 @@ class PostReceiveHook extends ReceiveHook private function getCommitInfo($revision) { - $raw = \Git::gitExec('rev-list -n 1 --format="%%P%%n%%an%%n%%ae%%n%%aD%%n%%cn%%n%%ce%%n%%cD%%n%%B" %s', escapeshellarg($revision)); - $raw = explode("\n", $raw, 9); //8 elements separated by \n, last element - log message, first(skipped) element - "commit sha" - return [ - 'parents' => $raw[1], // %P - 'author' => $raw[2], // %an - 'author_email' => $raw[3], // %ae - 'author_date' => $raw[4], // %aD - 'committer' => $raw[5], // %cn - 'committer_email' => $raw[6], // %ce - 'committer_date' => $raw[7], // %cD - 'log' => $raw[8] // %B - ]; + if (!isset($this->commitsData[$revision])) { + $raw = \Git::gitExec('rev-list -n 1 --format="%%P%%n%%an%%n%%ae%%n%%aD%%n%%cn%%n%%ce%%n%%cD%%n%%s%%n%%B" %s', escapeshellarg($revision)); + $raw = explode("\n", $raw, 9); //9 elements separated by \n, last element - log message, first(skipped) element - "commit sha" + $this->commitsData[$revision] = [ + 'parents' => $raw[1], // %P + 'author' => $raw[2], // %an + 'author_email' => $raw[3], // %ae + 'author_date' => $raw[4], // %aD + 'committer' => $raw[5], // %cn + 'committer_email' => $raw[6], // %ce + 'committer_date' => $raw[7], // %cD + 'subject' => $raw[8], // %s + 'log' => $raw[9] // %B + ]; + } + return $this->commitsData[$revision]; } /** * Send mail about commit. - * Subject: [git] [commit] %PROJECT% %PATHS% + * Subject: [git] [commit] %PROJECT%: %PATHS% * Body: * Commit: %SHA% * Author: %USER% Thu, 08 Mar 2012 12:39:48 +0000 @@ -372,7 +416,7 @@ class PostReceiveHook extends ReceiveHook $diff = \Git::gitExec('diff-tree -c -p %s', escapeshellarg($revision)); $mail = new \Mail(); - $mail->setSubject($this->emailPrefix . '[commit] ' . $this->getRepositoryName() . ' ' . implode(' ', array_keys($paths))); + $mail->setSubject($this->emailPrefix . '[commit] ' . $this->getRepositoryName() . ': ' . implode(' ', array_keys($paths))); $message = ''; @@ -429,18 +473,6 @@ class PostReceiveHook extends ReceiveHook $mail->send(); } - /** - * @param $subject string - * @param $message string - */ - private function mail($subject, $message) { - $headers = [ - 'From: ' . $this->pushAuthor . '@php.net', - 'Reply-To: ' . $this->pushAuthor . '@php.net' - ]; - - mail($this->mailingList, $subject, $message, implode("\r\n", $headers)); - } /** * @param $revision string Thank you for your contribution. -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php