2023-05-16 10:47:08 +08:00

300 lines
7.0 KiB
PHP

<?php
/**
* The syncer of svn.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package svn
* @version $Id$
* @link http://www.zentao.net
*/
error_reporting(E_ALL ^ E_STRICT ^ E_WARNING);
include './config.php';
include './api.class.php';
$syncer = new syncer($config);
$syncer->run();
class syncer
{
/**
* The svn binary svnClient.
*
* @var string
* @access public
*/
public $svnClient;
/**
* The zentao client.
*
* @var string
* @access public
*/
public $zentaoClient;
/**
* Repos.
*
* @var array
* @access public
*/
public $repos = array();
/**
* The log root.
*
* @var string
* @access public
*/
public $logRoot = '';
/**
* The construct function.
*
* @access public
* @return void
*/
public function __construct($config)
{
$this->setConfig($config);
$this->setTimeZone();
$this->setRepos();
$this->setLogRoot();
$this->loginZentao();
}
/**
* Set config.
*
* @param object $config
* @access public
* @return void
*/
public function setConfig($config)
{
$this->config = $config;
}
/**
* Set timezone.
*
* @access public
* @return void
*/
public function setTimeZone()
{
date_default_timezone_set($this->config->timezone);
}
/**
* Set the repos.
*
* @access public
* @return void
*/
public function setRepos()
{
if(!$this->config->svn->repos) die("You must set one svn repo.\n");
$this->repos = $this->config->svn->repos;
}
/**
* Set the log root.
*
* @access public
* @return void
*/
public function setLogRoot()
{
$this->logRoot = './log/';
if(!is_dir($this->logRoot)) mkdir($this->logRoot);
}
/**
* Login to zentao.
*
* @access public
* @return void
*/
public function loginZentao()
{
if(!$this->config->zentao->path or !$this->config->zentao->user) die("You must set the zentao path and user.\n");
$zentaoConfig = $this->config->zentao;
$this->zentaoClient = new ztclient($zentaoConfig->path, $zentaoConfig->user, $zentaoConfig->password);
}
/**
* Run.
*
* @access public
* @return void
*/
public function run()
{
while(true)
{
foreach($this->repos as $name => $repo)
{
$this->printLog("begin repo $name");
$repo = (object)$repo;
$repo->name = $name;
$this->setRepo($repo);
$savedRevision = $this->getSavedRevision();
$this->printLog("start from revision $savedRevision");
$logs = $this->getRepoLogs($repo, $savedRevision);
$revisions = $this->getRevisionsFromLogs($logs);
if(!$revisions)
{
$this->printLog("no logs");
continue;
}
$this->printLog('fetched ' . count($revisions) . ' logs');
$this->printLog('begin posting logs');
$objects = $this->zentaoClient->post('svn', 'apiSync', array('logs' => $logs, 'repoRoot' => $this->repoRoot));
$objects = $objects->parsedObjects;
$this->printLog('parsed objects:');
echo 'story: ' . join(',', (array)$objects->stories) . "\n";
echo 'task: ' . join(',', (array)$objects->tasks) . "\n";
echo 'bugs: ' . join(',', (array)$objects->bugs) . "\n";
$this->saveLastRevision(max($revisions));
echo "----------------------\n";
}
$this->printLog("sleeping {$this->config->sleep} seconds");
sleep($this->config->sleep);
}
}
/**
* Set repo.
*
* @param object $repo
* @access public
* @return void
*/
public function setRepo($repo)
{
$this->setClient($repo);
$this->setLogFile($repo->name);
$this->setRepoRoot($repo);
}
/**
* Set the svn binary svnClient of a repo.
*
* @param object $repo
* @access public
* @return void
*/
public function setClient($repo)
{
if($this->config->svn->client == '') die("You must set the svn svnClient file.\n");
$this->svnClient = $this->config->svn->client . " --non-interactive";
if(isset($repo->username)) $this->svnClient .= " --username $repo->username --password $repo->password --no-auth-cache";
}
/**
* Set the log file of a repo.
*
* @param string $repoName
* @access public
* @return void
*/
public function setLogFile($repoName)
{
$this->logFile = $this->logRoot . $repoName;
}
/**
* set the root path of a repo.
*
* @param object $repo
* @access public
* @return void
*/
public function setRepoRoot($repo)
{
$cmd = $this->svnClient . " info --xml $repo->path";
$info = `$cmd`;
$info = simplexml_load_string($info);
$repoRoot = (string)$info->entry->repository->root;
$this->repoRoot = $repoRoot;
}
/**
* Get repo logs.
*
* @param object $repo
* @param int $fromRevision
* @access public
* @return string
*/
public function getRepoLogs($repo, $fromRevision)
{
$parsedLogs = array();
/* The svn log command. */
$cmd = $this->svnClient . " log -r $fromRevision:HEAD -v --xml $repo->path";
$logs = `$cmd`;
return $logs;
}
/**
* Get the saved revision.
*
* @access public
* @return int
*/
public function getSavedRevision()
{
if(!file_exists($this->logFile)) return 0;
return (int)trim(file_get_contents($this->logFile));
}
/**
* Get revisons from logs.
*
* @param string $logs
* @access public
* @return array|bool
*/
public function getRevisionsFromLogs($logs)
{
if(!preg_match_all('|revision="(.*)"|', $logs, $results)) return false;
$revisions = $results[1];
return $revisions;
}
/**
* Save the last revision.
*
* @param int $revision
* @access public
* @return void
*/
public function saveLastRevision($revision)
{
file_put_contents($this->logFile, $revision);
}
/**
* Pring log.
*
* @param sting $log
* @access public
* @return void
*/
public function printLog($log)
{
echo date('Y-m-d H:i:s') . " $log\n";
}
}