From 7099bbec85431b5be87c8bd7bd2bb04fe4a39db7 Mon Sep 17 00:00:00 2001 From: Chuck Hagenbuch Date: Sat, 27 Nov 2010 21:04:05 -0500 Subject: [PATCH] Bug #4578: Individual patchset view that includes the full diff. --- chora/app/helpers/Diff.php | 10 ++-- chora/app/views/diff/diff.html.php | 3 +- chora/commit.php | 61 ++------------------- chora/diff.php | 9 +--- chora/lib/Chora.php | 2 +- chora/templates/patchsets/ps_single.inc | 79 ++++++++++++++++----------- chora/themes/default/screen.css | 80 +++++++++++++++++++--------- framework/Vcs/lib/Horde/Vcs/Patchset/Cvs.php | 3 +- framework/Vcs/lib/Horde/Vcs/Patchset/Git.php | 18 ++----- 9 files changed, 127 insertions(+), 138 deletions(-) diff --git a/chora/app/helpers/Diff.php b/chora/app/helpers/Diff.php index 87b1e11a0..ae2d6ca10 100644 --- a/chora/app/helpers/Diff.php +++ b/chora/app/helpers/Diff.php @@ -15,13 +15,15 @@ class Chora_Diff_Helper extends Horde_View_Helper_Base */ protected $_context = ''; - public function diff($diff) + public function diff(Horde_Vcs_File $file, $r1, $r2, $id = null) { - if (!$diff) { - return '

' . _("No Visible Changes") . '

'; + try { + $diff = $GLOBALS['VC']->diff($file, $r1, $r2, array('human' => true)); + } catch (Horde_Vcs_Exception $e) { + return '

' . sprintf(_("There was an error generating the diff: %s"), $e->getMessage()) . '

'; } - return $this->render('app/views/diff/diff.html.php', array('diff' => $diff)); + return $this->render('app/views/diff/diff.html.php', array('diff' => $diff, 'file' => $file, 'r1' => $r1, 'r2' => $r2, 'id' => $id)); } public function diffAdd($change) diff --git a/chora/app/views/diff/diff.html.php b/chora/app/views/diff/diff.html.php index 4d73155c3..7f0fe0a89 100644 --- a/chora/app/views/diff/diff.html.php +++ b/chora/app/views/diff/diff.html.php @@ -1,4 +1,5 @@ -
+
> +

queryModulePath() ?>

