/** * Constructor * * @param Horde_Vcs $rep A Horde_Vcs repository object. * @param string $file The filename to create patchsets for. */ public function __construct($rep, $opts = array()) { // TODO: Allow access via 'range' $fileOb = $rep->getFile($opts['file']); foreach ($fileOb->getLog() as $rev => $log) { $this->_patchsets[$rev] = array_merge($log->toHash(), array('members' => array())); foreach ($log->getFiles() as $file => $info) { $to = $rev; $status = Horde_Vcs_Patchset::MODIFIED; if ($info['status'] == 'A') { $from = null; $status = Horde_Vcs_Patchset::ADDED; } elseif ($info['status'] == 'D') { $from = $to; $to = null; $status = Horde_Vcs_Patchset::DELETED; } else { // This technically isn't the previous revision, // but it works for diffing purposes. $from = $to - 1; } $this->_patchsets[$rev]['members'][] = array('file' => $file, 'from' => $from, 'to' => $to, 'status' => $status); } } }
public function setUp() { if (!self::$conf) { $this->markTestSkipped('No test configuration'); } $this->vcs = Horde_Vcs::factory('Git', array_merge(self::$conf, array('sourceroot' => __DIR__ . '/repos/git'))); }
public function setUp() { $this->markTestIncomplete('No RCS available on Travis at the moment.'); if (!self::$conf) { $this->markTestSkipped('No test configuration'); } $this->vcs = Horde_Vcs::factory('Rcs', array_merge(self::$conf, array('sourceroot' => __DIR__ . '/repos/rcs'))); }
public function setUp() { if (!self::$conf) { $this->markTestSkipped('No test configuration'); } $conf = self::$conf; $conf['paths']['cvsps_home'] = Horde_Util::createTempDir(true, $conf['paths']['cvsps_home']); $conf['sourceroot'] = __DIR__ . '/repos/cvs'; $this->vcs = Horde_Vcs::factory('Cvs', $conf); }
/** * Constructor * * @param Horde_Vcs $rep A Horde_Vcs repository object. * @param array $opts Additional options. * <pre> * 'file' - (string) The filename to produce patchsets for. * 'range' - (array) The patchsets to process. * DEFAULT: None (all patchsets are processed). * </pre> */ public function __construct($rep, $opts = array()) { $revs = array(); if (isset($opts['file'])) { $ob = $rep->getFile($opts['file']); $revs = $ob->getLog(); } elseif (!empty($opts['range'])) { foreach ($opts['range'] as $val) { /* Grab a filename in the patchset to get log info. */ list($resource, $stream) = $rep->runCommand('diff-tree --name-only -r ' . escapeshellarg($val)); /* The first line is the SHA1 hash. */ $ob = $rep->getFile(fgets($stream)); fclose($stream); proc_close($resource); $revs[$val] = $ob->getLog($val); } } reset($revs); while (list($rev, $log) = each($revs)) { if (empty($log)) { continue; } $this->_patchsets[$rev] = array_merge($log->toHash(), array('members' => array())); foreach ($log->getFiles() as $file) { $from = $log->getParent(); $to = $rev; switch ($file['status']) { case 'A': $status = Horde_Vcs_Patchset::ADDED; break; case 'D': $status = Horde_Vcs_Patchset::DELETED; break; default: $status = Horde_Vcs_Patchset::MODIFIED; } $statinfo = isset($file['added']) ? array('added' => $file['added'], 'deleted' => $file['deleted']) : array(); $this->_patchsets[$rev]['members'][] = array_merge(array('file' => $file['srcPath'], 'from' => $from, 'status' => $status, 'to' => $to), $statinfo); } } }
/** * Global variables defined: * $chora_conf * $sourceroots */ protected function _init() { global $acts, $conf, $defaultActs, $where, $atdir, $fullname, $sourceroot, $page_output; // TODO: If chora isn't fully/properly setup, init() will throw fatal // errors. Don't want that if this class is being loaded simply to // obtain basic chora application information. $initial_app = $GLOBALS['registry']->initialApp == 'chora'; try { $GLOBALS['sourceroots'] = Horde::loadConfiguration('backends.php', 'sourceroots'); } catch (Horde_Exception $e) { $GLOBALS['sourceroots'] = array(); if (!$initial_app) { return; } $GLOBALS['notification']->push($e); } $sourceroots = Chora::sourceroots(); /** * Variables we wish to propagate across web pages * ha = Hide Attic Files * ord = Sort order * sbt = Sort By Type (name, age, author, etc) * * Obviously, defaults go into $defaultActs :) * TODO: defaults of 1 will not get propagated correctly - avsm * XXX: Rewrite this propagation code, since it sucks - avsm */ $defaultActs = $acts = array('onb' => 0, 'ord' => Horde_Vcs::SORT_ASCENDING, 'rev' => 0, 'rt' => null, 'sa' => 0, 'sbt' => constant($conf['options']['defaultsort']), 'ws' => 1); /* See if any actions have been passed as form variables, and if so, * assign them into the acts array. */ $vars = Horde_Variables::getDefaultVariables(); foreach (array_keys($acts) as $key) { if (isset($vars->{$key})) { $acts[$key] = $vars->{$key}; } } /* Use the value of the 'rt' form value for the sourceroot. If not * present, use the last sourceroot used as the default value if the * user has that preference. Otherwise, use default sourceroot. */ $last_sourceroot = $GLOBALS['prefs']->getValue('last_sourceroot'); if (is_null($acts['rt'])) { if (!empty($last_sourceroot) && !empty($sourceroots[$last_sourceroot]) && is_array($sourceroots[$last_sourceroot])) { $acts['rt'] = $last_sourceroot; } else { foreach ($sourceroots as $key => $val) { if (!isset($acts['rt']) || isset($val['default'])) { $acts['rt'] = $key; break; } } if (is_null($acts['rt'])) { if ($initial_app) { Chora::fatal(new Chora_Exception(_("No repositories found."))); } return; } } } if (!isset($sourceroots[$acts['rt']])) { if ($initial_app) { Chora::fatal(new Chora_Exception(sprintf(_("The repository with the slug '%s' was not found"), $acts['rt']))); } return; } $sourcerootopts = $sourceroots[$acts['rt']]; $sourceroot = $acts['rt']; /* Store last repository viewed */ if ($acts['rt'] != $last_sourceroot) { $GLOBALS['prefs']->setValue('last_sourceroot', $acts['rt']); } // Cache. $cache = empty($conf['caching']) ? null : $GLOBALS['injector']->getInstance('Horde_Cache'); $GLOBALS['chora_conf'] = array('cvsusers' => $sourcerootopts['location'] . '/' . (isset($sourcerootopts['cvsusers']) ? $sourcerootopts['cvsusers'] : ''), 'introText' => CHORA_BASE . '/config/' . (isset($sourcerootopts['intro']) ? $sourcerootopts['intro'] : ''), 'introTitle' => isset($sourcerootopts['title']) ? $sourcerootopts['title'] : '', 'sourceRootName' => $sourcerootopts['name']); $chora_conf =& $GLOBALS['chora_conf']; $GLOBALS['VC'] = Horde_Vcs::factory(Horde_String::ucfirst($sourcerootopts['type']), array('cache' => $cache, 'sourceroot' => $sourcerootopts['location'], 'paths' => array_merge($conf['paths'], array('temp' => Horde::getTempDir())), 'username' => isset($sourcerootopts['username']) ? $sourcerootopts['username'] : '', 'password' => isset($sourcerootopts['password']) ? $sourcerootopts['password'] : '')); if (!$initial_app) { return; } $where = Horde_Util::getFormData('f', '/'); /* Location relative to the sourceroot. */ $where = preg_replace(array('|^/|', '|\\.\\.|'), '', $where); $fullname = $sourcerootopts['location'] . (substr($sourcerootopts['location'], -1) == '/' ? '' : '/') . $where; if ($sourcerootopts['type'] == 'cvs') { $fullname = preg_replace('|/$|', '', $fullname); $atdir = @is_dir($fullname); } else { $atdir = !$where || substr($where, -1) == '/'; } $where = preg_replace('|/$|', '', $where); if ($sourcerootopts['type'] == 'cvs' && !@is_dir($sourcerootopts['location'])) { Chora::fatal(new Chora_Exception(_("Sourceroot not found. This could be a misconfiguration by the server administrator, or the server could be having temporary problems. Please try again later."))); } if (Chora::isRestricted($where)) { Chora::fatal(new Chora_Exception(sprintf(_("%s: Forbidden by server configuration"), $where))); } }
/** * Constructor * * @param Horde_Vcs $rep A Horde_Vcs repository object. * @param string $file The filename to create a patchset for. * @param array $opts Additional options. * - 'file': (string) The filename to process. * REQUIRED for this driver. * - 'range': (array) The patchsets to process. * DEFAULT: None (all patchsets are processed). * - 'timezone': (string) The current timezone. * * @throws Horde_Vcs_Exception */ public function __construct($rep, $opts = array()) { $file = $rep->sourceroot . '/' . $opts['file']; /* Check that we are actually in the filesystem. */ if (!$rep->isFile($file)) { throw new Horde_Vcs_Exception('File Not Found'); } /* Set environment. */ $env = array(); if (!empty($opts['timezone'])) { $env[] = 'TZ=' . escapeshellarg($opts['timezone']); } /* Call cvsps to retrieve all patchsets for this file. */ $cvsps_home = $rep->getPath('cvsps_home'); if (!empty($cvsps_home)) { $env[] = 'HOME=' . escapeshellarg($cvsps_home); } $rangecmd = empty($opts['range']) ? '' : ' -s ' . escapeshellarg(implode(',', $opts['range'])); $ret_array = array(); $cmd = implode(' ', $env) . ' ' . escapeshellcmd($rep->getPath('cvsps')) . $rangecmd . ' -u --cvs-direct --root ' . escapeshellarg($rep->sourceroot) . ' -f ' . escapeshellarg(basename($file)) . ' -q ' . escapeshellarg(dirname($file)); exec($cmd, $ret_array, $retval); if ($retval) { throw new Horde_Vcs_Exception('Failed to spawn cvsps to retrieve patchset information.'); } $state = 'begin'; reset($ret_array); while (list(, $line) = each($ret_array)) { $line = trim($line); if ($line == '---------------------') { $state = 'begin'; continue; } switch ($state) { case 'begin': $id = str_replace('PatchSet ', '', $line); $this->_patchsets[$id] = array('revision' => $id); $state = 'info'; break; case 'info': $info = explode(':', $line, 2); $info[1] = ltrim($info[1]); switch ($info[0]) { case 'Date': $d = new DateTime($info[1]); $this->_patchsets[$id]['date'] = $d->format('U'); break; case 'Author': $this->_patchsets[$id]['author'] = $info[1]; break; case 'Branch': $this->_patchsets[$id]['branches'] = $info[1] == 'HEAD' ? array() : array($info[1]); break; case 'Tag': $this->_patchsets[$id]['tags'] = $info[1] == '(none)' ? array() : array($info[1]); break; case 'Log': $state = 'log'; $this->_patchsets[$id]['log'] = ''; break; } break; case 'log': if ($line == 'Members:') { $state = 'members'; $this->_patchsets[$id]['log'] = rtrim($this->_patchsets[$id]['log']); $this->_patchsets[$id]['members'] = array(); } else { $this->_patchsets[$id]['log'] .= $line . "\n"; } break; case 'members': if (!empty($line)) { $parts = explode(':', $line); list($from, $to) = explode('->', $parts[1], 2); $status = Horde_Vcs_Patchset::MODIFIED; if ($from == 'INITIAL') { $from = null; $status = Horde_Vcs_Patchset::ADDED; } elseif (substr($to, -6) == '(DEAD)') { $to = null; $status = Horde_Vcs_Patchset::DELETED; } $this->_patchsets[$id]['members'][] = array('file' => $parts[0], 'from' => $from, 'status' => $status, 'to' => $to); } break; } } }