require_once 'MTrack/Config.php';
require_once 'MTrack/Project.php';
require_once 'MTrack/SCMFileEvent.php';
-require_once 'MTrack/ACL.php';
-require_once 'MTrack/Changeset.php';
-require_once 'MTrack/Wiki.php';
+ //require_once 'MTrack/Changeset.php';
+//require_once 'MTrack/Wiki.php';
class MTrack_Repo extends MTrackSCM
{
- public $repoid = null;
+ public $id = null;
public $shortname = null;
public $scmtype = null;
public $repopath = null;
static function factory($ar)
{
- print_r($ar);
+ //print_r($ar);
$type = ucfirst($ar['scmtype']);
$fn = 'MTrack/SCM/'.$type .'/Repo.php';
$cls = 'MTrack_SCM_'.$type .'_Repo';
return $ret;
}
+
static function getAvailableSCMs()
{
}
return $ret;
}
-
-
- /*static function loadById($id) {
- list($row) = MTrackDB::q(
- 'select repoid, scmtype from repos where repoid = ?',
- $id)->fetchAll();
- if (isset($row[0])) {
- $type = $row[1];
- if (isset(self::$scms[$type])) {
- $class = self::$scms[$type];
- return new $class($row[0]);
- }
- throw new Exception("unsupported repo type $type");
- }
- return null;
- }
- static function loadByName($name) {
- $bits = explode('/', $name);
- if (count($bits) > 1 && $bits[0] == 'default') {
- array_shift($bits);
- $name = $bits[0];
- }
- if (count($bits) > 1) {
- // wez/reponame -> per user repo
- $u = "user:$bits[0]";
- $p = "project:$bits[0]";
- $rows = MTrackDB::q(
- 'select repoid, scmtype from repos where shortname = ? and (parent = ? OR parent = ?)',
- $bits[1], $u, $p)->fetchAll();
- } else {
- $rows = MTrackDB::q(
- "select repoid, scmtype from repos where shortname = ? and parent =''",
- $name)->fetchAll();
- }
- if (is_array($rows) && isset($rows[0])) {
- $row = $rows[0];
- if (isset($row[0])) {
- $type = $row[1];
- if (isset(self::$scms[$type])) {
- $class = self::$scms[$type];
- return new $class($row[0]);
- }
- throw new Exception("unsupported repo type $type");
- }
- }
- return null;
- }
- static function loadByLocation($path)
- {
-
- // we have magic configuration - end users commit into SVN
- // backend is really git... - so pre-commit hooks have to be from svn
- list($row) = MTrackDB::q('select repoid, scmtype from repos where repopath = ?', $path)->fetchAll();
- if (isset($row[0])) {
- $type = $row[1];
- if (isset(self::$scms[$type])) {
- $class = self::$scms[$type];
- return new $class($row[0]);
- }
- throw new Exception("unsupported repo type $type");
- }
- return null;
- }
-
- static function loadByChangeSet($cs)
- {
+
+ function __construct($ar = null) {
- static $re = array();
- if (isset($re[$cs])) {
- return $re[$cs];
+ if (!is_array($ar)) {
+ return; // can accept empty ctrs
}
- //using (repoid) ??
- $q = MTrackDB::q("
- select
- r.shortname as repo,
- p.shortname as proj
- from
- repos r
- left join
- project_repo_link l on r.repoid = l.repoid
- left join
- projects p on p.projid = r.projectid
- where
- (parent is null or length(parent) = 0)
- AND
- (
- ( ? like CONCAT(proj), '%')
- OR
- ( ? like CONCAT(repo), '%')
- )
- ");
- $ar = $q->fetchAll(PDO::FETCH_ASSOC);
- if ($ar) {
- $re[$cs] = self::loadByName($ar['repo']);
- return $re[$cs];
- }
- $re[$cs] = false;
- return $re[$cs];
- }
- */
- // methods
-
- function __construct($id = null) {
- if ($id !== null) {
- list($row) = MTrackDB::q(
- 'select * from repos where repoid = ?',
- $id)->fetchAll();
- if (isset($row[0])) {
- $this->repoid = $row['repoid'];
- $this->shortname = $row['shortname'];
- $this->scmtype = $row['scmtype'];
- $this->repopath = $row['repopath'];
- $this->browserurl = $row['browserurl'];
- $this->browsertype = $row['browsertype'];
- $this->description = $row['description'];
- $this->parent = $row['parent'];
- $this->clonedfrom = $row['clonedfrom'];
- $this->serverurl = $row['serverurl'];
- return;
- }
- throw new Exception("unable to find repo with id = $id");
+ foreach($ar as $k=>$v) {
+ $this->$k = $v;
}
+
}
- function reconcileRepoSettings() {
- if (!isset(self::$scms[$this->scmtype])) {
- throw new Exception("invalid scm type $this->scmtype");
- }
- $c = self::$scms[$this->scmtype];
- $s = new $c;
+ function reconcileRepoSettings()
+ {
+ $c = self::Factory(array('scmtype'=>$this->scmtype));
$s->reconcileRepoSettings($this);
}
-
- function getSCMMetaData() {
- return null;
- }
-
- function getServerURL() {
- if ($this->serverurl) {
- return $this->serverurl;
- }
- $url = MTrackConfig::get('repos', "$this->scmtype.serverurl");
- if ($url) {
- return $url . $this->getBrowseRootName();
+
+ function getServerURL()
+ {
+ if ($this->serverurl) {
+ return $this->serverurl;
+ }
+ /*
+ $url = MTrackConfig::get('repos', "$this->scmtype.serverurl");
+ if ($url) {
+ return $url . $this->getBrowseRootName();
+ }
+ */
+ return null;
}
- return null;
- }
function getCheckoutCommand() {
- $url = $this->getServerURL();
- if (strlen($url)) {
- return $this->scmtype . ' clone ' . $this->getServerURL();
+ $url = $this->getServerURL();
+ if (strlen($url)) {
+ return $this->scmtype . ' clone ' . $this->getServerURL();
+ }
+ return null;
}
- return null;
- }
function canFork() {
- return false;
- }
+ return false;
+ }
function getWorkingCopy() {
- throw new Exception("cannot getWorkingCopy from a generic repo object");
- }
-
+ throw new Exception("cannot getWorkingCopy from a generic repo object");
+ }
+ /*
function deleteRepo(MTrackChangeset $CS) {
- MTrackDB::q('delete from repos where repoid = ?', $this->repoid);
- mtrack_rmdir($this->repopath);
- }
-
- function save(MTrackChangeset $CS) {
- if (!isset(self::$scms[$this->scmtype])) {
- throw new Exception("unsupported repo type " . $this->scmtype);
- }
-
- if ($this->repoid) {
- list($row) = MTrackDB::q(
- 'select * from repos where repoid = ?',
- $this->repoid)->fetchAll();
- $old = $row;
- MTrackDB::q(
- 'update repos set shortname = ?, scmtype = ?, repopath = ?,
- browserurl = ?, browsertype = ?, description = ?,
- parent = ?, serverurl = ?, clonedfrom = ? where repoid = ?',
- $this->shortname, $this->scmtype, $this->repopath,
- $this->browserurl, $this->browsertype, $this->description,
- $this->parent, $this->serverurl, $this->clonedfrom, $this->repoid);
- } else {
- $acl = null;
-
- if (!strlen($this->repopath)) {
- if (!MTrackConfig::get('repos', 'allow_user_repo_creation')) {
- throw new Exception("configuration does not allow repo creation");
- }
- $repodir = MTrackConfig::get('repos', 'basedir');
- if ($repodir == null) {
- $repodir = MTrackConfig::get('core', 'vardir') . '/repos';
- }
- if (!is_dir($repodir)) {
- mkdir($repodir);
- }
-
- if (!$this->parent) {
- $owner = mtrack_canon_username(MTrackAuth::whoami());
- $this->parent = 'user:' . $owner;
- } else {
- list($type, $owner) = explode(':', $this->parent, 2);
- switch ($type) {
- case 'project':
- $P = MTrackProject::loadByName($owner);
- if (!$P) {
- throw new Exception("invalid project $owner");
- }
- MTrackACL::requireAllRights("project:$P->projid", 'modify');
- break;
- case 'user':
- if ($owner != mtrack_canon_username(MTrackAuth::whoami())) {
- throw new Exception("can't make a repo for another user");
- }
- break;
- default:
- throw new Exception("invalid parent ($this->parent)");
- }
- }
- if (preg_match("/[^a-zA-Z0-9_.-]/", $owner)) {
- throw new Exception("$owner must not contain special characters");
- }
- $this->repopath = $repodir . DIRECTORY_SEPARATOR . $owner;
- if (!is_dir($this->repopath)) {
- mkdir($this->repopath);
- }
- $this->repopath .= DIRECTORY_SEPARATOR . $this->shortname;
-
- /* default ACL is allow user all rights, block everybody else */
- $acl = array(
- array($owner, 'read', 1),
- array($owner, 'modify', 1),
- array($owner, 'delete', 1),
- array($owner, 'checkout', 1),
- array($owner, 'commit', 1),
- array('*', 'read', 0),
- array('*', 'modify', 0),
- array('*', 'delete', 0),
- array('*', 'checkout', 0),
- array('*', 'commit', 0),
- );
- }
-
- MTrackDB::q('insert into repos (shortname, scmtype,
- repopath, browserurl, browsertype, description, parent,
- serverurl, clonedfrom)
- values (?, ?, ?, ?, ?, ?, ?, ?, ?)',
- $this->shortname, $this->scmtype, $this->repopath,
- $this->browserurl, $this->browsertype, $this->description,
- $this->parent, $this->serverurl, $this->clonedfrom);
-
- $this->repoid = MTrackDB::lastInsertId('repos', 'repoid');
- $old = null;
-
- if ($acl !== null) {
- MTrackACL::setACL("repo:$this->repoid", 0, $acl);
- $me = mtrack_canon_username(MTrackAuth::whoami());
- foreach (array('ticket', 'changeset') as $e) {
- MTrackDB::q(
- 'insert into watches (otype, oid, userid, medium, event, active) values (?, ?, ?, ?, ?, 1)',
- 'repo', $this->repoid, $me, 'email', $e);
- }
- }
- }
- $this->reconcileRepoSettings();
- if (!$this->parent) {
- /* for SSH access, populate a symlink from the repos basedir to the
- * actual path for this repo */
- $repodir = MTrackConfig::get('repos', 'basedir');
- if ($repodir == null) {
- $repodir = MTrackConfig::get('core', 'vardir') . '/repos';
- }
- if (!is_dir($repodir)) {
- mkdir($repodir);
- }
- $repodir .= '/default';
- if (!is_dir($repodir)) {
- mkdir($repodir);
- }
- $repodir .= '/' . $this->shortname;
- if (!file_exists($repodir)) {
- symlink($this->repopath, $repodir);
- } else if (is_link($repodir) && readlink($repodir) != $this->repopath) {
- unlink($repodir);
- symlink($this->repopath, $repodir);
- }
- }
- $CS->add("repo:" . $this->repoid . ":shortname", $old['shortname'], $this->shortname);
- $CS->add("repo:" . $this->repoid . ":scmtype", $old['scmtype'], $this->scmtype);
- $CS->add("repo:" . $this->repoid . ":repopath", $old['repopath'], $this->repopath);
- $CS->add("repo:" . $this->repoid . ":browserurl", $old['browserurl'], $this->browserurl);
- $CS->add("repo:" . $this->repoid . ":browsertype", $old['browsertype'], $this->browsertype);
- $CS->add("repo:" . $this->repoid . ":description", $old['description'], $this->description);
- $CS->add("repo:" . $this->repoid . ":parent", $old['parent'], $this->parent);
- $CS->add("repo:" . $this->repoid . ":clonedfrom", $old['clonedfrom'], $this->clonedfrom);
- $CS->add("repo:" . $this->repoid . ":serverurl", $old['serverurl'], $this->serverurl);
-
- foreach ($this->links_to_add as $link) {
- MTrackDB::q('insert into project_repo_link (projid, repoid, repopathregex) values (?, ?, ?)', $link[0], $this->repoid, $link[1]);
- }
- foreach ($this->links_to_remove as $linkid) {
- MTrackDB::q('delete from project_repo_link where repoid = ? and linkid = ?', $this->repoid, $linkid);
- }
- }
-
+ MTrackDB::q('delete from repos where repoid = ?', $this->repoid);
+ mtrack_rmdir($this->repopath);
+ }
+ */
+
+/**
+ * i could not find where this is used..
function getLinks()
{
if ($this->links === null) {
{
$this->links_to_remove[$linkid] = $linkid;
}
+ */
+// these are needed just to implement the abstract interface..
function getBranches() {}
function getTags() {}
function readdir($path, $object = null, $ident = null) {}
function history($path, $limit = null, $object = null, $ident = null){}
function diff($path, $from = null, $to = null) {}
function getRelatedChanges($revision) {}
-
- function projectFromPath($filename)
- {
- static $links = array();
- if (!isset($links[$this->repoid]) || $links[$this->repoid] === null) {
- $links[$this->repoid] = array();
- foreach (MTrackDB::q(
- 'select projid, repopathregex from project_repo_link where repoid = ?',
- $this->repoid) as $row) {
- $re = str_replace('/', '\\/', $row[1]);
- $links[$this->repoid][] = array($row[0], "/$re/");
- }
- }
- if (is_array($filename)) {
- $proj_incidence = array();
- foreach ($filename as $file) {
- $proj = $this->projectFromPath($file);
- if ($proj === null) continue;
- if (isset($proj_incidence[$proj])) {
- $proj_incidence[$proj]++;
- } else {
- $proj_incidence[$proj] = 1;
- }
- }
- $the_proj = null;
- $the_proj_count = 0;
- foreach ($proj_incidence as $proj => $count) {
- if ($count > $the_proj_count) {
- $the_proj_count = $count;
- $the_proj = $proj;
- }
- }
- return $the_proj;
- }
-
- if ($filename instanceof MTrackSCMFileEvent) {
- $filename = $filename->name;
- }
-
- // walk through the regexes; take the longest match as definitive
- $longest = null;
- $longest_id = null;
- if ($filename[0] != '/') {
- $filename = '/' . $filename;
- }
- foreach ($links[$this->repoid] as $link) {
- if (preg_match($link[1], $filename, $M)) {
- if (strlen($M[0]) > strlen($longest)) {
- $longest = $M[0];
- $longest_id = $link[0];
- }
- }
- }
- return $longest_id;
- }
-
- function historyWithChangelog($path, $limit = null, $object = null, $ident = null)
- {
-
- $ents = $this->history($path, $limit, $object, $ident);
- $data = new StdClass;
- if (!count($ents)) {
- $data->ent = null;
- return $data;
- }
- $ent = $ents[0];
- $data->ent = $ent;
-
- // Determine project from the file list
- $the_proj = $this->projectFromPath($ent->files);
- if ($the_proj > 1) {
- $proj = MTrackProject::loadById($the_proj);
- $changelog = $proj->adjust_links($ent->changelog, true);
- } else {
- $changelog = $ent->changelog;
- }
- $data->changelog = $changelog;
-
- //if (is_array($ent->files)) foreach ($ent->files as $file) {
- // $file->diff = mtrack_diff($repo->diff($file, $ent->rev));
- //}
-
-
- return $data;
- }
- function historyWithChangelogAndDiff($path, $limit = null, $object = null, $ident = null)
- {
- $ret = $this->historyWithChangelog($path, $limit, $object, $ident);
- if (!$ret->ent) {
- return $ret;
- }
- if (!is_array($ret->ent->files)) {
- return $ret;
- }
- foreach ($ret->ent->files as $file) {
- // where is mtrack_diff...
- $file->diff = mtrack_diff($this->diff($file, $ret->ent->rev));
- }
-
-
- return $data;
- }
- // rendering..
-
- function displayName()
- {
- // fixme - this code needs to be in here.. rather than in SCM?
- return MTrackSCM::makeDisplayName($this);
- }
- function descriptionToHtml()
- {
- return MTrack_Wiki::format_to_html($this->description);
- }
-
- static function defaultRepo($cfg = null)
- {
- static $defrepo = null;
- if ($defrepo !== null) {
- return $defrepo; // already to it..
- }
-
- $defrepo = $cfg;
- if ($defrepo !== null) {
- $defrepo = strpos($defrepo, '/') === false ? 'default/' . $defrepo : $defrepo;
- return $defrepo;
- }
-
- $defrepo = '';
- $q = MTrackDB::q( 'select parent, shortname from repos order by shortname');
- foreach($q->fetchAll() as $row) {
- $defrepo = MTrackSCM::makeDisplayName($row);
- return $defrepo;
- }
- return '';
-
+ function getSCMMetaData() { return null; }
+ /**
+ * converts a commit log message (cached locally into a working object..)
+ * see Browse.php
+ */
+ function commitLogToEvent($str) {
+ throw new Exception("no implementation for commitLogToEvent");
}
-
}