import
[web.mtrack] / bin / svn-commit-hook
1 #!/usr/bin/env php
2 <?php # vim:ts=2:sw=2:et:ft=php:
3 /* For licensing and copyright terms, see the file named LICENSE */
4 // called as:
5 // svn-commit-hook what svnrepopath svntxn [mtrackconfig]
6
7 $action = $argv[1];
8 $svnrepo = $argv[2];
9 $svntxn = $argv[3];
10
11 if (isset($argv[4])) {
12   putenv("MTRACK_CONFIG_FILE=" . $argv[4]);
13 }
14
15 if ($action == 'pre') {
16   $svntxn = "-t $svntxn";
17 } else {
18   $svntxn = "-r $svntxn";
19 }
20
21 include dirname(__FILE__) . '/../inc/common.php';
22 if (file_exists(MTrackConfig::get('core', 'vardir') . '/.initializing')) {
23   exit(0);
24 }
25
26
27 class SvnCommitHookBridge implements IMTrackCommitHookBridge {
28   var $repo;
29   var $svnlook;
30   var $svnrepo;
31   var $svntxn;
32
33   function __construct($repo, $svnrepo, $svntxn) {
34     $this->repo = $repo;
35     $this->svnlook = MTrackConfig::get('tools', 'svnlook');
36     $this->svnrepo = $svnrepo;
37     $this->svntxn = $svntxn;
38   }
39
40   function enumChangedOrModifiedFileNames() {
41     $files = array();
42     $fp = popen("$this->svnlook changed $this->svntxn $this->svnrepo", 'r');
43     while (($line = fgets($fp)) !== false) {
44       if (preg_match("/^(\w)\s+(.*)$/", trim($line), $M)) {
45         $action = $M[1];
46         $path = $M[2];
47         if ($action == 'A' || $action == 'U' || $action == 'UU') {
48           $files[] = $path;
49         }
50       }
51     }
52     return $files;
53   }
54
55   function getCommitMessage() {
56     $fp = popen("$this->svnlook log $this->svntxn $this->svnrepo", 'r');
57     $log = stream_get_contents($fp);
58     $log = preg_replace('/\[(\d+)\]/',
59       "[changeset:" . $this->repo->getBrowseRootName() . ",\$1]", $log);
60     return $log;
61   }
62
63   function getFileStream($path) {
64     return popen(
65       "$this->svnlook cat $this->svntxn $this->svnrepo $path", 'r');
66   }
67
68   function getChangesetDescriptor() {
69     $rev = trim(str_replace('-r ', '', $this->svntxn));
70     return '[changeset:' . $this->repo->getBrowseRootName() . ",$rev]";
71   }
72 }
73
74 try {
75   $repo = MTrackRepo::loadByLocation($svnrepo);
76   $bridge = new SvnCommitHookBridge($repo, $svnrepo, $svntxn);
77   $author = trim(shell_exec("$bridge->svnlook author $svntxn $svnrepo"));
78   $author = mtrack_canon_username($author);
79   MTrackAuth::su($author);
80   $checker = new MTrackCommitChecker($repo);
81   if ($action == 'pre') {
82     $checker->preCommit($bridge);
83   } else {
84     $checker->postCommit($bridge);
85   }
86   exit(0);
87 } catch (Exception $e) {
88   fwrite(STDERR, "\n" . $e->getMessage() . "\n\n ** Commit failed [$action]\n");
89   exit(1);
90 }
91