blob: e3e7d86979ea7566c700a50915a2b3b4cea31856 [file] [log] [blame]
<?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);
}
?>