<?php

$repos 
"";

if (!isset(
$argv[1])) {
    die(
$argv[0]." REPOS_PATH\n");
}
$repos $argv[1];

if (!
file_exists($repos.'/format')) {
    echo 
$argv[1].": is not a valid subversion repository.\n";
    die(
$argv[0]." REPOS_PATH\n");
}

$king = new SVNKing($argv[1]);

$king->determineSubversionKing();
$king->printSubversionKing();


class 
SVNKing {
    
    public 
$repos;
    public 
$delta = array();
    public 
$total_delta 0;
    
    public 
$commitsPerUser = array();
    public 
$total_commits 0;
    
    
    public function 
__construct($repos) {
        
$this->repos $repos;
    }
    
    public function 
determineSubversionKing() {
        
$this_month     date('n');      
        
$youngest       $this->getYoungestRevision();
        
$youngest_date  $this->getRevisionDate($youngest);
        
$youngest_month date('n'$youngest_date);
         
        
$revision       $youngest;
        
$revision_month $youngest_month;
        
        while (
$revision_month == $youngest_month) {            
            
$revision--;
            
$revision_date  $this->getRevisionDate($revision);
            
$revision_month date('n'$revision_date);
            
            if (
$revision_month $youngest_month) {
                break;
            }

            
$author $this->getRevisionAuthor($revision);
            
// echo "$author $revision ".date("d.m.Y H:i:s", $revision_date)."\n";
            
if (trim($author) == "") {
                
$author "Unknown";
            }
            if (!isset(
$this->delta[$author])) {
                
$this->delta[$author] = 0;
            }
            if (!isset(
$this->commitsPerUser[$author])) {
                
$this->commitsPerUser[$author] = 0
            }
            
$delta $this->getRevisionLineDelta($revision);
            
$this->delta[$author] += $delta;
            
$this->commitsPerUser[$author]++;
            
            
$this->total_delta += $delta;
            
$this->total_commits++;
        }
    }
    
    public function 
printSubversionKing() {
        
arsort($this->delta);
        
arsort($this->commitsPerUser);
        
        
$i 1;
        echo 
"Repository: "$this->repos."\n";
        echo 
"Total number of commits: ".$this->total_commits."\n";
        echo 
"Total line delta in the repository: " $this->total_delta."\n";
        echo 
"--- Most productive users for ".date("m/Y")." ---\n";
        
        foreach (
$this->delta as $user => $lines) {
            
$percent round( ($lines $this->total_delta ) * 1002);
            echo 
str_pad($i,      4);
            echo 
str_pad($user,  20);
            echo 
str_pad($lines10);
            echo 
str_pad(sprintf("%05s%%"$percent), 10);
            echo 
"\n";
            
$i++;
        }
        
$i 1;
        echo 
"--- Most active commiters for ".date("m/Y")." ---\n";        
        foreach (
$this->commitsPerUser as $user => $commits) {
            
$percent round( ($commits $this->total_commits ) * 1002);
            echo 
str_pad($i,        4);
            echo 
str_pad($user,    20);
            echo 
str_pad($commits10);
            echo 
str_pad(sprintf("%02d%%"$percent), 10);
            echo 
"\n";
            
$i++;
        }
        echo 
"-----------------------------------------\n";
    }
    
    public function 
getYoungestRevision() {
        
$repos $this->repos;
        
$revision trim(`svnlook youngest $repos`);
        return 
$revision;
    }
    
    public function 
getRevisionDate($revision) {
        
$repos $this->repos;
        
$date trim(`svnlook date -r $revision $repos`);
        
        
$iso substr($date0strpos($date"(")-); 
        
        
$timestamp strtotime($iso);
        if (!
$timestamp) {
            throw new 
Exception("Could not parse revision date.");
        }
        return 
$timestamp;
    }
    
    public function 
getRevisionAuthor($revision) {
        
$repos $this->repos;
        return 
trim(`svnlook author -r $revision $repos`);
    }

    public function 
getRevisionLineDelta($revision) {
        
$modified 0;
        
$repos $this->repos;
        
$diff = `svnlook diff -r $revision $repos`;
        
$lines explode("\n"$diff);
        foreach (
$lines as $line) {
            if (
substr($line01) == '+') {
                
$modified++;
            }
            if (
substr($line01) == '-') {
                
$modified--;
            }
        }
        return 
$modified;
    }
}