mirror of
https://github.com/vitalif/viewvc-4intranet
synced 2019-04-16 04:14:59 +03:00
Compare commits
47 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
629af127f7 | ||
![]() |
a4c5fc498e | ||
![]() |
c0d0e0b097 | ||
![]() |
383ad7aac2 | ||
![]() |
8a446830cc | ||
![]() |
06e8eec7ca | ||
![]() |
0225c7dc13 | ||
![]() |
b08bea6a1d | ||
![]() |
ac34cc35ce | ||
![]() |
1567b2ee0c | ||
![]() |
3ce548a72b | ||
![]() |
c771aa971c | ||
![]() |
0adab05e44 | ||
![]() |
f45fc973b7 | ||
![]() |
14b35861c2 | ||
![]() |
6f0e5334ff | ||
![]() |
5129453aa8 | ||
![]() |
59b1e1d817 | ||
![]() |
fde7ddfa78 | ||
![]() |
e55a53826a | ||
![]() |
2e42e8210a | ||
![]() |
07019eaf2b | ||
![]() |
ee17367b8b | ||
![]() |
63e89c6517 | ||
![]() |
89c5af7d9d | ||
![]() |
743fcdd6ae | ||
![]() |
9451f373e8 | ||
![]() |
c0ce6b9dbe | ||
![]() |
e498d9fdbe | ||
![]() |
1bb0b7ee38 | ||
![]() |
7bafa7b77e | ||
![]() |
1bc2914f4b | ||
![]() |
06f6ba27d0 | ||
![]() |
6cf12dd9b3 | ||
![]() |
a234ea1105 | ||
![]() |
fd3db29ade | ||
![]() |
2e684b109f | ||
![]() |
39c10d903b | ||
![]() |
25a30fb45f | ||
![]() |
2f1008737a | ||
![]() |
e800659377 | ||
![]() |
f75096b6c6 | ||
![]() |
8f28ea0798 | ||
![]() |
2a6c68b575 | ||
![]() |
b1becd4c33 | ||
![]() |
e3514e6a3d | ||
![]() |
2337c9be23 |
31
CHANGES
31
CHANGES
@@ -1,3 +1,34 @@
|
||||
Version 1.1.10 (released 10-Mar-2010)
|
||||
|
||||
* security fix: escape user-provided query form input to avoid XSS attack
|
||||
* fix errors viewing remote Subversion paths with URI-unsafe characters
|
||||
* fix regexp input validation (issue #426, #427, #440)
|
||||
|
||||
Version 1.0.9 (released 11-Aug-2009)
|
||||
|
||||
* security fix: validate the 'view' parameter to avoid XSS attack
|
||||
* security fix: avoid printing illegal parameter names and values
|
||||
|
||||
Version 1.0.8 (released 05-May-2009)
|
||||
|
||||
* fix directory view sorting UI
|
||||
* tolerate malformed Accept-Language headers (issue #396)
|
||||
* fix directory log views in revision-less Subversion repositories
|
||||
* fix exception in rev-sorted remote Subversion directory views (issue #409)
|
||||
|
||||
Version 1.0.7 (released 14-Oct-2008)
|
||||
|
||||
* fix regression in the 'as text' download view (issue #373)
|
||||
|
||||
Version 1.0.6 (released 16-Sep-2008)
|
||||
|
||||
* security fix: ignore arbitrary user-provided MIME types (issue #354)
|
||||
* fix bug in regexp search filter when used with sticky tag (issue #346)
|
||||
* fix bug in handling of certain 'co' output (issue #348)
|
||||
* fix regexp search filter template bug
|
||||
* fix annotate code syntax error
|
||||
* fix mod_python import cycle (issue #369)
|
||||
|
||||
Version 1.0.5 (released 28-Feb-2008)
|
||||
|
||||
* security fix: omit commits of all-forbidden files from query results
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -42,9 +42,23 @@ if LIBRARY_DIR:
|
||||
sys.path.insert(0, LIBRARY_DIR)
|
||||
|
||||
import sapi
|
||||
import viewvc
|
||||
import query
|
||||
reload(query) # need reload because initial import loads this stub file
|
||||
import imp
|
||||
|
||||
# Import real ViewVC module
|
||||
fp, pathname, description = imp.find_module('viewvc', [LIBRARY_DIR])
|
||||
try:
|
||||
viewvc = imp.load_module('viewvc', fp, pathname, description)
|
||||
finally:
|
||||
if fp:
|
||||
fp.close()
|
||||
|
||||
# Import real ViewVC Query modules
|
||||
fp, pathname, description = imp.find_module('query', [LIBRARY_DIR])
|
||||
try:
|
||||
query = imp.load_module('query', fp, pathname, description)
|
||||
finally:
|
||||
if fp:
|
||||
fp.close()
|
||||
|
||||
cfg = viewvc.load_config(CONF_PATHNAME)
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -42,9 +42,15 @@ if LIBRARY_DIR:
|
||||
sys.path.insert(0, LIBRARY_DIR)
|
||||
|
||||
import sapi
|
||||
import viewvc
|
||||
reload(viewvc) # need reload because initial import loads this stub file
|
||||
import imp
|
||||
|
||||
# Import real ViewVC module
|
||||
fp, pathname, description = imp.find_module('viewvc', [LIBRARY_DIR])
|
||||
try:
|
||||
viewvc = imp.load_module('viewvc', fp, pathname, description)
|
||||
finally:
|
||||
if fp:
|
||||
fp.close()
|
||||
|
||||
def index(req):
|
||||
server = sapi.ModPythonServer(req)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 2004 James Henstridge
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
|
@@ -89,7 +89,7 @@ th.caption {
|
||||
<li><a href="#compat-tarball">'<code>tarball=1</code>' Parameter ⇒ '<code>view=tar</code>'</a></li>
|
||||
<li><a href="#compat-graph">'<code>graph=1</code>' Parameter ⇒ '<code>view=graph</code>'</a></li>
|
||||
<li><a href="#compat-makeimage">'<code>graph=1&makeimage=1</code>' Parameters ⇒ '<code>view=graphimg</code>'</a></li>
|
||||
<li><a href="#compat-content_type">'<code>content_type=text/vnd.viewcvs-markup</code>' and '<code>content_type=text/x-cvsweb-markup</code>' Parameters⇒ '<code>view=markup</code>'
|
||||
<li><a href="#compat-content_type">'<code>content-type=text/vnd.viewcvs-markup</code>' and '<code>content-type=text/x-cvsweb-markup</code>' Parameters⇒ '<code>view=markup</code>'
|
||||
<li><a href="#compat-attic">'<code>Attic/FILE</code>' Paths ⇒ '<code>FILE</code>'</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -284,11 +284,6 @@ th.caption {
|
||||
<td>depends</td>
|
||||
<td><a href="#view-param"><code>view</code> parameter</a>, not needed if the <code>default_file_view</code> configuration variable is set to <code>co</code>, since that makes the checkout view the default view for file paths. Also not needed if the <code>/*checkout*</code> magic prefix or the <code>revision</code> parameter is present.
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>content-type=<var>TYPE</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>MIME type to send with checked out file, default is a guess based on file extension</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>revision=<var>REVISION</var></code></td>
|
||||
<td>optional</td>
|
||||
@@ -872,7 +867,7 @@ th.caption {
|
||||
<td>file query string</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>file_match=FILE_MATCH</code></td>
|
||||
<td><code>file_match=<var>FILE_MATCH</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"exact" "like" "glob" "regex" or "notregex" determining type of file match</td>
|
||||
</tr>
|
||||
@@ -882,37 +877,37 @@ th.caption {
|
||||
<td>author query string</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>who_match=WHO_MATCH</code></td>
|
||||
<td><code>who_match=<var>WHO_MATCH</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"exact" "like" "glob" "regex" or "notregex" determining type of author match</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>querysort=SORT</code></td>
|
||||
<td><code>querysort=<var>SORT</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"date" "author" or "file" determining order of query results</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>date=DATE</code></td>
|
||||
<td><code>date=<var>DATE</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"hours" "day" "week" "month" "all" or "explicit" to filter query results by date</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>hours=HOURS</code></td>
|
||||
<td><code>hours=<var>HOURS</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>number of hours back to include results from when <code><var>DATE</var></code> is "hours"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>mindate=MINDATE</code></td>
|
||||
<td><code>mindate=<var>MINDATE</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>earliest date to include results from when <code><var>DATE</var></code> is "explicit"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>maxdate=MAXDATE</code></td>
|
||||
<td><code>maxdate=<var>MAXDATE</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>latest date to include results from when <code><var>DATE</var></code> is "explicit"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>limit_changes=LIMIT_CHANGES</code></td>
|
||||
<td><code>limit_changes=<var>LIMIT_CHANGES</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>maximum number of files to list per commit in query results. Default is value of <code>limit_changes</code> configuration option</td>
|
||||
</tr>
|
||||
@@ -970,7 +965,7 @@ th.caption {
|
||||
<td>branch query string</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>branch_match=BRANCH_MATCH</code></td>
|
||||
<td><code>branch_match=<var>BRANCH_MATCH</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"exact" "like" "glob" "regex" or "notregex" determining type of branch match</td>
|
||||
</tr>
|
||||
@@ -985,7 +980,7 @@ th.caption {
|
||||
<td>file query string</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>file_match=FILE_MATCH</code></td>
|
||||
<td><code>file_match=<var>FILE_MATCH</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"exact" "like" "glob" "regex" or "notregex" determining type of file match</td>
|
||||
</tr>
|
||||
@@ -995,47 +990,47 @@ th.caption {
|
||||
<td>author query string</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>who_match=WHO_MATCH</code></td>
|
||||
<td><code>who_match=<var>WHO_MATCH</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"exact" "like" "glob" "regex" or "notregex" determining type of author match</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>querysort=SORT</code></td>
|
||||
<td><code>querysort=<var>SORT</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"date" "author" or "file" determining order of query results</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>date=DATE</code></td>
|
||||
<td><code>date=<var>DATE</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"hours" "day" "week" "month" "all" or "explicit" to filter query results by date</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>hours=HOURS</code></td>
|
||||
<td><code>hours=<var>HOURS</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>number of hours back to include results from when <code><var>DATE</var></code> is "hours"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>mindate=MINDATE</code></td>
|
||||
<td><code>mindate=<var>MINDATE</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>earliest date to include results from when <code><var>DATE</var></code> is "explicit"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>maxdate=MAXDATE</code></td>
|
||||
<td><code>maxdate=<var>MAXDATE</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>latest date to include results from when <code><var>DATE</var></code> is "explicit"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>format=FORMAT</code></td>
|
||||
<td><code>format=<var>FORMAT</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>"rss" or "backout" values to generate an rss feed or list of commands to back out changes instead showing a normal query result page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>limit=LIMIT</code></td>
|
||||
<td><code>limit=<var>LIMIT</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>maximum number of file-revisions to process during a query. Default is value of <code>row_limit</code> configuration option</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>limit_changes=LIMIT_CHANGES</code></td>
|
||||
<td><code>limit_changes=<var>LIMIT_CHANGES</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>maximum number of files to list per commit in query results. Default is value of <code>limit_changes</code> configuration option</td>
|
||||
</tr>
|
||||
@@ -1087,7 +1082,7 @@ th.caption {
|
||||
<td><a href="#revision-param"><code>revision</code> parameter</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>limit_changes=LIMIT_CHANGES</code></td>
|
||||
<td><code>limit_changes=<var>LIMIT_CHANGES</var></code></td>
|
||||
<td>optional</td>
|
||||
<td>maximum number of files to list per commit. Default is value of <code>limit_changes</code> configuration option</td>
|
||||
</tr>
|
||||
@@ -1233,8 +1228,8 @@ th.caption {
|
||||
<h3 id="compat-makeimage">'<code>graph=1&makeimage=1</code>' Parameters ⇒ '<code>view=graphimg</code>'</h3>
|
||||
<p>A <code>graph=1&makeimage=1</code> parameter is treated like a <code>view=graph</code> parameter. There is currently no redirect when it is encountered, but there could be one in the future.</p>
|
||||
|
||||
<h3 id="compat-content_type">'<code>content_type=text/vnd.viewcvs-markup</code>' and '<code>content_type=text/x-cvsweb-markup</code>' Parameters⇒ '<code>view=markup</code>'</h3>
|
||||
<p><code>content_type=text/vnd.viewcvs-markup</code> and <code>content_type=text/x-cvsweb-markup</code> parameters are treated like a <code>view=markup</code> parameter. There is currently no redirect when it is encountered, but there could be one in the future.</p>
|
||||
<h3 id="compat-content_type">'<code>content-type=text/vnd.viewcvs-markup</code>' and '<code>content-type=text/x-cvsweb-markup</code>' Parameters⇒ '<code>view=markup</code>'; other values ignored</h3>
|
||||
<p><code>content-type=text/vnd.viewcvs-markup</code> and <code>content-type=text/x-cvsweb-markup</code> parameters are treated like a <code>view=markup</code> parameter. There is currently no redirect when it is encountered, but there could be one in the future. Other values of the <code>content-type</code> parameter, which were used to dictate the MIME type of files displayed in the checkout/download view prior to ViewVC 1.0.6, are ignored.</p>
|
||||
|
||||
<h3 id="compat-attic">'<code>Attic/FILE</code>' Paths ⇒ '<code>FILE</code>'</h3>
|
||||
<p>When ViewVC encounters an invalid repository path whose last or second-to-last component is named <code>Attic</code>, and stripping the component yields a valid path, it will redirect to a URL with that path.</p>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -39,7 +39,7 @@ def _parse(hdr, result):
|
||||
while pos < len(hdr):
|
||||
name = _re_token.match(hdr, pos)
|
||||
if not name:
|
||||
raise AcceptParseError()
|
||||
raise AcceptLanguageParseError()
|
||||
a = result.item_class(string.lower(name.group(1)))
|
||||
pos = name.end()
|
||||
while 1:
|
||||
@@ -210,7 +210,7 @@ class _LanguageSelector:
|
||||
def append(self, item):
|
||||
self.requested.append(item)
|
||||
|
||||
class AcceptParseError(Exception):
|
||||
class AcceptLanguageParseError(Exception):
|
||||
pass
|
||||
|
||||
def _test():
|
||||
|
10
lib/blame.py
10
lib/blame.py
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
@@ -33,7 +33,6 @@ import time
|
||||
import math
|
||||
import cgi
|
||||
import vclib
|
||||
import vclib.ccvs.blame
|
||||
|
||||
|
||||
re_includes = re.compile('\\#(\\s*)include(\\s*)"(.*?)"')
|
||||
@@ -100,6 +99,7 @@ class _item:
|
||||
|
||||
|
||||
def make_html(root, rcs_path):
|
||||
import vclib.ccvs.blame
|
||||
bs = vclib.ccvs.blame.BlameSource(os.path.join(root, rcs_path))
|
||||
|
||||
count = bs.num_lines
|
||||
@@ -161,9 +161,9 @@ def make_html(root, rcs_path):
|
||||
|
||||
# Close the highlighted section
|
||||
#if (defined $mark_cmd and mark_cmd != 'begin'):
|
||||
# chop($output)
|
||||
# output = output + endOfRow + (startOfRow % row_color)
|
||||
# inMark = 0
|
||||
# chop($output)
|
||||
# output = output + endOfRow + (startOfRow % row_color)
|
||||
# inMark = 0
|
||||
|
||||
print output
|
||||
print endOfRow + '</table>'
|
||||
|
14
lib/debug.py
14
lib/debug.py
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -38,13 +38,17 @@ if SHOW_TIMES:
|
||||
else:
|
||||
_times[which] = t
|
||||
|
||||
def dump():
|
||||
for name, value in _times.items():
|
||||
print '%s: %.6f<br />' % (name, value)
|
||||
def t_dump(out):
|
||||
out.write('<div>')
|
||||
names = _times.keys()
|
||||
names.sort()
|
||||
for name in names:
|
||||
out.write('%s: %.6fs<br/>\n' % (name, _times[name]))
|
||||
out.write('</div>')
|
||||
|
||||
else:
|
||||
|
||||
t_start = t_end = dump = lambda *args: None
|
||||
t_start = t_end = t_dump = lambda *args: None
|
||||
|
||||
|
||||
class ViewVCException:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -364,11 +364,11 @@ class _pipe:
|
||||
else:
|
||||
if self.thread:
|
||||
self.thread.join()
|
||||
if type(self.child_pid) == type([]):
|
||||
if type(self.child_pid) == type([]):
|
||||
for pid in self.child_pid:
|
||||
exit = os.waitpid(pid, 0)[1]
|
||||
return exit
|
||||
else:
|
||||
else:
|
||||
return os.waitpid(self.child_pid, 0)[1]
|
||||
return None
|
||||
|
||||
|
@@ -25,6 +25,7 @@ import time
|
||||
|
||||
import cvsdb
|
||||
import viewvc
|
||||
import vclib
|
||||
import ezt
|
||||
import debug
|
||||
import urllib
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -534,31 +534,25 @@ def _parse_co_header(fp):
|
||||
raise COMalformedOutput, "Unable to find filename in co output stream"
|
||||
filename = match.group(1)
|
||||
|
||||
# look for a revision in the second line.
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
raise COMalformedOutput, "Missing second line from co output stream"
|
||||
match = _re_co_revision.match(line)
|
||||
if match:
|
||||
return filename, match.group(1)
|
||||
elif _re_co_missing_rev.match(line) or _re_co_side_branches.match(line):
|
||||
raise COMissingRevision, "Got missing revision error from co output stream"
|
||||
elif _re_co_warning.match(line):
|
||||
pass
|
||||
else:
|
||||
raise COMalformedOutput, "Unable to find revision in co output stream"
|
||||
# look through subsequent lines for a revision. we might encounter
|
||||
# some ignorable or problematic lines along the way.
|
||||
while 1:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
# look for a revision.
|
||||
match = _re_co_revision.match(line)
|
||||
if match:
|
||||
return filename, match.group(1)
|
||||
elif _re_co_missing_rev.match(line) or _re_co_side_branches.match(line):
|
||||
raise COMissingRevision, "Got missing revision error from co output stream"
|
||||
elif _re_co_warning.match(line):
|
||||
pass
|
||||
else:
|
||||
break
|
||||
|
||||
# if we get here, the second line wasn't a revision, but it was a
|
||||
# warning we can ignore. look for a revision in the third line.
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
raise COMalformedOutput, "Missing third line from co output stream"
|
||||
match = _re_co_revision.match(line)
|
||||
if match:
|
||||
return filename, match.group(1)
|
||||
raise COMalformedOutput, "Unable to find revision in co output stream"
|
||||
|
||||
|
||||
# if your rlog doesn't use 77 '=' characters, then this must change
|
||||
LOG_END_MARKER = '=' * 77 + '\n'
|
||||
ENTRY_END_MARKER = '-' * 28 + '\n'
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 2000 Curt Hagenlocher <curt@hagenlocher.org>
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
@@ -346,7 +346,7 @@ class CVSParser(rcsparse.Sink):
|
||||
is_trunk_revision = self.trunk_rev.match(revision) is not None
|
||||
|
||||
if is_trunk_revision:
|
||||
diffs = self.deltatext_split(last_revision)
|
||||
diffs = self.deltatext_split(last_revision)
|
||||
|
||||
# Revisions on the trunk specify deltas that transform a
|
||||
# revision into an earlier revision, so invert the translation
|
||||
@@ -379,7 +379,7 @@ class CVSParser(rcsparse.Sink):
|
||||
# the trunk. They specify deltas that transform a revision
|
||||
# into a later revision.
|
||||
adjust = 0
|
||||
diffs = self.deltatext_split(revision)
|
||||
diffs = self.deltatext_split(revision)
|
||||
for command in diffs:
|
||||
if skip > 0:
|
||||
skip = skip - 1
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -78,7 +78,7 @@ class RCSStopParser(Exception):
|
||||
#
|
||||
|
||||
class _Parser:
|
||||
stream_class = None # subclasses need to define this
|
||||
stream_class = None # subclasses need to define this
|
||||
|
||||
def parse_rcs_admin(self):
|
||||
while 1:
|
||||
@@ -196,7 +196,7 @@ class _Parser:
|
||||
if token == ';':
|
||||
break
|
||||
author = author + token + ' '
|
||||
author = author[:-1] # toss the trailing space
|
||||
author = author[:-1] # toss the trailing space
|
||||
|
||||
# Parse state
|
||||
self.ts.match('state')
|
||||
@@ -206,7 +206,7 @@ class _Parser:
|
||||
if token == ';':
|
||||
break
|
||||
state = state + token + ' '
|
||||
state = state[:-1] # toss the trailing space
|
||||
state = state[:-1] # toss the trailing space
|
||||
|
||||
# Parse branches
|
||||
self.ts.match('branches')
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -26,7 +26,7 @@ class _TokenStream:
|
||||
# note: we use a multiple of a standard block size
|
||||
CHUNK_SIZE = 192 * 512 # about 100k
|
||||
|
||||
# CHUNK_SIZE = 5 # for debugging, make the function grind...
|
||||
# CHUNK_SIZE = 5 # for debugging, make the function grind...
|
||||
|
||||
def __init__(self, file):
|
||||
self.rcsfile = file
|
||||
@@ -51,7 +51,7 @@ class _TokenStream:
|
||||
buf = self.rcsfile.read(self.CHUNK_SIZE)
|
||||
if buf == '':
|
||||
# signal EOF by returning None as the token
|
||||
del self.buf # so we fail if get() is called again
|
||||
del self.buf # so we fail if get() is called again
|
||||
return None
|
||||
idx = 0
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -25,7 +25,7 @@ _tt = TextTools
|
||||
_idchar_list = map(chr, range(33, 127)) + map(chr, range(160, 256))
|
||||
_idchar_list.remove('$')
|
||||
_idchar_list.remove(',')
|
||||
#_idchar_list.remove('.') leave as part of 'num' symbol
|
||||
#_idchar_list.remove('.') # leave as part of 'num' symbol
|
||||
_idchar_list.remove(':')
|
||||
_idchar_list.remove(';')
|
||||
_idchar_list.remove('@')
|
||||
@@ -41,10 +41,10 @@ _T_STRING_START = 40
|
||||
_T_STRING_SPAN = 60
|
||||
_T_STRING_END = 70
|
||||
|
||||
_E_COMPLETE = 100 # ended on a complete token
|
||||
_E_TOKEN = 110 # ended mid-token
|
||||
_E_STRING_SPAN = 130 # ended within a string
|
||||
_E_STRING_END = 140 # ended with string-end ('@') (could be mid-@@)
|
||||
_E_COMPLETE = 100 # ended on a complete token
|
||||
_E_TOKEN = 110 # ended mid-token
|
||||
_E_STRING_SPAN = 130 # ended within a string
|
||||
_E_STRING_END = 140 # ended with string-end ('@') (could be mid-@@)
|
||||
|
||||
_SUCCESS = +100
|
||||
|
||||
@@ -65,7 +65,7 @@ class _mxTokenStream:
|
||||
# note: we use a multiple of a standard block size
|
||||
CHUNK_SIZE = 192 * 512 # about 100k
|
||||
|
||||
# CHUNK_SIZE = 5 # for debugging, make the function grind...
|
||||
# CHUNK_SIZE = 5 # for debugging, make the function grind...
|
||||
|
||||
def __init__(self, file):
|
||||
self.rcsfile = file
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -239,6 +239,9 @@ class NodeHistory:
|
||||
|
||||
|
||||
def _get_history(svnrepos, full_name, rev, options={}):
|
||||
if svnrepos.youngest == 0:
|
||||
return {}
|
||||
|
||||
fsroot = svnrepos._getroot(rev)
|
||||
show_all_logs = options.get('svn_show_all_dir_logs', 0)
|
||||
if not show_all_logs:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -20,6 +20,7 @@ import re
|
||||
import tempfile
|
||||
import popen2
|
||||
import time
|
||||
import urllib
|
||||
from vclib.svn import Revision, ChangedPath, _datestr_to_date, _compare_paths, _cleanup_path
|
||||
from svn import core, delta, client, wc, ra
|
||||
|
||||
@@ -220,7 +221,7 @@ def get_logs(svnrepos, full_name, rev, files):
|
||||
rev, author, date, log, changes = \
|
||||
_get_rev_details(svnrepos, entry.created_rev, subpool)
|
||||
rev_info_cache[entry.created_rev] = rev, author, date, log
|
||||
file.rev = rev
|
||||
file.rev = str(rev)
|
||||
file.author = author
|
||||
file.date = _datestr_to_date(date, subpool)
|
||||
file.log = log
|
||||
@@ -234,7 +235,7 @@ def temp_checkout(svnrepos, path, rev, pool):
|
||||
"""Check out file revision to temporary file"""
|
||||
temp = tempfile.mktemp()
|
||||
stream = core.svn_stream_from_aprfile(temp, pool)
|
||||
url = svnrepos.rootpath + (path and '/' + path)
|
||||
url = svnrepos._geturl(path)
|
||||
client.svn_client_cat(core.Stream(stream), url, _rev2optrev(rev),
|
||||
svnrepos.ctx, pool)
|
||||
core.svn_stream_close(stream)
|
||||
@@ -323,10 +324,10 @@ class SubversionRepository(vclib.Repository):
|
||||
raise vclib.ItemNotFound(path_parts)
|
||||
|
||||
def openfile(self, path_parts, rev):
|
||||
path = self._getpath(path_parts)
|
||||
rev = self._getrev(rev)
|
||||
url = self.rootpath
|
||||
if len(path_parts):
|
||||
url = self.rootpath + '/' + self._getpath(path_parts)
|
||||
url = self._geturl(path)
|
||||
|
||||
tmp_file = tempfile.mktemp()
|
||||
stream = core.svn_stream_from_aprfile(tmp_file, self.pool)
|
||||
### rev here should be the last history revision of the URL
|
||||
@@ -353,18 +354,15 @@ class SubversionRepository(vclib.Repository):
|
||||
get_logs(self, self._getpath(path_parts), self._getrev(rev), entries)
|
||||
|
||||
def itemlog(self, path_parts, rev, options):
|
||||
full_name = self._getpath(path_parts)
|
||||
path = self._getpath(path_parts)
|
||||
rev = self._getrev(rev)
|
||||
url = self._geturl(path)
|
||||
|
||||
# It's okay if we're told to not show all logs on a file -- all
|
||||
# the revisions should match correctly anyway.
|
||||
lc = LogCollector(full_name, options.get('svn_show_all_dir_logs', 0))
|
||||
dir_url = self.rootpath
|
||||
if full_name:
|
||||
dir_url = dir_url + '/' + full_name
|
||||
|
||||
lc = LogCollector(path, options.get('svn_show_all_dir_logs', 0))
|
||||
cross_copies = options.get('svn_cross_copies', 0)
|
||||
client.svn_client_log([dir_url], _rev2optrev(rev), _rev2optrev(1),
|
||||
client.svn_client_log([url], _rev2optrev(rev), _rev2optrev(1),
|
||||
1, not cross_copies, lc.add_log,
|
||||
self.ctx, self.pool)
|
||||
revs = lc.logs
|
||||
@@ -379,7 +377,7 @@ class SubversionRepository(vclib.Repository):
|
||||
def annotate(self, path_parts, rev):
|
||||
path = self._getpath(path_parts)
|
||||
rev = self._getrev(rev)
|
||||
url = self.rootpath + (path and '/' + path)
|
||||
url = self._geturl(path)
|
||||
|
||||
blame_data = []
|
||||
|
||||
@@ -429,13 +427,17 @@ class SubversionRepository(vclib.Repository):
|
||||
raise vclib.InvalidRevision(rev)
|
||||
return rev
|
||||
|
||||
def _geturl(self, path=None):
|
||||
if not path:
|
||||
return self.rootpath
|
||||
return self.rootpath + '/' + urllib.quote(path, "/*~")
|
||||
|
||||
def _get_dirents(self, path, rev):
|
||||
dir_url = self._geturl(path)
|
||||
if path:
|
||||
key = str(rev) + '/' + path
|
||||
dir_url = self.rootpath + '/' + path
|
||||
else:
|
||||
key = str(rev)
|
||||
dir_url = self.rootpath
|
||||
dirents = self._dirent_cache.get(key)
|
||||
if dirents:
|
||||
return dirents
|
||||
|
244
lib/viewvc.py
244
lib/viewvc.py
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -14,7 +14,7 @@
|
||||
#
|
||||
# -----------------------------------------------------------------------
|
||||
|
||||
__version__ = '1.0.5'
|
||||
__version__ = '1.0.10'
|
||||
|
||||
# this comes from our library; measure the startup time
|
||||
import debug
|
||||
@@ -112,7 +112,10 @@ class Request:
|
||||
|
||||
# process the Accept-Language: header
|
||||
hal = server.getenv('HTTP_ACCEPT_LANGUAGE','')
|
||||
self.lang_selector = accept.language(hal)
|
||||
try:
|
||||
self.lang_selector = accept.language(hal)
|
||||
except accept.AcceptLanguageParseError:
|
||||
self.lang_selector = accept.language('en')
|
||||
self.language = self.lang_selector.select_from(cfg.general.languages)
|
||||
|
||||
# load the key/value files, given the selected language
|
||||
@@ -147,6 +150,9 @@ class Request:
|
||||
|
||||
# Process the query params
|
||||
for name, values in self.server.params().items():
|
||||
# we only care about the first value
|
||||
value = values[0]
|
||||
|
||||
# patch up old queries that use 'cvsroot' to look like they used 'root'
|
||||
if name == 'cvsroot':
|
||||
name = 'root'
|
||||
@@ -158,12 +164,12 @@ class Request:
|
||||
needs_redirect = 1
|
||||
|
||||
# validate the parameter
|
||||
_validate_param(name, values[0])
|
||||
|
||||
_validate_param(name, value)
|
||||
|
||||
# if we're here, then the parameter is okay
|
||||
self.query_dict[name] = values[0]
|
||||
self.query_dict[name] = value
|
||||
|
||||
# handle view parameter
|
||||
# Resolve the view parameter into a handler function.
|
||||
self.view_func = _views.get(self.query_dict.get('view', None),
|
||||
self.view_func)
|
||||
|
||||
@@ -191,7 +197,7 @@ class Request:
|
||||
# handle tarball magic suffixes
|
||||
if self.view_func is download_tarball:
|
||||
if (self.query_dict.get('parent')):
|
||||
del path_parts[-1]
|
||||
del path_parts[-1]
|
||||
elif path_parts[-1][-7:] == ".tar.gz":
|
||||
path_parts[-1] = path_parts[-1][:-7]
|
||||
|
||||
@@ -295,7 +301,7 @@ class Request:
|
||||
|
||||
if self.pathtype is None:
|
||||
# Path doesn't exist, see if it could be an old-style ViewVC URL
|
||||
# with a fake suffix.
|
||||
# with a fake suffix.
|
||||
result = _strip_suffix('.diff', path_parts, pathrev, vclib.FILE, \
|
||||
self.repos, view_diff) or \
|
||||
_strip_suffix('.tar.gz', path_parts, pathrev, vclib.DIR, \
|
||||
@@ -314,7 +320,7 @@ class Request:
|
||||
if result:
|
||||
self.path_parts, self.pathtype, self.view_func = result
|
||||
self.where = _path_join(self.path_parts)
|
||||
needs_redirect = 1
|
||||
needs_redirect = 1
|
||||
else:
|
||||
raise debug.ViewVCException('%s: unknown location'
|
||||
% self.where, '404 Not Found')
|
||||
@@ -346,7 +352,7 @@ class Request:
|
||||
self.view_func = view_roots
|
||||
elif self.pathtype == vclib.DIR:
|
||||
# ViewCVS 0.9.2 used to put ?tarball=1 at the end of tarball urls
|
||||
if self.query_dict.has_key('tarball'):
|
||||
if self.query_dict.has_key('tarball'):
|
||||
self.view_func = download_tarball
|
||||
else:
|
||||
self.view_func = view_directory
|
||||
@@ -505,7 +511,7 @@ class Request:
|
||||
if view_func is download_tarball:
|
||||
if not where and not cfg.options.root_as_url_component:
|
||||
url = url + '/' + rootname + '-root'
|
||||
params['parent'] = '1'
|
||||
params['parent'] = '1'
|
||||
url = url + '.tar.gz'
|
||||
|
||||
# add trailing slash for a directory
|
||||
@@ -596,34 +602,48 @@ def _validate_param(name, value):
|
||||
this function throws an exception. Otherwise, it simply returns None.
|
||||
"""
|
||||
|
||||
# First things first -- check that we have a legal parameter name.
|
||||
try:
|
||||
validator = _legal_params[name]
|
||||
except KeyError:
|
||||
raise debug.ViewVCException(
|
||||
'An illegal parameter name ("%s") was passed.' % name,
|
||||
'An illegal parameter name was provided.',
|
||||
'400 Bad Request')
|
||||
|
||||
# Is there a validator? Is it a regex or a function? Validate if
|
||||
# we can, returning without incident on valid input.
|
||||
if validator is None:
|
||||
return
|
||||
elif hasattr(validator, 'match'):
|
||||
if validator.match(value):
|
||||
return
|
||||
else:
|
||||
if validator(value):
|
||||
return
|
||||
|
||||
# is the validator a regex?
|
||||
if hasattr(validator, 'match'):
|
||||
if not validator.match(value):
|
||||
raise debug.ViewVCException(
|
||||
'An illegal value ("%s") was passed as a parameter.' %
|
||||
value, '400 Bad Request')
|
||||
return
|
||||
|
||||
# the validator must be a function
|
||||
validator(value)
|
||||
# If we get here, the input value isn't valid.
|
||||
raise debug.ViewVCException(
|
||||
'An illegal value was provided for the "%s" parameter.' % (name),
|
||||
'400 Bad Request')
|
||||
|
||||
def _validate_regex(value):
|
||||
# hmm. there isn't anything that we can do here.
|
||||
|
||||
### we need to watch the flow of these parameters through the system
|
||||
### to ensure they don't hit the page unescaped. otherwise, these
|
||||
### parameters could constitute a CSS attack.
|
||||
pass
|
||||
try:
|
||||
re.compile(value)
|
||||
return True
|
||||
except:
|
||||
return None
|
||||
|
||||
def _validate_view(value):
|
||||
# Return true iff VALUE is one of our allowed views.
|
||||
return _views.has_key(value)
|
||||
|
||||
def _validate_mimetype(value):
|
||||
# For security purposes, we only allow mimetypes from a predefined set
|
||||
# thereof.
|
||||
return value in (viewcvs_mime_type, alt_mime_type, 'text/plain')
|
||||
|
||||
# obvious things here. note that we don't need uppercase for alpha.
|
||||
_re_validate_alpha = re.compile('^[a-z]+$')
|
||||
@@ -632,17 +652,13 @@ _re_validate_number = re.compile('^[0-9]+$')
|
||||
# when comparing two revs, we sometimes construct REV:SYMBOL, so ':' is needed
|
||||
_re_validate_revnum = re.compile('^[-_.a-zA-Z0-9:~\\[\\]/]*$')
|
||||
|
||||
# it appears that RFC 2045 also says these chars are legal: !#$%&'*+^{|}~`
|
||||
# but woah... I'll just leave them out for now
|
||||
_re_validate_mimetype = re.compile('^[-_.a-zA-Z0-9/]+$')
|
||||
|
||||
# date time values
|
||||
_re_validate_datetime = re.compile(r'^(\d\d\d\d-\d\d-\d\d(\s+\d\d:\d\d(:\d\d)?)?)?$')
|
||||
|
||||
# the legal query parameters and their validation functions
|
||||
_legal_params = {
|
||||
'root' : None,
|
||||
'view' : None,
|
||||
'view' : _validate_view,
|
||||
'search' : _validate_regex,
|
||||
'p1' : None,
|
||||
'p2' : None,
|
||||
@@ -668,7 +684,7 @@ _legal_params = {
|
||||
'tr2' : _re_validate_revnum,
|
||||
'rev' : _re_validate_revnum,
|
||||
'revision' : _re_validate_revnum,
|
||||
'content-type' : _re_validate_mimetype,
|
||||
'content-type' : _validate_mimetype,
|
||||
|
||||
# for query
|
||||
'branch' : _validate_regex,
|
||||
@@ -1551,16 +1567,9 @@ def view_directory(request):
|
||||
cfg.options.hide_attic))
|
||||
options["cvs_subdirs"] = (cfg.options.show_subdir_lastmod and
|
||||
cfg.options.show_logs)
|
||||
|
||||
file_data = request.repos.listdir(request.path_parts, request.pathrev,
|
||||
options)
|
||||
|
||||
# Filter file list if a regex is specified
|
||||
search_re = request.query_dict.get('search', '')
|
||||
if cfg.options.use_re_search and search_re:
|
||||
file_data = search_files(request.repos, request.path_parts, request.pathrev,
|
||||
file_data, search_re)
|
||||
|
||||
# Retrieve log messages, authors, revision numbers, timestamps
|
||||
request.repos.dirlogs(request.path_parts, request.pathrev, file_data, options)
|
||||
|
||||
@@ -1570,6 +1579,12 @@ def view_directory(request):
|
||||
sort_file_data(file_data, request.roottype, sortdir, sortby,
|
||||
cfg.options.sort_group_dirs)
|
||||
|
||||
# If a regex is specified, build a compiled form thereof for filtering
|
||||
searchstr = None
|
||||
search_re = request.query_dict.get('search', '')
|
||||
if cfg.options.use_re_search and search_re:
|
||||
searchstr = re.compile(search_re)
|
||||
|
||||
# loop through entries creating rows and changing these values
|
||||
rows = [ ]
|
||||
num_displayed = 0
|
||||
@@ -1636,10 +1651,17 @@ def view_directory(request):
|
||||
escape=1)
|
||||
|
||||
elif file.kind == vclib.FILE:
|
||||
if searchstr is not None:
|
||||
if request.roottype == 'cvs' and (file.errors or file.dead):
|
||||
continue
|
||||
if not search_file(request.repos, request.path_parts + [file.name],
|
||||
request.pathrev, searchstr):
|
||||
continue
|
||||
if request.roottype == 'cvs' and file.dead:
|
||||
num_dead = num_dead + 1
|
||||
if hideattic:
|
||||
continue
|
||||
|
||||
num_displayed = num_displayed + 1
|
||||
|
||||
file_where = where_prefix + file.name
|
||||
@@ -1712,6 +1734,9 @@ def view_directory(request):
|
||||
data['sortby_%s_href' % sortby] = request.get_url(params={'sortdir':
|
||||
revsortdir},
|
||||
escape=1)
|
||||
# CVS doesn't support sorting by rev
|
||||
if request.roottype == "cvs":
|
||||
data['sortby_rev_href'] = None
|
||||
|
||||
# set cvs-specific fields
|
||||
if request.roottype == 'cvs':
|
||||
@@ -2190,7 +2215,7 @@ def view_annotate(request):
|
||||
|
||||
diff_url = request.get_url(view_func=view_diff,
|
||||
params={'r1': None, 'r2': None},
|
||||
escape=1, partial=1)
|
||||
escape=1, partial=1)
|
||||
|
||||
include_url = request.get_url(view_func=view_log, where='/WHERE/',
|
||||
pathtype=vclib.FILE, params={}, escape=1)
|
||||
@@ -2272,58 +2297,23 @@ def view_cvsgraph(request):
|
||||
request.server.header()
|
||||
generate_page(request, "graph", data)
|
||||
|
||||
def search_files(repos, path_parts, rev, files, search_re):
|
||||
""" Search files in a directory for a regular expression.
|
||||
|
||||
Does a check-out of each file in the directory. Only checks for
|
||||
the first match.
|
||||
"""
|
||||
|
||||
# Pass in search regular expression. We check out
|
||||
# each file and look for the regular expression. We then return the data
|
||||
# for all files that match the regex.
|
||||
|
||||
# Compile to make sure we do this as fast as possible.
|
||||
searchstr = re.compile(search_re)
|
||||
|
||||
# Will become list of files that have at least one match.
|
||||
# new_file_list also includes directories.
|
||||
new_file_list = [ ]
|
||||
|
||||
# Loop on every file (and directory)
|
||||
for file in files:
|
||||
# Is this a directory? If so, append name to new_file_list
|
||||
# and move to next file.
|
||||
if file.kind != vclib.FILE:
|
||||
new_file_list.append(file)
|
||||
continue
|
||||
|
||||
# Only files at this point
|
||||
|
||||
# Shouldn't search binary files, or should we?
|
||||
# Should allow all text mime types to pass.
|
||||
if not is_text(guess_mime(file.name)):
|
||||
continue
|
||||
|
||||
# Only text files at this point
|
||||
|
||||
# Assign contents of checked out file to fp.
|
||||
fp = repos.openfile(path_parts + [file.name], rev)[0]
|
||||
|
||||
# Read in each line, use re.search to search line.
|
||||
# If successful, add file to new_file_list and break.
|
||||
while 1:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
if searchstr.search(line):
|
||||
new_file_list.append(file)
|
||||
# close down the pipe (and wait for the child to terminate)
|
||||
fp.close()
|
||||
break
|
||||
|
||||
return new_file_list
|
||||
def search_file(repos, path_parts, rev, search_re):
|
||||
"""Return 1 iff the contents of the file at PATH_PARTS in REPOS as
|
||||
of revision REV matches regular expression SEARCH_RE."""
|
||||
|
||||
# Read in each line of a checked-out file, and then use re.search to
|
||||
# search line.
|
||||
fp = repos.openfile(path_parts, rev)[0]
|
||||
matches = 0
|
||||
while 1:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
if search_re.search(line):
|
||||
matches = 1
|
||||
fp.close()
|
||||
break
|
||||
return matches
|
||||
|
||||
def view_doc(request):
|
||||
"""Serve ViewVC static content locally.
|
||||
@@ -3005,8 +2995,9 @@ def download_tarball(request):
|
||||
|
||||
def view_revision(request):
|
||||
if request.roottype == "cvs":
|
||||
raise ViewVCException("Revision view not supported for CVS repositories "
|
||||
"at this time.", "400 Bad Request")
|
||||
raise debug.ViewVCException("Revision view not supported for CVS "
|
||||
"repositories at this time.",
|
||||
"400 Bad Request")
|
||||
|
||||
data = common_template_data(request)
|
||||
query_dict = request.query_dict
|
||||
@@ -3177,19 +3168,22 @@ def view_queryform(request):
|
||||
data['query_action'], data['query_hidden_values'] = \
|
||||
request.get_form(view_func=view_query, params={'limit_changes': None})
|
||||
|
||||
def escaped_query_dict_get(itemname, itemdefault=''):
|
||||
return request.server.escape(request.query_dict.get(itemname, itemdefault))
|
||||
|
||||
# default values ...
|
||||
data['branch'] = request.query_dict.get('branch', '')
|
||||
data['branch_match'] = request.query_dict.get('branch_match', 'exact')
|
||||
data['dir'] = request.query_dict.get('dir', '')
|
||||
data['file'] = request.query_dict.get('file', '')
|
||||
data['file_match'] = request.query_dict.get('file_match', 'exact')
|
||||
data['who'] = request.query_dict.get('who', '')
|
||||
data['who_match'] = request.query_dict.get('who_match', 'exact')
|
||||
data['querysort'] = request.query_dict.get('querysort', 'date')
|
||||
data['date'] = request.query_dict.get('date', 'hours')
|
||||
data['hours'] = request.query_dict.get('hours', '2')
|
||||
data['mindate'] = request.query_dict.get('mindate', '')
|
||||
data['maxdate'] = request.query_dict.get('maxdate', '')
|
||||
data['branch'] = escaped_query_dict_get('branch', '')
|
||||
data['branch_match'] = escaped_query_dict_get('branch_match', 'exact')
|
||||
data['dir'] = escaped_query_dict_get('dir', '')
|
||||
data['file'] = escaped_query_dict_get('file', '')
|
||||
data['file_match'] = escaped_query_dict_get('file_match', 'exact')
|
||||
data['who'] = escaped_query_dict_get('who', '')
|
||||
data['who_match'] = escaped_query_dict_get('who_match', 'exact')
|
||||
data['querysort'] = escaped_query_dict_get('querysort', 'date')
|
||||
data['date'] = escaped_query_dict_get('date', 'hours')
|
||||
data['hours'] = escaped_query_dict_get('hours', '2')
|
||||
data['mindate'] = escaped_query_dict_get('mindate', '')
|
||||
data['maxdate'] = escaped_query_dict_get('maxdate', '')
|
||||
data['limit_changes'] = int(request.query_dict.get('limit_changes',
|
||||
request.cfg.options.limit_changes))
|
||||
|
||||
@@ -3419,27 +3413,29 @@ def build_commit(request, files, max_files, dir_strip, format):
|
||||
return commit
|
||||
|
||||
def query_backout(request, commits):
|
||||
request.server.header('text/plain')
|
||||
if commits:
|
||||
print '# This page can be saved as a shell script and executed.'
|
||||
print '# It should be run at the top of your work area. It will update'
|
||||
print '# your working copy to back out the changes selected by the'
|
||||
print '# query.'
|
||||
print
|
||||
else:
|
||||
print '# No changes were selected by the query.'
|
||||
print '# There is nothing to back out.'
|
||||
server_fp = get_writeready_server_file(request, 'text/plain')
|
||||
if not commits:
|
||||
server_fp.write("""\
|
||||
# No changes were selected by the query.
|
||||
# There is nothing to back out.
|
||||
""")
|
||||
return
|
||||
server_fp.write("""\
|
||||
# This page can be saved as a shell script and executed.
|
||||
# It should be run at the top of your work area. It will update
|
||||
# your working copy to back out the changes selected by the
|
||||
# query.
|
||||
""")
|
||||
for commit in commits:
|
||||
for fileinfo in commit.files:
|
||||
if request.roottype == 'cvs':
|
||||
print 'cvs update -j %s -j %s %s/%s' \
|
||||
% (fileinfo.rev, prev_rev(fileinfo.rev),
|
||||
fileinfo.dir, fileinfo.file)
|
||||
server_fp.write('cvs update -j %s -j %s %s/%s\n'
|
||||
% (fileinfo.rev, prev_rev(fileinfo.rev),
|
||||
fileinfo.dir, fileinfo.file))
|
||||
elif request.roottype == 'svn':
|
||||
print 'svn merge -r %s:%s %s/%s' \
|
||||
% (fileinfo.rev, prev_rev(fileinfo.rev),
|
||||
fileinfo.dir, fileinfo.file)
|
||||
server_fp.write('svn merge -r %s:%s %s/%s\n'
|
||||
% (fileinfo.rev, prev_rev(fileinfo.rev),
|
||||
fileinfo.dir, fileinfo.file))
|
||||
|
||||
def view_query(request):
|
||||
if not is_query_supported(request):
|
||||
@@ -3737,9 +3733,9 @@ def view_error(server, cfg):
|
||||
exc_dict = debug.GetExceptionData()
|
||||
status = exc_dict['status']
|
||||
if exc_dict['msg']:
|
||||
exc_dict['msg'] = htmlify(exc_dict['msg'])
|
||||
exc_dict['msg'] = server.escape(exc_dict['msg'])
|
||||
if exc_dict['stacktrace']:
|
||||
exc_dict['stacktrace'] = htmlify(exc_dict['stacktrace'])
|
||||
exc_dict['stacktrace'] = server.escape(exc_dict['stacktrace'])
|
||||
handled = 0
|
||||
|
||||
# use the configured error template if possible
|
||||
@@ -3771,7 +3767,7 @@ def main(server, cfg):
|
||||
|
||||
finally:
|
||||
debug.t_end('main')
|
||||
debug.dump()
|
||||
debug.t_dump(server.file())
|
||||
debug.DumpChildren(server)
|
||||
|
||||
|
||||
|
@@ -50,7 +50,7 @@ numbers, and not literal):
|
||||
|
||||
9. Go into an empty directory and run the 'make-release' script:
|
||||
|
||||
tools/make-release viewvc-X.Y.Z X.Y.Z
|
||||
tools/make-release viewvc-X.Y.Z tags/X.Y.Z
|
||||
|
||||
10. Verify the archive files:
|
||||
|
||||
|
@@ -4,22 +4,30 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="vc_header[is sortby "file"]_sort[end]" colspan="2">
|
||||
<a href="[sortby_file_href]#dirlist">File
|
||||
[if-any sortby_file_href]<a href="[sortby_file_href]#dirlist">File</a>[else]File[end]
|
||||
[is sortby "file"]
|
||||
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
|
||||
width="13" height="13"
|
||||
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
|
||||
[end]
|
||||
</a>
|
||||
</th>
|
||||
[if-any sortby_rev_href]
|
||||
<th class="vc_header[is sortby "rev"]_sort[end]">
|
||||
<a href="[sortby_rev_href]#dirlist">Last Change
|
||||
<a href="[sortby_rev_href]#dirlist">Last Change</a>
|
||||
[is sortby "rev"]
|
||||
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
|
||||
width="13" height="13"
|
||||
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
|
||||
[end]
|
||||
</a>
|
||||
[else]
|
||||
<th class="vc_header[is sortby "date"]_sort[end]">
|
||||
[if-any sortby_date_href]<a href="[sortby_date_href]#dirlist">Last Change</a>[else]Last Change[end]
|
||||
[is sortby "date"]
|
||||
<img class="vc_sortarrow" alt="[is sortdir "down"](date)[end]"
|
||||
width="13" height="13"
|
||||
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
|
||||
[end]
|
||||
[end]
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@@ -4,50 +4,45 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="vc_header[is sortby "file"]_sort[end]" colspan="2">
|
||||
<a href="[sortby_file_href]#dirlist">File
|
||||
[if-any sortby_file_href]<a href="[sortby_file_href]#dirlist">File</a>[else]File[end]
|
||||
[is sortby "file"]
|
||||
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
|
||||
width="13" height="13"
|
||||
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
|
||||
[end]
|
||||
</a>
|
||||
</th>
|
||||
<th class="vc_header[is sortby "rev"]_sort[end]">
|
||||
<a href="[sortby_rev_href]#dirlist">Rev.
|
||||
[if-any sortby_rev_href]<a href="[sortby_rev_href]#dirlist">Rev.</a>[else]Rev.[end]
|
||||
[is sortby "rev"]
|
||||
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
|
||||
width="13" height="13"
|
||||
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
|
||||
[end]
|
||||
</a>
|
||||
</th>
|
||||
<th class="vc_header[is sortby "date"]_sort[end]">
|
||||
<a href="[sortby_date_href]#dirlist">Age
|
||||
[if-any sortby_date_href]<a href="[sortby_date_href]#dirlist">Age</a>[else]Age[end]
|
||||
[is sortby "date"]
|
||||
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
|
||||
width="13" height="13"
|
||||
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
|
||||
[end]
|
||||
</a>
|
||||
</th>
|
||||
<th class="vc_header[is sortby "author"]_sort[end]">
|
||||
<a href="[sortby_author_href]#dirlist">Author
|
||||
[if-any sortby_author_href]<a href="[sortby_author_href]#dirlist">Author</a>[else]Author[end]
|
||||
[is sortby "author"]
|
||||
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
|
||||
width="13" height="13"
|
||||
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
|
||||
[end]
|
||||
</a>
|
||||
</th>
|
||||
[is cfg.options.show_logs "1"]
|
||||
<th class="vc_header[is sortby "log"]_sort[end]">
|
||||
<a href="[sortby_log_href]#dirlist">Last log entry
|
||||
[if-any sortby_log_href]<a href="[sortby_log_href]#dirlist">Last log entry</a>[else]Last log entry[end]
|
||||
[is sortby "log"]
|
||||
<img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
|
||||
width="13" height="13"
|
||||
src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
|
||||
[end]
|
||||
</a>
|
||||
</th>
|
||||
[end]
|
||||
</tr>
|
||||
|
@@ -1,34 +1,24 @@
|
||||
[if-any search_re_form]
|
||||
<hr />
|
||||
[# this table holds the selectors on the left, and reset on the right ]
|
||||
<table class="auto">
|
||||
<tr>
|
||||
<td>Show files containing the regular expression:</td>
|
||||
<td>
|
||||
<form method="get" action="[search_re_action]">
|
||||
<div>
|
||||
[search_re_hidden_values]
|
||||
<input type="text" name="search" value="[search_re]" />
|
||||
<input type="submit" value="Show" />
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
[if-any search_re]
|
||||
<tr>
|
||||
<td> </td>
|
||||
<td>
|
||||
<form method="get" action="[search_tag_action]">
|
||||
<div>
|
||||
[search_tag_hidden_values]
|
||||
<input type="submit" value="Show all files" />
|
||||
</div>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
[end]
|
||||
</table>
|
||||
<hr />
|
||||
<div>
|
||||
Show files containing the regular expression:
|
||||
<form method="get" action="[search_re_action]" style="display: inline;">
|
||||
<div style="display: inline;">
|
||||
[search_re_hidden_values]
|
||||
<input type="text" name="search" value="[search_re]" />
|
||||
<input type="submit" value="Show" />
|
||||
</div>
|
||||
</form>
|
||||
[if-any search_re]
|
||||
<form method="get" action="[search_re_action]" style="display: inline;">
|
||||
<div style="display: inline;">
|
||||
[search_re_hidden_values]
|
||||
<input type="submit" value="Show all files" />
|
||||
</div>
|
||||
</form>
|
||||
[end]
|
||||
[end]
|
||||
</div>
|
||||
|
||||
[# if you want to disable tarball generation remove the following: ]
|
||||
[if-any tarball_href]
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved.
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
# the LICENSE.html file which can be found at the top level of the ViewVC
|
||||
@@ -17,17 +17,18 @@
|
||||
|
||||
### Validate input
|
||||
if test $# != 2 && test $# != 1; then
|
||||
echo "Usage: $0 TARGET-DIRECTORY [TAGNAME]"
|
||||
echo "Usage: $0 TARGET-DIRECTORY [BRANCH]"
|
||||
echo ""
|
||||
echo "If TAGNAME is not provided, the release will be rolled from trunk."
|
||||
echo "If BRANCH (i.e. \"tags/1.1.0\" or \"branches/1.0.x\") is not provided,"
|
||||
echo "the release will be rolled from trunk."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
TARGET=${1}
|
||||
if test $# == 1; then
|
||||
if test $# = 1; then
|
||||
ROOT=trunk
|
||||
else
|
||||
ROOT=tags/${2}
|
||||
ROOT=${2}
|
||||
fi
|
||||
|
||||
if test -e ${TARGET}; then
|
||||
@@ -36,7 +37,8 @@ if test -e ${TARGET}; then
|
||||
fi
|
||||
|
||||
### Grab an export from the Subversion repository.
|
||||
echo "Exporting into:" ${TARGET}
|
||||
EXPORT_URL="http://viewvc.tigris.org/svn/viewvc/${ROOT}"
|
||||
echo "Exporting '${EXPORT_URL}' into '${TARGET}'"
|
||||
|
||||
for PLATFORM in unix windows; do
|
||||
if test ${PLATFORM} = windows; then
|
||||
@@ -48,7 +50,7 @@ for PLATFORM in unix windows; do
|
||||
echo "Beginning build for ${PLATFORM}:"
|
||||
|
||||
echo " Exporting source code..."
|
||||
svn export --quiet ${EOL} http://viewvc.tigris.org/svn/viewvc/${ROOT} ${TARGET}
|
||||
svn export --quiet ${EOL} ${EXPORT_URL} ${TARGET}
|
||||
|
||||
### Various shifting, cleanup.
|
||||
|
||||
|
@@ -1,2 +0,0 @@
|
||||
*.tar.gz
|
||||
*.zip
|
@@ -1,68 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>ViewVC: Contact</title>
|
||||
<link rel="stylesheet" type="text/css" href="./styles.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="title">
|
||||
<a href="http://www.viewvc.org/"><img
|
||||
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
|
||||
</div>
|
||||
|
||||
<div id="menu">
|
||||
<p><a href="./index.html">Home</a> |
|
||||
<a href="http://viewvc.tigris.org/">Project Page</a> |
|
||||
<a href="./download.html">Download</a> |
|
||||
<a href="./upgrading.html">Upgrading</a> |
|
||||
<a href="./contributing.html">Contributing</a> |
|
||||
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
|
||||
<a href="./contact.html">Contact</a> |
|
||||
<a href="./who.html">About</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table id="pagetable">
|
||||
<tr>
|
||||
<td id="pagecolumn1">
|
||||
|
||||
<h4>On this page:</h4>
|
||||
|
||||
<ul id="bookmarks">
|
||||
<li><a href="#sec-contacting-us">Contacting Us</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Group</a></address>
|
||||
|
||||
</td>
|
||||
<td id="pagecolumn2">
|
||||
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-contacting-us">Contacting Us</h2>
|
||||
|
||||
<p>Please send any comments, questions, or suggestions to the <a
|
||||
href="mailto:users@viewvc.tigris.org">ViewVC users mailing
|
||||
list</a>. There is also a <a
|
||||
href="mailto:dev@viewvc.tigris.org">mailing list specifically for
|
||||
ViewVC developers</a>. You can subscribe to these lists, as well
|
||||
view the list archives, (and other
|
||||
project lists) <a
|
||||
href="http://viewvc.tigris.org/servlets/ProjectMailingListList"
|
||||
>here</a>.</p>
|
||||
|
||||
<p>ViewVC is an <a href="http://www.opensource.org/">Open
|
||||
Source</a> project, and all <a href="./contributing.html">contributions</a>
|
||||
are welcome.</p>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@@ -1,276 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>ViewVC: Contributing</title>
|
||||
<link rel="stylesheet" type="text/css" href="./styles.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="title">
|
||||
<a href="http://www.viewvc.org/"><img
|
||||
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
|
||||
</div>
|
||||
|
||||
<div id="menu">
|
||||
<p><a href="./index.html">Home</a> |
|
||||
<a href="http://viewvc.tigris.org/">Project Page</a> |
|
||||
<a href="./download.html">Download</a> |
|
||||
<a href="./upgrading.html">Upgrading</a> |
|
||||
<a href="./contributing.html">Contributing</a> |
|
||||
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
|
||||
<a href="./contact.html">Contact</a> |
|
||||
<a href="./who.html">About</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table id="pagetable">
|
||||
<tr>
|
||||
<td id="pagecolumn1">
|
||||
|
||||
<h4>On this page:</h4>
|
||||
|
||||
<ul id="bookmarks">
|
||||
<li><a href="#sec-getting-started">Getting Started</a></li>
|
||||
<li><a href="#sec-testing">Testing and Reporting</a></li>
|
||||
<li><a href="#sec-coding-style">Coding Style</a></li>
|
||||
<li><a href="#sec-patches">Submitting Patches</a></li>
|
||||
<li><a href="#sec-security">Security</a></li>
|
||||
<li><a href="#sec-adding-features">Adding Features</a></li>
|
||||
<li><a href="#sec-templates">Hacking on Templates</a></li>
|
||||
<li><a href="#sec-releasing">Release Management</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Group</a></address>
|
||||
|
||||
</td>
|
||||
<td id="pagecolumn2">
|
||||
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-getting-started">Getting Started</h2>
|
||||
|
||||
<p>Some basic knowledge about <a
|
||||
href="http://www.python.org">Python</a> and development tools like
|
||||
<code>diff</code> is required. Your best bet is to start with a
|
||||
fresh source code snapshot, which you may obtain from our
|
||||
Subversion repository (see instructions <a
|
||||
href="./download.html#sec-subversion">here</a>).</p>
|
||||
|
||||
<p>Version control history can be obtained using Subversion clients,
|
||||
but is also browsable using <a
|
||||
href="http://viewvc.tigris.org/source/browse/viewvc/trunk/"
|
||||
>tigris.org's integrated ViewVC tool</a>.</p>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-testing">Testing and Reporting</h2>
|
||||
|
||||
<p>Testing usability and the installation process on different
|
||||
platforms is also a valuable contribution. Please report your
|
||||
results back to us developers. Bandwidth is getting cheaper daily,
|
||||
so don't be afraid — in fact, feel encouraged — to dump
|
||||
as much detail about the problems you are seeing as possible into
|
||||
your bug reports. Here are some things you definitely should
|
||||
try to include:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>What version of ViewVC you are using (if you are using a source
|
||||
snapshot, tell us the date of that snapshot).</li>
|
||||
|
||||
<li>What operating system your ViewVC is running on.</li>
|
||||
|
||||
<li>What version of Python you are using.</li>
|
||||
|
||||
<li>Whether you are running ViewVC standalone, or as a CGI program
|
||||
under a web server (and if so, what web server).</li>
|
||||
|
||||
<li>The URL of your ViewVC instantiation, if it is public.
|
||||
Sometimes, letting developers see the problem for themselves can
|
||||
save everyone alot of time.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-coding-style">Coding Style</h2>
|
||||
|
||||
<p>Unlike its predecessor, CvsWeb, ViewVC is written in Python, so it
|
||||
doesn't suffer from the "unmaintainable code effect" that hits most
|
||||
Perl projects sooner or later:</p>
|
||||
|
||||
<blockquote><em>"[Perl] combines all the worst aspects of C and Lisp: a
|
||||
billion different sublanguages in one monolithic executable. It
|
||||
combines the power of C with the readability of PostScript."</em>
|
||||
— Jamie Zawinski
|
||||
</blockquote>
|
||||
|
||||
<p>Of course, a symphony of insanity can be composed in any language,
|
||||
so we do try to stick to some basic guiding principles. Maintain
|
||||
whatever style is present in the code being modified. New code can
|
||||
use anything sane (which generally means <a
|
||||
href="http://python.sourceforge.net/peps/pep-0008.html">PEP 8</a>).
|
||||
Our only real peeve is if someone writes a function call as:
|
||||
<code>some_func (args)</code> — that space between the
|
||||
function name and opening parenthesis is Huge Badness. Oh, and we
|
||||
do <strong>not</strong> use Subversion keywords (such as
|
||||
<code>$</code><code>Id$</code>) within the source.</p>
|
||||
|
||||
<p>Otherwise… <em>shrug</em>.</p>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-patches">Submitting Patches</h2>
|
||||
|
||||
<p>Nothing speaks more loudly when bugs or features are the topic than
|
||||
a patch. And quite frankly, sometimes if you want something done,
|
||||
you gotta do it yourself. So, patches are always welcome. If you
|
||||
aren't sure what exactly a "patch" is, or don't know how
|
||||
to generate one, but you've got code contributions to make, please
|
||||
don't hesitate to ask questions on the mailing lists. Patch
|
||||
generation and application are pretty easy thing to get the hang of,
|
||||
and drastically simplify code submission and review.</p>
|
||||
|
||||
<p>Please use the <a
|
||||
href="http://viewvc.tigris.org/servlets/ProjectIssues">Issue
|
||||
Tracker</a> to submit your patches. Unified contextual diffs
|
||||
against the latest development snapshot are preferred.</p>
|
||||
|
||||
<p>If you have commit access, then you should know what you're doing.
|
||||
Just make changes directly. Subscribing to the <a
|
||||
href="http://viewvc.tigris.org/servlets/ProjectMailingListList"
|
||||
><tt>dev@</tt> developer mailing list</a> is recommended in any
|
||||
case.</p>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-security">Security</h2>
|
||||
|
||||
<p>Since ViewVC is used on the Internet, security is a major concern.
|
||||
If you need to pass data from the request into an external program,
|
||||
please don't use <code>os.system()</code> or
|
||||
<code>os.popen()</code>. Please use the module
|
||||
<code>lib/popen.py</code> that is included in the ViewVC
|
||||
distribution instead.</p>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-adding-features">Adding Features</h2>
|
||||
|
||||
<p>If you need a new configuration option think carefully, into which
|
||||
section it belongs. Try to keep the content of
|
||||
<code>cgi/viewvc.conf.dist</code> file and the library module
|
||||
<code>lib/config.py</code> in sync.</p>
|
||||
|
||||
<p>Because ViewVC is a Web-based application, people will have ViewVC
|
||||
URLs hyperlinked from other sites, embedded in emails, bookmarked
|
||||
in their browsers, etc. It is very important to ensure that those
|
||||
URLs continue to retrieve the information they were intended to
|
||||
retrieve even if ViewVC is upgraded on the hosting server. In
|
||||
other words, as new features require modifications to the <a
|
||||
href="./url-reference.html">ViewVC URL schema</a>, make sure those
|
||||
modifications preserve the existing functionality of all ViewVC
|
||||
URLs.</p>
|
||||
|
||||
<p>The library subdirectory contains a module <code>debug.py</code>,
|
||||
which you may find useful for performance testing.</p>
|
||||
|
||||
<p>If a new file or module is added, a new line in the installer
|
||||
program <code>viewvc-install</code> is required.</p>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-templates">Hacking on Templates</h2>
|
||||
|
||||
<p>The library module <code>ezt.py</code> contains a module docstring
|
||||
which describes the directives used in the HTML templates used by
|
||||
ViewVC. The templates themselves can be found in the
|
||||
<code>templates</code> subdirectory. We're currently developing a
|
||||
how-to guide for <a href="./template-authoring-guide.html">ViewVC
|
||||
template customization</a>.</p>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-releasing">Release Management</h2>
|
||||
|
||||
<p>There is a script, <code>tools/make-release</code>, which creates a
|
||||
release directory and the various archive files that we distribute.
|
||||
All other steps required to get a ViewVC release out of the door
|
||||
require manual execution (currently by C. Michael Pilato). Those
|
||||
steps are as follows:</p>
|
||||
|
||||
<ol>
|
||||
|
||||
<li>Add a new subsection to the file
|
||||
<code>website/upgrading.html</code> describing all user visible
|
||||
changes for users of previous releases of ViewVC.</li>
|
||||
|
||||
<li>Update the <code>CHANGES</code> file</li>
|
||||
|
||||
<li>Update the <code>website/index.html</code> file to refer to the
|
||||
new X.Y files. (there are three links to update)</li>
|
||||
|
||||
<li>Edit the file <code>lib/viewvc.py</code> and remove the
|
||||
<tt>"-dev"</tt> suffix from <code>__version__</code>. The
|
||||
remainder should be of the form X.Y.Z, where X, Y, and Z are
|
||||
positive integers.</li>
|
||||
|
||||
<li>Ensure all of the above changes have been committed.</li>
|
||||
|
||||
<li>Test, Test, Test! At the time of this writing (1.0-dev) there
|
||||
is no automatic testsuite available. So just run with
|
||||
permuting different <code>viewvc.conf</code> settings…
|
||||
and pray.</li>
|
||||
|
||||
<li>Review any open <a
|
||||
href="http://viewvc.tigris.org/servlets/ProjectIssues">bug
|
||||
reports.</a></li>
|
||||
|
||||
<li>Use <code>svn cp</code> to tag the release to
|
||||
<code>/tags/<i>X</i>.<i>Y</i>.<i>Z</i></code>, where
|
||||
<i>X</i>, <i>Y</i>, and <i>Z</i> should be replaced by the
|
||||
release number from above. If a developer is willing to
|
||||
volunteer as a bug fix patch release manager, it is now
|
||||
possible to start here at this point with a feature-frozen
|
||||
branch using <code>svn cp</code> to copy the tag to
|
||||
<code>/branches/<i>X</i>.<i>Y</i>.x</code>.</li>
|
||||
|
||||
<li>Go into an empty directory and run <code>tools/make-release
|
||||
viewvc-<i>X.Y.Z</i> <i>X.Y.Z</i></code>. This step requires
|
||||
read access to the Subversion source code repository.</li>
|
||||
|
||||
<li>Upload the created archive files (tar.gz and zip) into the
|
||||
Files and Documents section of the Tigris.org project.</li>
|
||||
|
||||
<li>Edit the file <code>lib/viewvc.py</code> again and this time
|
||||
increment the <code>__version__</code> for the next release
|
||||
cycle, again append the <code>-dev</code> to the version and
|
||||
again <code>svn commit -m "Begin a new release cycle."
|
||||
lib/viewvc.py</code>.</li>
|
||||
|
||||
<li>Write an announcement explaining all the cool new features and
|
||||
post it <a
|
||||
href="mailto:announce@viewvc.tigris.org">announce@viewvc.tigris.org</a>,
|
||||
to the project's News area, and to other places interested in
|
||||
this sort of stuff (such as <a
|
||||
href="http://www.freshmeat.net">Freshmeat</a>).</p>
|
||||
|
||||
</ol>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@@ -1,79 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>ViewVC: Download</title>
|
||||
<link rel="stylesheet" type="text/css" href="./styles.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="title">
|
||||
<a href="http://www.viewvc.org/"><img
|
||||
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
|
||||
</div>
|
||||
|
||||
<div id="menu">
|
||||
<p><a href="./index.html">Home</a> |
|
||||
<a href="http://viewvc.tigris.org/">Project Page</a> |
|
||||
<a href="./download.html">Download</a> |
|
||||
<a href="./upgrading.html">Upgrading</a> |
|
||||
<a href="./contributing.html">Contributing</a> |
|
||||
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
|
||||
<a href="./contact.html">Contact</a> |
|
||||
<a href="./who.html">About</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table id="pagetable">
|
||||
<tr>
|
||||
<td id="pagecolumn1">
|
||||
|
||||
<h4>On this page:</h4>
|
||||
|
||||
<ul id="bookmarks">
|
||||
<li><a href="#sec-download">Downloading</a></li>
|
||||
<li><a href="#sec-subversion">Subversion</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Group</a></address>
|
||||
|
||||
</td>
|
||||
<td id="pagecolumn2">
|
||||
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-download">Downloading</h2>
|
||||
|
||||
<p>You can download the ViewVC (and the older ViewCVS releases, too)
|
||||
from our <a
|
||||
href="http://viewvc.tigris.org/servlets/ProjectDocumentList?folderID=6004"
|
||||
>File and Documents</a> area. For information about what has
|
||||
changed in each release, see the <a
|
||||
href="http://viewvc.tigris.org/source/browse/viewvc/trunk/CHANGES?rev=HEAD"
|
||||
>CHANGES</a> file.</p>
|
||||
|
||||
<p>We are also making <a href="./nightly/">nightly snapshots</a>
|
||||
available in tar.gz and zip formats.</p>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-subversion">Subversion</h2>
|
||||
|
||||
<p>The source code for ViewVC is maintained in a Subversion repository
|
||||
at Tigris.org. You can checkout the trunk of our development tree
|
||||
from <a href="http://viewvc.tigris.org/svn/viewvc/trunk/"
|
||||
><tt>http://viewvc.tigris.org/svn/viewvc/trunk/</tt></a>. You'll
|
||||
need to provide your Tigris.org username and password when so
|
||||
prompted, or, if you don't have a Tigris.org account, use "guest"
|
||||
as both the username and password.</p>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 30 KiB |
Binary file not shown.
@@ -1,192 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>ViewVC: Repository Browsing</title>
|
||||
<link rel="stylesheet" type="text/css" href="./styles.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="title">
|
||||
<a href="http://www.viewvc.org/"><img
|
||||
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
|
||||
</div>
|
||||
|
||||
<div id="menu">
|
||||
<p><a href="./index.html">Home</a> |
|
||||
<a href="http://viewvc.tigris.org/">Project Page</a> |
|
||||
<a href="./download.html">Download</a> |
|
||||
<a href="./upgrading.html">Upgrading</a> |
|
||||
<a href="./contributing.html">Contributing</a> |
|
||||
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
|
||||
<a href="./contact.html">Contact</a> |
|
||||
<a href="./who.html">About</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table id="pagetable">
|
||||
<tr>
|
||||
<td id="pagecolumn1">
|
||||
|
||||
<h4>On this page:</h4>
|
||||
|
||||
<ul id="bookmarks">
|
||||
<li><a href="#sec-what-is-viewvc">What Is ViewVC?</a></li>
|
||||
<li><a href="#sec-requirements">Requirements</a></li>
|
||||
<li><a href="#sec-future">Future Plans</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Group</a></address>
|
||||
|
||||
</td>
|
||||
<td id="pagecolumn2">
|
||||
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-what-is-viewvc">What Is ViewVC?</h2>
|
||||
|
||||
<p>ViewVC is a browser interface for CVS and Subversion version
|
||||
control repositories. It generates templatized HTML to present
|
||||
navigable directory, revision, and change log listings. It can
|
||||
display specific versions of files as well as diffs between those
|
||||
versions. Basically, ViewVC provides the bulk of the report-like
|
||||
functionality you expect out of your version control tool, but much
|
||||
more prettily than the average textual command-line program
|
||||
output.</p>
|
||||
|
||||
<p>Here are some of the additional features of ViewVC:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>Support for filesystem-accessible CVS and Subversion repositories.</li>
|
||||
|
||||
<li>Individually configurable virtual host support.</li>
|
||||
|
||||
<li>Line-based annotation/blame display.</li>
|
||||
|
||||
<li>Revision graph capabilities (via integration with <a
|
||||
href="http://www.akhphd.au.dk/~bertho/cvsgraph/">CvsGraph</a>)
|
||||
(<em>CVS only</em>).</li>
|
||||
|
||||
<li>Syntax highlighting support (via integration with <a
|
||||
href="http://www.codento.com/people/mtr/genscript/">GNU
|
||||
enscript</a> or
|
||||
<a href="http://www.andre-simon.de/">Highlight</a>).</li>
|
||||
|
||||
<li><a href="http://www.mozilla.org/projects/bonsai/">Bonsai</a>-like
|
||||
repository query facilities.</li>
|
||||
|
||||
<li>Template-driven output generation.</li>
|
||||
|
||||
<li>Colorized, side-by-side differences.</li>
|
||||
|
||||
<li>Tarball generation (by tag/branch for CVS, by revision for
|
||||
Subversion).</li>
|
||||
|
||||
<li>I18N support based on the Accept-Language request header.</li>
|
||||
|
||||
<li>Ability to run either as CGI script or as a standalone
|
||||
server.</li>
|
||||
|
||||
<li>Regexp-based file searching.</li>
|
||||
|
||||
<li>INI-like configuration file (as opposed to requiring actual code
|
||||
tweaks).</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p>For a complete list of changes present in each release, see
|
||||
ViewVC's <a
|
||||
href="http://viewvc.tigris.org/source/browse/viewvc/trunk/CHANGES?rev=HEAD"
|
||||
>CHANGES</a> file.</p>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-requirements">Requirements</h2>
|
||||
|
||||
<p>The only hard software requirement for running ViewVC is <a
|
||||
href="http://www.python.org/">Python 1.5.2</a> or later. All other
|
||||
requirements depend on what you want to do with the tool.</p>
|
||||
|
||||
<p>If you plan to use ViewVC with CVS repositories, you need the
|
||||
following things:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><a href="http://www.cs.purdue.edu/homes/trinkle/RCS/">RCS</a>
|
||||
(Revision Control System)</li>
|
||||
|
||||
<li><a href="http://www.gnu.org/software/diffutils/diffutils.html">GNU
|
||||
diff</a></li>
|
||||
|
||||
<li>Read-only, physical access to a CVS repository.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p>For use with Subversion repositories, you need these things:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><a href="http://subversion.tigris.org/">Subversion</a> 1.2 or
|
||||
later and its SWIG Python bindings.</li>
|
||||
|
||||
<li><a href="http://www.gnu.org/software/diffutils/diffutils.html">GNU
|
||||
diff</a></li>
|
||||
|
||||
<li>Physical access to a Subversion repository (though there is
|
||||
limited, use-at-your-risk support for remote access, too).</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<p>ViewVC integrates with additional pieces of software to provide
|
||||
certain bits of optional functionality:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><a href="http://www.mysql.com/">MySQL</a> — Needed to use
|
||||
the commit database query functionality.</li>
|
||||
|
||||
<li><a href="http://www.codento.com/people/mtr/genscript/">GNU
|
||||
enscript</a> — Needed for syntax highlighting in versioned
|
||||
file contents displays</li>
|
||||
|
||||
<li><a href="http://www.akhphd.au.dk/~bertho/cvsgraph/">CvsGraph</a>
|
||||
— Needed for version graph displays.</li>
|
||||
|
||||
<li><a href="http://httpd.apache.org/">Apache HTTP Server</a>, or
|
||||
another server capable of running CGI programs — unless
|
||||
you just want ViewVC to run in standalone server mode.</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-future">Future Plans</h2>
|
||||
|
||||
<p>ViewVC is an Open Source project. So any future development
|
||||
depends on the <a href="./contributing.html">contributions</a> that
|
||||
will be made by its user community. Certainly working patches have
|
||||
a greater chance to become realized quickly than feature requests,
|
||||
but please don't hesitate to submit your suggestions to our <a
|
||||
href="http://viewvc.tigris.org/servlets/ProjectIssues">issue
|
||||
tracker</a>.</p>
|
||||
|
||||
<p>Some things we're thinking about include:</p>
|
||||
|
||||
<ul>
|
||||
<li>UI streamlining/simplification.</li>
|
||||
<li>Integration with CVS and Subversion commit mail scripts.</li>
|
||||
<li>Integration with an indexer such as LXR.</li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
@@ -1,95 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
DATE=`date +"%Y%m%d"`
|
||||
EXPORTDIR="viewvc-${DATE}"
|
||||
PUBLISH_DIR=/www/viewvc/nightly
|
||||
|
||||
# export HEAD of trunk
|
||||
svn export --quiet http://viewvc.tigris.org/svn/viewvc/trunk ${EXPORTDIR} --username guest --password ""
|
||||
|
||||
# use Python to determine the version number, reading it from
|
||||
# viewvc.__version__
|
||||
cd $EXPORTDIR/lib
|
||||
VERSION=`python -c "import viewvc; print viewvc.__version__"`
|
||||
TARGET=viewvc-${VERSION}-${DATE}
|
||||
|
||||
# make a release
|
||||
cd ../tools
|
||||
./make-release ${TARGET}
|
||||
|
||||
# remove results of last build
|
||||
rm -rf ${PUBLISH_DIR}/viewvc*.tar.gz ${PUBLISH_DIR}/viewvc*.zip ${PUBLISH_DIR}/index.html
|
||||
|
||||
# publish new build
|
||||
mv ${TARGET}.* ${PUBLISH_DIR}
|
||||
cd ../..
|
||||
|
||||
cat > ${PUBLISH_DIR}/index.html <<EOF
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>ViewVC: Nightly Snapshots</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<link rel="stylesheet" type="text/css" href="../styles.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="title">
|
||||
<a href="http://www.viewvc.org/"><img
|
||||
src="../images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
|
||||
</div>
|
||||
|
||||
<div id="menu">
|
||||
<p><a href="../index.html">Home</a> |
|
||||
<a href="http://viewvc.tigris.org/">Project Page</a> |
|
||||
<a href="../download.html">Download</a> |
|
||||
<a href="../contributing.html">Contributing</a> |
|
||||
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
|
||||
<a href="../contact.html">Contact</a> |
|
||||
<a href="../who.html">About</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table id="pagetable">
|
||||
<tr>
|
||||
<td id="pagecolumn1">
|
||||
|
||||
<h4>On this page:</h4>
|
||||
|
||||
<ul id="bookmarks">
|
||||
<li><a href="#sec-snapshots">Snapshots</a></li>
|
||||
</ul>
|
||||
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img
|
||||
src="http://www.w3.org/Icons/valid-xhtml10"
|
||||
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
|
||||
</p>
|
||||
|
||||
</td>
|
||||
<td id="pagecolumn2">
|
||||
|
||||
<div class="section">
|
||||
|
||||
<h2 id="sec-snapshots">Snapshots</h2>
|
||||
|
||||
<ul>
|
||||
EOF
|
||||
|
||||
echo "<li><a href=\"${TARGET}.tar.gz\">${TARGET}.tar.gz</a></li>" >> ${PUBLISH_DIR}/index.html
|
||||
echo "<li><a href=\"${TARGET}.zip\">${TARGET}.zip</a></li>" >> ${PUBLISH_DIR}/index.html
|
||||
|
||||
cat >> ${PUBLISH_DIR}/index.html <<EOF
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# more cleanup
|
||||
rm -rf ${EXPORTDIR}
|
@@ -1,151 +0,0 @@
|
||||
body {
|
||||
background-color: rgb(180,193,205);
|
||||
background-image: url('./images/bg-grad.jpg');
|
||||
background-repeat: repeat-x;
|
||||
color: black;
|
||||
font-family: arial, sans-serif;
|
||||
font-size: 90%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#title {
|
||||
background-color: rgb(100,128,150);
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 95%;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
address {
|
||||
text-align: center;
|
||||
font-size: 60%;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
h2 {
|
||||
background-color: rgb(204,213,221);
|
||||
padding: 2px 0.5em 2px 0.5em;
|
||||
margin: 0;
|
||||
border-bottom: dotted 1px rgb(180,193,205);
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
h3 {
|
||||
padding: 2px 0.5em 2px 0.5em;
|
||||
margin: 0;
|
||||
font-size: 100%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h4 {
|
||||
padding: 2px 0.5em 2px 0.5em;
|
||||
margin: 0;
|
||||
font-size: 90%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
p, dl, ul, ol {
|
||||
padding: 0.5em;
|
||||
margin: 0;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
padding: 0.5em;
|
||||
margin: 0 0 0 0.25in;
|
||||
}
|
||||
|
||||
li {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
code {
|
||||
font-size: 105%;
|
||||
font-style: italic;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
padding: 0.5em;
|
||||
margin: 0 0.25in 0 0.25in;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
.section {
|
||||
background: white;
|
||||
border-color: rgb(24,24,24);
|
||||
border-width: 1px 2px 2px 1px;
|
||||
border-style: solid;
|
||||
padding: 0;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
#menu {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#menu a, #menu a:visited {
|
||||
background: black;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#menu a:hover {
|
||||
background: black;
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#submenu {
|
||||
background: rgb(90%,97%,99%);
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
#pagetable tr {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
#pagetable {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#pagecolumn1 {
|
||||
width: 175px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#pagecolumn1 a, #pagecolumn1 a:visited {
|
||||
color: rgb(0,0,164);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#pagecolumn1 a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#pagecolumn2 {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#pagecolumn2 a, #pagecolumn2 a:visited {
|
||||
color: rgb(0,0,164);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#pagecolumn2 a:hover {
|
||||
background-color: rgb(180,193,205);
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#bookmarks {
|
||||
padding-left: 0.25in;
|
||||
font-size: 80%;
|
||||
white-space: nowrap;
|
||||
}
|
@@ -1,159 +0,0 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>ViewVC: About</title>
|
||||
<link rel="stylesheet" type="text/css" href="./styles.css"/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="title">
|
||||
<a href="http://www.viewvc.org/"><img
|
||||
src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
|
||||
</div>
|
||||
|
||||
<div id="menu">
|
||||
<p><a href="./index.html">Home</a> |
|
||||
<a href="http://viewvc.tigris.org/">Project Page</a> |
|
||||
<a href="./download.html">Download</a> |
|
||||
<a href="./upgrading.html">Upgrading</a> |
|
||||
<a href="./contributing.html">Contributing</a> |
|
||||
<a href="http://viewvc.tigris.org/nonav/source/browse/*checkout*/viewvc/trunk/LICENSE.html">License</a> |
|
||||
<a href="./contact.html">Contact</a> |
|
||||
<a href="./who.html">About</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<table id="pagetable">
|
||||
<tr>
|
||||
<td id="pagecolumn1">
|
||||
|
||||
<h4>On this page:</h4>
|
||||
|
||||
<ul id="bookmarks">
|
||||
<li><a href="#sec-history">The History of ViewVC</a></li>
|
||||
<li><a href="#sec-viewcvs-group">The ViewCVS Group</a></li>
|
||||
<li><a href="#sec-site-credits">About This Site</a></li>
|
||||
</ul>
|
||||
|
||||
<hr/>
|
||||
|
||||
<address><a href="mailto:users@viewvc.tigris.org">ViewVC Users Group</a></address>
|
||||
|
||||
</td>
|
||||
<td id="pagecolumn2">
|
||||
|
||||
<div class="section">
|
||||
<h2 id="sec-history">The History of ViewVC</h2>
|
||||
|
||||
<p>The ViewVC software was inspired by <a
|
||||
href="http://people.freebsd.org/~fenner/cvsweb/">cvsweb</a>
|
||||
(originally written by Bill Fenner and then further developed by <a
|
||||
href="mailto:zeller@think.de">Henner Zeller</a>). Greg Stein
|
||||
wanted to make some changes and updates, but cvsweb was implemented
|
||||
in Perl. He wrote:</p>
|
||||
|
||||
<blockquote style="font-style: italic;">"While I can manage some
|
||||
Perl, cvsweb was rather unmaintainable for me. So I undertook the
|
||||
task to convert the software to Python. As a result, I've actually
|
||||
been able to go <em>way</em> beyond the simple changes that I had
|
||||
envisioned."</blockquote>
|
||||
|
||||
<p>So ViewVC started out as just a port of the cvsweb script,
|
||||
originally called ViewCVS. Along the way, it has had numerous
|
||||
cleanups and other modifications, a process simplified by the
|
||||
elegance of the <a href="http://www.python.org/">Python</a>
|
||||
language.</p>
|
||||
|
||||
<p>In 2001, the ViewCVS project was moved to <a
|
||||
href="http://www.sourceforge.net">SourceForge</a>, a popular
|
||||
software collaboration environment. There the project continued to
|
||||
mature, releasing several stable-yet-pre-1.0 versions. In 2002,
|
||||
C. Michael Pilato began implementing support for Subversion in
|
||||
ViewCVS, building atop the beginnings of a version control
|
||||
abstraction layer begun by Lucas Bruand. Along the way, Russell
|
||||
Yanofsky delivered large improvements to that abstraction, and to
|
||||
ViewCVS as whole. ViewCVS was well on its way to releasing a 1.0
|
||||
version.</p>
|
||||
|
||||
<p>Of course, now that ViewCVS could browse Subversion repositories as
|
||||
easily as CVS ones, the ViewCVS name seemed inappropriate. Also,
|
||||
SourceForge's lack of support for Subversion (which was already
|
||||
well past its 1.0 release, and becoming hugely popular) in its
|
||||
project version control offerings was annoying ViewCVS primary
|
||||
developers. So in late 2005, the decision was made to rename the
|
||||
project to ViewVC, to convert the project's CVS data to Subversion,
|
||||
and to move the project and its Subversion data to <a
|
||||
href="http://www.tigris.org">Tigris.org</a>.</p>
|
||||
|
||||
<p>Today, ViewVC is being developed at <a
|
||||
href="http://viewvc.tigris.org">http://viewvc.tigris.org</a> by a
|
||||
small community of folks</a>.</p>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2 id="sec-viewcvs-group">The ViewCVS Group</h2>
|
||||
|
||||
<p>The ViewCVS Group is an informal group of people working on and
|
||||
developing the ViewVC package. The current set of members are
|
||||
listed below with some of their notable contributions:</p>
|
||||
|
||||
<dl>
|
||||
<dt><a href="http://www.lyra.org/greg/">Greg Stein</a></dt>
|
||||
<dd>original python port of Henner Zeller's cvsweb, secure popen
|
||||
implementation, configuration file implementation, rcsparse
|
||||
module, and EZT template engine</dd>
|
||||
|
||||
<dt>Jay Painter</dt>
|
||||
<dd>CVSdb query engine</dd>
|
||||
|
||||
<dt>Tanaka Akira</dt>
|
||||
<dd>enscript colorization and tarball generation
|
||||
</dd>
|
||||
|
||||
<dt>Tim Cera</dt>
|
||||
<dd>CvsGraph support, log_table template, regular expression search,
|
||||
and paging capability</dd>
|
||||
|
||||
<dt>Peter Funk</dt>
|
||||
<dd>standalone server, blimp logo, and numerous improvements to
|
||||
ViewVC's interfaces and documentation</dd>
|
||||
|
||||
<dt>Lucas Bruand</dt>
|
||||
|
||||
<dd>C++ RCS parser (tparse) and vclib module for supporting new
|
||||
version control systems</dd>
|
||||
|
||||
<dt><a href="http://www.cmichaelpilato.com/">C. Michael Pilato</a></dt>
|
||||
<dd>Subversion support, root_as_url alternative URL scheme,
|
||||
templatization work, website design, documentation</dd>
|
||||
|
||||
<dt>Russell Yanofsky</dt>
|
||||
<dd>Windows support and the sapi module for supporting multiple web
|
||||
server interfaces, sweeping abstraction and UI improvements</dd>
|
||||
|
||||
<dt>James Henstridge</dt>
|
||||
<dd>integrated query interface, support for querying Subversion
|
||||
repositories, caching support, CSS formatting, and the EZT
|
||||
"define" directive</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2 id="sec-site-credits">About This Site</h2>
|
||||
|
||||
<p>The ViewVC website was designed by <a
|
||||
href="http://www.cmichaelpilato.com/">C. Michael Pilato</a>. All
|
||||
HTML was hand-edited in Emacs, and the little splashes of graphical
|
||||
goodness owe their existence to Adobe PhotoShop. Textual content
|
||||
for the site is mostly the work of Greg Stein, but has been tweaked
|
||||
through the ages by various ViewVC contributors.</p>
|
||||
|
||||
</div>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user