Create a separate class which handles command streaming over mtn automate stdio. Use that everywhere instead of the direct system calls.
This commit is contained in:
		@@ -25,10 +25,248 @@
 | 
				
			|||||||
 * Monotone utils.
 | 
					 * Monotone utils.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class IDF_Scm_Monotone_Stdio
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static $SUPPORTED_STDIO_VERSION = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private $repo;
 | 
				
			||||||
 | 
					    private $proc;
 | 
				
			||||||
 | 
					    private $pipes;
 | 
				
			||||||
 | 
					    private $oob;
 | 
				
			||||||
 | 
					    private $cmdnum;
 | 
				
			||||||
 | 
					    private $lastcmd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __construct($repo)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->repo = $repo;
 | 
				
			||||||
 | 
					        $this->start();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function __destruct()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->stop();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function start()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (is_resource($this->proc))
 | 
				
			||||||
 | 
					            $this->stop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
				
			||||||
 | 
					            .sprintf("%s -d %s automate stdio --no-workspace --norc",
 | 
				
			||||||
 | 
					                         Pluf::f('mtn_path', 'mtn'),
 | 
				
			||||||
 | 
					                         escapeshellarg($this->repo));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $descriptors = array(
 | 
				
			||||||
 | 
					            0 => array("pipe", "r"),
 | 
				
			||||||
 | 
					            1 => array("pipe", "w"),
 | 
				
			||||||
 | 
					            2 => array("pipe", "r")
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->proc = proc_open($cmd, $descriptors, $this->pipes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!is_resource($this->proc))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new IDF_Scm_Exception("could not start stdio process");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->_checkVersion();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->cmdnum = -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function stop()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!is_resource($this->proc))
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fclose($this->pipes[0]);
 | 
				
			||||||
 | 
					        fclose($this->pipes[1]);
 | 
				
			||||||
 | 
					        fclose($this->pipes[2]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        proc_close($this->proc);
 | 
				
			||||||
 | 
					        $this->proc = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function _checkVersion()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $version = fgets($this->pipes[1]);
 | 
				
			||||||
 | 
					        if (!preg_match('/^format-version: (\d+)$/', $version, $m) ||
 | 
				
			||||||
 | 
					            $m[1] != self::$SUPPORTED_STDIO_VERSION)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new IDF_Scm_Exception(
 | 
				
			||||||
 | 
					                "stdio format version mismatch, expected '".
 | 
				
			||||||
 | 
					                self::$SUPPORTED_STDIO_VERSION."', got '".@$m[1]."'"
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        fgets($this->pipes[1]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function _write($args, $options = array())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $cmd = "";
 | 
				
			||||||
 | 
					        if (count($options) > 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $cmd = "o";
 | 
				
			||||||
 | 
					            foreach ($options as $k => $v)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                $cmd .= strlen((string)$k) . ":" . (string)$k;
 | 
				
			||||||
 | 
					                $cmd .= strlen((string)$v) . ":" . (string)$v;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $cmd .= "e ";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $cmd .= "l";
 | 
				
			||||||
 | 
					        foreach ($args as $arg)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $cmd .= strlen((string)$arg) . ":" . (string)$arg;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $cmd .= "e\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!fwrite($this->pipes[0], $cmd))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new IDF_Scm_Exception("could not write '$cmd' to process");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $this->lastcmd = $cmd;
 | 
				
			||||||
 | 
					        $this->cmdnum++;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function _read()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->oob = array('w' => array(),
 | 
				
			||||||
 | 
					                           'p' => array(),
 | 
				
			||||||
 | 
					                           't' => array(),
 | 
				
			||||||
 | 
					                           'e' => array());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $output = "";
 | 
				
			||||||
 | 
					        $errcode = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        while (true)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            $read = array($this->pipes[1]);
 | 
				
			||||||
 | 
					            $write = null;
 | 
				
			||||||
 | 
					            $except = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $streamsChanged = stream_select(
 | 
				
			||||||
 | 
					                $read, $write, $except, 0, 20000
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($streamsChanged === false)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new IDF_Scm_Exception(
 | 
				
			||||||
 | 
					                    "Could not select() on read pipe"
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ($streamsChanged == 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $data = array(0,"",0);
 | 
				
			||||||
 | 
					            $idx = 0;
 | 
				
			||||||
 | 
					            while (true)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                $c = fgetc($this->pipes[1]);
 | 
				
			||||||
 | 
					                if ($c == ':')
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    if ($idx == 2)
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    ++$idx;
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (is_numeric($c))
 | 
				
			||||||
 | 
					                    $data[$idx] = $data[$idx] * 10 + $c;
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                    $data[$idx] .= $c;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // sanity
 | 
				
			||||||
 | 
					            if ($this->cmdnum != $data[0])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                throw new IDF_Scm_Exception(
 | 
				
			||||||
 | 
					                    "command numbers out of sync; ".
 | 
				
			||||||
 | 
					                    "expected {$this->cmdnum}, got {$data[0]}"
 | 
				
			||||||
 | 
					                );
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            $toRead = $data[2];
 | 
				
			||||||
 | 
					            $buffer = "";
 | 
				
			||||||
 | 
					            while ($toRead > 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                $buffer .= fread($this->pipes[1], $toRead);
 | 
				
			||||||
 | 
					                $toRead = $data[2] - strlen($buffer);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch ($data[1])
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                case 'w':
 | 
				
			||||||
 | 
					                case 'p':
 | 
				
			||||||
 | 
					                case 't':
 | 
				
			||||||
 | 
					                case 'e':
 | 
				
			||||||
 | 
					                    $this->oob[$data[1]][] = $buffer;
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                case 'm':
 | 
				
			||||||
 | 
					                    $output .= $buffer;
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                case 'l':
 | 
				
			||||||
 | 
					                    $errcode = $buffer;
 | 
				
			||||||
 | 
					                    break 2;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ($errcode != 0)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            throw new IDF_Scm_Exception(
 | 
				
			||||||
 | 
					                "command '{$this->lastcmd}' returned error code $errcode: ".
 | 
				
			||||||
 | 
					                implode(" ", $this->oob['e'])
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $output;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function exec($args, $options = array())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->_write($args, $options);
 | 
				
			||||||
 | 
					        return $this->_read();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getLastWarnings()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array_key_exists('w', $this->oob) ?
 | 
				
			||||||
 | 
					            $this->oob['w'] : array();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getLastProgress()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array_key_exists('p', $this->oob) ?
 | 
				
			||||||
 | 
					            $this->oob['p'] : array();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getLastTickers()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array_key_exists('t', $this->oob) ?
 | 
				
			||||||
 | 
					            $this->oob['t'] : array();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function getLastErrors()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return array_key_exists('e', $this->oob) ?
 | 
				
			||||||
 | 
					            $this->oob['e'] : array();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IDF_Scm_Monotone extends IDF_Scm
 | 
					class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public static $MIN_INTERFACE_VERSION = 12.0;
 | 
					    public static $MIN_INTERFACE_VERSION = 12.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private $stdio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* ============================================== *
 | 
					    /* ============================================== *
 | 
				
			||||||
     *                                                *
 | 
					     *                                                *
 | 
				
			||||||
     *   Common Methods Implemented By All The SCMs   *
 | 
					     *   Common Methods Implemented By All The SCMs   *
 | 
				
			||||||
@@ -39,6 +277,7 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->repo = $repo;
 | 
					        $this->repo = $repo;
 | 
				
			||||||
        $this->project = $project;
 | 
					        $this->project = $project;
 | 
				
			||||||
 | 
					        $this->stdio = new IDF_Scm_Monotone_Stdio($repo);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getRepositorySize()
 | 
					    public function getRepositorySize()
 | 
				
			||||||
@@ -56,19 +295,14 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function isAvailable()
 | 
					    public function isAvailable()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $out = array();
 | 
					        try
 | 
				
			||||||
        try {
 | 
					        {
 | 
				
			||||||
            $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					            $out = $this->stdio->exec(array("interface_version"));
 | 
				
			||||||
                .sprintf("%s -d %s automate interface_version",
 | 
					            return floatval($out) >= self::$MIN_INTERFACE_VERSION;
 | 
				
			||||||
                         Pluf::f('mtn_path', 'mtn'),
 | 
					 | 
				
			||||||
                         escapeshellarg($this->repo));
 | 
					 | 
				
			||||||
            self::exec('IDF_Scm_Monotone::isAvailable',
 | 
					 | 
				
			||||||
                   $cmd, $out, $return);
 | 
					 | 
				
			||||||
        } catch (IDF_Scm_Exception $e) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        catch (IDF_Scm_Exception $e) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return count($out) > 0 && floatval($out[0]) >= self::$MIN_INTERFACE_VERSION;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function getBranches()
 | 
					    public function getBranches()
 | 
				
			||||||
@@ -77,25 +311,18 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
            return $this->cache['branches'];
 | 
					            return $this->cache['branches'];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // FIXME: introduce handling of suspended branches
 | 
					        // FIXME: introduce handling of suspended branches
 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					        $out = $this->stdio->exec(array("branches"));
 | 
				
			||||||
            .sprintf("%s -d %s automate branches",
 | 
					
 | 
				
			||||||
                     Pluf::f('mtn_path', 'mtn'),
 | 
					 | 
				
			||||||
                     escapeshellarg($this->repo));
 | 
					 | 
				
			||||||
        self::exec('IDF_Scm_Monotone::getBranches',
 | 
					 | 
				
			||||||
                   $cmd, $out, $return);
 | 
					 | 
				
			||||||
        if ($return != 0) {
 | 
					 | 
				
			||||||
            throw new IDF_Scm_Exception(sprintf($this->error_tpl,
 | 
					 | 
				
			||||||
                                                $cmd, $return,
 | 
					 | 
				
			||||||
                                                implode("\n", $out)));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $res = array();
 | 
					 | 
				
			||||||
        // FIXME: we could expand each branch with one of its head revisions
 | 
					        // FIXME: we could expand each branch with one of its head revisions
 | 
				
			||||||
        // here, but these would soon become bogus anyway and we cannot
 | 
					        // here, but these would soon become bogus anyway and we cannot
 | 
				
			||||||
        // map multiple head revisions here either, so we just use the
 | 
					        // map multiple head revisions here either, so we just use the
 | 
				
			||||||
        // selector as placeholder
 | 
					        // selector as placeholder
 | 
				
			||||||
        foreach ($out as $b) {
 | 
					        $res = array();
 | 
				
			||||||
 | 
					        foreach (preg_split("/\n/", $out, -1, PREG_SPLIT_NO_EMPTY) as $b)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            $res["h:$b"] = $b;
 | 
					            $res["h:$b"] = $b;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->cache['branches'] = $res;
 | 
					        $this->cache['branches'] = $res;
 | 
				
			||||||
        return $res;
 | 
					        return $res;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -121,14 +348,8 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private function _resolveSelector($selector)
 | 
					    private function _resolveSelector($selector)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					        $out = $this->stdio->exec(array("select", $selector));
 | 
				
			||||||
            .sprintf("%s -d %s automate select %s",
 | 
					        return preg_split("/\n/", $out, -1, PREG_SPLIT_NO_EMPTY);
 | 
				
			||||||
                     Pluf::f('mtn_path', 'mtn'),
 | 
					 | 
				
			||||||
                     escapeshellarg($this->repo),
 | 
					 | 
				
			||||||
                     escapeshellarg($selector));
 | 
					 | 
				
			||||||
        self::exec('IDF_Scm_Monotone::_resolveSelector',
 | 
					 | 
				
			||||||
                   $cmd, $out, $return);
 | 
					 | 
				
			||||||
        return $out;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -139,9 +360,6 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
     */
 | 
					     */
 | 
				
			||||||
    private static function _parseBasicIO($in)
 | 
					    private static function _parseBasicIO($in)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (substr($in, -1) != "\n")
 | 
					 | 
				
			||||||
            $in .= "\n";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $pos = 0;
 | 
					        $pos = 0;
 | 
				
			||||||
        $stanzas = array();
 | 
					        $stanzas = array();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -208,15 +426,9 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if (!array_key_exists($rev, $certCache))
 | 
					        if (!array_key_exists($rev, $certCache))
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					            $out = $this->stdio->exec(array("certs", $rev));
 | 
				
			||||||
                .sprintf("%s -d %s automate certs %s",
 | 
					 | 
				
			||||||
                         Pluf::f('mtn_path', 'mtn'),
 | 
					 | 
				
			||||||
                         escapeshellarg($this->repo),
 | 
					 | 
				
			||||||
                         escapeshellarg($rev));
 | 
					 | 
				
			||||||
            self::exec('IDF_Scm_Monotone::_getCerts',
 | 
					 | 
				
			||||||
                       $cmd, $out, $return);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $stanzas = self::_parseBasicIO(implode("\n", $out));
 | 
					            $stanzas = self::_parseBasicIO($out);
 | 
				
			||||||
            $certs = array();
 | 
					            $certs = array();
 | 
				
			||||||
            foreach ($stanzas as $stanza)
 | 
					            foreach ($stanzas as $stanza)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
@@ -264,16 +476,11 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private function _getLastChangeFor($file, $startrev)
 | 
					    private function _getLastChangeFor($file, $startrev)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					        $out = $this->stdio->exec(array(
 | 
				
			||||||
            .sprintf("%s -d %s automate get_content_changed %s %s",
 | 
					            "get_content_changed", $startrev, $file
 | 
				
			||||||
                     Pluf::f('mtn_path', 'mtn'),
 | 
					        ));
 | 
				
			||||||
                     escapeshellarg($this->repo),
 | 
					 | 
				
			||||||
                     escapeshellarg($startrev),
 | 
					 | 
				
			||||||
                     escapeshellarg($file));
 | 
					 | 
				
			||||||
        self::exec('IDF_Scm_Monotone::_getLastChangeFor',
 | 
					 | 
				
			||||||
                   $cmd, $out, $return);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $stanzas = self::_parseBasicIO(implode("\n", $out));
 | 
					        $stanzas = self::_parseBasicIO($out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // FIXME: we only care about the first returned content mark
 | 
					        // FIXME: we only care about the first returned content mark
 | 
				
			||||||
        // everything else seem to be very rare cases
 | 
					        // everything else seem to be very rare cases
 | 
				
			||||||
@@ -305,17 +512,15 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
     **/
 | 
					     **/
 | 
				
			||||||
    public function getTags()
 | 
					    public function getTags()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (isset($this->cache['tags'])) {
 | 
					        if (isset($this->cache['tags']))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            return $this->cache['tags'];
 | 
					            return $this->cache['tags'];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					
 | 
				
			||||||
                .sprintf("%s -d %s automate tags",
 | 
					        $out = $this->stdio->exec(array("tags"));
 | 
				
			||||||
                         Pluf::f('mtn_path', 'mtn'),
 | 
					 | 
				
			||||||
                         escapeshellarg($this->repo));
 | 
					 | 
				
			||||||
        self::exec('IDF_Scm_Monotone::getTags', $cmd, $out, $return);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $tags = array();
 | 
					        $tags = array();
 | 
				
			||||||
        $stanzas = self::_parseBasicIO(implode("\n", $out));
 | 
					        $stanzas = self::_parseBasicIO($out);
 | 
				
			||||||
        foreach ($stanzas as $stanza)
 | 
					        foreach ($stanzas as $stanza)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            $tagname = null;
 | 
					            $tagname = null;
 | 
				
			||||||
@@ -360,15 +565,12 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
            return array();
 | 
					            return array();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					        $out = $this->stdio->exec(array(
 | 
				
			||||||
                .sprintf("%s -d %s automate get_manifest_of %s",
 | 
					            "get_manifest_of", $revs[0]
 | 
				
			||||||
                         Pluf::f('mtn_path', 'mtn'),
 | 
					        ));
 | 
				
			||||||
                         escapeshellarg($this->repo),
 | 
					 | 
				
			||||||
                         escapeshellarg($revs[0]));
 | 
					 | 
				
			||||||
        self::exec('IDF_Scm_Monotone::getTree', $cmd, $out, $return);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $files = array();
 | 
					        $files = array();
 | 
				
			||||||
        $stanzas = self::_parseBasicIO(implode("\n", $out));
 | 
					        $stanzas = self::_parseBasicIO($out);
 | 
				
			||||||
        $folder = $folder == '/' || empty($folder) ? '' : $folder.'/';
 | 
					        $folder = $folder == '/' || empty($folder) ? '' : $folder.'/';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($stanzas as $stanza)
 | 
					        foreach ($stanzas as $stanza)
 | 
				
			||||||
@@ -501,15 +703,12 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
        if (count($revs) == 0)
 | 
					        if (count($revs) == 0)
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					        $out = $this->stdio->exec(array(
 | 
				
			||||||
                .sprintf("%s -d %s automate get_manifest_of %s",
 | 
					            "get_manifest_of", $revs[0]
 | 
				
			||||||
                         Pluf::f('mtn_path', 'mtn'),
 | 
					        ));
 | 
				
			||||||
                         escapeshellarg($this->repo),
 | 
					 | 
				
			||||||
                         escapeshellarg($revs[0]));
 | 
					 | 
				
			||||||
        self::exec('IDF_Scm_Monotone::getPathInfo', $cmd, $out, $return);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $files = array();
 | 
					        $files = array();
 | 
				
			||||||
        $stanzas = self::_parseBasicIO(implode("\n", $out));
 | 
					        $stanzas = self::_parseBasicIO($out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($stanzas as $stanza)
 | 
					        foreach ($stanzas as $stanza)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -562,13 +761,13 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function getFile($def, $cmd_only=false)
 | 
					    public function getFile($def, $cmd_only=false)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					        // this won't work with remote databases
 | 
				
			||||||
                .sprintf("%s -d %s automate get_file %s",
 | 
					        if ($cmd_only)
 | 
				
			||||||
                         Pluf::f('mtn_path', 'mtn'),
 | 
					        {
 | 
				
			||||||
                         escapeshellarg($this->repo),
 | 
					            throw new Pluf_Exception_NotImplemented();
 | 
				
			||||||
                         escapeshellarg($def->hash));
 | 
					        }
 | 
				
			||||||
        return ($cmd_only)
 | 
					
 | 
				
			||||||
            ? $cmd : self::shell_exec('IDF_Scm_Monotone::getFile', $cmd);
 | 
					        return $this->stdio->exec(array("get_file", $def->hash));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function _getDiff($target, $source = null)
 | 
					    private function _getDiff($target, $source = null)
 | 
				
			||||||
@@ -594,16 +793,10 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
            return "";
 | 
					            return "";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					        return $this->stdio->exec(
 | 
				
			||||||
            .sprintf("%s -d %s automate content_diff -r %s -r %s",
 | 
					            array("content_diff"),
 | 
				
			||||||
                     Pluf::f('mtn_path', 'mtn'),
 | 
					            array("r" => $sources[0], "r" => $targets[0])
 | 
				
			||||||
                     escapeshellarg($this->repo),
 | 
					        );
 | 
				
			||||||
                     escapeshellarg($sources[0]),
 | 
					 | 
				
			||||||
                     escapeshellarg($targets[0]));
 | 
					 | 
				
			||||||
        self::exec('IDF_Scm_Monotone::_getDiff',
 | 
					 | 
				
			||||||
                   $cmd, $out, $return);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return implode("\n", $out);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -655,16 +848,12 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
        if (count($revs) == 0)
 | 
					        if (count($revs) == 0)
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '')
 | 
					        $out = $this->stdio->exec(array(
 | 
				
			||||||
            .sprintf("%s -d %s automate get_revision %s",
 | 
					            "get_revision", $revs[0]
 | 
				
			||||||
                     Pluf::f('mtn_path', 'mtn'),
 | 
					        ));
 | 
				
			||||||
                     escapeshellarg($this->repo),
 | 
					 | 
				
			||||||
                     escapeshellarg($revs[0]));
 | 
					 | 
				
			||||||
        self::exec('IDF_Scm_Monotone::isCommitLarge',
 | 
					 | 
				
			||||||
                   $cmd, $out, $return);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $newAndPatchedFiles = 0;
 | 
					        $newAndPatchedFiles = 0;
 | 
				
			||||||
        $stanzas = self::_parseBasicIO(implode("\n", $out));
 | 
					        $stanzas = self::_parseBasicIO($out);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        foreach ($stanzas as $stanza)
 | 
					        foreach ($stanzas as $stanza)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -682,16 +871,8 @@ class IDF_Scm_Monotone extends IDF_Scm
 | 
				
			|||||||
     * @param int Number of changes (10).
 | 
					     * @param int Number of changes (10).
 | 
				
			||||||
     * @return array Changes.
 | 
					     * @return array Changes.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function getChangeLog($commit='HEAD', $n=10)
 | 
					    public function getChangeLog($commit=null, $n=10)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($n === null) $n = '';
 | 
					        throw new Pluf_Exception_NotImplemented();
 | 
				
			||||||
        else $n = ' -'.$n;
 | 
					 | 
				
			||||||
        $cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log%s --date=iso --pretty=format:\'%s\' %s',
 | 
					 | 
				
			||||||
                       escapeshellarg($this->repo), $n, $this->mediumtree_fmt,
 | 
					 | 
				
			||||||
                       escapeshellarg($commit));
 | 
					 | 
				
			||||||
        $out = array();
 | 
					 | 
				
			||||||
        $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
 | 
					 | 
				
			||||||
        self::exec('IDF_Scm_Monotone::getChangeLog', $cmd, $out);
 | 
					 | 
				
			||||||
        return self::parseLog($out);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user