diff --git a/chora/commit.php b/chora/commit.php index ad6478669..1d8e542e0 100644 --- a/chora/commit.php +++ b/chora/commit.php @@ -34,67 +34,16 @@ try { if (empty($patchsets)) { Chora::fatal(_("Commit Not Found"), '404 Not Found'); } +reset($patchsets); +$patchset = current($patchsets); -$extraLink = Chora::getFileViews($where, 'patchsets'); +// Cache the commit output for a week - it can be longer, since it should never +// change. +header('Cache-Control: max-age=604800'); Horde::addScriptFile('tables.js', 'horde'); require CHORA_TEMPLATES . '/common-header.inc'; require CHORA_TEMPLATES . '/menu.inc'; require CHORA_TEMPLATES . '/headerbar.inc'; - -$diff_img = Horde::img('diff.png', _("Diff")); - -$files = $tags = array(); - -reset($patchsets); -$patchset = current($patchsets); -foreach ($patchset['members'] as $member) { - $file = array(); - - $file['file'] = Chora::url('co', $member['file'])->link() - . htmlspecialchars($member['file']) . ''; - - if ($member['status'] == Horde_Vcs_Patchset::ADDED) { - $file['from'] = '' . _("New File") . ''; - $file['diff'] = ''; - } else { - $file['from'] = Chora::url('co', $member['file'], array('r' => $member['from'])) - ->link(array('title' => $member['from'])) - . htmlspecialchars($VC->abbrev($member['from'])) . ''; - $file['diff'] = Chora::url('diff', $member['file'], array('r1' => $member['from'], 'r2' => $member['to'])) - ->link(array('title' => _("Diff"))) - . ' ' . $diff_img . ''; - } - - if ($member['status'] == Horde_Vcs_Patchset::DELETED) { - $file['to'] = '' . _("Deleted") . ''; - $file['diff'] = ''; - } else { - $file['to'] = Chora::url('co', $member['file'], array('r' => $member['to'])) - ->link(array('title' => $member['to'])) - . htmlspecialchars($VC->abbrev($member['to'])) . ''; - } - - if (isset($member['added'])) { - $file['added'] = $member['added']; - $file['deleted'] = $member['deleted']; - } - - $files[] = $file; -} - -$commitDate = Chora::formatDate($patchset['date']); -$readableDate = Chora::readableTime($patchset['date'], true); -$author = Chora::showAuthorName($patchset['author'], true); -$logMessage = Chora::formatLogMessage($patchset['log']); - -if (!empty($patchset['branch'])) { - $tags = $patchset['branch']; -} - -if (!empty($patchset['tag'])) { - $tags = array_merge($tags, $patchset['tag']); -} - require CHORA_TEMPLATES . '/patchsets/ps_single.inc'; require $registry->get('templates', 'horde') . '/common-footer.inc'; diff --git a/chora/diff.php b/chora/diff.php index 9304b5617..3d22110b2 100644 --- a/chora/diff.php +++ b/chora/diff.php @@ -34,11 +34,6 @@ if (Horde_Util::getFormData('ty') == 'u') { $type = 'unified'; } -/* Unless otherwise specified, show whitespace differences and 3 lines - * of context. */ -$ws = Horde_Util::getFormData('ws', 1); -$num = (int)Horde_Util::getFormData('num', 3); - /* Cache the output of the diff for a week - it can be longer, since * it should never change. */ header('Cache-Control: max-age=604800'); @@ -47,7 +42,7 @@ header('Cache-Control: max-age=604800'); * the end of the file - patch requires it. */ if ($type != 'colored') { header('Content-Type: text/plain'); - echo implode("\n", $VC->diff($fl, $r1, $r2, array('num' => $num, 'type' => $type, 'ws' => $ws))) . "\n"; + echo implode("\n", $VC->diff($fl, $r1, $r2, array('num' => $num, 'type' => $type))) . "\n"; exit; } @@ -83,7 +78,7 @@ if (substr($mime_type, 0, 6) == 'image/') { } else { $view = $injector->createInstance('Horde_View'); $view->addHelper('Chora_Diff_Helper'); - echo $view->diff($VC->diff($fl, $r1, $r2, array('human' => true, 'num' => $num, 'ws' => $ws))); + echo $view->diff($fl, $r1, $r2); echo $view->diffCaption(); } diff --git a/chora/lib/Chora.php b/chora/lib/Chora.php index 018ed5555..045bdd760 100644 --- a/chora/lib/Chora.php +++ b/chora/lib/Chora.php @@ -128,7 +128,7 @@ class Chora case 'patchsets.php': if (!empty($args['ps'])) { - $script = urlencode(isset($args['rt']) ? $args['rt'] : $GLOBALS['acts']['rt']) . '/-/commits/' . $args['ps']; + $script = urlencode(isset($args['rt']) ? $args['rt'] : $GLOBALS['acts']['rt']) . '/-/commit/' . $args['ps']; unset($arglist['ps']); } break; diff --git a/chora/templates/patchsets/ps_single.inc b/chora/templates/patchsets/ps_single.inc index 35c5ecdd4..841eb63f5 100644 --- a/chora/templates/patchsets/ps_single.inc +++ b/chora/templates/patchsets/ps_single.inc @@ -1,30 +1,49 @@ -
- : - -
- -
- : -
- - -
- : -
- - -
- : -
- -
- -
- : -
- -
    - -
  • +' . $file['added'] . ', -' . $file['deleted'] . ') ') : '') . ': ' . $file['from'] . ' -> ' . $file['to'] . ' ' . $file['diff'] ?>
  • - -
+createInstance('Horde_View'); +$view->addHelper('Chora_Diff_Helper'); + +echo $view->renderPartial('app/views/logMessage', array('collection' => array($patchset['log']))); + +echo '
    '; +$i = 0; +foreach ($patchset['members'] as $member) { + $i++; + + switch ($member['status']) { + case Horde_Vcs_Patchset::ADDED: + $class = 'commit-file-added'; + $alt = '+'; + break; + + case Horde_Vcs_Patchset::DELETED: + $class = 'commit-file-deleted'; + $alt = '-'; + break; + + default: + $class = 'commit-file-modified'; + $alt = '*'; + } + + echo '
  • ' . $alt . '' + . htmlspecialchars($member['file']) . '' . (isset($member['added']) ? (' (+' . $member['added'] . ', -' . $member['deleted'] . ') ') : '') . '
  • '; +} +echo '
