| <?php |
| /******************************************************************************* |
| * Copyright (c) 2011 Eclipse Foundation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Wayne Beaton (Eclipse Foundation)- initial API and implementation |
| *******************************************************************************/ |
| require_once dirname(__FILE__) . '/git-functions.inc'; |
| |
| class GitAuthorProcessor extends GitLogProcessor { |
| var $repo; |
| var $record; |
| |
| function __construct($repo) { |
| $this->repo = $repo; |
| } |
| |
| function startCommit($ref) { |
| $this->record = array('size' => 0); |
| } |
| |
| function data($ref, $key, $value) { |
| $this->record[$key] = $value; |
| } |
| |
| function file($ref, $filename, $filetype, $size) { |
| $this->record['files'][] = $filename; |
| $this->record['size'] += $size; |
| } |
| |
| function endCommit($ref) { |
| // Commits with no files don't count. |
| if (!isset($this->record['files'])) return; |
| |
| |
| @$committer = $this->record['committer']; |
| @$author = $this->record['author']; |
| @$authorName = mysql_real_escape_string($this->record['authorName']); |
| $size = $this->record['size']; |
| @$comment = mysql_real_escape_string($this->record['comment']); |
| $changeId = $this->getChangeId($comment); |
| $changeId = $changeId ? "'$changeId'" : 'NULL'; |
| $date = date('Y-m-d H:i:s', $this->record['date']); |
| |
| $sql = " |
| insert ignore into gitlogcache |
| (repo, ref, changeId, committer, author, authorName, size, comment, commitDate) |
| values ('$this->repo', '$ref', $changeId, '$committer', '$author', '$authorName', $size, '$comment', '$date') |
| "; |
| |
| dashboard_sql($sql); |
| } |
| |
| /** |
| * Get the Gerrit change id from the commit comment (if it has been specified). |
| */ |
| function getChangeId($comment) { |
| if (!preg_match('/Change\-Id: (\w+)/', $comment, $matches)) return null; |
| return $matches[1]; |
| } |
| } |
| |
| /** |
| * Create the gitlogcache table if it does not already exist. |
| * @internal |
| */ |
| function ensureGitLogCacheTableExists() { |
| $sql = " |
| create table if not exists gitlogcache ( |
| repo varchar(128) not null, |
| ref varchar(40) not null, |
| changeId varchar(60), |
| committer varchar(50) not null, |
| author varchar(128) not null, |
| authorName varchar(128), |
| size int unsigned, |
| comment varchar(1024) not null, |
| commitDate datetime not null, |
| CONSTRAINT UNIQUE (repo, ref), |
| INDEX (repo), |
| INDEX (ref), |
| INDEX (commitDate)) ENGINE=InnoDB; |
| "; |
| dashboard_sql($sql); |
| } |
| |
| function ensureGitLogCacheLogTableExists() { |
| $sql = " |
| create table if not exists gitlogcachelog ( |
| repo varchar(128) not null, |
| updateDate datetime not null, |
| INDEX (repo)) ENGINE=InnoDB; |
| "; |
| dashboard_sql($sql); |
| } |
| |
| /** |
| * @internal |
| * @param string $repo file path of a Git repository |
| * @return int The date of the most recent commit |
| */ |
| function findLastCommitDate($repo) { |
| $sql = "select max(updateDate) as date from gitlogcachelog where repo='$repo'"; |
| $result = dashboard_sql($sql); |
| $row = mysql_fetch_assoc($result); |
| |
| // The result will either be a date, or null |
| // strtotime(null) == the beginning of time |
| return strtotime($row['date']); |
| } |
| |
| /** |
| * This function updates the cache with information extracted from the |
| * repository. Scans the repository for refs added after the date of the |
| * most recent commit we already have in the cache. There is a risk that |
| * some commits may be lost if they are pushed after the cache is updated |
| * with commits that occurred more recently. |
| * |
| * @param string $repo file path of a Git repository |
| */ |
| function updateGitLogCache($repo, $fullscan = false) { |
| ensureGitLogCacheTableExists(); |
| ensureGitLogCacheLogTableExists(); |
| |
| $currentDate = date('Y-m-d H:i:s'); |
| |
| $date = $fullscan ? null : findLastCommitDate($repo); |
| $since = $date ? '--since="' . date('Y-m-d H:i:s', $date) .'"' : ''; |
| $path = escapeshellcmd($repo); |
| $gitCommand = "/usr/local/bin/git --git-dir=$path log --branches --numstat --format=fuller $since --reverse"; |
| logMessage("Git", $gitCommand); |
| $handle = popen($gitCommand, 'r'); |
| parseGitLog($handle, new GitAuthorProcessor($repo)); |
| pclose($handle); |
| |
| // Log the current date (as captured before we started the scan) |
| $sql = "insert into gitlogcachelog (repo, updateDate) values ('$repo', '$currentDate')"; |
| dashboard_sql($sql); |
| } |
| ?> |