'property'
);
-require_once('./global.php');
-
-$navbar = $controller->construct_breadcrumb();
+define('SVN', '$Id$');
-// ###################################################################
+require_once('./global.php');
+require_once('./includes/class_diff.php');
-$link['log'] = $controller->href_compound('log.php');
+$navbar = ConstructNavbar();
// ###################################################################
-if (isset($viewsvn->in['rev']))
-{
- $high = Paths::fetch_rev_num(false);
-}
-else
-{
- $revs = Paths::fetch_rev_num(true);
- $high = $revs['high'];
- $low = $revs['low'];
-}
-
-if ($high == 'HEAD')
-{
- $high = $controller->cachev->fetch_head_revision();
-}
-
-if ($low == 0)
-{
- $low = $controller->cachev->fetch_prev_revision($high);
- $low = $low['revision'];
-}
+$link['log'] = ConstructLink('log', $input->in['repos'], $input->in['path'], $input->in['rev']);
// ###################################################################
-$show['fullchangeset'] = (Paths::is_root_path($controller->path) ? false : true);
+$show['fullchangeset'] = ($input->in['path'] == '' OR $input->in['path'] == '/');
if ($show['fullchangeset'])
{
- $link['changeset'] = $controller->href_struct('diff.php' . Paths::fetch_rev_str(true, $high, $low), '');
+ $link['changeset'] = ConstructLink('diff', $input->in['repos'], null, $input->in['rev']);
}
-$log = $controller->cachev->fetch_revision($high);
+$revision = new Revision($input->in['repos'], $input->in['rev'], $input->in['path']);
+$revision->getRevisionInfo();
-$log['message_clean'] = SVNCommon::format_log_message($log['message']);
-$log['date'] = SVNCommon::format_date_string($log['dateline']);
-
-$files = SVNCommon::construct_file_changes($log['files'], $controller->repos, $high);
+$files = ConstructFileChanges($revision->files, $input->in['repos'], $revision->revision);
// ###################################################################
-$diff = new SVNDiff($controller, $low, $high);
-
-$isdir = (bool)$controller->cachev->isdir();
+$diff = new Diff($lib->run('diff -c' . $revision->revision . ' ' . $lib->arg($repos->fetchPath($input->in['repos']) . '/' . $input->in['path'])));
$changes = '';
-
foreach ($diff->fetch() AS $filename => $file)
{
$hunktpl = '';
if ($key == 'hunk' AND isset($line['old']))
{
$filepath = ($isdir ? $controller->path . $filename : $controller->path);
- $rlow = $controller->href_struct('view.php' . Paths::fetch_rev_str(false, $low), $filepath);
- $rhigh = $controller->href_struct('view.php' . Paths::fetch_rev_str(false, $high), $filepath);
+ // $rlow = $controller->href_struct('view.php' . Paths::fetch_rev_str(false, $low), $filepath);
+ // $rhigh = $controller->href_struct('view.php' . Paths::fetch_rev_str(false, $high), $filepath);
$show['hunk'] = true;
}
else
$class = 'diff_norm';
}
- $line['line_clean'] = SVNCommon::format($line['line']);
+ $line['line_clean'] = FormatCode($line['line']);
}
eval('$lines .= "' . $template->fetch('diff_line') . '";');
eval('$hunktpl .= "' . $template->fetch('diff_hunk') . '";');
}
- foreach ($props AS $name => $values)
+ if (is_array($props))
{
- // modified
- if (isset($values['add']) AND isset($values['del']))
- {
- $data = sprintf($lang->string('Property <strong>%1$s</strong> changed from <em>%2$s</em> to <em>%3$s</em>'), $name, $values['del'], $values['add']);
- }
- // added
- else if (isset($values['add']))
- {
- $data = sprintf($lang->string('Property <strong>%1$s</strong> set to <em>%2$s</em>'), $name, $values['add']);
- }
- // removed
- else if (isset($values['del']))
+ foreach ($props AS $name => $values)
{
- $data = sprintf($lang->string('Property <strong>%1$s</strong> deleted'), $name);
+ // modified
+ if (isset($values['add']) AND isset($values['del']))
+ {
+ $data = sprintf(_('Property <strong>%1$s</strong> changed from <em>%2$s</em> to <em>%3$s</em>'), $name, $values['del'], $values['add']);
+ }
+ // added
+ else if (isset($values['add']))
+ {
+ $data = sprintf(_('Property <strong>%1$s</strong> set to <em>%2$s</em>'), $name, $values['add']);
+ }
+ // removed
+ else if (isset($values['del']))
+ {
+ $data = sprintf(_('Property <strong>%1$s</strong> deleted'), $name);
+ }
+ eval('$proplist .= "' . $template->fetch('property') . '";');
}
- eval('$proplist .= "' . $template->fetch('property') . '";');
}
eval('$changes .= "' . $template->fetch('diff_file') . '";');
/*=====================================================================*\
|| ###################################################################
|| # ViewSVN [#]version[#]
-|| # Copyright ©2002-[#]year[#] Iris Studios, Inc.
+|| # Copyright ©2002-[#]year[#] Blue Static
|| #
|| # This program is free software; you can redistribute it and/or modify
|| # it under the terms of the GNU General Public License as published by
\*=====================================================================*/
/**
-* Command line library and SVN-PHP bridge extension
+* Diff
*
-* @package ViewSVN
-*/
-
-/**
-* This class acts as the bridge between the command line Xquery class
-* and the various display files. It handles preparation of Xquery
-* code.
+* This class parses a diff file from a unified diff file and turns it
+* into a HTML-prettied output
*
-* @package ViewSVN
-* @version $Id$
-*/
-class SVNLib
-{
- /**
- * Path to the SVN binary
- * @var string
- * @access private
- */
- var $svnpath;
-
- /**
- * Controller
- * @var object
- * @access private
- */
- var $controller;
-
- // ###################################################################
- /**
- * Constructor: validate SVN path
- *
- * @param object Controller
- */
- function SVNLib(&$controller)
- {
- $this->controller =& $controller;
-
- $this->svnpath =& $this->controller->xquery->cmd($this->controller->registry->svnpath);
-
- $access = $this->controller->xquery->exec($this->svnpath . ' --version');
-
- if (!$access)
- {
- $this->controller->registry->trigger->error($this->controller->registry->lang->string('The SVN binary could not be located'));
- }
-
- if (!preg_match('#^svn, version (.*?)\)$#i', trim($access[0])))
- {
- $this->controller->registry->trigger->error($this->controller->registry->lang->string('The SVN binary does not appear to be valid (it failed our tests)'));
- }
- }
-
- // ###################################################################
- /**
- * Executes the SVN binary
- *
- * @access private
- *
- * @param string Command
- *
- * @return array Output
- */
- function svn($command)
- {
- $output = $this->controller->xquery->exec($this->svnpath . ' ' . $command . ' 2>&1');
-
- $temp = implode("\n", $output);
- if (strpos($temp, '(apr' . '_err=') !== false)
- {
- $this->controller->registry->trigger->error(nl2br($temp));
- }
- return $output;
- }
-
- // ###################################################################
- /**
- * This function is used to prepare a common command. It sends the
- * specified command along with the repository path and the current
- * node. The revision is either fectched from the argument list or
- * from the node, too.
- *
- * @access public
- *
- * @param string SVN command
- * @param bool Alternate revision
- *
- * @return array Lines of output
- */
- function command($command, $rev = false)
- {
- global $viewsvn;
-
- $revision = ($rev !== false ? $rev : SVNCommon::rev($this->controller->revnum));
-
- return $this->svn($command . ' ' . $this->controller->repospath . $this->controller->path . ($revision !== null ? '@' . $revision : ''));
- }
-
- // ###################################################################
- /**
- * A library complicator function that handles the diff command because
- * the standard command() system does not work with more complex args.
- *
- * @access public
- *
- * @param integer Lower revision
- * @param integer Higher revision
- *
- * @return array Lines of diff output
- */
- function diff($lorev, $hirev)
- {
- global $viewsvn;
-
- $hirev = SVNCommon::rev($hirev);
- $lorev = SVNCommon::rev($lorev);
- if ($lorev == 'HEAD')
- {
- $lorev = 1;
- }
-
- if (is_integer($hirev) AND is_integer($lorev))
- {
- if ($lorev > $hirev)
- {
- $lorev = $hirev - 1;
- }
- if ($lorev == $hirev)
- {
- $lorev = 0;
- }
- }
-
- return $this->svn('diff -r' . $lorev . ':' . $hirev . ' ' . $this->controller->repospath . $this->controller->path);
- }
-
- // ###################################################################
- /**
- * A library complicator function to create log output. This is needed
- * because command() doesn't handle ranged revisions.
- *
- * @access public
- *
- * @param string Repository
- * @param string Path
- * @param integer Lower revision
- * @param integer Higher revision
- *
- * @return array Lines of log output
- */
- function log($lorev, $hirev)
- {
- global $viewsvn;
-
- $hirev = $this->rev($hirev);
- $lorev = $this->rev($hirev);
- if ($lorev == 'HEAD')
- {
- $lorev = 0;
- }
-
- if (is_integer($hirev) AND is_integer($lorev))
- {
- if ($lorev > $hirev)
- {
- $lorev = $hirev - 1;
- }
- if ($lorev == $hirev)
- {
- $lorev = 0;
- }
- }
-
- $repospath = $viewsvn->repos->fetch_path($repos, false);
-
- return $this->svn('log -v -r' . $hirev . ':' . $lorev . ' ' . $repospath . $path);
- }
-}
-
-/**
-* Diff system; constructs a diff array that is ready for output
+* @author Blue Static
+* @copyright Copyright (c)2002 - [#]year[#], Blue Static
+* @version $Revision$
+* @package ViewSVN
*
-* @package ViewSVN
-* @version $Id$
*/
-class SVNDiff
+class Diff
{
/**
- * Array of diff information
- * @var array
- * @access private
+ * Raw unified diff text
+ * @var string
*/
- var $diff = array();
+ private $raw;
/**
- * Raw "svn diff" output
- * @var array
- * @access private
+ * The current index (file)
+ * @var string
*/
- var $rawoutput;
+ private $index;
// ###################################################################
/**
- * Constructor: create and store diff data
+ * Constructor
*
- * @param object Controller
- * @param integer Lower revision
- * @param integer Higher revision
+ * @param string Raw unified diff output
*/
- function SVNDiff(&$controller, $lorev, $hirev)
+ public function __construct($raw)
{
- $this->rawoutput = $controller->library->diff($lorev, $hirev);
- $this->process();
+ $this->raw = $raw;
}
// ###################################################################
/**
- * Returns diffs for display
- *
- * @access public
+ * This function initiates the parsing process and returns the output
+ * in hunks, line-by-line
*
- * @return array Diff data
+ * @return array Array of outputted hunked information
*/
- function fetch()
- {
- return $this->diff;
- }
-
- // ###################################################################
- /**
- * Processes and prepares diff data
- *
- * @access private
- */
- function process()
+ public function fetch()
{
global $viewsvn;
$delstack = array();
- foreach ($this->rawoutput AS $line)
+ foreach ($this->raw AS $line)
{
if (preg_match('#^@@ \-([0-9]*),([0-9]*) \+([0-9]*),([0-9]*) @@$#', $line, $bits))
{
{
$lastline = array_shift($delstack);
- if ($delta = @$this->fetch_diff_extent($lastline['line'], $content))
+ if ($delta = @$this->_fetchDiffExtent($lastline['line'], $content))
{
if (strlen($lastline['line']) > ($delta['start'] - $delta['end']))
{
$end = strlen($lastline['line']) + $delta['end'];
- $viewsvn->debug("RM delta- = " . $end);
+ BSRegister::Debug("RM delta- = " . $end);
$change = '{@-' . '-}' . substr($lastline['line'], $delta['start'], $end - $delta['start']) . '{/@-' . '-}';
$this->diff["$index"]["$chunk"]["$lastline[INDEX]"]['line'] = substr($lastline['line'], 0, $delta['start']) . $change . substr($lastline['line'], $end);
}
if (strlen($content) > $delta['start'] - $delta['end'])
{
$end = strlen($content) + $delta['end'];
- $viewsvn->debug("MK delta+ = " . $end);
+ BSRegister::Debug("MK delta+ = " . $end);
$change = '{@+' . '+}' . substr($content, $delta['start'], $end - $delta['start']) . '{/@+' . '+}';
$content = substr($content, 0, $delta['start']) . $change . substr($content, $end);
}
{
if (preg_match('#^__*_$#', trim($line)))
{
- $viewsvn->debug("skipping: $line");
+ BSRegister::Debug("skipping: $line");
continue;
}
if (preg_match('#Name: (.*?)$#', $line, $matches))
{
$curprop = $matches[1];
- $viewsvn->debug("prop: $curprop");
+ BSRegister::Debug("prop: $curprop");
continue;
}
else
$delstack = array();
}
}
+
+ return $this->diff;
}
// ###################################################################
/**
* Returns the amount of change that occured between two lines
*
- * @access private
- *
* @param string Old line
* @param string New line
*
* @return array Difference of positions
*/
- function fetch_diff_extent($old, $new)
+ private function _fetchDiffExtent($old, $new)
{
global $viewsvn;
$start = 0;
$min = min(strlen($old), strlen($new));
- $viewsvn->debug("min1 = $min");
+ BSRegister::Debug("min1 = $min");
while ($start < $min AND $old["$start"] == $new["$start"])
{
$end = -1;
$min = $min - $start;
- $viewsvn->debug("min2 = $min");
+ BSRegister::Debug("min2 = $min");
- $viewsvn->debug("checking: " . $old[ strlen($old) + $end ] . ' == ' . $new[ strlen($new) + $end ]);
+ BSRegister::Debug("checking: " . $old[ strlen($old) + $end ] . ' == ' . $new[ strlen($new) + $end ]);
while (-$end <= $min AND $old[ strlen($old) + $end ] == $new[ strlen($new) + $end ])
{
*/
public $datetime;
+ /**
+ * Files changed by the revision
+ * @var array
+ */
+ public $files = array();
+
// ###################################################################
/**
* Creates a new revision for a given repository and revision
*/
public function getRevisionInfo()
{
- $xml = BSXml::Parse(BSRegister::Get('lib')->run('log --xml -r' . $this->revision . ' ' . BSRegister::Get('lib')->arg($this->path), true));
+ $xml = BSXml::Parse(BSRegister::Get('lib')->run('log --xml -v -r' . $this->revision . ' ' . BSRegister::Get('lib')->arg($this->path), true));
$this->message = FormatLogMessage($xml['log']['logentry']['msg']['value']);
$this->messasgeClean = $xml['log']['logentry']['msg']['value'];
$this->datetime = FormatSvnDate($xml['log']['logentry']['date']['value']);
$this->author = $xml['log']['logentry']['author']['value'];
+ $this->files = $xml['log']['logentry']['paths']['path'];
+ BSXml::UnifyNode($this->files);
}
// ###################################################################
return $thestring;
}
+// ###################################################################
+/**
+* Takes in an array of files with a path and an action and constructs
+* the HTML block describing them
+*
+* @param array List of file changes
+* @param string The repository
+* @param integer Current revision
+*
+* @return string Processed HTML
+*/
+function ConstructFileChanges($changes, $repos, $revision)
+{
+ $files = '';
+
+ foreach ($changes AS $file)
+ {
+ switch ($file['action'])
+ {
+ case 'A':
+ $class = 'file_add';
+ $tooltip = _('Added');
+ break;
+ case 'D':
+ $class = 'file_delete';
+ $tooltip = _('Deleted');
+ break;
+ case 'M':
+ $class = 'file_modify';
+ $tooltip = _('Modified');
+ break;
+ case 'R':
+ $class = 'file_replace';
+ $tooltip = _('Replaced');
+ break;
+ }
+
+ $show['from'] = (bool)$file['from'];
+
+ if ($file['from'])
+ {
+ $class = 'file_move';
+ $tooltip = _('Moved/Copied');
+ preg_match('#(.*):([0-9]+)#', $file['from'], $matches);
+ $link['from'] = ConstructLink('view', $repos, $matches[1], $revision);
+ }
+
+ $link['file'] = ConstructLink('view', $repos, $file['value'], $revision);
+
+ eval('$files .= "' . BSRegister::Get('template')->fetch('file_change') . '";');
+ }
+
+ return $files;
+}
+
/*=====================================================================*\
|| ###################################################################
|| # $HeadURL$
// load options
BSRegister::Register('svnpath', $conf['paths']['svn']);
-require_once('./includes/svncommon.php');
-
// ###################################################################
// imaginary reporter
require_once('./includes/imaginary.php');
+++ /dev/null
-<?php
-/*=====================================================================*\
-|| ###################################################################
-|| # ViewSVN [#]version[#]
-|| # Copyright ©2002-[#]year[#] Iris Studios, Inc.
-|| #
-|| # This program is free software; you can redistribute it and/or modify
-|| # it under the terms of the GNU General Public License as published by
-|| # the Free Software Foundation; version [#]gpl[#] of the License.
-|| #
-|| # This program is distributed in the hope that it will be useful, but
-|| # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-|| # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
-|| # more details.
-|| #
-|| # You should have received a copy of the GNU General Public License along
-|| # with this program; if not, write to the Free Software Foundation, Inc.,
-|| # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-|| ###################################################################
-\*=====================================================================*/
-
-/**
-* Common functions that aren't Xquery-related and advanced query systems
-*
-* @package ViewSVN
-*/
-
-/**
-* This is a utility class that should be accessed in a static fashion. It
-* is responsbile for various parsing mechanisms, mainly.
-*
-* @package ViewSVN
-* @version $Id$
-*/
-class SVNCommon
-{
- // ###################################################################
- /**
- * Prints the file changed list
- *
- * @access public
- *
- * @public array List of file changes
- * @public string The repository
- * @public integer Current revision
- *
- * @return string Processed HTML
- */
- function construct_file_changes($changes, $repos, $revision)
- {
- global $viewsvn;
-
- $files = '';
-
- foreach ($changes AS $file)
- {
- switch ($file['action'])
- {
- case 'A':
- $class = 'file_add';
- $tooltip = $viewsvn->lang->string('Added');
- break;
- case 'D':
- $class = 'file_delete';
- $tooltip = $viewsvn->lang->string('Deleted');
- break;
- case 'M':
- $class = 'file_modify';
- $tooltip = $viewsvn->lang->string('Modified');
- break;
- case 'R':
- $class = 'file_replace';
- $tooltip = $viewsvn->lang->string('Replaced');
- break;
- }
-
- $show['from'] = (bool)$file['from'];
-
- if ($file['from'])
- {
- $class = 'file_move';
- $tooltip = 'Moved/Copied';
- preg_match('#(.*):([0-9]+)#', $file['from'], $matches);
- $link['from'] = $viewsvn->path . '/view.php/' . $repos . '/' . $matches[1] . Paths::fetch_rev_str(false, $matches[2]);
- }
-
- $link['file'] = $viewsvn->path . '/view.php/' . $repos . $file['value'] . Paths::fetch_rev_str(false, $revision);
-
- eval('$files .= "' . $viewsvn->template->fetch('file_change') . '";');
- }
-
- return $files;
- }
-
- // ###################################################################
- /**
- * Generates a clean revision number
- *
- * @access public
- *
- * @param integer Revision number
- *
- * @return mixed Cleaned revision or HEAD
- */
- function rev($revision)
- {
- if (($revision = intval($revision)) < 1)
- {
- $revision = 'HEAD';
- }
- return $revision;
- }
-}
-
-/*=====================================================================*\
-|| ###################################################################
-|| # $HeadURL$
-|| # $Id$
-|| ###################################################################
-\*=====================================================================*/
-?>
\ No newline at end of file
<html lang="##LANG##" xml:lang="##XML-LANG##">
<head>
$headinclude
- <link rel="stylesheet" href="$viewsvn->path/templates/default/diff.css" media="screen" />
- <link rel="stylesheet" href="$viewsvn->path/templates/default/file.css" media="screen" />
+ <link rel="stylesheet" href="{BSRegister::Get('webpath')}/templates/default/diff.css" media="screen" />
+ <link rel="stylesheet" href="{BSRegister::Get('webpath')}/templates/default/file.css" media="screen" />
<title>{@"Diff"}</title>
</head>
</span>
</div>
<div class="content">
- <div><strong>{@"Revision"}:</strong> $log[revision]</div>
- <div><strong>{@"Author"}:</strong> $log[author]</div>
- <div><strong>{@"Date"}:</strong> $log[date]</div>
- <div><strong>{@"Message"}:</strong> $log[message_clean]</div>
+ <div><strong>{@"Revision"}:</strong> $revision->revision</div>
+ <div><strong>{@"Author"}:</strong> $revision->author</div>
+ <div><strong>{@"Date"}:</strong> $revision->datetime</div>
+ <div><strong>{@"Message"}:</strong> $revision->message</div>
</div>
<div class="subhead" style="border-width: 0px 1px 0px 1px">{@"File Changes"}</div>
<div class="content">