'; + +$segmentStart = microtime(true); +$i = 0; +foreach ($patchset['members'] as $member) { + $i++; + echo $view->diff($VC->getFileObject($member['file']), $member['from'], $member['to'], "diff-$i"); + + // Flush every .1 seconds to keep the page rendering. + $now = microtime(true); + if ($now - $segmentStart > .1) { + ob_flush(); + flush(); + $segmentStart = $now; + } +} + +echo $view->diffCaption(); diff --git a/chora/themes/default/screen.css b/chora/themes/default/screen.css index ffd4342d5..5cdcf2e4e 100644 --- a/chora/themes/default/screen.css +++ b/chora/themes/default/screen.css @@ -150,25 +150,6 @@ h3.checkout, h3.file-view-header { width: 35%; } -.singleps span.headerLabel { - font-size: 110%; - font-weight: bold; - padding-right: 5px; -} -.singleps span.ago a:hover { - text-decoration: none; -} -.singlepslog { - padding: 10px 0 20px 20px; -} -ul.singlepsfiles { - list-style: none; - padding: 10px 0 0 20px; -} -ul.singlepsfiles li { - padding-bottom: 4px; -} - .commit-list h3 { font-size: 130%; font-weight: bold; @@ -183,6 +164,7 @@ ul.singlepsfiles li { } .commit-message { font-size: 110%; + font-family: Menlo,Consolas,"Lucida Console","DejaVu Sans Mono",monospace; margin-bottom: .5em; } .commit-info { @@ -198,7 +180,42 @@ ul.singlepsfiles li { margin-bottom: .5em; } .commit-author { - font-size: 90%; +} + +ul.commit-filelist { + margin: 1em 0; + border-top: thin solid #ccc; + list-style: none; +} +ul.commit-filelist li { + font-family: Menlo,Consolas,"Lucida Console","DejaVu Sans Mono",monospace; + padding: .2em; + border-bottom: thin solid #ccc; +} +ul.commit-filelist li:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + +span.commit-file-added, span.commit-file-deleted, span.commit-file-modified { + display: block; + float: left; + height: 1em; + width: 1em; + margin-right: .5em; + text-indent: -9999px; +} +span.commit-file-added { + background: #cfc; +} +span.commit-file-deleted { + background: #fcc; +} +span.commit-file-modified { + background: #def; } /* Diff stat information. */ @@ -209,6 +226,7 @@ ul.singlepsfiles li { color: red; } + /* Checkout, File view */ div.checkout, div.file-view-contents { padding: 3px; @@ -254,6 +272,20 @@ table.annotate .logentry { div.diff { font-size: 100%; color: #111; + border: 1px solid #ccc; + margin: 1.5em 0; +} +div.diff-header { + border-bottom: 1px solid #ccc; + background: #eee; + background: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#eee), color-stop(0.5, #eee)); + background: -moz-linear-gradient(top, #fff, #eee 50%); + padding: .5em; +} +div.diff-header h4 { + font-weight: normal; + font-family: Menlo,Consolas,"Lucida Console","DejaVu Sans Mono",monospace; + font-size: 110%; } div.diff-section { margin-top: 1em; @@ -289,8 +321,8 @@ div.diff-right { } .diff-added-empty { background: #efe; - background: -webkit-gradient(linear, left top, right top, from(#efe), to(#cfc), color-stop(0.5, #cfc)); - background: -moz-linear-gradient(left top, #efe, #cfc 50%); + background: -webkit-gradient(linear, left top, right top, from(#fff), to(#cfc), color-stop(0.5, #cfc)); + background: -moz-linear-gradient(left top, #fff, #cfc 50%); } .diff-modified { background: #def; @@ -300,8 +332,8 @@ div.diff-right { } .diff-removed-empty { background: #fee; - background: -webkit-gradient(linear, right top, left top, from(#fee), to(#fcc), color-stop(0.5, #fcc)); - background: -moz-linear-gradient(right top, #fee, #fcc 50%); + background: -webkit-gradient(linear, right top, left top, from(#fff), to(#fcc), color-stop(0.5, #fcc)); + background: -moz-linear-gradient(right top, #fff, #fcc 50%); } .diff-caption { diff --git a/framework/Vcs/lib/Horde/Vcs/Patchset/Cvs.php b/framework/Vcs/lib/Horde/Vcs/Patchset/Cvs.php index 4802e3f09..7f7687ebc 100644 --- a/framework/Vcs/lib/Horde/Vcs/Patchset/Cvs.php +++ b/framework/Vcs/lib/Horde/Vcs/Patchset/Cvs.php @@ -1,6 +1,6 @@ _patchsets[$rev] = array( - 'date' => $log->queryDate(), - 'author' => $log->queryAuthor(), - 'branches' => $log->queryBranch(), - 'tags' => $log->queryTags(), - 'log' => $log->queryLog(), + 'log' => $log, 'members' => array(), ); foreach ($log->queryFiles() as $file) { + $from = $log->queryParent(); $to = $rev; - $status = self::MODIFIED; switch ($file['status']) { case 'A': - $from = null; $status = self::ADDED; break; case 'D': - $from = $to; - $to = null; $status = self::DELETED; break; default: - $from = $log->queryParent(); + $status = self::MODIFIED; } $statinfo = isset($file['added']) @@ -91,5 +84,4 @@ class Horde_Vcs_Patchset_Git extends Horde_Vcs_Patchset } } } - -} \ No newline at end of file +} -- 2.11.0