mirror of
https://github.com/vitalif/viewvc-4intranet
synced 2019-04-16 04:14:59 +03:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1f399bbd6d |
28
CHANGES
28
CHANGES
@@ -1,28 +1,3 @@
|
||||
Version 1.1.14 (released 12-Jun-2012)
|
||||
|
||||
* fix annotation of svn files with non-URI-safe paths (issue #504)
|
||||
* handle file:/// Subversion rootpaths as local roots (issue #446)
|
||||
* fix bug caused by trying to case-normalize anon usernames (issue #505)
|
||||
* speed up log handling by reusing tokenization results (issue #506)
|
||||
* add support for custom review log markup rules (issue #429)
|
||||
|
||||
Version 1.1.13 (released 23-Jan-2012)
|
||||
|
||||
* fix svndbadmin failure on deleted paths under Subversion 1.7 (issue #499)
|
||||
* fix annotation of files in svn roots with non-URI-safe paths
|
||||
* fix stray annotation warning in markup display of images
|
||||
* more gracefully handle attempts to display binary content (issue #501)
|
||||
|
||||
Version 1.1.12 (released 03-Nov-2011)
|
||||
|
||||
* fix path display in patch and certain diff views (issue #485)
|
||||
* fix broken cvsdb glob searching (issue 486)
|
||||
* allow svn revision specifiers to have leading r's (issue #441, #448)
|
||||
* allow environmental override of configuration location (issue #494)
|
||||
* fix exception HTML-escaping non-string data under WSGI (issue #454)
|
||||
* add links to root logs from roots view (issue #470)
|
||||
* use Pygments lexer-guessing functionality (issue #495)
|
||||
|
||||
Version 1.1.11 (released 17-May-2011)
|
||||
|
||||
* security fix: remove user-reachable override of cvsdb row limit
|
||||
@@ -31,7 +6,7 @@ Version 1.1.11 (released 17-May-2011)
|
||||
* fix stack trace when asked to checkout a directory (issue #478)
|
||||
* improve memory usage and speed of revision log markup (issue #477)
|
||||
* fix broken annotation view in CVS keyword-bearing files (issue #479)
|
||||
* warn users when query results are incomplete (issue #433)
|
||||
* warn users when query results are incomplete (issue #443)
|
||||
* avoid parsing errors on RCS newphrases in the admin section (issue #483)
|
||||
* make rlog parsing code more robust in certain error cases (issue #444)
|
||||
|
||||
@@ -46,6 +21,7 @@ Version 1.1.9 (released 18-Feb-2011)
|
||||
* make revision log "extra pages" count configurable
|
||||
* fix Subversion 1.4.x revision log compatibility code regression
|
||||
* display sanitized error when authzfile is malformed
|
||||
* handle file:/// Subversion rootpaths as local roots (issue #446)
|
||||
* restore markup of URLs in file contents (issue #455)
|
||||
* optionally display last-committed metadata in roots view (issue #457)
|
||||
|
||||
|
55
INSTALL
55
INSTALL
@@ -34,7 +34,7 @@ Congratulations on getting this far. :-)
|
||||
(http://www.python.org/)
|
||||
* Subversion, Version Control System, 1.3.1 or later
|
||||
(binary installation and Python bindings)
|
||||
(http://subversion.apache.org/)
|
||||
(http://subversion.tigris.org/)
|
||||
|
||||
Optional:
|
||||
|
||||
@@ -176,24 +176,7 @@ APACHE CONFIGURATION
|
||||
or /etc/local. Use the vendor documentation or the find utility if
|
||||
in doubt.
|
||||
|
||||
2) Depending on how your Apache configuration is setup by default, you
|
||||
might need to explicitly allow high-level access to the ViewVC
|
||||
install location.
|
||||
|
||||
<Directory <VIEWVC_INSTALLATION_DIRECTORY>>
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
For example, if ViewVC is installed in /usr/local/viewvc-1.0 on
|
||||
your system:
|
||||
|
||||
<Directory /usr/local/viewvc-1.0>
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
3) Configure Apache to expose ViewVC to users at the URL of your choice.
|
||||
2) Configure Apache to expose ViewVC to users at the URL of your choice.
|
||||
|
||||
ViewVC provides several different ways to do this. Choose one of
|
||||
the following methods:
|
||||
@@ -204,13 +187,13 @@ APACHE CONFIGURATION
|
||||
The ScriptAlias directive is very useful for pointing
|
||||
directly to the viewvc.cgi script. Simply insert a line containing
|
||||
|
||||
ScriptAlias /viewvc <VIEWVC_INSTALLATION_DIRECTORY>/bin/cgi/viewvc.cgi
|
||||
ScriptAlias /viewvc <VIEWVC_INSTALLATION_DIRECTORY>/bin/cgi/viewvc.cgi
|
||||
|
||||
into your httpd.conf file. Choose the location in httpd.conf where
|
||||
also the other ScriptAlias lines reside. Some examples:
|
||||
|
||||
ScriptAlias /viewvc /usr/local/viewvc-1.0/bin/cgi/viewvc.cgi
|
||||
ScriptAlias /query /usr/local/viewvc-1.0/bin/cgi/query.cgi
|
||||
ScriptAlias /viewvc /usr/local/viewvc-1.0/bin/cgi/viewvc.cgi
|
||||
ScriptAlias /query /usr/local/viewvc-1.0/bin/cgi/query.cgi
|
||||
|
||||
----------------------------------------
|
||||
METHOD B: CGI mode in cgi-bin directory
|
||||
@@ -218,10 +201,6 @@ APACHE CONFIGURATION
|
||||
Copy the CGI scripts from
|
||||
<VIEWVC_INSTALLATION_DIRECTORY>/bin/cgi/*.cgi
|
||||
to the /cgi-bin/ directory configured in your httpd.conf file.
|
||||
|
||||
You can override configuration file location using:
|
||||
|
||||
SetEnv VIEWVC_CONF_PATHNAME /etc/viewvc.conf
|
||||
|
||||
------------------------------------------
|
||||
METHOD C: CGI mode in ExecCGI'd directory
|
||||
@@ -231,8 +210,8 @@ APACHE CONFIGURATION
|
||||
to the directory of your choosing in the Document Root adding the following
|
||||
Apache directives for the directory in httpd.conf or an .htaccess file:
|
||||
|
||||
Options +ExecCGI
|
||||
AddHandler cgi-script .cgi
|
||||
Options +ExecCGI
|
||||
AddHandler cgi-script .cgi
|
||||
|
||||
Note: For this to work mod_cgi has to be loaded. And for the .htaccess file
|
||||
to be effective, "AllowOverride All" or "AllowOverride Options FileInfo"
|
||||
@@ -248,10 +227,6 @@ APACHE CONFIGURATION
|
||||
In httpd.conf, make sure that "AllowOverride All" or at least
|
||||
"AllowOverride FileInfo Options" are enabled for the directory
|
||||
you copied the files to.
|
||||
|
||||
You can override configuration file location using:
|
||||
|
||||
SetEnv VIEWVC_CONF_PATHNAME /etc/viewvc.conf
|
||||
|
||||
Note: If you are using Mod_Python under Apache 1.3 the tarball generation
|
||||
feature may not work because it uses multithreading. This works fine
|
||||
@@ -303,6 +278,13 @@ APACHE CONFIGURATION
|
||||
ScriptAlias /viewvc /usr/local/viewvc/bin/wsgi/viewvc.fcgi
|
||||
ScriptAlias /query /usr/local/viewvc/bin/wsgi/query.fcgi
|
||||
|
||||
3) Restart Apache.
|
||||
|
||||
The commands to do this vary. "httpd -k restart" and "apache -k
|
||||
restart" are two common variants. On RedHat Linux it is done using
|
||||
the command "/sbin/service httpd restart" and on SuSE Linux it is
|
||||
done with "rcapache restart". Other systems use "apachectl restart".
|
||||
|
||||
4) [Optional] Add access control.
|
||||
|
||||
In your httpd.conf you can control access to certain modules by
|
||||
@@ -324,14 +306,7 @@ APACHE CONFIGURATION
|
||||
http://<server_name>/viewvc/~checkout~/<module_name>
|
||||
http://<server_name>/viewvc/<module_name>.tar.gz?view=tar
|
||||
|
||||
5) Restart Apache.
|
||||
|
||||
The commands to do this vary. "httpd -k restart" and "apache -k
|
||||
restart" are two common variants. On RedHat Linux it is done using
|
||||
the command "/sbin/service httpd restart" and on SuSE Linux it is
|
||||
done with "rcapache restart". Other systems use "apachectl restart".
|
||||
|
||||
6) Optional: Protect your ViewVC instance from server-whacking webcrawlers.
|
||||
5) Optional: Protect your ViewVC instance from server-whacking webcrawlers.
|
||||
|
||||
As ViewVC is a web-based application which each page containing various
|
||||
links to other pages and views, you can expect your server's performance
|
||||
|
@@ -15,7 +15,7 @@
|
||||
|
||||
<blockquote>
|
||||
|
||||
<p><strong>Copyright © 1999-2012 The ViewCVS Group. All rights
|
||||
<p><strong>Copyright © 1999-2011 The ViewCVS Group. All rights
|
||||
reserved.</strong></p>
|
||||
|
||||
<p>By using ViewVC, you agree to the terms and conditions set forth
|
||||
@@ -62,7 +62,6 @@
|
||||
<li>March 18, 2009 — copyright years updated</li>
|
||||
<li>March 29, 2010 — copyright years updated</li>
|
||||
<li>February 18, 2011 — copyright years updated</li>
|
||||
<li>January 23, 2012 — copyright years updated</li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 2004-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 2004-2008 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 2004-2007 James Henstridge
|
||||
#
|
||||
# By using this file, you agree to the terms and conditions set forth in
|
||||
@@ -153,7 +153,7 @@ class SvnRev:
|
||||
fsroot = self._get_root_for_rev(rev)
|
||||
|
||||
# find changes in the revision
|
||||
editor = svn.repos.ChangeCollector(repo.fs, fsroot)
|
||||
editor = svn.repos.RevisionChangeCollector(repo.fs, rev)
|
||||
e_ptr, e_baton = svn.delta.make_editor(editor)
|
||||
svn.repos.svn_repos_replay(fsroot, e_ptr, e_baton)
|
||||
|
||||
@@ -164,33 +164,21 @@ class SvnRev:
|
||||
continue
|
||||
|
||||
# deal with the change types we handle
|
||||
action = None
|
||||
base_root = None
|
||||
base_path = change.base_path
|
||||
if change.base_path:
|
||||
base_root = self._get_root_for_rev(change.base_rev)
|
||||
|
||||
# figure out what kind of change this is, and get a diff
|
||||
# object for it. note that prior to 1.4 Subversion's
|
||||
# bindings didn't give us change.action, but that's okay
|
||||
# because back then deleted paths always had a change.path
|
||||
# of None.
|
||||
if hasattr(change, 'action') \
|
||||
and change.action == svn.repos.CHANGE_ACTION_DELETE:
|
||||
action = 'remove'
|
||||
elif not change.path:
|
||||
|
||||
if not change.path:
|
||||
action = 'remove'
|
||||
elif change.added:
|
||||
action = 'add'
|
||||
else:
|
||||
action = 'change'
|
||||
|
||||
if action == 'remove':
|
||||
diffobj = svn.fs.FileDiff(base_root, base_path, None, None)
|
||||
else:
|
||||
diffobj = svn.fs.FileDiff(base_root, base_path,
|
||||
fsroot, change.path)
|
||||
|
||||
diffobj = svn.fs.FileDiff(base_root and base_root or None,
|
||||
base_root and change.base_path or None,
|
||||
change.path and fsroot or None,
|
||||
change.path and change.path or None)
|
||||
diff_fp = diffobj.get_pipe()
|
||||
plus, minus = _get_diff_counts(diff_fp)
|
||||
self.changes.append((path, action, plus, minus))
|
||||
@@ -300,7 +288,7 @@ def usage():
|
||||
located at REPOS-PATH.
|
||||
|
||||
Usage: 1. %s [-v] rebuild REPOS-PATH
|
||||
2. %s [-v] update REPOS-PATH [REV[:REV2]] [--force]
|
||||
2. %s [-v] update REPOS-PATH [REV:[REV2]] [--force]
|
||||
3. %s [-v] purge REPOS-PATH
|
||||
|
||||
1. Rebuild the commit database information for the repository located
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -86,8 +86,8 @@
|
||||
|
||||
## cvs_roots: Specifies each of the CVS roots on your system and
|
||||
## assigns names to them. Each root should be given by a "name: path"
|
||||
## value (where the path is an absolute filesystem path). Multiple roots
|
||||
## should be separated by commas and can be placed on separate lines.
|
||||
## value. Multiple roots should be separated by commas and can be
|
||||
## placed on separate lines.
|
||||
##
|
||||
## Example:
|
||||
## cvs_roots = cvsroot: /opt/cvs/repos1,
|
||||
@@ -97,13 +97,8 @@
|
||||
|
||||
## svn_roots: Specifies each of the Subversion roots (repositories) on
|
||||
## your system and assigns names to them. Each root should be given by
|
||||
## a "name: path" value (where the path is an absolute filesystem path).
|
||||
## Multiple roots should be separated by commas and can be placed on
|
||||
## separate lines.
|
||||
##
|
||||
## NOTE: ViewVC offers *experimental* support for displaying remote
|
||||
## Subversion repositories. Simply use the repository's URL instead
|
||||
## of a local filesystem path when defining the root.
|
||||
## a "name: path" value. Multiple roots should be separated by commas
|
||||
## and can be placed on separate lines.
|
||||
##
|
||||
## Example:
|
||||
## svn_roots = svnrepos: /opt/svn/,
|
||||
@@ -114,8 +109,7 @@
|
||||
## root_parents: Specifies a list of directories under which any
|
||||
## number of repositories may reside. You can specify multiple root
|
||||
## parents separated by commas or new lines, each of which is of the
|
||||
## form "path: type" (where the type is either "cvs" or "svn", and
|
||||
## the path is an absolute filesystem path).
|
||||
## form "path: type" (where type is either "cvs" or "svn").
|
||||
##
|
||||
## Rather than force you to add a new entry to 'cvs_roots' or
|
||||
## 'svn_roots' each time you create a new repository, ViewVC rewards
|
||||
@@ -351,43 +345,7 @@
|
||||
## allowed_views: List the ViewVC views which are enabled. Views not
|
||||
## in this comma-delited list will not be served (or, will return an
|
||||
## error on attempted access).
|
||||
##
|
||||
## Valid items for this list include: "annotate", "co", "diff", "markup",
|
||||
## "roots", "tar".
|
||||
##
|
||||
## ----------+---------------------------------------------------------
|
||||
## VIEW | DESCRIPTION
|
||||
## ----------+---------------------------------------------------------
|
||||
## annotate | The 'annotate' view shows the contents of a single
|
||||
## | revision of a versioned file in exactly the same way as
|
||||
## | the markup view, but with additional line-by-line
|
||||
## | change attribution (the revision number, author, etc.
|
||||
## | the most recent edit to that line of text as of the
|
||||
## | displayed version).
|
||||
## ----------+---------------------------------------------------------
|
||||
## co | The 'co' (aka "checkout" or "download") view isn't
|
||||
## | really a branded view at all, but allows for direct
|
||||
## | downloading of the contents of a single revision of a
|
||||
## | versioned file.
|
||||
## ----------+---------------------------------------------------------
|
||||
## diff | The 'diff' view displays line-based differences between
|
||||
## | two revisions of a versioned file in a variety of
|
||||
## | different user-selectable formats.
|
||||
## ----------+---------------------------------------------------------
|
||||
## markup | The 'markup' view shows the contents of a single
|
||||
## | revision of a versioned file, with syntax highlighting
|
||||
## | where possible and enabled. It can also optionally
|
||||
## | show change log information for that revision of the
|
||||
## | file.
|
||||
## ----------+---------------------------------------------------------
|
||||
## roots | The 'roots' view is a simple listing of the various
|
||||
## | repositories which ViewVC has been configured to serve
|
||||
## | to users.
|
||||
## ----------+---------------------------------------------------------
|
||||
## tar | The 'tar' view isn't a branded view, but generates
|
||||
## | a GNU Tar archive file containing a single versioned
|
||||
## | directory and its contents (recursively).
|
||||
## ----------+---------------------------------------------------------
|
||||
## Possible values: "annotate", "co", "diff", "markup", "roots", "tar"
|
||||
##
|
||||
#allowed_views = annotate, diff, markup, roots
|
||||
|
||||
@@ -433,26 +391,6 @@
|
||||
##
|
||||
#mangle_email_addresses = 0
|
||||
|
||||
## custom_log_formatting: Specifies mappings of regular expressions to
|
||||
## substitution format strings used to URL-ize strings found in
|
||||
## revision log messages. Multiple mappings (specified as
|
||||
## REGEXP:FORMATSTRING) may be defined, separated by commas.
|
||||
##
|
||||
## NOTE: Due to a limitation of the configuration format, commas may
|
||||
## not be used in the regular expression portion of each mapping.
|
||||
## Commas "in the raw" may not be used in the format string portion,
|
||||
## either, but you can probably use the URI-encoded form of the comma
|
||||
## ("%2C") instead with no ill side-effects. If you must specify a
|
||||
## colon character in either the regular expression or the format
|
||||
## string, escape it with a preceding backslash ("\:").
|
||||
##
|
||||
## Example:
|
||||
## custom_log_formatting =
|
||||
## artf[0-9]+ : http://example.com/tracker?id=\0,
|
||||
## issue ([0-9]+) : http://example.com/bug?id=\1&opts=full%2csortby=id
|
||||
##
|
||||
#custom_log_formatting =
|
||||
|
||||
## default_file_view: "log", "co", or "markup"
|
||||
## Controls whether the default view for file URLs is a checkout view or
|
||||
## a log view. "log" is the default for backwards compatibility with old
|
||||
@@ -665,13 +603,7 @@
|
||||
#short_log_len = 80
|
||||
|
||||
## enable_syntax_coloration: Should we colorize known file content
|
||||
## syntaxes?
|
||||
##
|
||||
## NOTE: This feature requires the Pygments Python module
|
||||
## (http://pygments.org) and works only when ViewVC can determine the
|
||||
## MIME content type of the file whose contents it wishes to colorize.
|
||||
## Use the 'mime_types_files' configuration option to specify MIME
|
||||
## type mapping files useful for making that determination.
|
||||
## syntaxes? [Requires Pygments Python module]
|
||||
##
|
||||
#enable_syntax_coloration = 1
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>ViewVC 1.1 Template Authoring Guide</title>
|
||||
<title>ViewVC 1.0 Template Authoring Guide</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: rgb(180,193,205);
|
||||
@@ -38,13 +38,13 @@ td {
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>ViewVC 1.1 Template Authoring Guide</h1>
|
||||
<h1>ViewVC 1.0 Template Authoring Guide</h1>
|
||||
|
||||
<div class="h2">
|
||||
<h2 id="introduction">Introduction</h2>
|
||||
|
||||
<p>This document represents an (unfinished) attempt at providing
|
||||
instructions for how to customize ViewVC's HTML output via
|
||||
documentation for how to customize ViewVC 1.0-dev's HTML output via
|
||||
modification of its templates.</p>
|
||||
|
||||
</div>
|
||||
@@ -802,11 +802,6 @@ td {
|
||||
<td>String</td>
|
||||
<td>This is a URL for the markup view of the left file.</td>
|
||||
</tr>
|
||||
<tr class="varlevel1">
|
||||
<td class="varname">patch_href</td>
|
||||
<td>String</td>
|
||||
<td>URL of the patch view for the file.</td>
|
||||
</tr>
|
||||
<tr class="varlevel1">
|
||||
<td class="varname">raw_diff</td>
|
||||
<td>String</td>
|
||||
@@ -2183,12 +2178,6 @@ td {
|
||||
<td>String</td>
|
||||
<td>Log message of last modification to the root.</td>
|
||||
</tr>
|
||||
<tr class="varlevel2">
|
||||
<td class="varname">roots.log_href</td>
|
||||
<td>String</td>
|
||||
<td>URL of log revision view for the top-most (root) directory of
|
||||
the root (repository).</td>
|
||||
</tr>
|
||||
<tr class="varlevel2">
|
||||
<td class="varname">roots.name</td>
|
||||
<td>String</td>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2010 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
|
||||
@@ -74,8 +74,7 @@ class HTMLBlameSource:
|
||||
self.path_parts = path_parts
|
||||
self.diff_url = diff_url
|
||||
self.include_url = include_url
|
||||
self.annotation, self.revision = self.repos.annotate(path_parts, opt_rev,
|
||||
True)
|
||||
self.annotation, self.revision = self.repos.annotate(path_parts, opt_rev)
|
||||
|
||||
def __getitem__(self, idx):
|
||||
item = self.annotation.__getitem__(idx)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2007 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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
|
||||
@@ -112,7 +112,6 @@ class Config:
|
||||
_force_multi_value = (
|
||||
# Configuration values with multiple, comma-separated values.
|
||||
'allowed_views',
|
||||
'custom_log_formatting',
|
||||
'cvs_roots',
|
||||
'kv_files',
|
||||
'languages',
|
||||
@@ -399,7 +398,6 @@ class Config:
|
||||
self.options.allowed_views = ['annotate', 'diff', 'markup', 'roots']
|
||||
self.options.authorizer = None
|
||||
self.options.mangle_email_addresses = 0
|
||||
self.options.custom_log_formatting = []
|
||||
self.options.default_file_view = "log"
|
||||
self.options.http_expiration_time = 600
|
||||
self.options.generate_etags = 1
|
||||
|
14
lib/cvsdb.py
14
lib/cvsdb.py
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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
|
||||
@@ -352,17 +352,9 @@ class CheckinDatabase:
|
||||
match = " LIKE "
|
||||
elif query_entry.match == "glob":
|
||||
match = " REGEXP "
|
||||
# Use fnmatch to translate the glob into a regular
|
||||
# expression. Sadly, we have to account for the fact
|
||||
# that in Python 2.6, fnmatch.translate() started
|
||||
# sticking '\Z(?ms)' at the end of the regular
|
||||
# expression instead of just '$', and doesn't prepend
|
||||
# the '^'.
|
||||
# use fnmatch to translate the glob into a regexp
|
||||
data = fnmatch.translate(data)
|
||||
if data[0] != '^':
|
||||
data = '^' + data
|
||||
if data[-7:] == '\Z(?ms)':
|
||||
data = data[:-7] + '$'
|
||||
if data[0] != '^': data = '^' + data
|
||||
elif query_entry.match == "regex":
|
||||
match = " REGEXP "
|
||||
elif query_entry.match == "notregex":
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
@@ -233,6 +233,9 @@ class WsgiServer(Server):
|
||||
self.header(status='301 Moved')
|
||||
self._wsgi_write('This document is located <a href="%s">here</a>.' % url)
|
||||
|
||||
def escape(self, s, quote = None):
|
||||
return cgi.escape(s, quote)
|
||||
|
||||
def getenv(self, name, value=None):
|
||||
return self._environ.get(name, value)
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 2006-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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 2006-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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 2008-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 2008-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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 2006-2011 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
|
||||
@@ -34,9 +34,9 @@ class ViewVCAuthorizer(vcauth.GenericViewVCAuthorizer):
|
||||
# See if the admin wants us to do case normalization of usernames.
|
||||
self.force_username_case = params.get('force_username_case')
|
||||
if self.force_username_case == "upper":
|
||||
self.username = username and string.upper(username) or username
|
||||
self.username = username.upper()
|
||||
elif self.force_username_case == "lower":
|
||||
self.username = username and string.lower(username) or username
|
||||
self.username = username.lower()
|
||||
elif not self.force_username_case:
|
||||
self.username = username
|
||||
else:
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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
|
||||
@@ -170,19 +170,12 @@ class Repository:
|
||||
Return value is a python file object
|
||||
"""
|
||||
|
||||
def annotate(self, path_parts, rev, include_text=False):
|
||||
"""Return a list of Annotation object, sorted by their
|
||||
"line_number" components, which describe the lines of given
|
||||
version of a file.
|
||||
def annotate(self, path_parts, rev):
|
||||
"""Return a list of annotate file content lines and a revision.
|
||||
|
||||
The file path is specified as a list of components, relative to
|
||||
the root of the repository. e.g. ["subdir1", "subdir2", "filename"]
|
||||
|
||||
rev is the revision of the item to return information about.
|
||||
|
||||
If include_text is true, populate the Annotation objects' "text"
|
||||
members with the corresponding line of file content; otherwise,
|
||||
leave that member set to None."""
|
||||
The result is a list of Annotation objects, sorted by their
|
||||
line_number components.
|
||||
"""
|
||||
|
||||
def revinfo(self, rev):
|
||||
"""Return information about a global revision
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
@@ -14,7 +14,6 @@ import os.path
|
||||
|
||||
|
||||
def canonicalize_rootpath(rootpath):
|
||||
assert os.path.isabs(rootpath)
|
||||
return os.path.normpath(rootpath)
|
||||
|
||||
|
||||
@@ -23,7 +22,6 @@ def expand_root_parent(parent_path):
|
||||
# "CVSROOT/config" is added the set of returned roots. Or, if the
|
||||
# PARENT_PATH itself contains a child "CVSROOT/config", then all its
|
||||
# subdirectories are returned as roots.
|
||||
assert os.path.isabs(parent_path)
|
||||
roots = {}
|
||||
subpaths = os.listdir(parent_path)
|
||||
cvsroot = os.path.exists(os.path.join(parent_path, "CVSROOT", "config"))
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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
|
||||
@@ -332,13 +332,13 @@ class BinCVSRepository(BaseCVSRepository):
|
||||
args = rcs_args
|
||||
return popen.popen(cmd, args, mode, capture_err)
|
||||
|
||||
def annotate(self, path_parts, rev=None, include_text=False):
|
||||
def annotate(self, path_parts, rev=None):
|
||||
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
|
||||
raise vclib.Error("Path '%s' is not a file."
|
||||
% (string.join(path_parts, "/")))
|
||||
|
||||
from vclib.ccvs import blame
|
||||
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, include_text)
|
||||
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev)
|
||||
return source, source.revision
|
||||
|
||||
def revinfo(self, rev):
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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
|
||||
@@ -414,7 +414,7 @@ class CVSParser(rcsparse.Sink):
|
||||
|
||||
|
||||
class BlameSource:
|
||||
def __init__(self, rcs_file, opt_rev=None, include_text=False):
|
||||
def __init__(self, rcs_file, opt_rev=None):
|
||||
# Parse the CVS file
|
||||
parser = CVSParser()
|
||||
revision = parser.parse_cvs_file(rcs_file, opt_rev)
|
||||
@@ -428,7 +428,6 @@ class BlameSource:
|
||||
self.lines = lines
|
||||
self.num_lines = count
|
||||
self.parser = parser
|
||||
self.include_text = include_text
|
||||
|
||||
# keep track of where we are during an iteration
|
||||
self.idx = -1
|
||||
@@ -448,8 +447,6 @@ class BlameSource:
|
||||
line_number = idx + 1
|
||||
author = self.parser.revision_author[rev]
|
||||
thisline = self.lines[idx]
|
||||
if not self.include_text:
|
||||
thisline = None
|
||||
### TODO: Put a real date in here.
|
||||
item = vclib.Annotation(thisline, line_number, rev, prev_rev, author, None)
|
||||
self.last = item
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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
|
||||
@@ -142,11 +142,11 @@ class CCVSRepository(BaseCVSRepository):
|
||||
return vclib._diff_fp(temp1, temp2, info1, info2,
|
||||
self.utilities.diff or 'diff', diff_args)
|
||||
|
||||
def annotate(self, path_parts, rev=None, include_text=False):
|
||||
def annotate(self, path_parts, rev=None):
|
||||
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
|
||||
raise vclib.Error("Path '%s' is not a file."
|
||||
% (string.join(path_parts, "/")))
|
||||
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, include_text)
|
||||
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev)
|
||||
return source, source.revision
|
||||
|
||||
def revinfo(self, rev):
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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
|
||||
@@ -19,46 +19,26 @@ import urllib
|
||||
|
||||
_re_url = re.compile('^(http|https|file|svn|svn\+[^:]+)://')
|
||||
|
||||
def _canonicalize_path(path):
|
||||
import svn.core
|
||||
try:
|
||||
return svn.core.svn_path_canonicalize(path)
|
||||
except AttributeError: # svn_path_canonicalize() appeared in 1.4.0 bindings
|
||||
# There's so much more that we *could* do here, but if we're
|
||||
# here at all its because there's a really old Subversion in
|
||||
# place, and those older Subversion versions cared quite a bit
|
||||
# less about the specifics of path canonicalization.
|
||||
if re.search(_re_url, path):
|
||||
return path.rstrip('/')
|
||||
else:
|
||||
return os.path.normpath(path)
|
||||
|
||||
|
||||
def canonicalize_rootpath(rootpath):
|
||||
# Try to canonicalize the rootpath using Subversion semantics.
|
||||
rootpath = _canonicalize_path(rootpath)
|
||||
|
||||
# ViewVC's support for local repositories is more complete and more
|
||||
# performant than its support for remote ones, so if we're on a
|
||||
# Unix-y system and we have a file:/// URL, convert it to a local
|
||||
# path instead.
|
||||
if os.name == 'posix':
|
||||
rootpath_lower = rootpath.lower()
|
||||
if rootpath_lower in ['file://localhost',
|
||||
'file://localhost/',
|
||||
'file://',
|
||||
'file:///'
|
||||
]:
|
||||
return '/'
|
||||
if rootpath_lower.startswith('file://localhost/'):
|
||||
rootpath = os.path.normpath(urllib.unquote(rootpath[16:]))
|
||||
elif rootpath_lower.startswith('file:///'):
|
||||
rootpath = os.path.normpath(urllib.unquote(rootpath[7:]))
|
||||
|
||||
# Ensure that we have an absolute path (or URL), and return.
|
||||
if not re.search(_re_url, rootpath):
|
||||
assert os.path.isabs(rootpath)
|
||||
return rootpath
|
||||
try:
|
||||
import svn.core
|
||||
return svn.core.svn_path_canonicalize(rootpath)
|
||||
except:
|
||||
if os.name == 'posix':
|
||||
rootpath_lower = rootpath.lower()
|
||||
if rootpath_lower in ['file://localhost',
|
||||
'file://localhost/',
|
||||
'file://',
|
||||
'file:///'
|
||||
]:
|
||||
return '/'
|
||||
if rootpath_lower.startswith('file://localhost/'):
|
||||
return os.path.normpath(urllib.unquote(rootpath[16:]))
|
||||
elif rootpath_lower.startswith('file:///'):
|
||||
return os.path.normpath(urllib.unquote(rootpath[7:]))
|
||||
if re.search(_re_url, rootpath):
|
||||
return rootpath.rstrip('/')
|
||||
return os.path.normpath(rootpath)
|
||||
|
||||
|
||||
def expand_root_parent(parent_path):
|
||||
@@ -68,7 +48,6 @@ def expand_root_parent(parent_path):
|
||||
else:
|
||||
# Any subdirectories of PARENT_PATH which themselves have a child
|
||||
# "format" are returned as roots.
|
||||
assert os.path.isabs(parent_path)
|
||||
subpaths = os.listdir(parent_path)
|
||||
for rootname in subpaths:
|
||||
rootpath = os.path.join(parent_path, rootname)
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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,10 +20,7 @@ import re
|
||||
import tempfile
|
||||
import time
|
||||
import urllib
|
||||
from svn_repos import Revision, SVNChangedPath, _datestr_to_date, \
|
||||
_compare_paths, _path_parts, _cleanup_path, \
|
||||
_rev2optrev, _fix_subversion_exception, \
|
||||
_split_revprops, _canonicalize_path
|
||||
from svn_repos import Revision, SVNChangedPath, _datestr_to_date, _compare_paths, _path_parts, _cleanup_path, _rev2optrev, _fix_subversion_exception, _split_revprops
|
||||
from svn import core, delta, client, wc, ra
|
||||
|
||||
|
||||
@@ -341,7 +338,7 @@ class RemoteSubversionRepository(vclib.Repository):
|
||||
_rev2optrev(rev), 0, self.ctx)
|
||||
return pairs and pairs[0][1] or {}
|
||||
|
||||
def annotate(self, path_parts, rev, include_text=False):
|
||||
def annotate(self, path_parts, rev):
|
||||
path = self._getpath(path_parts)
|
||||
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
|
||||
raise vclib.Error("Path '%s' is not a file." % path)
|
||||
@@ -355,13 +352,12 @@ class RemoteSubversionRepository(vclib.Repository):
|
||||
prev_rev = None
|
||||
if revision > 1:
|
||||
prev_rev = revision - 1
|
||||
if not include_text:
|
||||
line = None
|
||||
blame_data.append(vclib.Annotation(line, line_no + 1, revision, prev_rev,
|
||||
blame_data.append(vclib.Annotation(line, line_no+1, revision, prev_rev,
|
||||
author, None))
|
||||
|
||||
client.svn_client_blame(url, _rev2optrev(1), _rev2optrev(rev),
|
||||
_blame_cb, self.ctx)
|
||||
|
||||
return blame_data, rev
|
||||
|
||||
def revinfo(self, rev):
|
||||
@@ -411,11 +407,8 @@ class RemoteSubversionRepository(vclib.Repository):
|
||||
if rev is None or rev == 'HEAD':
|
||||
return self.youngest
|
||||
try:
|
||||
if type(rev) == type(''):
|
||||
while rev[0] == 'r':
|
||||
rev = rev[1:]
|
||||
rev = int(rev)
|
||||
except:
|
||||
except ValueError:
|
||||
raise vclib.InvalidRevision(rev)
|
||||
if (rev < 0) or (rev > self.youngest):
|
||||
raise vclib.InvalidRevision(rev)
|
||||
@@ -424,8 +417,7 @@ class RemoteSubversionRepository(vclib.Repository):
|
||||
def _geturl(self, path=None):
|
||||
if not path:
|
||||
return self.rootpath
|
||||
path = self.rootpath + '/' + urllib.quote(path)
|
||||
return _canonicalize_path(path)
|
||||
return self.rootpath + '/' + urllib.quote(path, "/*~")
|
||||
|
||||
def _get_dirents(self, path, rev):
|
||||
"""Return a 2-type of dirents and locks, possibly reading/writing
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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
|
||||
@@ -22,7 +22,6 @@ import time
|
||||
import tempfile
|
||||
import popen
|
||||
import re
|
||||
import urllib
|
||||
from svn import fs, repos, core, client, delta
|
||||
|
||||
|
||||
@@ -43,14 +42,7 @@ def _fix_subversion_exception(e):
|
||||
e.apr_err = e[1]
|
||||
if not hasattr(e, 'message'):
|
||||
e.message = e[0]
|
||||
|
||||
### Pre-1.4 Subversion doesn't have svn_path_canonicalize()
|
||||
def _canonicalize_path(path):
|
||||
try:
|
||||
return core.svn_path_canonicalize(path)
|
||||
except AttributeError:
|
||||
return path
|
||||
|
||||
|
||||
def _allow_all(root, path, pool):
|
||||
"""Generic authz_read_func that permits access to all paths"""
|
||||
return 1
|
||||
@@ -116,16 +108,11 @@ def _rev2optrev(rev):
|
||||
|
||||
def _rootpath2url(rootpath, path):
|
||||
rootpath = os.path.abspath(rootpath)
|
||||
drive, rootpath = os.path.splitdrive(rootpath)
|
||||
if rootpath and rootpath[0] != '/':
|
||||
rootpath = '/' + rootpath
|
||||
if os.sep != '/':
|
||||
rootpath = string.replace(rootpath, os.sep, '/')
|
||||
rootpath = urllib.quote(rootpath)
|
||||
path = urllib.quote(path)
|
||||
if drive:
|
||||
url = 'file:///' + drive + rootpath + '/' + path
|
||||
else:
|
||||
url = 'file://' + rootpath + '/' + path
|
||||
return _canonicalize_path(url)
|
||||
return 'file://' + string.join([rootpath, path], "/")
|
||||
|
||||
|
||||
# Given a dictionary REVPROPS of revision properties, pull special
|
||||
@@ -295,11 +282,10 @@ class FileContentsPipe:
|
||||
|
||||
|
||||
class BlameSource:
|
||||
def __init__(self, local_url, rev, first_rev, include_text, config_dir):
|
||||
def __init__(self, local_url, rev, first_rev, config_dir):
|
||||
self.idx = -1
|
||||
self.first_rev = first_rev
|
||||
self.blame_data = []
|
||||
self.include_text = include_text
|
||||
|
||||
ctx = client.svn_client_create_context()
|
||||
core.svn_config_ensure(config_dir)
|
||||
@@ -320,8 +306,6 @@ class BlameSource:
|
||||
prev_rev = None
|
||||
if rev > self.first_rev:
|
||||
prev_rev = rev - 1
|
||||
if not self.include_text:
|
||||
text = None
|
||||
self.blame_data.append(vclib.Annotation(text, line_no + 1, rev,
|
||||
prev_rev, author, None))
|
||||
|
||||
@@ -537,7 +521,7 @@ class LocalSubversionRepository(vclib.Repository):
|
||||
fsroot = self._getroot(rev)
|
||||
return fs.node_proplist(fsroot, path)
|
||||
|
||||
def annotate(self, path_parts, rev, include_text=False):
|
||||
def annotate(self, path_parts, rev):
|
||||
path = self._getpath(path_parts)
|
||||
path_type = self.itemtype(path_parts, rev) # does auth-check
|
||||
if path_type != vclib.FILE:
|
||||
@@ -548,8 +532,8 @@ class LocalSubversionRepository(vclib.Repository):
|
||||
{'svn_cross_copies': 1})
|
||||
youngest_rev, youngest_path = history[0]
|
||||
oldest_rev, oldest_path = history[-1]
|
||||
source = BlameSource(_rootpath2url(self.rootpath, path), youngest_rev,
|
||||
oldest_rev, include_text, self.config_dir)
|
||||
source = BlameSource(_rootpath2url(self.rootpath, path),
|
||||
youngest_rev, oldest_rev, self.config_dir)
|
||||
return source, youngest_rev
|
||||
|
||||
def revinfo(self, rev):
|
||||
@@ -825,11 +809,8 @@ class LocalSubversionRepository(vclib.Repository):
|
||||
if rev is None or rev == 'HEAD':
|
||||
return self.youngest
|
||||
try:
|
||||
if type(rev) == type(''):
|
||||
while rev[0] == 'r':
|
||||
rev = rev[1:]
|
||||
rev = int(rev)
|
||||
except:
|
||||
except ValueError:
|
||||
raise vclib.InvalidRevision(rev)
|
||||
if (rev < 0) or (rev > self.youngest):
|
||||
raise vclib.InvalidRevision(rev)
|
||||
|
463
lib/viewvc.py
463
lib/viewvc.py
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2011 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.1.14'
|
||||
__version__ = '1.1.11'
|
||||
|
||||
# this comes from our library; measure the startup time
|
||||
import debug
|
||||
@@ -1099,29 +1099,6 @@ _re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@'
|
||||
# Matches revision references
|
||||
_re_rewrite_svnrevref = re.compile(r'\b(r|rev #?|revision #?)([0-9]+)\b')
|
||||
|
||||
class ViewVCHtmlFormatterTokens:
|
||||
def __init__(self, tokens):
|
||||
self.tokens = tokens
|
||||
|
||||
def get_result(self, maxlen=0):
|
||||
"""Format the tokens per the registered set of formatters, and
|
||||
limited to MAXLEN visible characters (or unlimited if MAXLEN is
|
||||
0). Return a 3-tuple containing the formatted result string, the
|
||||
number of visible characters in the result string, and a boolean
|
||||
flag indicating whether or not S was truncated."""
|
||||
out = ''
|
||||
out_len = 0
|
||||
for token in self.tokens:
|
||||
chunk, chunk_len = token.converter(token.match, token.userdata, maxlen)
|
||||
out = out + chunk
|
||||
out_len = out_len + chunk_len
|
||||
if maxlen:
|
||||
maxlen = maxlen - chunk_len
|
||||
if maxlen <= 0:
|
||||
return out, out_len, 1
|
||||
return out, out_len, 0
|
||||
|
||||
|
||||
class ViewVCHtmlFormatter:
|
||||
"""Format a string as HTML-encoded output with customizable markup
|
||||
rules, for example turning strings that look like URLs into anchor links.
|
||||
@@ -1207,30 +1184,6 @@ class ViewVCHtmlFormatter:
|
||||
sapi.escape(trunc_s)), \
|
||||
len(trunc_s)
|
||||
|
||||
def format_custom_url(self, mobj, userdata, maxlen=0):
|
||||
"""Return a 2-tuple containing:
|
||||
- the text represented by MatchObject MOBJ, formatted as an
|
||||
linkified URL created by substituting match groups 0-9 into
|
||||
USERDATA (which is a format string that uses \N to
|
||||
represent the substitution locations) and with no more than
|
||||
MAXLEN characters in the non-HTML-tag portions. If MAXLEN
|
||||
is 0, there is no maximum.
|
||||
- the number of characters returned.
|
||||
"""
|
||||
format = userdata
|
||||
text = mobj.group(0)
|
||||
url = format
|
||||
for i in range(9):
|
||||
try:
|
||||
repl = mobj.group(i)
|
||||
except:
|
||||
repl = ''
|
||||
url = url.replace('\%d' % (i), repl)
|
||||
trunc_s = maxlen and text[:maxlen] or text
|
||||
return '<a href="%s">%s</a>' % (sapi.escape(url),
|
||||
sapi.escape(trunc_s)), \
|
||||
len(trunc_s)
|
||||
|
||||
def format_text(self, s, unused, maxlen=0):
|
||||
"""Return a 2-tuple containing:
|
||||
- the text S, HTML-escaped, containing no more than MAXLEN
|
||||
@@ -1263,14 +1216,20 @@ class ViewVCHtmlFormatter:
|
||||
"""
|
||||
out = ''
|
||||
out_len = 0
|
||||
tokens = self.tokenize_text(s)
|
||||
return tokens.get_result()
|
||||
for token in self._tokenize_text(s):
|
||||
chunk, chunk_len = token.converter(token.match, token.userdata, maxlen)
|
||||
out = out + chunk
|
||||
out_len = out_len + chunk_len
|
||||
if maxlen:
|
||||
maxlen = maxlen - chunk_len
|
||||
if maxlen <= 0:
|
||||
return out, out_len, 1
|
||||
return out, out_len, 0
|
||||
|
||||
def tokenize_text(self, s):
|
||||
"""Return a ViewVCHtmlFormatterTokens object containing the tokens
|
||||
created when parsing the string S. Callers can use that object's
|
||||
get_result() function to retrieve HTML-formatted text.
|
||||
"""
|
||||
def _entity_encode(self, s):
|
||||
return string.join(map(lambda x: '&#%d;' % (ord(x)), s), '')
|
||||
|
||||
def _tokenize_text(self, s):
|
||||
tokens = []
|
||||
# We could just have a "while s:" here instead of "for line: while
|
||||
# line:", but for really large log messages with heavy
|
||||
@@ -1317,79 +1276,36 @@ class ViewVCHtmlFormatter:
|
||||
converter=self.format_text,
|
||||
userdata=None))
|
||||
line = ''
|
||||
return ViewVCHtmlFormatterTokens(tokens)
|
||||
|
||||
def _entity_encode(self, s):
|
||||
return string.join(map(lambda x: '&#%d;' % (ord(x)), s), '')
|
||||
return tokens
|
||||
|
||||
|
||||
class LogFormatter:
|
||||
def __init__(self, request, log):
|
||||
self.request = request
|
||||
self.log = log or ''
|
||||
self.tokens = None
|
||||
self.cache = {} # (maxlen, htmlize) => resulting_log
|
||||
def format_log(request, log, maxlen=0, htmlize=1):
|
||||
if not log:
|
||||
return log
|
||||
|
||||
def get(self, maxlen=0, htmlize=1):
|
||||
cfg = self.request.cfg
|
||||
|
||||
# Prefer the cache.
|
||||
if self.cache.has_key((maxlen, htmlize)):
|
||||
return self.cache[(maxlen, htmlize)]
|
||||
|
||||
# If we are HTML-izing...
|
||||
if htmlize:
|
||||
# ...and we don't yet have ViewVCHtmlFormatter() object tokens...
|
||||
if not self.tokens:
|
||||
# ... then get them.
|
||||
lf = ViewVCHtmlFormatter()
|
||||
|
||||
# Rewrite URLs.
|
||||
lf.add_formatter(_re_rewrite_url, lf.format_url)
|
||||
|
||||
# Rewrite Subversion revision references.
|
||||
if self.request.roottype == 'svn':
|
||||
def revision_to_url(rev):
|
||||
return self.request.get_url(view_func=view_revision,
|
||||
params={'revision': rev},
|
||||
escape=1)
|
||||
lf.add_formatter(_re_rewrite_svnrevref, lf.format_svnrevref,
|
||||
revision_to_url)
|
||||
|
||||
# Rewrite email addresses.
|
||||
if cfg.options.mangle_email_addresses == 2:
|
||||
lf.add_formatter(_re_rewrite_email, lf.format_email_truncated)
|
||||
elif cfg.options.mangle_email_addresses == 1:
|
||||
lf.add_formatter(_re_rewrite_email, lf.format_email_obfuscated)
|
||||
else:
|
||||
lf.add_formatter(_re_rewrite_email, lf.format_email)
|
||||
|
||||
# Add custom rewrite handling per configuration.
|
||||
for rule in cfg.options.custom_log_formatting:
|
||||
rule = rule.replace('\\:', '\x01')
|
||||
regexp, format = map(lambda x: x.strip(), rule.split(':', 1))
|
||||
regexp = regexp.replace('\x01', ':')
|
||||
format = format.replace('\x01', ':')
|
||||
lf.add_formatter(re.compile(regexp), lf.format_custom_url, format)
|
||||
|
||||
# Tokenize the log message.
|
||||
self.tokens = lf.tokenize_text(self.log)
|
||||
|
||||
# Use our formatter to ... you know ... format.
|
||||
log, log_len, truncated = self.tokens.get_result(maxlen)
|
||||
result_log = log + (truncated and '…' or '')
|
||||
|
||||
# But if we're not HTML-izing...
|
||||
cfg = request.cfg
|
||||
if htmlize:
|
||||
lf = ViewVCHtmlFormatter()
|
||||
lf.add_formatter(_re_rewrite_url, lf.format_url)
|
||||
if request.roottype == 'svn':
|
||||
def revision_to_url(rev):
|
||||
return request.get_url(view_func=view_revision,
|
||||
params={'revision': rev},
|
||||
escape=1)
|
||||
lf.add_formatter(_re_rewrite_svnrevref, lf.format_svnrevref,
|
||||
revision_to_url)
|
||||
if cfg.options.mangle_email_addresses == 2:
|
||||
lf.add_formatter(_re_rewrite_email, lf.format_email_truncated)
|
||||
elif cfg.options.mangle_email_addresses == 1:
|
||||
lf.add_formatter(_re_rewrite_email, lf.format_email_obfuscated)
|
||||
else:
|
||||
# ...then do much more simplistic transformations as necessary.
|
||||
if cfg.options.mangle_email_addresses == 2:
|
||||
log = re.sub(_re_rewrite_email, r'\1@...', log)
|
||||
result_log = maxlen and log[:maxlen] or log
|
||||
|
||||
# In either case, populate the cache and return the results.
|
||||
self.cache[(maxlen, htmlize)] = result_log
|
||||
return result_log
|
||||
|
||||
lf.add_formatter(_re_rewrite_email, lf.format_email)
|
||||
log, log_len, truncated = lf.get_result(log, maxlen)
|
||||
return log + (truncated and '…' or '')
|
||||
else:
|
||||
if cfg.options.mangle_email_addresses == 2:
|
||||
log = re.sub(_re_rewrite_email, r'\1@...', log)
|
||||
return maxlen and log[:maxlen] or log
|
||||
|
||||
_time_desc = {
|
||||
1 : 'second',
|
||||
@@ -1631,36 +1547,33 @@ def markup_escaped_urls(s):
|
||||
return "<a href=\"%s\">%s</a>" % (unescaped_url, url)
|
||||
return re.sub(_re_rewrite_escaped_url, _url_repl, s)
|
||||
|
||||
|
||||
def markup_stream(request, cfg, blame_data, file_lines, filename,
|
||||
mime_type, encoding, colorize):
|
||||
"""Return the contents of a versioned file as a list of
|
||||
vclib.Annotation objects, each representing one line of the file's
|
||||
contents. Use BLAME_DATA as the annotation information for the file
|
||||
if provided. Use FILE_LINES as the lines of file content text
|
||||
themselves. MIME_TYPE is the MIME content type of the file;
|
||||
ENCODING is its character encoding. If COLORIZE is true, attempt to
|
||||
apply syntax coloration to the file contents, and use the
|
||||
HTML-marked-up results as the text in the return vclib.Annotation
|
||||
objects."""
|
||||
|
||||
# Nothing to mark up? So be it.
|
||||
if not file_lines:
|
||||
return []
|
||||
|
||||
# Determine if we should (and can) use Pygments to highlight our
|
||||
# output. Reasons not to include a) being told not to by the
|
||||
# configuration, b) not being able to import the Pygments modules,
|
||||
# and c) Pygments not having a lexer for our file's format.
|
||||
pygments_lexer = None
|
||||
if colorize:
|
||||
def markup_stream_pygments(request, cfg, blame_data, fp, filename,
|
||||
mime_type, encoding):
|
||||
# Determine if we should use Pygments to highlight our output.
|
||||
# Reasons not to include a) being told not to by the configuration,
|
||||
# b) not being able to import the Pygments modules, and c) Pygments
|
||||
# not having a lexer for our file's format.
|
||||
blame_source = []
|
||||
if blame_data:
|
||||
for i in blame_data:
|
||||
i.text = sapi.escape(i.text)
|
||||
i.diff_href = None
|
||||
if i.prev_rev:
|
||||
i.diff_href = request.get_url(view_func=view_diff,
|
||||
params={'r1': i.prev_rev,
|
||||
'r2': i.rev},
|
||||
escape=1, partial=1)
|
||||
blame_source.append(i)
|
||||
blame_data = blame_source
|
||||
lexer = None
|
||||
use_pygments = cfg.options.enable_syntax_coloration
|
||||
try:
|
||||
from pygments import highlight
|
||||
from pygments.formatters import HtmlFormatter
|
||||
from pygments.lexers import ClassNotFound, \
|
||||
get_lexer_by_name, \
|
||||
get_lexer_for_mimetype, \
|
||||
get_lexer_for_filename, \
|
||||
guess_lexer
|
||||
get_lexer_for_filename
|
||||
if not encoding:
|
||||
encoding = 'guess'
|
||||
if cfg.options.detect_encoding:
|
||||
@@ -1669,50 +1582,50 @@ def markup_stream(request, cfg, blame_data, file_lines, filename,
|
||||
encoding = 'chardet'
|
||||
except (SyntaxError, ImportError):
|
||||
pass
|
||||
|
||||
# First, see if there's a Pygments lexer associated with MIME_TYPE.
|
||||
if mime_type:
|
||||
try:
|
||||
lexer = get_lexer_for_mimetype(mime_type,
|
||||
encoding=encoding,
|
||||
tabsize=cfg.options.tabsize,
|
||||
stripnl=False)
|
||||
except ClassNotFound:
|
||||
try:
|
||||
pygments_lexer = get_lexer_for_mimetype(mime_type,
|
||||
encoding=encoding,
|
||||
tabsize=cfg.options.tabsize,
|
||||
stripnl=False)
|
||||
lexer = get_lexer_for_filename(filename,
|
||||
encoding=encoding,
|
||||
tabsize=cfg.options.tabsize,
|
||||
stripnl=False)
|
||||
except ClassNotFound:
|
||||
pygments_lexer = None
|
||||
use_pygments = 0
|
||||
except ImportError:
|
||||
use_pygments = 0
|
||||
|
||||
# If we've no lexer thus far, try to find one based on the FILENAME.
|
||||
if not pygments_lexer:
|
||||
try:
|
||||
pygments_lexer = get_lexer_for_filename(filename,
|
||||
encoding=encoding,
|
||||
tabsize=cfg.options.tabsize,
|
||||
stripnl=False)
|
||||
except ClassNotFound:
|
||||
pygments_lexer = None
|
||||
|
||||
# Still no lexer? If we've reason to believe this is a text
|
||||
# file, try to guess the lexer based on the file's content.
|
||||
if not pygments_lexer and is_text(mime_type) and file_lines:
|
||||
try:
|
||||
pygments_lexer = guess_lexer(file_lines[0])
|
||||
except ClassNotFound:
|
||||
pygments_lexer = None
|
||||
|
||||
# If we aren't highlighting, just return an amalgamation of the
|
||||
# BLAME_DATA (if any) and the FILE_LINES.
|
||||
if not pygments_lexer:
|
||||
lines = []
|
||||
for i in range(len(file_lines)):
|
||||
line = file_lines[i]
|
||||
line = sapi.escape(string.expandtabs(line, cfg.options.tabsize))
|
||||
line = markup_escaped_urls(line)
|
||||
if blame_data:
|
||||
blame_item = blame_data[i]
|
||||
blame_item.text = line
|
||||
else:
|
||||
blame_item = vclib.Annotation(line, i + 1, None, None, None, None)
|
||||
blame_item.diff_href = None
|
||||
lines.append(blame_item)
|
||||
# If we aren't going to be highlighting anything, just return the
|
||||
# BLAME_SOURCE. If there's no blame_source, we'll generate a fake
|
||||
# one from the file contents we fetch with PATH and REV.
|
||||
if not use_pygments:
|
||||
if blame_source:
|
||||
class BlameSourceTabsizeWrapper:
|
||||
def __init__(self, blame_source, tabsize):
|
||||
self.blame_source = blame_source
|
||||
self.tabsize = cfg.options.tabsize
|
||||
def __getitem__(self, idx):
|
||||
item = self.blame_source.__getitem__(idx)
|
||||
item.text = string.expandtabs(item.text, self.tabsize)
|
||||
item.text = markup_escaped_urls(item.text)
|
||||
return item
|
||||
return BlameSourceTabsizeWrapper(blame_source, cfg.options.tabsize)
|
||||
else:
|
||||
lines = []
|
||||
line_no = 0
|
||||
while 1:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
line_no = line_no + 1
|
||||
line = sapi.escape(string.expandtabs(line, cfg.options.tabsize))
|
||||
line = markup_escaped_urls(line)
|
||||
item = vclib.Annotation(line, line_no, None, None, None, None)
|
||||
item.diff_href = None
|
||||
lines.append(item)
|
||||
return lines
|
||||
|
||||
# If we get here, we're highlighting something.
|
||||
@@ -1736,9 +1649,8 @@ def markup_stream(request, cfg, blame_data, file_lines, filename,
|
||||
item.diff_href = None
|
||||
self.blame_data.append(item)
|
||||
self.line_no = self.line_no + 1
|
||||
|
||||
ps = PygmentsSink(blame_data)
|
||||
highlight(string.join(file_lines, ''), pygments_lexer,
|
||||
ps = PygmentsSink(blame_source)
|
||||
highlight(fp.read(), lexer,
|
||||
HtmlFormatter(nowrap=True,
|
||||
classprefix="pygments-",
|
||||
encoding='utf-8'), ps)
|
||||
@@ -1777,8 +1689,7 @@ def get_itemprops(request, path_parts, rev):
|
||||
propnames.sort()
|
||||
props = []
|
||||
for name in propnames:
|
||||
lf = LogFormatter(request, itemprops[name])
|
||||
value = lf.get(maxlen=0, htmlize=1)
|
||||
value = format_log(request, itemprops[name])
|
||||
undisplayable = ezt.boolean(0)
|
||||
# skip non-utf8 property names
|
||||
try:
|
||||
@@ -1837,71 +1748,34 @@ def markup_or_annotate(request, is_annotate):
|
||||
fp.close()
|
||||
if check_freshness(request, None, revision, weak=1):
|
||||
return
|
||||
if is_annotate:
|
||||
annotation = 'binary'
|
||||
annotation = 'binary'
|
||||
image_src_href = request.get_url(view_func=view_checkout,
|
||||
params={'revision': rev}, escape=1)
|
||||
|
||||
# Not a viewable image.
|
||||
else:
|
||||
blame_data = None
|
||||
|
||||
# If this was an annotation request, try to annotate this file.
|
||||
# If something goes wrong, that's okay -- we'll gracefully revert
|
||||
# to a plain markup display.
|
||||
blame_source = None
|
||||
if is_annotate:
|
||||
# Try to annotate this file, but don't croak if we fail.
|
||||
try:
|
||||
blame_source, revision = request.repos.annotate(path, rev, False)
|
||||
blame_source, revision = request.repos.annotate(path, rev)
|
||||
annotation = 'annotated'
|
||||
if check_freshness(request, None, revision, weak=1):
|
||||
return
|
||||
# Create BLAME_DATA list from BLAME_SOURCE, adding diff_href
|
||||
# items to each relevant "line".
|
||||
blame_data = []
|
||||
for item in blame_source:
|
||||
item.diff_href = None
|
||||
if item.prev_rev:
|
||||
item.diff_href = request.get_url(view_func=view_diff,
|
||||
params={'r1': item.prev_rev,
|
||||
'r2': item.rev},
|
||||
escape=1, partial=1)
|
||||
blame_data.append(item)
|
||||
annotation = 'annotated'
|
||||
except vclib.NonTextualFileContents:
|
||||
annotation = 'binary'
|
||||
except:
|
||||
annotation = 'error'
|
||||
|
||||
# Grab the file contents.
|
||||
fp, revision = request.repos.openfile(path, rev, {'cvs_oldkeywords' : 1})
|
||||
if check_freshness(request, None, revision, weak=1):
|
||||
fp.close()
|
||||
return
|
||||
file_lines = fp.readlines()
|
||||
lines = markup_stream_pygments(request, cfg, blame_source, fp,
|
||||
path[-1], mime_type, encoding)
|
||||
fp.close()
|
||||
|
||||
# Do we have a differing number of file content lines and
|
||||
# annotation items? That's no good. Call it an error and don't
|
||||
# bother attempting the annotation display.
|
||||
if blame_data and (len(file_lines) != len(blame_data)):
|
||||
annotation = 'error'
|
||||
blame_data = None
|
||||
|
||||
# Try to markup the file contents/annotation. If we get an error
|
||||
# and we were colorizing the stream, try once more without the
|
||||
# colorization enabled.
|
||||
colorize = cfg.options.enable_syntax_coloration
|
||||
try:
|
||||
lines = markup_stream(request, cfg, blame_data, file_lines,
|
||||
path[-1], mime_type, encoding, colorize)
|
||||
except:
|
||||
if colorize:
|
||||
lines = markup_stream(request, cfg, blame_data, file_lines,
|
||||
path[-1], mime_type, encoding, False)
|
||||
else:
|
||||
raise debug.ViewVCException('Error displaying file contents',
|
||||
'500 Internal Server Error')
|
||||
|
||||
data = common_template_data(request, revision, mime_type)
|
||||
data = common_template_data(request, revision)
|
||||
data.merge(ezt.TemplateData({
|
||||
'mime_type' : mime_type,
|
||||
'log' : None,
|
||||
@@ -1929,12 +1803,10 @@ def markup_or_annotate(request, is_annotate):
|
||||
revs = request.repos.itemlog(path, revision, vclib.SORTBY_REV,
|
||||
0, 1, options)
|
||||
entry = revs[-1]
|
||||
lf = LogFormatter(request, entry.log)
|
||||
|
||||
data['date'] = make_time_string(entry.date, cfg)
|
||||
data['author'] = entry.author
|
||||
data['changed'] = entry.changed
|
||||
data['log'] = lf.get(maxlen=0, htmlize=1)
|
||||
data['log'] = format_log(request, entry.log)
|
||||
data['size'] = entry.size
|
||||
|
||||
if entry.date is not None:
|
||||
@@ -2050,27 +1922,20 @@ def view_roots(request):
|
||||
rootnames = allroots.keys()
|
||||
rootnames.sort(icmp)
|
||||
for rootname in rootnames:
|
||||
root_path, root_type, lastmod = allroots[rootname]
|
||||
href = request.get_url(view_func=view_directory,
|
||||
where='', pathtype=vclib.DIR,
|
||||
params={'root': rootname}, escape=1)
|
||||
if root_type == vclib.SVN:
|
||||
log_href = request.get_url(view_func=view_log,
|
||||
where='', pathtype=vclib.DIR,
|
||||
params={'root': rootname}, escape=1)
|
||||
else:
|
||||
log_href = None
|
||||
lastmod = allroots[rootname][2]
|
||||
roots.append(_item(name=request.server.escape(rootname),
|
||||
type=root_type,
|
||||
path=root_path,
|
||||
type=allroots[rootname][1],
|
||||
path=allroots[rootname][0],
|
||||
author=lastmod and lastmod.author or None,
|
||||
ago=lastmod and lastmod.ago or None,
|
||||
date=lastmod and lastmod.date or None,
|
||||
log=lastmod and lastmod.log or None,
|
||||
short_log=lastmod and lastmod.short_log or None,
|
||||
rev=lastmod and lastmod.rev or None,
|
||||
href=href,
|
||||
log_href=log_href))
|
||||
href=href))
|
||||
|
||||
data = common_template_data(request)
|
||||
data.merge(ezt.TemplateData({
|
||||
@@ -2170,11 +2035,9 @@ def view_directory(request):
|
||||
row.date = make_time_string(file.date, cfg)
|
||||
row.ago = html_time(request, file.date)
|
||||
if cfg.options.show_logs:
|
||||
debug.t_start("dirview_logformat")
|
||||
lf = LogFormatter(request, file.log)
|
||||
row.log = lf.get(maxlen=0, htmlize=1)
|
||||
row.short_log = lf.get(maxlen=cfg.options.short_log_len, htmlize=1)
|
||||
debug.t_end("dirview_logformat")
|
||||
row.log = format_log(request, file.log)
|
||||
row.short_log = format_log(request, file.log,
|
||||
maxlen=cfg.options.short_log_len)
|
||||
row.lockinfo = file.lockinfo
|
||||
row.anchor = request.server.escape(file.name)
|
||||
row.name = request.server.escape(file.name)
|
||||
@@ -2551,6 +2414,7 @@ def view_log(request):
|
||||
entry.ago = None
|
||||
if rev.date is not None:
|
||||
entry.ago = html_time(request, rev.date, 1)
|
||||
entry.log = format_log(request, rev.log or '')
|
||||
entry.size = rev.size
|
||||
entry.lockinfo = rev.lockinfo
|
||||
entry.branch_point = None
|
||||
@@ -2558,9 +2422,6 @@ def view_log(request):
|
||||
entry.orig_path = None
|
||||
entry.copy_path = None
|
||||
|
||||
lf = LogFormatter(request, rev.log or '')
|
||||
entry.log = lf.get(maxlen=0, htmlize=1)
|
||||
|
||||
entry.view_href = None
|
||||
entry.download_href = None
|
||||
entry.download_text_href = None
|
||||
@@ -3125,8 +2986,7 @@ class DiffSource:
|
||||
class DiffSequencingError(Exception):
|
||||
pass
|
||||
|
||||
def diff_parse_headers(fp, diff_type, path1, path2, rev1, rev2,
|
||||
sym1=None, sym2=None):
|
||||
def diff_parse_headers(fp, diff_type, rev1, rev2, sym1=None, sym2=None):
|
||||
date1 = date2 = log_rev1 = log_rev2 = flag = None
|
||||
header_lines = []
|
||||
|
||||
@@ -3155,15 +3015,15 @@ def diff_parse_headers(fp, diff_type, path1, path2, rev1, rev2,
|
||||
if match:
|
||||
date1 = match.group(1)
|
||||
log_rev1 = match.group(2)
|
||||
line = '%s%s\t%s\t%s%s\n' % (f1, path1, date1, log_rev1,
|
||||
sym1 and ' ' + sym1 or '')
|
||||
if sym1:
|
||||
line = line[:-1] + ' %s\n' % sym1
|
||||
elif line[:len(f2)] == f2:
|
||||
match = _re_extract_rev.match(line)
|
||||
if match:
|
||||
date2 = match.group(1)
|
||||
log_rev2 = match.group(2)
|
||||
line = '%s%s\t%s\t%s%s\n' % (f2, path2, date2, log_rev2,
|
||||
sym2 and ' ' + sym2 or '')
|
||||
if sym2:
|
||||
line = line[:-1] + ' %s\n' % sym2
|
||||
parsing = 0
|
||||
elif line[:3] == 'Bin':
|
||||
flag = _RCSDIFF_IS_BINARY
|
||||
@@ -3291,11 +3151,8 @@ def view_patch(request):
|
||||
raise debug.ViewVCException('Invalid path(s) or revision(s) passed '
|
||||
'to diff', '400 Bad Request')
|
||||
|
||||
path_left = _path_join(p1)
|
||||
path_right = _path_join(p2)
|
||||
date1, date2, flag, headers = diff_parse_headers(fp, diff_type,
|
||||
path_left, path_right,
|
||||
rev1, rev2, sym1, sym2)
|
||||
date1, date2, flag, headers = diff_parse_headers(fp, diff_type, rev1, rev2,
|
||||
sym1, sym2)
|
||||
|
||||
server_fp = get_writeready_server_file(request, 'text/plain')
|
||||
server_fp.write(headers)
|
||||
@@ -3391,7 +3248,6 @@ def view_diff(request):
|
||||
changes = []
|
||||
if fp:
|
||||
date1, date2, flag, headers = diff_parse_headers(fp, diff_type,
|
||||
path_left, path_right,
|
||||
rev1, rev2, sym1, sym2)
|
||||
if human_readable:
|
||||
if flag is not None:
|
||||
@@ -3409,8 +3265,7 @@ def view_diff(request):
|
||||
fvi = get_file_view_info(request, path_left, rev1)
|
||||
left = _item(date=make_time_string(log_entry1.date, cfg),
|
||||
author=log_entry1.author,
|
||||
log=LogFormatter(request,
|
||||
log_entry1.log).get(maxlen=0, htmlize=1),
|
||||
log=format_log(request, log_entry1.log),
|
||||
size=log_entry1.size,
|
||||
ago=ago1,
|
||||
path=path_left,
|
||||
@@ -3426,8 +3281,7 @@ def view_diff(request):
|
||||
fvi = get_file_view_info(request, path_right, rev2)
|
||||
right = _item(date=make_time_string(log_entry2.date, cfg),
|
||||
author=log_entry2.author,
|
||||
log=LogFormatter(request,
|
||||
log_entry2.log).get(maxlen=0, htmlize=1),
|
||||
log=format_log(request, log_entry2.log),
|
||||
size=log_entry2.size,
|
||||
ago=ago2,
|
||||
path=path_right,
|
||||
@@ -3675,8 +3529,7 @@ def view_revision(request):
|
||||
propnames.sort()
|
||||
props = []
|
||||
for name in propnames:
|
||||
lf = LogFormatter(request, revprops[name])
|
||||
value = lf.get(maxlen=0, htmlize=1)
|
||||
value = format_log(request, revprops[name])
|
||||
undisplayable = ezt.boolean(0)
|
||||
# skip non-utf8 property names
|
||||
try:
|
||||
@@ -3799,14 +3652,13 @@ def view_revision(request):
|
||||
escape=1)
|
||||
jump_rev_action, jump_rev_hidden_values = \
|
||||
request.get_form(params={'revision': None})
|
||||
|
||||
lf = LogFormatter(request, msg)
|
||||
|
||||
data = common_template_data(request)
|
||||
data.merge(ezt.TemplateData({
|
||||
'rev' : str(rev),
|
||||
'author' : author,
|
||||
'date' : date_str,
|
||||
'log' : lf.get(maxlen=0, htmlize=1),
|
||||
'log' : format_log(request, msg),
|
||||
'properties' : props,
|
||||
'ago' : date is not None and html_time(request, date, 1) or None,
|
||||
'changes' : changes,
|
||||
@@ -4164,10 +4016,9 @@ def build_commit(request, files, max_files, dir_strip, format):
|
||||
commit.log = None
|
||||
commit.short_log = None
|
||||
else:
|
||||
lf = LogFormatter(request, desc)
|
||||
htmlize = (format != 'rss')
|
||||
commit.log = lf.get(maxlen=0, htmlize=htmlize)
|
||||
commit.short_log = lf.get(maxlen=cfg.options.short_log_len, htmlize=htmlize)
|
||||
commit.log = format_log(request, desc, 0, format != 'rss')
|
||||
commit.short_log = format_log(request, desc, cfg.options.short_log_len,
|
||||
format != 'rss')
|
||||
commit.author = request.server.escape(author)
|
||||
commit.rss_date = make_rss_time_string(date, request.cfg)
|
||||
if request.roottype == 'svn':
|
||||
@@ -4461,9 +4312,8 @@ def list_roots(request):
|
||||
date, author, msg, revprops, changes = repos.revinfo(youngest_rev)
|
||||
date_str = make_time_string(date, cfg)
|
||||
ago = html_time(request, date)
|
||||
lf = LogFormatter(request, msg)
|
||||
log = lf.get(maxlen=0, htmlize=1)
|
||||
short_log = lf.get(maxlen=cfg.options.short_log_len, htmlize=1)
|
||||
log = format_log(request, msg)
|
||||
short_log = format_log(request, msg, maxlen=cfg.options.short_log_len)
|
||||
lastmod = _item(ago=ago, author=author, date=date_str, log=log,
|
||||
short_log=short_log, rev=str(youngest_rev))
|
||||
except:
|
||||
@@ -4555,35 +4405,14 @@ def locate_root(cfg, rootname):
|
||||
return None, None
|
||||
|
||||
def load_config(pathname=None, server=None):
|
||||
"""Load the ViewVC configuration file. SERVER is the server object
|
||||
that will be using this configuration. Consult the environment for
|
||||
the variable VIEWVC_CONF_PATHNAME and VIEWCVS_CONF_PATHNAME (its
|
||||
legacy name) and, if set, use its value as the path of the
|
||||
configuration file; otherwise, use PATHNAME (if provided). Failing
|
||||
all else, use a hardcoded default configuration path."""
|
||||
|
||||
debug.t_start('load-config')
|
||||
|
||||
# See if the environment contains overrides to the configuration
|
||||
# path. If we have a SERVER object, consult its environment; use
|
||||
# the OS environment otherwise.
|
||||
env_pathname = None
|
||||
if server is not None:
|
||||
env_pathname = (server.getenv("VIEWVC_CONF_PATHNAME")
|
||||
or server.getenv("VIEWCVS_CONF_PATHNAME"))
|
||||
else:
|
||||
env_pathname = (os.environ.get("VIEWVC_CONF_PATHNAME")
|
||||
or os.environ.get("VIEWCVS_CONF_PATHNAME"))
|
||||
if pathname is None:
|
||||
pathname = (os.environ.get("VIEWVC_CONF_PATHNAME")
|
||||
or os.environ.get("VIEWCVS_CONF_PATHNAME")
|
||||
or os.path.join(os.path.dirname(os.path.dirname(__file__)),
|
||||
"viewvc.conf"))
|
||||
|
||||
# Try to find the configuration pathname by searching these ordered
|
||||
# locations: the environment, the passed-in PATHNAME, the hard-coded
|
||||
# default.
|
||||
pathname = (env_pathname
|
||||
or pathname
|
||||
or os.path.join(os.path.dirname(os.path.dirname(__file__)),
|
||||
"viewvc.conf"))
|
||||
|
||||
# Load the configuration!
|
||||
cfg = config.Config()
|
||||
cfg.set_defaults()
|
||||
cfg.load_config(pathname, server and server.getenv("HTTP_HOST"))
|
||||
|
@@ -1,6 +1,6 @@
|
||||
# -*-python-*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2007 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
|
||||
|
@@ -92,15 +92,13 @@ numbers, and not literal):
|
||||
Also, drop a copy of the archive files into the root directory of
|
||||
the viewvc.org website (unversioned).
|
||||
|
||||
15. Update the Tigris.org website (^/trunk/www/index.html) to refer to
|
||||
the new release files and commit.
|
||||
15. On trunk, update the websites (both the viewvc.org/ and www/ ones)
|
||||
to refer to the new release files, and copy the CHANGES for the
|
||||
new release into trunk's CHANGES file.
|
||||
|
||||
svn ci -m "Bump latest advertised release."
|
||||
|
||||
16. Back on the release branch, edit the file 'lib/viewvc.py' again,
|
||||
incrementing the patch number assigned to the __version__
|
||||
variable. Add a new empty block in the branch's CHANGES file.
|
||||
Commit your changes:
|
||||
16. Edit the file 'lib/viewvc.py' again, incrementing the patch number
|
||||
assigned to the __version__ variable. Add a new empty block in
|
||||
the branch's CHANGES file. Commit your changes:
|
||||
|
||||
svn ci -m "Begin a new release cycle."
|
||||
|
||||
@@ -115,6 +113,3 @@ numbers, and not literal):
|
||||
18. Send to the announce@ list a message explaining all the cool new
|
||||
features, and post similar announcements to other places interested
|
||||
in this sort of stuff, such as Freshmeat (http://www.freshmeat.net).
|
||||
|
||||
19. Merge CHANGES for this release into the CHANGES file for newer
|
||||
release lines and commit.
|
||||
|
@@ -27,7 +27,7 @@
|
||||
[roots.name]</a>
|
||||
</td>
|
||||
[is cfg.options.show_roots_lastmod "1"]
|
||||
<td style="width:20"> [if-any roots.log_href]<a href="[roots.log_href]">[roots.rev]</a>[else][roots.rev][end]</td>
|
||||
<td style="width:20"> [roots.rev]</td>
|
||||
<td style="width:20"> [roots.ago]</td>
|
||||
<td style="width:20"> [roots.author]</td>
|
||||
<td style="width:20"> [roots.short_log]</td>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2007 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
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2007 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
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved.
|
||||
# Copyright (C) 1999-2006 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
|
||||
|
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- Mode: python -*-
|
||||
#
|
||||
# Copyright (C) 1999-2012 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
|
||||
@@ -209,8 +209,6 @@ def install_file(src_path, dst_path, mode, subst_path_vars,
|
||||
temp = raw_input("Do you want to [O]verwrite, [D]o "
|
||||
"not overwrite, or [V]iew "
|
||||
"differences? ")
|
||||
if len(temp) == 0:
|
||||
continue
|
||||
temp = string.lower(temp[0])
|
||||
if temp == "v" and ext not in BINARY_FILE_EXTS:
|
||||
print """
|
||||
|
Reference in New Issue
Block a user