Copyright 2008-2016 Horde LLC (http://www.horde.org/) See the enclosed file COPYING for license information (LGPL). If you did not receive this file, see http://www.horde.org/licenses/lgpl21.
Example #1
0
 /**
  * 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);
         }
     }
 }
Example #2
0
 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')));
 }
Example #3
0
 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')));
 }
Example #4
0
 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);
 }
Example #5
0
 /**
  * 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);
         }
     }
 }
Example #6
0
 /**
  * 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)));
     }
 }
Example #7
0
 /**
  * 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;
         }
     }
 }