From ba9cf67fae412870112ad94f4dd3ecfd15be2d60 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 22 Dec 2008 15:30:16 +0000 Subject: [PATCH 002/353] On the issue-366-dev branch: Add a new version of the commits database schema that includes a `metadata' table (in which may be found the schema version). * lib/cvsdb.py (CVSDB_VERSION): New global variable. (CheckinDatabase.__init__): Init a new _version variable. (CheckinDatabase.Connect): Fetch a list of tables and see if the new `metadata' table is present. If so, use it to query the database schema version. (Else, assume version 0.) (CheckinDatabase.GetTableList, CheckinDatabase.GetMetadataValue, CheckinDatabase.SetMetadataValue): New functions. * bin/make-database Rework this to be able to write two different schemas -- the original, Bonsai-compatible one, and a new one -- triggered by the presence/absence of a command-line --bonsai-compatible parameter. git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/issue-366-dev@2073 8cb11bc2-c004-0410-86c3-e597b4017df7 --- bin/make-database | 124 +++++++++++++++++++++++++++++++++++++++++++++- lib/cvsdb.py | 57 +++++++++++++++++++++ 2 files changed, 179 insertions(+), 2 deletions(-) diff --git a/bin/make-database b/bin/make-database index e27860ae..6576284b 100755 --- a/bin/make-database +++ b/bin/make-database @@ -28,12 +28,20 @@ you. You will then need to set the appropriate parameters in the [cvsdb] section of your viewvc.conf file. """ -DATABASE_SCRIPT="""\ +## ------------------------------------------------------------------------ +## Stuff common to all schemas +## +DATABASE_SCRIPT_COMMON="""\ DROP DATABASE IF EXISTS ; CREATE DATABASE ; USE ; +""" +## ------------------------------------------------------------------------ +## Version 0: The original, Bonsai-compatible schema. +## +DATABASE_SCRIPT_VERSION_0="""\ DROP TABLE IF EXISTS branches; CREATE TABLE branches ( id mediumint(9) NOT NULL auto_increment, @@ -121,6 +129,113 @@ CREATE TABLE tags ( ) TYPE=MyISAM; """ +## ------------------------------------------------------------------------ +## Version 1: Adds the 'metadata' table. +## +DATABASE_SCRIPT_VERSION_1="""\ +DROP TABLE IF EXISTS branches; +CREATE TABLE branches ( + id mediumint(9) NOT NULL auto_increment, + branch varchar(64) binary DEFAULT '' NOT NULL, + PRIMARY KEY (id), + UNIQUE branch (branch) +) TYPE=MyISAM; + +DROP TABLE IF EXISTS checkins; +CREATE TABLE checkins ( + type enum('Change','Add','Remove'), + ci_when datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, + whoid mediumint(9) DEFAULT '0' NOT NULL, + repositoryid mediumint(9) DEFAULT '0' NOT NULL, + dirid mediumint(9) DEFAULT '0' NOT NULL, + fileid mediumint(9) DEFAULT '0' NOT NULL, + revision varchar(32) binary DEFAULT '' NOT NULL, + stickytag varchar(255) binary DEFAULT '' NOT NULL, + branchid mediumint(9) DEFAULT '0' NOT NULL, + addedlines int(11) DEFAULT '0' NOT NULL, + removedlines int(11) DEFAULT '0' NOT NULL, + descid mediumint(9), + UNIQUE repositoryid (repositoryid,dirid,fileid,revision), + KEY ci_when (ci_when), + KEY whoid (whoid), + KEY repositoryid_2 (repositoryid), + KEY dirid (dirid), + KEY fileid (fileid), + KEY branchid (branchid) +) TYPE=MyISAM; + +DROP TABLE IF EXISTS descs; +CREATE TABLE descs ( + id mediumint(9) NOT NULL auto_increment, + description text, + hash bigint(20) DEFAULT '0' NOT NULL, + PRIMARY KEY (id), + KEY hash (hash) +) TYPE=MyISAM; + +DROP TABLE IF EXISTS dirs; +CREATE TABLE dirs ( + id mediumint(9) NOT NULL auto_increment, + dir varchar(255) binary DEFAULT '' NOT NULL, + PRIMARY KEY (id), + UNIQUE dir (dir) +) TYPE=MyISAM; + +DROP TABLE IF EXISTS files; +CREATE TABLE files ( + id mediumint(9) NOT NULL auto_increment, + file varchar(255) binary DEFAULT '' NOT NULL, + PRIMARY KEY (id), + UNIQUE file (file) +) TYPE=MyISAM; + +DROP TABLE IF EXISTS people; +CREATE TABLE people ( + id mediumint(9) NOT NULL auto_increment, + who varchar(128) binary DEFAULT '' NOT NULL, + PRIMARY KEY (id), + UNIQUE who (who) +) TYPE=MyISAM; + +DROP TABLE IF EXISTS repositories; +CREATE TABLE repositories ( + id mediumint(9) NOT NULL auto_increment, + repository varchar(64) binary DEFAULT '' NOT NULL, + PRIMARY KEY (id), + UNIQUE repository (repository) +) TYPE=MyISAM; + +DROP TABLE IF EXISTS tags; +CREATE TABLE tags ( + repositoryid mediumint(9) DEFAULT '0' NOT NULL, + branchid mediumint(9) DEFAULT '0' NOT NULL, + dirid mediumint(9) DEFAULT '0' NOT NULL, + fileid mediumint(9) DEFAULT '0' NOT NULL, + revision varchar(32) binary DEFAULT '' NOT NULL, + UNIQUE repositoryid (repositoryid,dirid,fileid,branchid,revision), + KEY repositoryid_2 (repositoryid), + KEY dirid (dirid), + KEY fileid (fileid), + KEY branchid (branchid) +) TYPE=MyISAM; + +DROP TABLE IF EXISTS metadata; +CREATE TABLE metadata ( + name varchar(255) binary DEFAULT '' NOT NULL, + value text, + PRIMARY KEY (name), + UNIQUE name (name) +) TYPE=MyISAM; +INSERT INTO metadata (name, value) VALUES ('version', '1'); +""" + +BONSAI_COMPAT=""" +Creating Bonsai-compatible database version. Some ViewVC features may not +be available, or may not perform especially well. +""" + +## ------------------------------------------------------------------------ + if __name__ == "__main__": try: print INTRO_TEXT @@ -132,7 +247,12 @@ if __name__ == "__main__": dbase = raw_input("ViewVC Database Name [default: ViewVC]: ") or "ViewVC" # Create the database - dscript = string.replace(DATABASE_SCRIPT, "", dbase) + dscript = string.replace(DATABASE_SCRIPT_COMMON, "", dbase) + if "--bonsai-compatible" in sys.argv[1:]: + print BONSAI_COMPAT + dscript = dscript + DATABASE_SCRIPT_VERSION_0 + else: + dscript = dscript + DATABASE_SCRIPT_VERSION_1 host_option = host and "--host=%s" % (host) or "" if sys.platform == "win32": cmd = "mysql --user=%s --password=%s %s "\ diff --git a/lib/cvsdb.py b/lib/cvsdb.py index dd1ec221..5d836273 100644 --- a/lib/cvsdb.py +++ b/lib/cvsdb.py @@ -20,6 +20,13 @@ import re import vclib import dbi +## Current CVSDB version number. +## +## Version 0 was the original Bonsai-compatible version. +## +## Version 1 added the 'metadata' table (which hold the 'version' key). +## +CVSDB_VERSION = 1 ## error error = "cvsdb error" @@ -37,6 +44,7 @@ class CheckinDatabase: self._passwd = passwd self._database = database self._row_limit = row_limit + self._version = None ## database lookup caches self._get_cache = {} @@ -48,6 +56,19 @@ class CheckinDatabase: self._host, self._port, self._user, self._passwd, self._database) cursor = self.db.cursor() cursor.execute("SET AUTOCOMMIT=1") + table_list = self.GetTableList() + if 'metadata' in table_list: + version = self.GetMetadataValue("version") + if version is None: + self._version = 0 + else: + self._version = int(version) + else: + self._version = 0 + if self._version > CVSDB_VERSION: + raise Exception("Database version %d is newer than the last " + "version supported by this software." + % (self._version)) def sql_get_id(self, table, column, value, auto_set): sql = "SELECT id FROM %s WHERE %s=%%s" % (table, column) @@ -147,6 +168,42 @@ class CheckinDatabase: return list + def GetTableList(self): + sql = "SHOW TABLES" + cursor = self.db.cursor() + cursor.execute(sql) + list = [] + while 1: + row = cursor.fetchone() + if row == None: + break + list.append(row[0]) + return list + + def GetMetadataValue(self, name): + sql = "SELECT value FROM metadata WHERE name=%s" + sql_args = (name) + cursor = self.db.cursor() + cursor.execute(sql, sql_args) + try: + (value,) = cursor.fetchone() + except TypeError: + return None + return value + + def SetMetadataValue(self, name, value): + assert(self._version > 0) + sql = "REPLACE INTO metadata (name, value) VALUES (%s, %s)" + sql_args = (name, value) + cursor = self.db.cursor() + try: + cursor.execute(sql, sql_args) + except Exception, e: + raise Exception("Error setting metadata: '%s'\n" + "\tname = %s\n" + "\tvalue = %s\n" + % (str(e), name, value)) + def GetBranchID(self, branch, auto_set = 1): return self.get_id("branches", "branch", branch, auto_set) From 8f8dea6051ee6d1713a2a0b86375eb782f644c98 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 22 Dec 2008 15:38:09 +0000 Subject: [PATCH 003/353] On the 'issue-366-dev' branch: Add a new index to version 1 of the commits database schema, and use it (when present) in the 'purge' operation. * lib/cvsdb.py (CheckinDatabase.sql_purge): New function. (CheckinDatabase.PurgeRepository): If we have a schema version that supports it, use a much faster approach of purging. Otherwise, we have to suffer through a slow purge process. * bin/make-database (DATABASE_SCRIPT_VERSION_1): Add a new index of 'descid's to the 'checkins' table. Patch (mostly) by: Larry Shatzer, Jr. git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/issue-366-dev@2074 8cb11bc2-c004-0410-86c3-e597b4017df7 --- bin/make-database | 6 +++-- lib/cvsdb.py | 61 ++++++++++++++++++++++++++++++----------------- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/bin/make-database b/bin/make-database index 6576284b..540e9b0b 100755 --- a/bin/make-database +++ b/bin/make-database @@ -130,7 +130,8 @@ CREATE TABLE tags ( """ ## ------------------------------------------------------------------------ -## Version 1: Adds the 'metadata' table. +## Version 1: Adds the 'metadata' table. Adds 'descid' index to +## 'checkins' table. ## DATABASE_SCRIPT_VERSION_1="""\ DROP TABLE IF EXISTS branches; @@ -161,7 +162,8 @@ CREATE TABLE checkins ( KEY repositoryid_2 (repositoryid), KEY dirid (dirid), KEY fileid (fileid), - KEY branchid (branchid) + KEY branchid (branchid), + KEY descid (descid) ) TYPE=MyISAM; DROP TABLE IF EXISTS descs; diff --git a/lib/cvsdb.py b/lib/cvsdb.py index 5d836273..8255aa37 100644 --- a/lib/cvsdb.py +++ b/lib/cvsdb.py @@ -515,33 +515,50 @@ class CheckinDatabase: cursor = self.db.cursor() cursor.execute(sql, sql_args) + def sql_purge(self, table, key, fkey, ftable): + sql = "DELETE FROM %s WHERE %s NOT IN (SELECT %s FROM %s)" \ + % (table, key, fkey, ftable) + cursor = self.db.cursor() + cursor.execute(sql) + def PurgeRepository(self, repository): rep_id = self.GetRepositoryID(repository) if not rep_id: raise Exception, "Unknown repository '%s'" % (repository) - - sql = "SELECT * FROM checkins WHERE repositoryid=%s" - sql_args = (rep_id, ) - cursor = self.db.cursor() - cursor.execute(sql, sql_args) - checkins = [] - while 1: - try: - (ci_type, ci_when, who_id, repository_id, - dir_id, file_id, revision, sticky_tag, branch_id, - plus_count, minus_count, description_id) = cursor.fetchone() - except TypeError: - break - checkins.append([file_id, dir_id, branch_id, description_id, who_id]) - #self.sql_delete('repositories', 'id', rep_id) - self.sql_delete('checkins', 'repositoryid', rep_id) - for checkin in checkins: - self.sql_delete('files', 'id', checkin[0], 'fileid') - self.sql_delete('dirs', 'id', checkin[1], 'dirid') - self.sql_delete('branches', 'id', checkin[2], 'branchid') - self.sql_delete('descs', 'id', checkin[3], 'descid') - self.sql_delete('people', 'id', checkin[4], 'whoid') + if (self._version > 0): + self.sql_delete('repositories', 'id', rep_id) + self.sql_purge('checkins', 'repositoryid', 'id', 'repositories') + self.sql_purge('files', 'id', 'fileid', 'checkins') + self.sql_purge('dirs', 'id', 'dirid', 'checkins') + self.sql_purge('branches', 'id', 'branchid', 'checkins') + self.sql_purge('descs', 'id', 'descid', 'checkins') + self.sql_purge('people', 'id', 'whoid', 'checkins') + else: + sql = "SELECT * FROM checkins WHERE repositoryid=%s" + sql_args = (rep_id, ) + cursor = self.db.cursor() + cursor.execute(sql, sql_args) + checkins = [] + while 1: + try: + (ci_type, ci_when, who_id, repository_id, + dir_id, file_id, revision, sticky_tag, branch_id, + plus_count, minus_count, description_id) = \ + cursor.fetchone() + except TypeError: + break + checkins.append([file_id, dir_id, branch_id, + description_id, who_id]) + + #self.sql_delete('repositories', 'id', rep_id) + self.sql_delete('checkins', 'repositoryid', rep_id) + for checkin in checkins: + self.sql_delete('files', 'id', checkin[0], 'fileid') + self.sql_delete('dirs', 'id', checkin[1], 'dirid') + self.sql_delete('branches', 'id', checkin[2], 'branchid') + self.sql_delete('descs', 'id', checkin[3], 'descid') + self.sql_delete('people', 'id', checkin[4], 'whoid') ## the Commit class holds data on one commit, the representation is as ## close as possible to how it should be committed and retrieved to the From af83138e5ca5c5b7054f8ca32924e96526506f47 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 22 Dec 2008 21:04:12 +0000 Subject: [PATCH 004/353] On the 'issue-366-dev' branch: Rename the 'checkins' table to 'commits' in schema version 1 (so that old version-ignorant code will croak on a version-1 database). * lib/cvsdb.py (CheckinDatabase.AddCommit, CheckinDatabase.CreateSQLQueryString, CheckinDatabase.CheckCommit, CheckinDatabase.sql_delete, CheckinDatabase.PurgeRepository): Account for the fact that in version 1 of the commits database schema, the 'checkins' table has been renamed to 'commits'. * bin/make-database (DATABASE_SCRIPT_VERSION_1): Rename the 'checkins' table to 'commits'. git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/issue-366-dev@2075 8cb11bc2-c004-0410-86c3-e597b4017df7 --- bin/make-database | 6 ++-- lib/cvsdb.py | 82 +++++++++++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 34 deletions(-) diff --git a/bin/make-database b/bin/make-database index 540e9b0b..c468c5f7 100755 --- a/bin/make-database +++ b/bin/make-database @@ -131,7 +131,7 @@ CREATE TABLE tags ( ## ------------------------------------------------------------------------ ## Version 1: Adds the 'metadata' table. Adds 'descid' index to -## 'checkins' table. +## 'checkins' table, and renames that table to 'commits'. ## DATABASE_SCRIPT_VERSION_1="""\ DROP TABLE IF EXISTS branches; @@ -142,8 +142,8 @@ CREATE TABLE branches ( UNIQUE branch (branch) ) TYPE=MyISAM; -DROP TABLE IF EXISTS checkins; -CREATE TABLE checkins ( +DROP TABLE IF EXISTS commits; +CREATE TABLE commits ( type enum('Change','Add','Remove'), ci_when datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, whoid mediumint(9) DEFAULT '0' NOT NULL, diff --git a/lib/cvsdb.py b/lib/cvsdb.py index 8255aa37..f7470892 100644 --- a/lib/cvsdb.py +++ b/lib/cvsdb.py @@ -20,13 +20,14 @@ import re import vclib import dbi -## Current CVSDB version number. +## Current commits database schema version number. ## ## Version 0 was the original Bonsai-compatible version. ## -## Version 1 added the 'metadata' table (which hold the 'version' key). +## Version 1 added the 'metadata' table (which holds the 'version' key) +## and renamed all the 'repository'-related stuff to be 'root'- ## -CVSDB_VERSION = 1 +CURRENT_SCHEMA_VERSION = 1 ## error error = "cvsdb error" @@ -65,7 +66,7 @@ class CheckinDatabase: self._version = int(version) else: self._version = 0 - if self._version > CVSDB_VERSION: + if self._version > CURRENT_SCHEMA_VERSION: raise Exception("Database version %d is newer than the last " "version supported by this software." % (self._version)) @@ -308,7 +309,9 @@ class CheckinDatabase: minus_count = commit.GetMinusCount() or '0' description_id = self.GetDescriptionID(commit.GetDescription()) - sql = "REPLACE INTO checkins"\ + commits_table = self._version >= 1 and 'commits' or 'checkins' + sql = "REPLACE INTO %s" % (commits_table) + sql = sql + \ " (type,ci_when,whoid,repositoryid,dirid,fileid,revision,"\ " stickytag,branchid,addedlines,removedlines,descid)"\ "VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)" @@ -361,58 +364,69 @@ class CheckinDatabase: return "(%s)" % (string.join(sqlList, " OR ")) def CreateSQLQueryString(self, query): - tableList = [("checkins", None)] + commits_table = self._version >= 1 and 'commits' or 'checkins' + tableList = [(commits_table, None)] condList = [] if len(query.repository_list): tableList.append(("repositories", - "(checkins.repositoryid=repositories.id)")) + "(%s.repositoryid=repositories.id)" + % (commits_table))) temp = self.SQLQueryListString("repositories.repository", query.repository_list) condList.append(temp) if len(query.branch_list): - tableList.append(("branches", "(checkins.branchid=branches.id)")) + tableList.append(("branches", + "(%s.branchid=branches.id)" % (commits_table))) temp = self.SQLQueryListString("branches.branch", query.branch_list) condList.append(temp) if len(query.directory_list): - tableList.append(("dirs", "(checkins.dirid=dirs.id)")) + tableList.append(("dirs", + "(%s.dirid=dirs.id)" % (commits_table))) temp = self.SQLQueryListString("dirs.dir", query.directory_list) condList.append(temp) if len(query.file_list): - tableList.append(("files", "(checkins.fileid=files.id)")) + tableList.append(("files", + "(%s.fileid=files.id)" % (commits_table))) temp = self.SQLQueryListString("files.file", query.file_list) condList.append(temp) if len(query.author_list): - tableList.append(("people", "(checkins.whoid=people.id)")) + tableList.append(("people", + "(%s.whoid=people.id)" % (commits_table))) temp = self.SQLQueryListString("people.who", query.author_list) condList.append(temp) if len(query.comment_list): - tableList.append(("descs", "(checkins.descid=descs.id)")) + tableList.append(("descs", + "(%s.descid=descs.id)" % (commits_table))) temp = self.SQLQueryListString("descs.description", query.comment_list) condList.append(temp) if query.from_date: - temp = "(checkins.ci_when>=\"%s\")" % (str(query.from_date)) + temp = "(%s.ci_when>=\"%s\")" \ + % (commits_table, str(query.from_date)) condList.append(temp) if query.to_date: - temp = "(checkins.ci_when<=\"%s\")" % (str(query.to_date)) + temp = "(%s.ci_when<=\"%s\")" \ + % (commits_table, str(query.to_date)) condList.append(temp) if query.sort == "date": - order_by = "ORDER BY checkins.ci_when DESC,descid" + order_by = "ORDER BY %s.ci_when DESC,descid" % (commits_table) elif query.sort == "author": - tableList.append(("people", "(checkins.whoid=people.id)")) + tableList.append(("people", + "(%s.whoid=people.id)" % (commits_table))) order_by = "ORDER BY people.who,descid" elif query.sort == "file": - tableList.append(("files", "(checkins.fileid=files.id)")) + tableList.append(("files", + "(%s.fileid=files.id)" % (commits_table))) order_by = "ORDER BY files.file,descid" ## exclude duplicates from the table list, and split out join @@ -438,8 +452,8 @@ class CheckinDatabase: elif self._row_limit: limit = "LIMIT %s" % (str(self._row_limit)) - sql = "SELECT checkins.* FROM %s %s %s %s" % ( - tables, conditions, order_by, limit) + sql = "SELECT %s.* FROM %s %s %s %s" \ + % (commits_table, tables, conditions, order_by, limit) return sql @@ -490,8 +504,13 @@ class CheckinDatabase: if file_id == None: return None - sql = "SELECT * FROM checkins WHERE "\ - " repositoryid=%s AND dirid=%s AND fileid=%s AND revision=%s" + commits_table = self._version >= 1 and 'commits' or 'checkins' + sql = "SELECT * FROM %s WHERE "\ + " repositoryid=%%s "\ + " AND dirid=%%s"\ + " AND fileid=%%s"\ + " AND revision=%%s"\ + % (commits_table) sql_args = (repository_id, dir_id, file_id, commit.GetRevision()) cursor = self.db.cursor() @@ -508,10 +527,11 @@ class CheckinDatabase: def sql_delete(self, table, key, value, keep_fkey = None): sql = "DELETE FROM %s WHERE %s=%%s" % (table, key) sql_args = (value, ) + commits_table = self._version >= 1 and 'commits' or 'checkins' if keep_fkey: - sql += " AND %s NOT IN (SELECT %s FROM checkins WHERE %s = %%s)" \ - % (key, keep_fkey, keep_fkey) - sql_args = (value, value) + sql += " AND %s NOT IN (SELECT %s FROM %s WHERE %s = %%s)" \ + % (key, keep_fkey, commits_table, keep_fkey) + sql_args = (value, value) cursor = self.db.cursor() cursor.execute(sql, sql_args) @@ -526,14 +546,14 @@ class CheckinDatabase: if not rep_id: raise Exception, "Unknown repository '%s'" % (repository) - if (self._version > 0): + if (self._version >= 1): self.sql_delete('repositories', 'id', rep_id) - self.sql_purge('checkins', 'repositoryid', 'id', 'repositories') - self.sql_purge('files', 'id', 'fileid', 'checkins') - self.sql_purge('dirs', 'id', 'dirid', 'checkins') - self.sql_purge('branches', 'id', 'branchid', 'checkins') - self.sql_purge('descs', 'id', 'descid', 'checkins') - self.sql_purge('people', 'id', 'whoid', 'checkins') + self.sql_purge('commits', 'repositoryid', 'id', 'repositories') + self.sql_purge('files', 'id', 'fileid', 'commits') + self.sql_purge('dirs', 'id', 'dirid', 'commits') + self.sql_purge('branches', 'id', 'branchid', 'commits') + self.sql_purge('descs', 'id', 'descid', 'commits') + self.sql_purge('people', 'id', 'whoid', 'commits') else: sql = "SELECT * FROM checkins WHERE repositoryid=%s" sql_args = (rep_id, ) From b6486f5324e56e44498dd19e95a6f910645cac0e Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 22 Dec 2008 21:22:46 +0000 Subject: [PATCH 005/353] On the 'issue-366-dev' branch: add 'make-database --help' parameter. * bin/make-database (BONSAI_COMPAT): Tweak a little bit. (__main__): Add support for a --help parameter that prints a usage message. git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/issue-366-dev@2076 8cb11bc2-c004-0410-86c3-e597b4017df7 --- bin/make-database | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/bin/make-database b/bin/make-database index c468c5f7..203fecd9 100755 --- a/bin/make-database +++ b/bin/make-database @@ -232,13 +232,31 @@ INSERT INTO metadata (name, value) VALUES ('version', '1'); """ BONSAI_COMPAT=""" -Creating Bonsai-compatible database version. Some ViewVC features may not -be available, or may not perform especially well. +WARNING: Creating Bonsai-compatible legacy database version. Some ViewVC +features may not be available, or may not perform especially well. + """ ## ------------------------------------------------------------------------ if __name__ == "__main__": + + if "--help" in sys.argv[1:]: + sys.stderr.write("""\ +Usage: %s [OPTIONS] + +Create and initialize a ViewVC commits database. You will be prompted for +a MySQL hostname, and the username and password of a MySQL user who +has permission to create this database and its collection of tables. + +Options: + + --bonsai-compatible Create the database using the original ViewCVS + schema, which was designed for compatibility + with Bonsai. +""" % (os.path.basename(sys.argv[0]))) + sys.exit(0) + try: print INTRO_TEXT From a2cd81f30475ff9ceb1d85e7b2b91736f010924b Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 20 Aug 2009 20:38:32 +0000 Subject: [PATCH 006/353] Begin taking steps toward customizable log message markup/formatting, and I think, actually fix ancient issue #3 ("URL cut off in elipsis")! Incidentally, this change also makes the email address obfuscation stuff work as documented. Not sure how I started munging data when mangle_email_addresses=1 (by substituting " at " for the at-sign), but no more. * lib/viewvc.py (htmlify): Drop 'mangle_email_addresses' parameter, which was mostly unused, and no longer do anything except very basic HTML encoding. Callers updated. (_re_rewrite_url): Tweak to match *non*-HTML-encoded URLs now. (HtmlFormatToken, HtmlFormatter): New classes for log formatting. (mangle_email_addresses): Remove as unused. (format_log): Add 'maxlen' parameter, allowing this function to be used for both long- and short-form log message formatting. (copy_stream): Drop unnecessary 'cfg' parameter. Update call to htmlify(). (MarkupPipeWrapper.__init__): Drop 'cfg' parameter as unused. (MarkupPipeWrapper.__call__): Update call to htmlify(). (markup_or_annotate, view_revision, view_directory, view_log, build_commit): Use format_log() to format both long- and short-form log messages. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2244 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 215 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 160 insertions(+), 55 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index f63d126e..0007cd3e 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1075,55 +1075,164 @@ def get_file_view_info(request, where, rev=None, mime_type=None, pathrev=-1): revision_href=revision_href, prefer_markup=ezt.boolean(prefer_markup)) +def htmlify(html): + return html and cgi.escape(html) or html -# Regular expressions for location text that looks like URLs and email -# addresses. Note that the regexps assume the text is already HTML-encoded. + +# Matches URLs _re_rewrite_url = re.compile('((http|https|ftp|file|svn|svn\+ssh)' - '(://[-a-zA-Z0-9%.~:_/]+)((\?|\&)' + '(://[-a-zA-Z0-9%.~:_/]+)((\?|\&)' '([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*' '(#([-a-zA-Z0-9%.~:_]+)?)?)') +# Matches email addresses _re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@' '(([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})') -def mangle_email_addresses(text, style=0): - # style=2: truncation mangling - if style == 2: - return re.sub(_re_rewrite_email, r'\1@…', text) - # style=1: entity-encoding and at-wrapping - if style == 1: - def _match_replace(matchobj): - return string.join(map(lambda x: '&#%d;' % (ord(x)), - matchobj.group(1)), '') \ - + ' {at} ' + \ - string.join(map(lambda x: '&#%d;' % (ord(x)), - matchobj.group(2)), '') - return re.sub(_re_rewrite_email, _match_replace, text) +class HtmlFormatToken: + def __init__(self, mobj, converter): + self.mobj = mobj + self.converter = converter - # otherwise, no mangling - return text + +class HtmlFormatter: + def __init__(self): + self._formatters = [] -def htmlify(html, mangle_email_addrs=0): - if not html: - return html - html = cgi.escape(html) - html = re.sub(_re_rewrite_url, r'\1', html) - html = mangle_email_addresses(html, mangle_email_addrs) - return html + def format_url(self, mobj, maxlen=0): + """Return a 2-tuple containing: + - the text represented by MatchObject MOBJ, formatted as + linkified URL, with no more than MAXLEN characters in the + non-HTML-tag bits. If MAXLEN is 0, there is no maximum. + - the number of non-HTML-tag characters returned. + """ + s = mobj.group(0) + trunc_s = maxlen and s[:maxlen] or s + return '%s' % (cgi.escape(s), + cgi.escape(trunc_s)), \ + len(trunc_s) -def format_log(log, cfg, htmlize=1): + def format_email(self, mobj, maxlen=0): + """Return a 2-tuple containing: + - the text represented by MatchObject MOBJ, formatted as + linkified email address, with no more than MAXLEN characters + in the non-HTML-tag bits. If MAXLEN is 0, there is no maximum. + - the number of non-HTML-tag characters returned. + """ + s = mobj.group(0) + trunc_s = maxlen and s[:maxlen] or s + return '%s' % (urllib.quote(s), + self._entity_encode(trunc_s)), \ + len(trunc_s) + + def format_email_obfuscated(self, mobj, maxlen=0): + """Return a 2-tuple containing: + - the text represented by MatchObject MOBJ, formatted as an + entity-encoded email address, with no more than MAXLEN characters + in the non-HTML-tag bits. If MAXLEN is 0, there is no maximum. + - the number of non-HTML-tag characters returned. + """ + s = mobj.group(0) + trunc_s = maxlen and s[:maxlen] or s + return self._entity_encode(trunc_s), len(trunc_s) + + def format_email_truncated(self, mobj, maxlen=0): + """Return a 2-tuple containing: + - the text represented by MatchObject MOBJ, formatted as an + HTML-escaped truncated email address of no more than MAXLEN + characters. If MAXLEN is 0, there is no maximum. + - the number of characters returned. + """ + if (maxlen == 0) or (len(mobj.group(1)) < (maxlen - 2)): + return self._entity_encode(mobj.group(1)) + '@…', \ + len(mobj.group(1)) + 2 + else: + trunc_s = mobj.group(1)[:maxlen-1] + return self._entity_encode(trunc_s) + '…', len(trunc_s) + 1 + + def format_text(self, s, maxlen=0): + """Return a 2-tuple containing: + - the text S, HTML-escaped, containing no more than MAXLEN + characters. If MAXLEN is 0, there is no maximum. + - the number of characters returned. + """ + trunc_s = maxlen and s[:maxlen] or s + return cgi.escape(trunc_s), len(trunc_s) + + def add_formatter(self, regexp, conv): + """Register a formatter which finds instances of strings matching + REGEXP, and using the function CONV to format them. + + CONV is a function which accepts two parameters: the MatchObject + which holds the string portion to be formatted, and the maximum + number of characters from that string to use for human-readable + output (or 0 to indicate no maximum). + """ + if type(regexp) == type(''): + regexp = re.compile(regexp) + self._formatters.append([regexp, conv]) + + def get_result(self, s, maxlen=0): + """Return the string S, formatted per the set of added formatters, + with no more than MAXLEN characters of 'visible' output. + """ + out = '' + for token in self._tokenize_text(s): + chunk, chunk_len = token.converter(token.mobj, maxlen) + out = out + chunk + if maxlen: + maxlen = maxlen - chunk_len + if maxlen <= 0: + break + return out + + def _entity_encode(self, s): + return string.join(map(lambda x: '&#%d;' % (ord(x)), s), '') + + def _tokenize_text(self, s): + tokens = [] + while s: + best_match = None + best_conv = None + for test in self._formatters: + match = test[0].search(s) + if match \ + and ((best_match is None) \ + or (match.start() < best_match.start())): + best_match = match + best_conv = test[1] + if best_match: + # add any non-matching stuff at the beginning, then the matching bit. + start = best_match.start() + end = best_match.end() + if start > 0: + tokens.append(HtmlFormatToken(s[:start], self.format_text)) + tokens.append(HtmlFormatToken(best_match, best_conv)) + s = s[end:] + else: + # add the rest of the string. + tokens.append(HtmlFormatToken(s, self.format_text)) + s = '' + return tokens + +def format_log(log, cfg, maxlen=0, htmlize=1): if not log: return log + if htmlize: - s = htmlify(log[:cfg.options.short_log_len], - cfg.options.mangle_email_addresses) - else: - s = cgi.escape(log[:cfg.options.short_log_len]) + lf = HtmlFormatter() + lf.add_formatter(_re_rewrite_url, lf.format_url) if cfg.options.mangle_email_addresses == 2: - s = re.sub(_re_rewrite_email, r'\1@...', s) - if len(log) > cfg.options.short_log_len: - s = s + '...' - return s + 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) + return lf.get_result(log, maxlen) + 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', @@ -1319,22 +1428,21 @@ def retry_read(src, reqlen=CHUNK_SIZE): continue return chunk -def copy_stream(src, dst, cfg, htmlize=0): +def copy_stream(src, dst, htmlize=0): while 1: chunk = retry_read(src) if not chunk: break if htmlize: - chunk = htmlify(chunk, mangle_email_addrs=0) + chunk = htmlify(chunk) dst.write(chunk) class MarkupPipeWrapper: """An EZT callback that outputs a filepointer, plus some optional pre- and post- text.""" - def __init__(self, cfg, fp, pretext=None, posttext=None, htmlize=1): + def __init__(self, fp, pretext=None, posttext=None, htmlize=0): self.fp = fp - self.cfg = cfg self.pretext = pretext self.posttext = posttext self.htmlize = htmlize @@ -1342,7 +1450,7 @@ class MarkupPipeWrapper: def __call__(self, ctx): if self.pretext: ctx.fp.write(self.pretext) - copy_stream(self.fp, ctx.fp, self.cfg, self.htmlize) + copy_stream(self.fp, ctx.fp, self.htmlize) self.fp.close() if self.posttext: ctx.fp.write(self.posttext) @@ -1579,7 +1687,7 @@ def markup_or_annotate(request, is_annotate): data['date'] = make_time_string(entry.date, cfg) data['author'] = entry.author data['changed'] = entry.changed - data['log'] = htmlify(entry.log, cfg.options.mangle_email_addresses) + data['log'] = format_log(entry.log, cfg) data['size'] = entry.size if entry.date is not None: @@ -1795,8 +1903,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: - row.short_log = format_log(file.log, cfg) - row.log = htmlify(file.log, cfg.options.mangle_email_addresses) + row.log = format_log(file.log, cfg) + row.short_log = format_log(file.log, cfg, + maxlen=cfg.options.short_log_len) row.lockinfo = file.lockinfo row.anchor = request.server.escape(file.name) row.name = request.server.escape(file.name) @@ -1882,9 +1991,7 @@ def view_directory(request): 'entries' : rows, 'sortby' : sortby, 'sortdir' : sortdir, - 'search_re' : search_re \ - and htmlify(search_re, cfg.options.mangle_email_addresses) \ - or None, + 'search_re' : htmlify(search_re), 'dir_pagestart' : None, 'sortby_file_href' : request.get_url(params={'sortby': 'file', 'sortdir': None}, @@ -2171,7 +2278,7 @@ def view_log(request): entry.ago = None if rev.date is not None: entry.ago = html_time(request, rev.date, 1) - entry.log = htmlify(rev.log or "", cfg.options.mangle_email_addresses) + entry.log = format_log(rev.log or '', cfg) entry.size = rev.size entry.lockinfo = rev.lockinfo entry.branch_point = None @@ -2696,7 +2803,7 @@ class DiffSource: text = string.replace(text, ' ', ' \x01nbsp;') else: text = string.replace(text, ' ', '\x01nbsp;') - text = htmlify(text, mangle_email_addrs=0) + text = htmlify(text) text = string.replace(text, '\x01', '&') text = string.replace(text, '\x02', '\
') @@ -3071,9 +3178,7 @@ def view_diff(request): else: changes = DiffSource(fp, cfg) else: - raw_diff_fp = MarkupPipeWrapper(cfg, fp, - htmlify(headers, mangle_email_addrs=0), - None, 1) + raw_diff_fp = MarkupPipeWrapper(fp, htmlify(headers), None, 1) no_format_params = request.query_dict.copy() no_format_params['diff_format'] = None @@ -3449,7 +3554,7 @@ def view_revision(request): 'rev' : str(rev), 'author' : author, 'date' : date_str, - 'log' : msg and htmlify(msg, cfg.options.mangle_email_addresses) or None, + 'log' : format_log(msg, cfg), 'ago' : date is not None and html_time(request, date, 1) or None, 'changes' : changes, 'prev_href' : prev_rev_href, @@ -3580,8 +3685,7 @@ def english_query(request): ret.append('on all branches ') comment = request.query_dict.get('comment', '') if comment: - ret.append('with comment %s ' - % htmlify(comment, mangle_email_addrs=0)) + ret.append('with comment %s ' % htmlify(comment)) if who: ret.append('by %s ' % request.server.escape(who)) date = request.query_dict.get('date', 'hours') @@ -3769,8 +3873,9 @@ def build_commit(request, files, max_files, dir_strip, format): commit.log = None commit.short_log = None else: - commit.log = htmlify(desc) - commit.short_log = format_log(desc, cfg, format != 'rss') + commit.log = format_log(desc, cfg, format != 'rss') + commit.short_log = format_log(desc, cfg, format != 'rss', + cfg.options.short_log_len) commit.author = request.server.escape(author) commit.rss_date = make_rss_time_string(date, request.cfg) if request.roottype == 'svn': From 589f111f2060dc4c9200267301a96544ff27475a Mon Sep 17 00:00:00 2001 From: cmpilato Date: Fri, 21 Aug 2009 15:05:21 +0000 Subject: [PATCH 007/353] Follow-up to r2244 with some changes that allow you to register userdata along with the log message formatters for use by the conversion functions. While ViewVC doesn't use this right now, the feature has proven useful in writing an add-on that allows somewhat generic highlighting of issue/bug IDs to URLs. * lib/viewvc.py (HtmlFormatToken): Remove. (HtmlFormatter.format_url, HtmlFormatter.format_email_obfuscated, HtmlFormatter.format_email_truncated, HtmlFormatter.format_email, HtmlFormatter.format_text): Now accept (unused) 'userdata' parameter. (HtmlFormatter.add_formatter): Now accept 'userdata' parameter, associated with the formatter for future use. (HtmlFormatter.get_result): Pass the 'userdata' from the token to its converter. (HtmlFormatter._tokenize_text): Switch to using _item()s instead of HtmlFormatTokens. Associate with each item the userdata for its converter. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2245 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 0007cd3e..c67b5481 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1089,17 +1089,11 @@ _re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@' '(([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})') -class HtmlFormatToken: - def __init__(self, mobj, converter): - self.mobj = mobj - self.converter = converter - - class HtmlFormatter: def __init__(self): self._formatters = [] - def format_url(self, mobj, maxlen=0): + def format_url(self, mobj, userdata, maxlen=0): """Return a 2-tuple containing: - the text represented by MatchObject MOBJ, formatted as linkified URL, with no more than MAXLEN characters in the @@ -1112,7 +1106,7 @@ class HtmlFormatter: cgi.escape(trunc_s)), \ len(trunc_s) - def format_email(self, mobj, maxlen=0): + def format_email(self, mobj, userdata, maxlen=0): """Return a 2-tuple containing: - the text represented by MatchObject MOBJ, formatted as linkified email address, with no more than MAXLEN characters @@ -1125,7 +1119,7 @@ class HtmlFormatter: self._entity_encode(trunc_s)), \ len(trunc_s) - def format_email_obfuscated(self, mobj, maxlen=0): + def format_email_obfuscated(self, mobj, userdata, maxlen=0): """Return a 2-tuple containing: - the text represented by MatchObject MOBJ, formatted as an entity-encoded email address, with no more than MAXLEN characters @@ -1136,7 +1130,7 @@ class HtmlFormatter: trunc_s = maxlen and s[:maxlen] or s return self._entity_encode(trunc_s), len(trunc_s) - def format_email_truncated(self, mobj, maxlen=0): + def format_email_truncated(self, mobj, userdata, maxlen=0): """Return a 2-tuple containing: - the text represented by MatchObject MOBJ, formatted as an HTML-escaped truncated email address of no more than MAXLEN @@ -1150,7 +1144,7 @@ class HtmlFormatter: trunc_s = mobj.group(1)[:maxlen-1] return self._entity_encode(trunc_s) + '…', len(trunc_s) + 1 - def format_text(self, s, maxlen=0): + def format_text(self, s, unused, maxlen=0): """Return a 2-tuple containing: - the text S, HTML-escaped, containing no more than MAXLEN characters. If MAXLEN is 0, there is no maximum. @@ -1159,18 +1153,19 @@ class HtmlFormatter: trunc_s = maxlen and s[:maxlen] or s return cgi.escape(trunc_s), len(trunc_s) - def add_formatter(self, regexp, conv): + def add_formatter(self, regexp, conv, userdata=None): """Register a formatter which finds instances of strings matching - REGEXP, and using the function CONV to format them. + REGEXP, and using the function CONV and USERDATA to format them. - CONV is a function which accepts two parameters: the MatchObject - which holds the string portion to be formatted, and the maximum - number of characters from that string to use for human-readable - output (or 0 to indicate no maximum). + CONV is a function which accepts three parameters: + - the MatchObject which holds the string portion to be formatted, + - the USERDATA object, + - the maximum number of characters from that string to use for + human-readable output (or 0 to indicate no maximum). """ if type(regexp) == type(''): regexp = re.compile(regexp) - self._formatters.append([regexp, conv]) + self._formatters.append([regexp, conv, userdata]) def get_result(self, s, maxlen=0): """Return the string S, formatted per the set of added formatters, @@ -1178,7 +1173,7 @@ class HtmlFormatter: """ out = '' for token in self._tokenize_text(s): - chunk, chunk_len = token.converter(token.mobj, maxlen) + chunk, chunk_len = token.converter(token.match, token.userdata, maxlen) out = out + chunk if maxlen: maxlen = maxlen - chunk_len @@ -1192,8 +1187,7 @@ class HtmlFormatter: def _tokenize_text(self, s): tokens = [] while s: - best_match = None - best_conv = None + best_match = best_conv = best_userdata = None for test in self._formatters: match = test[0].search(s) if match \ @@ -1201,17 +1195,24 @@ class HtmlFormatter: or (match.start() < best_match.start())): best_match = match best_conv = test[1] + best_userdata = test[2] if best_match: # add any non-matching stuff at the beginning, then the matching bit. start = best_match.start() end = best_match.end() if start > 0: - tokens.append(HtmlFormatToken(s[:start], self.format_text)) - tokens.append(HtmlFormatToken(best_match, best_conv)) + tokens.append(_item(match=s[:start], + converter=self.format_text, + userdata=None)) + tokens.append(_item(match=best_match, + converter=best_conv, + userdata=best_userdata)) s = s[end:] else: # add the rest of the string. - tokens.append(HtmlFormatToken(s, self.format_text)) + tokens.append(_item(match=s, + converter=self.format_text, + userdata=None)) s = '' return tokens From 884a5de16d04b2e5c0ff15514e31c47197541bc7 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Fri, 21 Aug 2009 15:58:19 +0000 Subject: [PATCH 008/353] Follow-up to r2244 and r2245, supplying a way for the HtmlFormatter to indicate that truncation happened (so callers can tack on an ellipsis or somesuch). * lib/viewvc.py (HtmlFormatter.format_email_truncated): Fix logic to use ellipsis for mangling but not for truncation. (Also fix an off-by-one error in the logic.) (HtmlFormatter.get_result): Now return the result string and a "was-truncated" flag. (format_log): Update call to HtmlFormatter.get_result, and tack on an ellipsis if the log was truncated. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2247 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index c67b5481..9b8c2caf 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1137,12 +1137,15 @@ class HtmlFormatter: characters. If MAXLEN is 0, there is no maximum. - the number of characters returned. """ - if (maxlen == 0) or (len(mobj.group(1)) < (maxlen - 2)): - return self._entity_encode(mobj.group(1)) + '@…', \ - len(mobj.group(1)) + 2 + s = mobj.group(1) + s_len = len(s) + if (maxlen == 0) or (s_len < (maxlen - 1)): + return self._entity_encode(s) + '@…', s_len + 2 + elif s_len < maxlen: + return self._entity_encode(s) + '@', s_len + 1 else: - trunc_s = mobj.group(1)[:maxlen-1] - return self._entity_encode(trunc_s) + '…', len(trunc_s) + 1 + trunc_s = mobj.group(1)[:maxlen] + return self._entity_encode(trunc_s), len(trunc_s) def format_text(self, s, unused, maxlen=0): """Return a 2-tuple containing: @@ -1168,8 +1171,10 @@ class HtmlFormatter: self._formatters.append([regexp, conv, userdata]) def get_result(self, s, maxlen=0): - """Return the string S, formatted per the set of added formatters, - with no more than MAXLEN characters of 'visible' output. + """Format S per the set of formatters registered with this object, + and limited to MAXLEN visible characters (or unlimited if MAXLEN + is 0). Return a 2-tuple containing the formatted result string + and a boolean flag indicating whether or not S was truncated. """ out = '' for token in self._tokenize_text(s): @@ -1178,8 +1183,8 @@ class HtmlFormatter: if maxlen: maxlen = maxlen - chunk_len if maxlen <= 0: - break - return out + return out, 1 + return out, 0 def _entity_encode(self, s): return string.join(map(lambda x: '&#%d;' % (ord(x)), s), '') @@ -1229,7 +1234,8 @@ def format_log(log, cfg, maxlen=0, htmlize=1): lf.add_formatter(_re_rewrite_email, lf.format_email_obfuscated) else: lf.add_formatter(_re_rewrite_email, lf.format_email) - return lf.get_result(log, maxlen) + log, 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) From 6b4297e7f5e444a96a91a39887774b068b45b5ef Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 24 Aug 2009 15:08:58 +0000 Subject: [PATCH 009/353] Add configurable support for tabstop-to-space translation. * conf/viewvc.conf.dist (options.tabsize): New. * lib/config.py (Config.set_defaults): Set default value for the 'tabsize' option. * lib/viewvc.py (markup_stream_pygments): Pass the 'tabsize' parameter to Pygments' lexers. When not using pygments, use 'string.expandtabs' to do tab-to-space conversion (possibly with a new object that wraps BlameSource objects solely for that purpose). (DiffSource._format_text): Honor the tabsize configuration options when expanding tabs to spaces. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2249 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 5 +++++ lib/config.py | 1 + lib/viewvc.py | 18 ++++++++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index f9a9542f..f679853b 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -559,6 +559,11 @@ ## #enable_syntax_coloration = 1 +## tabsize: The number of spaces into which tabstops are converted +## when viewing file contents. +## +#tabsize = 8 + ## detect_encoding: Should we attempt to detect versioned file ## character encodings? [Requires 'chardet' module, and is currently ## used only by the syntax coloration logic -- if enabled -- for the diff --git a/lib/config.py b/lib/config.py index 04d01ae8..9f72cc4c 100644 --- a/lib/config.py +++ b/lib/config.py @@ -244,6 +244,7 @@ class Config: self.options.use_localtime = 0 self.options.short_log_len = 80 self.options.enable_syntax_coloration = 1 + self.options.tabsize = 8 self.options.detect_encoding = 0 self.options.use_cvsgraph = 0 self.options.cvsgraph_conf = "cvsgraph.conf" diff --git a/lib/viewvc.py b/lib/viewvc.py index 9b8c2caf..aca9b429 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1498,11 +1498,13 @@ def markup_stream_pygments(request, cfg, blame_data, fp, filename, mime_type): try: lexer = get_lexer_for_mimetype(mime_type, encoding=encoding, + tabsize=cfg.options.tabsize, stripnl=False) except ClassNotFound: try: lexer = get_lexer_for_filename(filename, encoding=encoding, + tabsize=cfg.options.tabsize, stripnl=False) except ClassNotFound: use_pygments = 0 @@ -1514,7 +1516,15 @@ def markup_stream_pygments(request, cfg, blame_data, fp, filename, mime_type): # one from the file contents we fetch with PATH and REV. if not use_pygments: if blame_source: - return 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) + return item + return BlameSourceTabsizeWrapper(blame_source, cfg.options.tabsize) else: lines = [] line_no = 0 @@ -1523,8 +1533,8 @@ def markup_stream_pygments(request, cfg, blame_data, fp, filename, mime_type): if not line: break line_no = line_no + 1 - item = vclib.Annotation(cgi.escape(line), line_no, - None, None, None, None) + line = cgi.escape(string.expandtabs(line, cfg.options.tabsize)) + item = vclib.Annotation(line, line_no, None, None, None, None) item.diff_href = None lines.append(item) return lines @@ -2796,7 +2806,7 @@ class DiffSource: return item def _format_text(self, text): - text = string.expandtabs(string.rstrip(text)) + text = string.expandtabs(string.rstrip(text), self.cfg.options.tabsize) hr_breakable = self.cfg.options.hr_breakable # in the code below, "\x01" will be our stand-in for "&". We don't want From 40581a211cb149c80be5b9dd1c380ff520af80a0 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 25 Aug 2009 15:22:04 +0000 Subject: [PATCH 010/353] * lib/viewvc.py (view_diff): Tweak some logic ordering, and ensure that 'changes' is initialized as a sequence (instead of None) as some template logic paths seem to care. Reported by: Lawrence Cutlip-Mason git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2251 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index aca9b429..4ce84d3c 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3180,15 +3180,12 @@ def view_diff(request): 'to diff', '400 Bad Request') path_left = _path_join(p1) path_right = _path_join(p2) + + date1 = date2 = raw_diff_fp = None + changes = [] if fp: date1, date2, flag, headers = diff_parse_headers(fp, diff_type, - rev1, rev2, - sym1, sym2) - else: - date1 = date2 = flag = headers = None - - raw_diff_fp = changes = None - if fp: + rev1, rev2, sym1, sym2) if human_readable: if flag is not None: changes = [ _item(type=flag) ] @@ -3199,6 +3196,8 @@ def view_diff(request): no_format_params = request.query_dict.copy() no_format_params['diff_format'] = None + diff_format_action, diff_format_hidden_values = \ + request.get_form(params=no_format_params) fvi = get_file_view_info(request, path_left, rev1) left = _item(date=rcsdiff_date_reformat(date1, cfg), @@ -3224,9 +3223,6 @@ def view_diff(request): revision_href=fvi.revision_href, prefer_markup=fvi.prefer_markup) - diff_format_action, diff_format_hidden_values = \ - request.get_form(params=no_format_params) - data = common_template_data(request) data.merge(ezt.TemplateData({ 'left' : left, From 8a8e8cd1f507f73f5a059f340f5f9131dbc73daf Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 25 Aug 2009 15:25:16 +0000 Subject: [PATCH 011/353] Make the installing of the 'templates-contrib' tree optional. * viewvc-install (TREE_LIST): Add a new field -- a boolean "is-optional" flag. (install_tree): New parameter 'is_optional', used to avoid whining when something in the source tree is missing. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2252 8cb11bc2-c004-0410-86c3-e597b4017df7 --- viewvc-install | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/viewvc-install b/viewvc-install index 71ca070c..dd93cc9f 100755 --- a/viewvc-install +++ b/viewvc-install @@ -75,11 +75,12 @@ if sys.platform == "win32": ## List of directories for installation. ## type (source path, ## destination path, +## boolean -- optional item?, ## boolean -- prompt before replacing?) TREE_LIST = [ - ("lib", "lib", 0), - ("templates", "templates", 1), - ("templates-contrib", "templates-contrib", 1), + ("lib", "lib", 0, 0), + ("templates", "templates", 0, 1), + ("templates-contrib", "templates-contrib", 1, 1), ] @@ -275,18 +276,22 @@ LEGEND py_compile.compile(destdir_path, destdir_path + "c" , dst_path) -def install_tree(src_path, dst_path, prompt_replace): +def install_tree(src_path, dst_path, is_optional, prompt_replace): """Install a tree whose source is at SRC_PATH (which is relative to the ViewVC source directory) into the location DST_PATH (which is relative both to the global ROOT_DIR and DESTDIR settings). If PROMPT_REPLACE is set (and is not overridden by global setting CLEAN_MODE), prompt the user for how to deal with already existing - files that differ from the to-be-installed version.""" + files that differ from the to-be-installed version. If + IS_OPTIONAL is set, don't fuss about a missing source item.""" orig_src_path = src_path orig_dst_path = dst_path src_path = _actual_src_path(src_path) dst_path = os.path.join(ROOT_DIR, string.replace(dst_path, '/', os.sep)) + if not os.path.isdir(src_path): + print " skipping %s" % (dst_path) + return destdir_path = os.path.join(DESTDIR + dst_path) # Get a list of items in the directory. @@ -306,7 +311,7 @@ def install_tree(src_path, dst_path, prompt_replace): # If the item is a subdirectory, recurse. Otherwise, install the file. if os.path.isdir(os.path.join(src_path, fname)): - install_tree(orig_src_child, orig_dst_child, prompt_replace) + install_tree(orig_src_child, orig_dst_child, 0, prompt_replace) else: set_paths = 0 compile_it = fname[-3:] == '.py' From e7a9e33a36305086f37ff36558c8f16dd4fef786 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 27 Aug 2009 15:17:37 +0000 Subject: [PATCH 012/353] Make some tweaks to the HtmlFormatter to allow more complex usages. * lib/viewvc.py (HtmlFormatter): Add docstring. (HtmlFormatter.get_result): Now return the total number of readable characters, too. (format_log): Update expected return values from lf.get_result(). git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2255 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 4ce84d3c..091e0474 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1090,6 +1090,14 @@ _re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@' class HtmlFormatter: + """Format a string as HTML-encoded output with customizable markup + rules, for example turning strings that look like URLs into anchor links. + + NOTE: While there might appear to be some unused portions of this + interface, there is a good chance that there are consumers outside + of ViewVC itself that make use of these things. + """ + def __init__(self): self._formatters = [] @@ -1173,18 +1181,21 @@ class HtmlFormatter: def get_result(self, s, maxlen=0): """Format S per the set of formatters registered with this object, and limited to MAXLEN visible characters (or unlimited if MAXLEN - is 0). Return a 2-tuple containing the formatted result string - and a boolean flag indicating whether or not S was truncated. + 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._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, 1 - return out, 0 + return out, out_len, 1 + return out, out_len, 0 def _entity_encode(self, s): return string.join(map(lambda x: '&#%d;' % (ord(x)), s), '') @@ -1234,7 +1245,7 @@ def format_log(log, cfg, maxlen=0, htmlize=1): lf.add_formatter(_re_rewrite_email, lf.format_email_obfuscated) else: lf.add_formatter(_re_rewrite_email, lf.format_email) - log, truncated = lf.get_result(log, maxlen) + log, log_len, truncated = lf.get_result(log, maxlen) return log + (truncated and '…' or '') else: if cfg.options.mangle_email_addresses == 2: From 0b42d41e431dd2136d9f4ec584c4cca55a815205 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 31 Aug 2009 14:54:26 +0000 Subject: [PATCH 013/353] * lib/viewvc.py (HtmlFormatter._tokenize_text): Give preference to the longer of overlapping matches that begin at the same point. Add some comments that better explain what we're doing. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2257 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 091e0474..efea67a4 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1206,14 +1206,25 @@ class HtmlFormatter: best_match = best_conv = best_userdata = None for test in self._formatters: match = test[0].search(s) + # If we find and match and (a) its our first one, or (b) it + # matches text earlier than our previous best match, or (c) it + # matches text at the same location as our previous best match + # but extends to cover more text than that match, then this is + # our new best match. + # + # Implied here is that when multiple formatters match exactly + # the same text, the first formatter in the registration list wins. if match \ and ((best_match is None) \ - or (match.start() < best_match.start())): + or (match.start() < best_match.start()) + or ((match.start() == best_match.start()) \ + and (match.end() > best_match.end()))): best_match = match best_conv = test[1] best_userdata = test[2] + # If we found a match... if best_match: - # add any non-matching stuff at the beginning, then the matching bit. + # ... add any non-matching stuff first, then the matching bit. start = best_match.start() end = best_match.end() if start > 0: @@ -1225,7 +1236,7 @@ class HtmlFormatter: userdata=best_userdata)) s = s[end:] else: - # add the rest of the string. + # Otherwise, just add the rest of the string. tokens.append(_item(match=s, converter=self.format_text, userdata=None)) From f72e67fa3e1c52d8276a8a1f77b3449c2b0aecd1 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 9 Sep 2009 14:18:15 +0000 Subject: [PATCH 014/353] * templates/file.ezt Don't point folks to the checkout view if it's disabled. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2259 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/file.ezt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/file.ezt b/templates/file.ezt index 17c09915..9ced2b5c 100644 --- a/templates/file.ezt +++ b/templates/file.ezt @@ -71,9 +71,9 @@ Revision [if-any revision_href][rev]< [if-any image_src_href][define hide_binary_garbage]0[end][end] [is hide_binary_garbage "1"] -

This file's contents are not viewable. Please - download this version of the - file in order to view it.

+

This file's contents are not viewable. + [if-any download_href]Please download + this version of the file in order to view it.[end]

[else] [define last_rev]0[end] From 761a97cb47aa5c55cc748bbc798a6165a11b401d Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 9 Sep 2009 15:57:43 +0000 Subject: [PATCH 015/353] * conf/viewvc.conf.dist (utilities): Clarify what we mean by "the directories in which certain programs live". Suggested by: Eric McCarty git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2261 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index f679853b..35fb1533 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -243,9 +243,14 @@ ## aren't installed in the executable search path, so here's where you can ## tell ViewVC where to find them. ## -## NOTE: Options with a "_dir" suffix are for configuring the directories -## in which certain programs live; otherwise, the option value should -## point to the actual program. +## NOTE: Options with a "_dir" suffix are for configuring the +## directories in which certain programs live. Note that this might +## not be the same directory into which the program's installer dumped +## the whole program package -- we want the deepest directory in which +## the executable program itself resides ("C:\rcstools\bin\win32" +## rather than just "C:\rcsroos", for example). The values of options +## whose names lack the "_dir" suffix should point to the actual +## program itself (such as "C:\Program Files\cvsnt\cvs.exe"). ## rcs_dir: Directory in which the RCS utilities are installed, used From 0f376ac9a41286a4e72a85813bdf7df4f94377b5 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 9 Sep 2009 16:03:02 +0000 Subject: [PATCH 016/353] [singing] A spoonful of proofreading helps the temperature go down... git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2263 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index 35fb1533..e16e572e 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -248,7 +248,7 @@ ## not be the same directory into which the program's installer dumped ## the whole program package -- we want the deepest directory in which ## the executable program itself resides ("C:\rcstools\bin\win32" -## rather than just "C:\rcsroos", for example). The values of options +## rather than just "C:\rcstools", for example). The values of options ## whose names lack the "_dir" suffix should point to the actual ## program itself (such as "C:\Program Files\cvsnt\cvs.exe"). From 9015d128857e1294f1b39712736fd0e84ce42a3a Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 9 Sep 2009 18:54:15 +0000 Subject: [PATCH 017/353] Fix issue #427 - regex filtering broken by bogus validator function. * lib/viewvc.py (_validate_regex): Try compiling the incoming regex, returning True on success and None otherwise. (Simply 'pass'ing caused all regexs to fail validation.) Patch by: Robert Fleming git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2265 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index efea67a4..0e1c41ff 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -633,12 +633,14 @@ def _validate_param(name, value): '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. From 98f1b93068e33b062df04bf8dd51c61b9d795777 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 6 Oct 2009 19:11:28 +0000 Subject: [PATCH 018/353] * lib/vclib/svn/svn_repos.py (LocalSubversionRepository.open): Remove custom SIGTERM handler. It's causing problems for mod_python deployments, and I can't seem to make it do anything meaningful for CGI deployments either. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2268 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/svn/svn_repos.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/lib/vclib/svn/svn_repos.py b/lib/vclib/svn/svn_repos.py index af7eea24..0638bdcc 100644 --- a/lib/vclib/svn/svn_repos.py +++ b/lib/vclib/svn/svn_repos.py @@ -17,7 +17,6 @@ import os import os.path import string import cStringIO -import signal import time import tempfile import popen @@ -383,22 +382,6 @@ class LocalSubversionRepository(vclib.Repository): raise vclib.ReposNotFound(name) def open(self): - # Register a handler for SIGTERM so we can have a chance to - # cleanup. If ViewVC takes too long to start generating CGI - # output, Apache will grow impatient and SIGTERM it. While we - # don't mind getting told to bail, we want to gracefully close the - # repository before we bail. - def _sigterm_handler(signum, frame, self=self): - sys.exit(-1) - try: - signal.signal(signal.SIGTERM, _sigterm_handler) - except ValueError: - # This is probably "ValueError: signal only works in main - # thread", which will get thrown by the likes of mod_python - # when trying to install a signal handler from a thread that - # isn't the main one. We'll just not care. - pass - # Open the repository and init some other variables. self.repos = repos.svn_repos_open(self.rootpath) self.fs_ptr = repos.svn_repos_fs(self.repos) From 6e4710d1c60fc8b4641e182b07743364ee4730d1 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 8 Oct 2009 14:48:02 +0000 Subject: [PATCH 019/353] Clarify the Apache configuration instructions. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2269 8cb11bc2-c004-0410-86c3-e597b4017df7 --- INSTALL | 66 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/INSTALL b/INSTALL index 74f28493..9c4da160 100644 --- a/INSTALL +++ b/INSTALL @@ -168,14 +168,23 @@ checkin database working are below. APACHE CONFIGURATION -------------------- -1) Find out where the web server configuration file is kept. Typical - locations are /etc/httpd/httpd.conf, /etc/httpd/conf/httpd.conf, - and /etc/apache/httpd.conf. Depending on how apache was installed, - you may also look under /usr/local/etc or /etc/local. Use the vendor - documentation or the find utility if in doubt. +1) Locate your Apache configuration file(s). -Either METHOD A: -2) The ScriptAlias directive is very useful for pointing + Typical locations are /etc/httpd/httpd.conf, + /etc/httpd/conf/httpd.conf, and /etc/apache/httpd.conf. Depending + on how Apache was installed, you may also look under /usr/local/etc + or /etc/local. Use the vendor documentation or the find utility if + in doubt. + +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: + + ----------------------------------- + METHOD A: CGI mode via ScriptAlias + ----------------------------------- + The ScriptAlias directive is very useful for pointing directly to the viewvc.cgi script. Simply insert a line containing ScriptAlias /viewvc /bin/cgi/viewvc.cgi @@ -186,20 +195,21 @@ Either METHOD A: ScriptAlias /viewvc /usr/local/viewvc-1.0/bin/cgi/viewvc.cgi ScriptAlias /query /usr/local/viewvc-1.0/bin/cgi/query.cgi - continue with step 3). - -or alternatively METHOD B: -2) Copy the CGI scripts from + ---------------------------------------- + METHOD B: CGI mode in cgi-bin directory + ---------------------------------------- + Copy the CGI scripts from /bin/cgi/*.cgi to the /cgi-bin/ directory configured in your httpd.conf file. - continue with step 3). -and then there's METHOD C: -2) Copy the CGI scripts from + ------------------------------------------ + METHOD C: CGI mode in ExecCGI'd directory + ------------------------------------------ + Copy the CGI scripts from /bin/cgi/*.cgi 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: + Apache directives for the directory in httpd.conf or an .htaccess file: Options +ExecCGI AddHandler cgi-script .cgi @@ -208,12 +218,12 @@ and then there's METHOD C: to be effective, "AllowOverride All" or "AllowOverride Options FileInfo" need to have been specified for the directory.) - continue with step 3). - -or if you've got Mod_Python installed you can use METHOD D: -2) Copy the Python scripts and .htaccess file from + --------------------------- + METHOD D: Using mod_python + --------------------------- + Copy the Python scripts and .htaccess file from /bin/mod_python/ - to a directory being served by apache. + to a directory being served by Apache. In httpd.conf, make sure that "AllowOverride All" or at least "AllowOverride FileInfo Options" are enabled for the directory @@ -223,17 +233,17 @@ or if you've got Mod_Python installed you can use METHOD D: feature may not work because it uses multithreading. This works fine under Apache 2. - continue with step 3). +3) Restart Apache. -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" + 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. +4) [Optional] Add access control. - In your httpd.conf you can control access to certain modules by adding - directives like this: + In your httpd.conf you can control access to certain modules by + adding directives like this: /"> AllowOverride None From 4c9aa8e1a619b1d3847bd13e33e770b0b301addc Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 8 Oct 2009 14:50:04 +0000 Subject: [PATCH 020/353] Minor tweaks. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2270 8cb11bc2-c004-0410-86c3-e597b4017df7 --- INSTALL | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/INSTALL b/INSTALL index 9c4da160..d08ef8e9 100644 --- a/INSTALL +++ b/INSTALL @@ -201,7 +201,6 @@ APACHE CONFIGURATION Copy the CGI scripts from /bin/cgi/*.cgi to the /cgi-bin/ directory configured in your httpd.conf file. - ------------------------------------------ METHOD C: CGI mode in ExecCGI'd directory @@ -218,9 +217,9 @@ APACHE CONFIGURATION to be effective, "AllowOverride All" or "AllowOverride Options FileInfo" need to have been specified for the directory.) - --------------------------- - METHOD D: Using mod_python - --------------------------- + ------------------------------------------ + METHOD D: Using mod_python (if installed) + ------------------------------------------ Copy the Python scripts and .htaccess file from /bin/mod_python/ to a directory being served by Apache. From f182d12e979f5cee08f307b27e06095d0030ba8a Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 8 Oct 2009 14:56:25 +0000 Subject: [PATCH 021/353] As part of issue #397, add initial support for mod_wsgi deployments. * lib/sapi.py (WsgiServer): New class. * bin/wsgi, * bin/wsgi/viewvc.wsgi, * bin/wsgi/query.wsgi New stubs. * viewvc-install (FILE_INFO_LIST): Also install WSGI scripts. * INSTALL Add instructions for WSGI deployment. Patch (mostly) by: Rune Halvorsen git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2271 8cb11bc2-c004-0410-86c3-e597b4017df7 --- INSTALL | 16 +++++++++++ bin/wsgi/query.wsgi | 42 +++++++++++++++++++++++++++++ bin/wsgi/viewvc.wsgi | 41 ++++++++++++++++++++++++++++ lib/sapi.py | 64 ++++++++++++++++++++++++++++++++++++++++++-- viewvc-install | 2 ++ 5 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 bin/wsgi/query.wsgi create mode 100644 bin/wsgi/viewvc.wsgi diff --git a/INSTALL b/INSTALL index d08ef8e9..d224a1d5 100644 --- a/INSTALL +++ b/INSTALL @@ -232,6 +232,22 @@ APACHE CONFIGURATION feature may not work because it uses multithreading. This works fine under Apache 2. + ---------------------------------------- + METHOD E: Using mod_wsgi (if installed) + ---------------------------------------- + Copy the Python scripts file from + /bin/mod_python/ + to the directory of your choosing. Modify httpd.conf with the + following directives: + + WSGIScriptAlias /viewvc /bin/wsgi/viewvc.wsgi + WSGIScriptAlias /query /bin/wsgi/query.wsgi + + You'll probably also need the following directive because of the + not-quite-sanctioned way that ViewVC manipulates Python objects. + + WSGIApplicationGroup %{GLOBAL} + 3) Restart Apache. The commands to do this vary. "httpd -k restart" and "apache -k diff --git a/bin/wsgi/query.wsgi b/bin/wsgi/query.wsgi new file mode 100644 index 00000000..b6217dd9 --- /dev/null +++ b/bin/wsgi/query.wsgi @@ -0,0 +1,42 @@ +# -*-python-*- +# +# 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 +# distribution or at http://viewvc.org/license-1.html. +# +# For more information, visit http://viewvc.org/ +# +# ----------------------------------------------------------------------- +# +# viewvc: View CVS/SVN repositories via a web browser +# +# ----------------------------------------------------------------------- +# +# This is a wsgi entry point for the query ViewVC app. It's appropriate +# for use with mod_wsgi. It defines a single application function that +# is a walid wsgi entry point. +# +# ----------------------------------------------------------------------- + +import sys, os + +LIBRARY_DIR = None +CONF_PATHNAME = None + +if LIBRARY_DIR: + sys.path.insert(0, LIBRARY_DIR) +else: + sys.path.insert(0, os.path.abspath(os.path.join(sys.argv[0], + "../../../lib"))) + +import sapi +import viewvc +import query + +def application(environ, start_response): + server = sapi.WsgiServer(environ, start_response) + cfg = viewvc.load_config(CONF_PATHNAME, server) + query.main(server, cfg, "viewvc.wsgi") + return [] diff --git a/bin/wsgi/viewvc.wsgi b/bin/wsgi/viewvc.wsgi new file mode 100644 index 00000000..7224981f --- /dev/null +++ b/bin/wsgi/viewvc.wsgi @@ -0,0 +1,41 @@ +# -*-python-*- +# +# 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 +# distribution or at http://viewvc.org/license-1.html. +# +# For more information, visit http://viewvc.org/ +# +# ----------------------------------------------------------------------- +# +# viewvc: View CVS/SVN repositories via a web browser +# +# ----------------------------------------------------------------------- +# +# This is a wsgi entry point for the main ViewVC app. It's appropriate +# for use with mod_wsgi. It defines a single application function that +# is a walid wsgi entry point. +# +# ----------------------------------------------------------------------- + +import sys, os + +LIBRARY_DIR = None +CONF_PATHNAME = None + +if LIBRARY_DIR: + sys.path.insert(0, LIBRARY_DIR) +else: + sys.path.insert(0, os.path.abspath(os.path.join(sys.argv[0], + "../../../lib"))) + +import sapi +import viewvc + +def application(environ, start_response): + server = sapi.WsgiServer(environ, start_response) + cfg = viewvc.load_config(CONF_PATHNAME, server) + viewvc.main(server, cfg) + return [] diff --git a/lib/sapi.py b/lib/sapi.py index e36774e7..22001cc7 100644 --- a/lib/sapi.py +++ b/lib/sapi.py @@ -22,8 +22,8 @@ import sys import re -# global server object. It will be either a CgiServer or a proxy to -# an AspServer or ModPythonServer object. +# global server object. It will be either a CgiServer, a WsgiServer, +# or a proxy to an AspServer or ModPythonServer object. server = None @@ -187,6 +187,66 @@ class CgiServer(Server): return sys.stdout +class WsgiServer(Server): + def __init__(self, environ, start_response): + Server.__init__(self) + + self._environ = environ + self._start_response = start_response; + self._headers = [] + self._wsgi_write = None + self.headerSent = False + + global server + server = self + + global cgi + import cgi + + def addheader(self, name, value): + self._headers.append((name, value)) + + def header(self, content_type='text/html; charset=UTF-8', status=None): + if not status: + status = "200 OK" + if not self.headerSent: + self.headerSent = True + self._headers.insert(0, ("Content-Type", content_type),) + self._wsgi_write = self._start_response("%s" % status, self._headers) + + def redirect(self, url): + """Redirect client to url. This discards any data that has been queued + to be sent to the user. But there should never by any anyway. + """ + self.addheader('Location', url) + self.header(status='301 Moved') + self._wsgi_write('This document is located here.' % url) + + def escape(self, s, quote = None): + return cgi.escape(s, quote) + + def getenv(self, name, value=None): + return self._environ.get(name, value) + + def params(self): + return cgi.parse(environ=self._environ, fp=self._environ["wsgi.input"]) + + def FieldStorage(self, fp=None, headers=None, outerboundary="", + environ=os.environ, keep_blank_values=0, strict_parsing=0): + return cgi.FieldStorage(self._environ["wsgi.input"], self._headers, + outerboundary, self._environ, keep_blank_values, + strict_parsing) + + def write(self, s): + self._wsgi_write(s) + + def flush(self): + pass + + def file(self): + return File(self) + + class AspServer(ThreadedServer): def __init__(self, Server, Request, Response, Application): ThreadedServer.__init__(self) diff --git a/viewvc-install b/viewvc-install index dd93cc9f..e868a025 100755 --- a/viewvc-install +++ b/viewvc-install @@ -49,6 +49,8 @@ CLEAN_MODE = None FILE_INFO_LIST = [ ("bin/cgi/viewvc.cgi", "bin/cgi/viewvc.cgi", 0755, 1, 0, 0), ("bin/cgi/query.cgi", "bin/cgi/query.cgi", 0755, 1, 0, 0), + ("bin/wsgi/viewvc.wsgi", "bin/wsgi/viewvc.wsgi", 0755, 1, 0, 0), + ("bin/wsgi/query.wsgi", "bin/wsgi/query.wsgi", 0755, 1, 0, 0), ("bin/mod_python/viewvc.py", "bin/mod_python/viewvc.py", 0755, 1, 0, 0), ("bin/mod_python/query.py", "bin/mod_python/query.py", 0755, 1, 0, 0), ("bin/mod_python/handler.py", "bin/mod_python/handler.py", 0755, 1, 0, 0), From 1f8c5aca3773628e961b2fc521c949fbeb6330b7 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 8 Oct 2009 17:53:14 +0000 Subject: [PATCH 022/353] Fix a bug that caused log message in the query view to be truncated to a single character. * lib/viewvc.py (build_commit): Fix calls to format_log(). It turns out that parameter ordering is, you know, somewhat important. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2273 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 0e1c41ff..b21d7b2f 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3910,9 +3910,9 @@ def build_commit(request, files, max_files, dir_strip, format): commit.log = None commit.short_log = None else: - commit.log = format_log(desc, cfg, format != 'rss') - commit.short_log = format_log(desc, cfg, format != 'rss', - cfg.options.short_log_len) + commit.log = format_log(desc, cfg, 0, format != 'rss') + commit.short_log = format_log(desc, cfg, 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': From 54086fd651b44a2b75bf6cf9b4996af2ac8ccb81 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Sun, 25 Oct 2009 20:46:09 +0000 Subject: [PATCH 023/353] Finish issue #431 - make revision metadata available in diff view. * lib/viewvc.py (view_diff): Use repos.itemlog() to fetch revision metadata about the left- and right-hand diff objects and expose 'author', 'log', 'ago', and 'size' to the templates. * docs/template-authoring-guide.html Document the newly added template data dictionary items. * templates/diff.ezt Display the revision authors in the diff view. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2275 8cb11bc2-c004-0410-86c3-e597b4017df7 --- docs/template-authoring-guide.html | 40 ++++++++++++++++++++++++++++++ lib/viewvc.py | 21 ++++++++++++++-- templates/diff.ezt | 4 +-- 3 files changed, 61 insertions(+), 4 deletions(-) diff --git a/docs/template-authoring-guide.html b/docs/template-authoring-guide.html index 1a87709d..ef4790fe 100644 --- a/docs/template-authoring-guide.html +++ b/docs/template-authoring-guide.html @@ -796,12 +796,22 @@ td { Container Container object for grouping information about the left file. + + left.ago + String + Text description of the time elapsed since left.date. + left.annotate_href String URL of the ViewVC annotation view for the left file. Valid only when entries.pathtype is file. + + left.author + String + Author of the revision of the left file. + left.date String @@ -819,6 +829,11 @@ td { URL to download the HEAD revision of the left file as text/plain. + + left.log + String + Log message of the left file revision. + left.path String @@ -842,6 +857,11 @@ td { current revision. Valid only when roottype is svn. + + left.size + String + Size of the left file revision, in bytes. Subversion only. + left.tag String @@ -863,12 +883,22 @@ td { Container Container object for grouping information about the right file. + + right.author + String + Author of the revision of the right file. + right.annotate_href String URL of the ViewVC annotation view for the right file. Valid only when entries.pathtype is file. + + right.author + String + Author of the revision of the right file. + right.date String @@ -886,6 +916,11 @@ td { URL to download the HEAD revision of the right file as text/plain. + + right.log + String + Log message of the right file revision. + right.path String @@ -909,6 +944,11 @@ td { current revision. Valid only when roottype is svn. + + right.size + String + Size of the right file revision, in bytes. Subversion only. + right.tag String diff --git a/lib/viewvc.py b/lib/viewvc.py index b21d7b2f..461d716e 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3144,6 +3144,15 @@ def view_diff(request): if check_freshness(request, None, '%s-%s' % (rev1, rev2), weak=1): return + # TODO: Is the slice necessary, or is limit enough? + log_entry1 = request.repos.itemlog(p1, rev1, vclib.SORTBY_REV, 0, 1, {})[-1] + log_entry2 = request.repos.itemlog(p2, rev2, vclib.SORTBY_REV, 0, 1, {})[-1] + + ago1 = log_entry1.date is not None \ + and html_time(request, log_entry1.date, 1) or None + ago2 = log_entry2.date is not None \ + and html_time(request, log_entry2.date, 2) or None + diff_type = None diff_options = {} human_readable = 0 @@ -3224,7 +3233,11 @@ def view_diff(request): request.get_form(params=no_format_params) fvi = get_file_view_info(request, path_left, rev1) - left = _item(date=rcsdiff_date_reformat(date1, cfg), + left = _item(date=make_time_string(log_entry1.date, cfg), + author=log_entry1.author, + log=format_log(log_entry1.log, cfg), + size=log_entry1.size, + ago=ago1, path=path_left, rev=rev1, tag=sym1, @@ -3236,7 +3249,11 @@ def view_diff(request): prefer_markup=fvi.prefer_markup) fvi = get_file_view_info(request, path_right, rev2) - right = _item(date=rcsdiff_date_reformat(date2, cfg), + right = _item(date=make_time_string(log_entry2.date, cfg), + author=log_entry2.author, + log=format_log(log_entry2.log, cfg), + size=log_entry2.size, + ago=ago2, path=path_right, rev=rev2, tag=sym2, diff --git a/templates/diff.ezt b/templates/diff.ezt index 069ae4c0..f01fbc4a 100644 --- a/templates/diff.ezt +++ b/templates/diff.ezt @@ -21,13 +21,13 @@ [is left.path right.path][else][left.path][end] - revision [if-any left_view_href][end][left.rev][if-any left_view_href][end], + revision [if-any left_view_href][end][left.rev][if-any left_view_href][end][if-any left.author] by [left.author][end], [left.date] [if-any left.tag]
Tag: [left.tag][end] [is left.path right.path][else][right.path][end] - revision [if-any right_view_href][end][right.rev][if-any right_view_href][end], + revision [if-any right_view_href][end][right.rev][if-any right_view_href][end][if-any right.author] by [right.author][end], [right.date] [if-any right.tag]
Tag: [right.tag][end] From 11efd97b23bbdc66a19853e9769b2e826e3f6983 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Sun, 25 Oct 2009 22:06:54 +0000 Subject: [PATCH 024/353] For issue #434, mark up URLs and email addresses in item property values as we do for revision property values. * lib/viewvc.py (get_itemprops): Pass property values through format_log(). Patch by: Senthil Kumaran S git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2277 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 461d716e..5c2aa20f 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1624,7 +1624,7 @@ def get_itemprops(request, path_parts, rev): props = [] has_binary_props = 0 for name in propnames: - value = itemprops[name] + value = format_log(itemprops[name], request.cfg) undisplayable = ezt.boolean(0) # skip non-utf8 property names try: From 7e3a9d7f4d4d2553c761908e5fdfa093f9d5d6e8 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 5 Nov 2009 16:35:05 +0000 Subject: [PATCH 025/353] Make ViewVC cross copies in Subversion history by default. * lib/config.py (Config.set_defaults): Make 'options.cross_copies' default to 1. At a minimum that makes it jive with the commented out default value shown in viewvc.conf.dist, but I believe that it's also the better of the two ways to resolve that disparity in terms of user experience. Noticed by: Tom Throckmorton git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2279 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/config.py b/lib/config.py index 9f72cc4c..f632112f 100644 --- a/lib/config.py +++ b/lib/config.py @@ -240,7 +240,7 @@ class Config: self.options.show_subdir_lastmod = 0 self.options.show_logs = 1 self.options.show_log_in_markup = 1 - self.options.cross_copies = 0 + self.options.cross_copies = 1 self.options.use_localtime = 0 self.options.short_log_len = 80 self.options.enable_syntax_coloration = 1 From cd62600043ca86ad917bfd36e6a4de314de77852 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 10 Nov 2009 22:16:17 +0000 Subject: [PATCH 026/353] Fix issue #438, a regression caused by a botched function signature change in r2244. * lib/viewvc.py (view_checkout, view_cvsgraph_image, view_doc, view_patch): Fix calls to copy_stream(). git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2281 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 5c2aa20f..566922d7 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -2581,7 +2581,7 @@ def view_checkout(request): or calculate_mime_type(request, path, rev) \ or 'text/plain' server_fp = get_writeready_server_file(request, mime_type) - copy_stream(fp, server_fp, cfg) + copy_stream(fp, server_fp) fp.close() def cvsgraph_make_reqopt(request, cfgname, queryparam, optvalue): @@ -2657,7 +2657,7 @@ def view_cvsgraph_image(request): cvsgraph_extraopts(request), rcsfile), 'rb', 0) - copy_stream(fp, get_writeready_server_file(request, 'image/png'), cfg) + copy_stream(fp, get_writeready_server_file(request, 'image/png')) fp.close() def view_cvsgraph(request): @@ -2781,7 +2781,7 @@ def view_doc(request): mime_type = 'text/css' else: # assume HTML: mime_type = None - copy_stream(fp, get_writeready_server_file(request, mime_type), cfg) + copy_stream(fp, get_writeready_server_file(request, mime_type)) fp.close() def rcsdiff_date_reformat(date_str, cfg): @@ -3126,7 +3126,7 @@ def view_patch(request): server_fp = get_writeready_server_file(request, 'text/plain') server_fp.write(headers) - copy_stream(fp, server_fp, cfg) + copy_stream(fp, server_fp) fp.close() From d1cbb81fb5734d683150f41b1b2e80f7584d6cb7 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 1 Dec 2009 14:53:10 +0000 Subject: [PATCH 027/353] Finish issue #440 (Database query by glob/exact match fails). Defer validation of certain query-view-related input whose format is unknown at the time of validation. That includes all the form fields whose interpretation (as an exact match, a blog, a regular expression, etc.) changes based on the another field's value. Instead, do that validation in the view funcs themselves. * lib/viewvc.py (_legal_params): Set the validator for the 'branch', 'file', 'who', and 'comment' parameters to None. (validate_query_args): New function for more careful query arg validation. (view_queryform, view_query): Call validate_query_args(). Tested by: Jon Foster git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2286 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 566922d7..dabaa856 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -698,15 +698,15 @@ _legal_params = { 'gmaxtag' : _re_validate_number, # for query - 'branch' : _validate_regex, - 'branch_match' : _re_validate_alpha, - 'dir' : None, - 'file' : _validate_regex, 'file_match' : _re_validate_alpha, - 'who' : _validate_regex, + 'branch_match' : _re_validate_alpha, 'who_match' : _re_validate_alpha, - 'comment' : _validate_regex, 'comment_match' : _re_validate_alpha, + 'dir' : None, + 'file' : None, + 'branch' : None, + 'who' : None, + 'comment' : None, 'querysort' : _re_validate_alpha, 'date' : _re_validate_alpha, 'hours' : _re_validate_number, @@ -3648,12 +3648,42 @@ def is_querydb_nonempty_for_root(request): return 1 return 0 +def validate_query_args(request): + # Do some additional input validation of query form arguments beyond + # what is offered by the CGI param validation loop in Request.run_viewvc(). + + for arg_base in ['branch', 'file', 'comment', 'who']: + # First, make sure the the XXX_match args have valid values: + arg_match = arg_base + '_match' + arg_match_value = request.query_dict.get(arg_match, 'exact') + if not arg_match_value in ('exact', 'like', 'glob', 'regex', 'notregex'): + raise debug.ViewVCException( + 'An illegal value was provided for the "%s" parameter.' + % (arg_match), + '400 Bad Request') + + # Now, for those args which are supposed to be regular expressions (per + # their corresponding XXX_match values), make sure they are. + if arg_match_value == 'regex' or arg_match_value == 'notregex': + arg_base_value = request.query_dict.get(arg_base) + if arg_base_value: + try: + re.compile(arg_base_value) + except: + raise debug.ViewVCException( + 'An illegal value was provided for the "%s" parameter.' + % (arg_base), + '400 Bad Request') + def view_queryform(request): if not is_query_supported(request): raise debug.ViewVCException('Can not query project root "%s" at "%s".' % (request.rootname, request.where), '403 Forbidden') + # Do some more precise input validation. + validate_query_args(request) + query_action, query_hidden_values = \ request.get_form(view_func=view_query, params={'limit_changes': None}) limit_changes = \ @@ -3976,6 +4006,9 @@ def view_query(request): cfg = request.cfg + # Do some more precise input validation. + validate_query_args(request) + # get form data branch = request.query_dict.get('branch', '') branch_match = request.query_dict.get('branch_match', 'exact') From 3a4ca4d18a66293caa3353cb106f0fdad842bb87 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 1 Dec 2009 14:58:32 +0000 Subject: [PATCH 028/353] * lib/viewvc.py (common_template_data): Default 'roots_href' to None, and only populate it if the roots listing is one of the configured allowed views. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2288 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index dabaa856..3e70646c 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1351,7 +1351,7 @@ def common_template_data(request, revision=None, mime_type=None): 'rootname' : request.rootname \ and request.server.escape(request.rootname) or None, 'rootpath' : request.rootpath, - 'roots_href' : request.get_url(view_func=view_roots, escape=1, params={}), + 'roots_href' : None, 'roottype' : request.roottype, 'rss_href' : None, 'tarball_href' : None, @@ -1387,6 +1387,10 @@ def common_template_data(request, revision=None, mime_type=None): where=dir, pathtype=vclib.DIR, params={}, escape=1) + if 'roots' in cfg.options.allowed_views: + data['roots_href'] = request.get_url(view_func=view_roots, + escape=1, params={}) + if request.pathtype == vclib.FILE: fvi = get_file_view_info(request, request.where, data['rev'], mime_type) data['view_href'] = fvi.view_href From 438eb061bba35202df8897b48722f704be0ae6f8 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 1 Dec 2009 17:36:41 +0000 Subject: [PATCH 029/353] * lib/config.py (Config.load_config): Remove 'rootname' parameter that's unused by callers, and the code that employs it within this function. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2291 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/config.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/config.py b/lib/config.py index f632112f..8c03844b 100644 --- a/lib/config.py +++ b/lib/config.py @@ -46,7 +46,7 @@ class Config: for section in self._sections: setattr(self, section, _sub_config()) - def load_config(self, pathname, vhost=None, rootname=None): + def load_config(self, pathname, vhost=None): self.conf_path = os.path.isfile(pathname) and pathname or None self.base = os.path.dirname(pathname) self.parser = ConfigParser.ConfigParser() @@ -59,9 +59,6 @@ class Config: if vhost and self.parser.has_section('vhosts'): self._process_vhost(self.parser, vhost) - if rootname: - self._process_root_options(self.parser, rootname) - def load_kv_files(self, language): kv = _sub_config() From eda31f60509ad883d1548cc605054f3364304dd5 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 1 Dec 2009 20:16:17 +0000 Subject: [PATCH 030/353] Take a crack at revamping the configuration subsystem to allow for a clear understanding of per-vhost and per-root configuration overrides. This should resolve issue #411 (Can't override authz-* sections in virtual host). * conf/viewvc.conf.dist Add comments about the scope and permissability of per-vhost and per-root overrides. * lib/config.py (): Add some comments about option layering -- including a fancy schmancy ASCII art diagram! -- and make some minor comment formatting tweaks. (Config._base_sections): Was Config._sections. Add 'authz-*'. (Config._force_multi_value): Reformat and comment. (Config._allowed_overrides): New mapping of valid overrides. (Config.__init__): Track renamed _base_sections member, and avoid instantiating _sub_config items for non-explicitly-name base sections found therein. (Config.load_config): Add docstring. Use _is_allowed_section() to determine which sections to process. (Config.load_kv_files): Add docstring. (Config.path): Minor docstring tweak. (Config._process_section): Instantiate missing _sub_config() items. Add a FIXME comment. (Config._is_allowed_section, Config._is_allowed_override): New functions. (Config._process_vhost): Now use _is_allowed_override() for section filtering. (Config._process_root_options): Removed, merged with tweaks into... (Config.overlay_root_options): ...here, which now uses _is_allowed_override for section filtering. (Config.get_authorizer_params): Look in the calculated configuration rather than specific configuration file regions. Add a FIXME comment. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2292 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 20 +++- lib/config.py | 216 ++++++++++++++++++++++++++++++++++-------- 2 files changed, 194 insertions(+), 42 deletions(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index e16e572e..fd25c704 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -815,6 +815,16 @@ ## ViewVC options typically found in the base configuration section ## named CONFIGSECTION ("general", "option", etc.) ## +## NOTE: Per-vhost overrides may only be applied to the following +## sections: +## +## general +## options +## utilities +## templates +## cvsdb +## authz-* +## ## Here is an example: ## ## [vhosts] @@ -844,7 +854,15 @@ ## basename of a root path in root_parents. Options found in this new ## configuration section override for this one root the corresponding ## options found in the base configuration section CONFIGSECTION -## ("options", "authz-*", etc.) +## ("options", "authz-*", etc.) as interpreted after per-vhost +## overrides (if any) have been applied. +## +## NOTE: Per-root overrides may only be applied to the following +## sections: +## +## options +## utilities +## authz-* ## ## Here is an example showing how to enable Subversion authz-based ## authorization for only the single root named "svnroot": diff --git a/lib/config.py b/lib/config.py index 8c03844b..0ea7b7a3 100644 --- a/lib/config.py +++ b/lib/config.py @@ -24,42 +24,141 @@ import fnmatch ######################################################################### # # CONFIGURATION +# ------------- # # There are three forms of configuration: # -# 1) edit the viewvc.conf created by the viewvc-install(er) -# 2) as (1), but delete all unchanged entries from viewvc.conf -# 3) do not use viewvc.conf and just edit the defaults in this file +# 1. edit the viewvc.conf created by the viewvc-install(er) +# 2. as (1), but delete all unchanged entries from viewvc.conf +# 3. do not use viewvc.conf and just edit the defaults in this file # # Most users will want to use (1), but there are slight speed advantages # to the other two options. Note that viewvc.conf values are a bit easier # to work with since it is raw text, rather than python literal values. # +# +# A WORD ABOUT OPTION LAYERING/OVERRIDES +# -------------------------------------- +# +# ViewVC has three "layers" of configuration options: +# +# 1. base configuration options - very basic configuration bits +# found in sections like 'general', 'options', etc. +# 2. vhost overrides - these options overlay/override the base +# configuration on a per-vhost basis. +# 3. root overrides - these options overlay/override the base +# configuration and vhost overrides on a per-root basis. +# +# Here's a diagram of the valid overlays/overrides: +# +# PER-ROOT PER-VHOST BASE +# +# ,-----------. ,-----------. +# | vhost-*/ | | | +# | general | --> | general | +# | | | | +# `-----------' `-----------' +# ,-----------. ,-----------. ,-----------. +# | root-*/ | | vhost-*/ | | | +# | options | --> | options | --> | options | +# | | | | | | +# `-----------' `-----------' `-----------' +# ,-----------. ,-----------. ,-----------. +# | root-*/ | | vhost-*/ | | | +# | templates | --> | templates | --> | templates | +# | | | | | | +# `-----------' `-----------' `-----------' +# ,-----------. ,-----------. ,-----------. +# | root-*/ | | vhost-*/ | | | +# | utilities | --> | utilities | --> | utilities | +# | | | | | | +# `-----------' `-----------' `-----------' +# ,-----------. ,-----------. +# | vhost-*/ | | | +# | cvsdb | --> | cvsdb | +# | | | | +# `-----------' `-----------' +# ,-----------. ,-----------. ,-----------. +# | root-*/ | | vhost-*/ | | | +# | authz-* | --> | authz-* | --> | authz-* | +# | | | | | | +# `-----------' `-----------' `-----------' +# ,-----------. +# | | +# | vhosts | +# | | +# `-----------' +# +# ### TODO: Figure out what this all means for the 'kv' stuff. +# ######################################################################### class Config: - _sections = ('general', 'utilities', 'options', 'cvsdb', 'templates') - _force_multi_value = ('cvs_roots', 'svn_roots', 'languages', 'kv_files', - 'root_parents', 'allowed_views', 'mime_types_files') + _base_sections = ( + # Base configuration sections. + 'authz-*', + 'cvsdb', + 'general', + 'options', + 'templates', + 'utilities', + ) + _force_multi_value = ( + # Configuration values with multiple, comma-separated values. + 'allowed_views', + 'cvs_roots', + 'kv_files', + 'languages', + 'mime_types_files', + 'root_parents', + 'svn_roots', + ) + _allowed_overrides = { + # Mapping of override types to allowed overridable sections. + 'vhost' : ('authz-*', + 'cvsdb', + 'general', + 'options', + 'templates', + 'utilities', + ), + 'root' : ('authz-*', + 'options', + 'templates', + 'utilities', + ) + } def __init__(self): - for section in self._sections: + for section in self._base_sections: + if section[-1] == '*': + continue setattr(self, section, _sub_config()) def load_config(self, pathname, vhost=None): + """Load the configuration file at PATHNAME, applying configuration + settings there as overrides to the built-in default values. If + VHOST is provided, also process the configuration overrides + specific to that virtual host.""" + self.conf_path = os.path.isfile(pathname) and pathname or None self.base = os.path.dirname(pathname) self.parser = ConfigParser.ConfigParser() self.parser.read(self.conf_path or []) - - for section in self._sections: - if self.parser.has_section(section): + + for section in self.parser.sections(): + if self._is_allowed_section(self.parser, section, + self._base_sections): self._process_section(self.parser, section, section) if vhost and self.parser.has_section('vhosts'): self._process_vhost(self.parser, vhost) def load_kv_files(self, language): + """Process the key/value (kv) files specified in the + configuration, merging their values into the configuration as + dotted heirarchical items.""" + kv = _sub_config() for fname in self.general.kv_files: @@ -89,10 +188,12 @@ class Config: return kv def path(self, path): - """Return path relative to the config file directory""" + """Return PATH relative to the config file directory.""" return os.path.join(self.base, path) def _process_section(self, parser, section, subcfg_name): + if not hasattr(self, subcfg_name): + setattr(self, subcfg_name, _sub_config()) sc = getattr(self, subcfg_name) for opt in parser.options(section): @@ -105,25 +206,55 @@ class Config: except ValueError: pass + ### FIXME: This feels like unnecessary depth of knowledge for a + ### semi-generic configuration object. if opt == 'cvs_roots' or opt == 'svn_roots': value = _parse_roots(opt, value) setattr(sc, opt, value) + def _is_allowed_section(self, parser, section, allowed_sections): + """Return 1 iff SECTION is an allowed section, defined as being + explicitly present in the ALLOWED_SECTIONS list or present in the + form 'someprefix-*' in that list.""" + + for allowed_section in allowed_sections: + if allowed_section[-1] == '*': + if _startswith(section, allowed_section[:-1]): + return 1 + elif allowed_section == section: + return 1 + return 0 + + def _is_allowed_override(self, parser, sectype, secspec, section): + """Test if SECTION is an allowed override section for sections of + type SECTYPE ('vhosts' or 'root', currently) and type-specifier + SECSPEC (a rootname or vhostname, currently). If it is, return + the overridden base section name. If it's not an override section + at all, return None. And if it's an override section but not an + allowed one, raise IllegalOverrideSection.""" + + cv = '%s-%s/' % (sectype, secspec) + lcv = len(cv) + if section[:lcv] != cv: + return None + base_section = section[lcv:] + if self._is_allowed_section(parser, base_section, + self._allowed_overrides[sectype]): + return base_section + raise IllegalOverrideSection(sectype, section) + def _process_vhost(self, parser, vhost): - # find a vhost name for this vhost, if any (if not, we've nothing to do) + # Find a vhost name for this VHOST, if any (else, we've nothing to do). canon_vhost = self._find_canon_vhost(parser, vhost) if not canon_vhost: return - # overlay any option sections associated with this vhost name - cv = 'vhost-%s/' % (canon_vhost) - lcv = len(cv) + # Overlay any option sections associated with this vhost name. for section in parser.sections(): - if section[:lcv] == cv: - base_section = section[lcv:] - if base_section not in self._sections: - raise IllegalOverrideSection('vhost', section) + base_section = self._is_allowed_override(parser, 'vhost', + canon_vhost, section) + if base_section: self._process_section(parser, section, base_section) def _find_canon_vhost(self, parser, vhost): @@ -138,26 +269,17 @@ class Config: return None - def _process_root_options(self, parser, rootname): - rn = 'root-%s/' % (rootname) - lrn = len(rn) - for section in parser.sections(): - if section[:lrn] == rn: - base_section = section[lrn:] - if base_section in self._sections: - if base_section == 'general': - raise IllegalOverrideSection('root', section) - self._process_section(parser, section, base_section) - elif _startswith(base_section, 'authz-'): - pass - else: - raise IllegalOverrideSection('root', section) - def overlay_root_options(self, rootname): - "Overly per-root options atop the existing option set." + """Overlay per-root options for ROOTNAME atop the existing option + set. This is a destructive change to the configuration.""" if not self.conf_path: return - self._process_root_options(self.parser, rootname) + + for section in self.parser.sections(): + base_section = self._is_allowed_override(self.parser, 'root', + rootname, section) + if base_section: + self._process_section(self.parser, section, base_section) def _get_parser_items(self, parser, section): """Basically implement ConfigParser.items() for pre-Python-2.3 versions.""" @@ -173,12 +295,24 @@ class Config: if not self.conf_path: return {} - params = {} authz_section = 'authz-%s' % (authorizer) - for section in self.parser.sections(): - if section == authz_section: - for key, value in self._get_parser_items(self.parser, section): - params[key] = value + params = {} + + # First, copy into PARAMS all the attributes from the + # base-configured authorizer sections. + if hasattr(self, authz_section): + sub_config = getattr(self, authz_section) + for attr in dir(sub_config): + params[attr] = getattr(sub_config, attr) + + # Now, if we've been given a rootname, check for per-root + # overrides of the authorizer parameters. + # + ### FIXME: This whole thing is a hack caused by our not being able + ### to non-destructively overlay root options when trying to do + ### something like a root listing (which might need to get + ### different authorizer bits for each and every root in the + ### list). See issue #371. if rootname: root_authz_section = 'root-%s/authz-%s' % (rootname, authorizer) for section in self.parser.sections(): From 59e6fa414e537dc9423c7e9868a20a3796e0b651 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 2 Dec 2009 16:01:49 +0000 Subject: [PATCH 031/353] Fix issue #442: Standalone server 1.1.2 fails to start under Python 1.5.2 * lib/viewvc.py (load_config): Tweak lambda usage for 1.5.2-compliance. Patch by: Dmitry Bulgakov git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2293 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 3e70646c..f205ea7e 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -4347,7 +4347,7 @@ def load_config(pathname=None, server=None): if cfg.general.mime_types_files: files = cfg.general.mime_types_files[:] files.reverse() - files = map(lambda x: os.path.join(os.path.dirname(pathname), x), files) + files = map(lambda x, y=pathname: os.path.join(os.path.dirname(y), x), files) mimetypes.init(files) debug.t_end('load-config') From a6565f89f9ea31f8ec16854057aa28989e891c34 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 2 Dec 2009 19:49:25 +0000 Subject: [PATCH 032/353] Appease the monster in me who growls every time he finds a website whose primary navigation links aren't preserved on every page. * viewvc.org/who.html, * viewvc.org/faq.html, * viewvc.org/download.html, * viewvc.org/contact.html Lose the 'Project Page' and 'Contributing' nav links. * viewvc.org/index.html Lose the 'Project Page' and 'Contributing' nav links. Put the (short) license on this page. * viewvc.org/contributing.html Lose the 'Project Page' and 'Contributing' nav links. Put info about the viewvc.tigris.org site on this page. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2295 8cb11bc2-c004-0410-86c3-e597b4017df7 --- viewvc.org/contact.html | 2 -- viewvc.org/contributing.html | 30 +++++++++++-------- viewvc.org/download.html | 2 -- viewvc.org/faq.html | 2 -- viewvc.org/index.html | 57 ++++++++++++++++++++++++++++++++++-- viewvc.org/who.html | 2 -- 6 files changed, 73 insertions(+), 22 deletions(-) diff --git a/viewvc.org/contact.html b/viewvc.org/contact.html index f8bfe60f..f9c78118 100644 --- a/viewvc.org/contact.html +++ b/viewvc.org/contact.html @@ -17,11 +17,9 @@

Compatibility

@@ -51,7 +51,7 @@ in the release for information on porting existing versions of those items for use with ViewVC 1.1.0.

-
+

Features and Fixes

@@ -90,7 +90,7 @@ including the one that permits display of remote Subversion repositories.

-
+

Subversion versioned properties display

@@ -103,7 +103,7 @@ properties are displayed at the bottom of that file's markup/annotate view.

-
+

Unified markup and annotation views

@@ -112,7 +112,7 @@ and feel (driven by a single EZT template). Both views support syntax highlighting and Subversion file property display.

-
+

Unified, hassle-free Pygments-based syntax highlighting

@@ -133,7 +133,7 @@ but this change should vastly simplify the discussions of such things.

-
+

Better MIME detection and handling

@@ -156,7 +156,7 @@ without potentially affecting the mappings used by other site services.

-
+

Support for full content diffs

@@ -166,7 +166,7 @@ shows the full contents of the changed file (instead of only the 3 or 15 lines of context shown via the older diff display types).

-
+

Support for per-root configuration overrides

@@ -176,7 +176,7 @@ the comments in the viewvc.conf.dist file for more on how to do this.

-
+

Optional email address obfuscation/mangling

@@ -192,7 +192,7 @@ information for the human reading the log message to know who to blame for the patch).

-
+

Pagination improvements

@@ -204,8 +204,9 @@ of border information." This provides a large performance enhancement for the default sort orderings.

-
- + + + From 48a59d30ad33e0e999c11230a8ce35b5a31eef7d Mon Sep 17 00:00:00 2001 From: cmpilato Date: Fri, 21 Oct 2011 14:46:35 +0000 Subject: [PATCH 207/353] * docs/release-notes/1.2.0.html New stub file. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2639 8cb11bc2-c004-0410-86c3-e597b4017df7 --- docs/release-notes/1.2.0.html | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docs/release-notes/1.2.0.html diff --git a/docs/release-notes/1.2.0.html b/docs/release-notes/1.2.0.html new file mode 100644 index 00000000..23cd7830 --- /dev/null +++ b/docs/release-notes/1.2.0.html @@ -0,0 +1,49 @@ + + + +ViewVC: 1.2.0 Release Notes + + + + + +

ViewVC 1.2.0 Release Notes

+ +
+

Introduction

+ +

ViewVC 1.2.0 is the superset of all previous ViewVC releases.

+ +
+ +
+

Compatibility

+ +

Each ViewVC release strives to maintain URL stability with previous + releases, and 1.2.0 is no exception. All URLs considered valid for + previous ViewVC releases should continue to work correctly in this + release, though possibly only via the use of HTTP redirects + (generated by ViewVC itself).

+ +
+ +
+

Features and Fixes

+ +
+

+ +
+ +
+ + + From 24cbe623e7ed620d43ee4142e5a757e23316f226 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Fri, 21 Oct 2011 14:47:02 +0000 Subject: [PATCH 208/353] * docs/template-authoring-guide.html Update to refer to ViewVC 1.2, not 1.0. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2640 8cb11bc2-c004-0410-86c3-e597b4017df7 --- docs/template-authoring-guide.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/template-authoring-guide.html b/docs/template-authoring-guide.html index 463c5d39..510411b3 100644 --- a/docs/template-authoring-guide.html +++ b/docs/template-authoring-guide.html @@ -1,6 +1,6 @@ -ViewVC 1.0 Template Authoring Guide +ViewVC 1.2 Template Authoring Guide @@ -700,30 +704,64 @@ td { COMMON variable set - changes + diff List - Set of objects which contain information about a single line of - file difference data. Valid only when diff_format is - h or l. + List of all blocks of differences between the two sides, including content + and property differences. - changes.have_left - Boolean - Specifies whether the left file has a line of content relevant - to the difference data line. Valid only when - changes.type is change. - - - changes.have_right - Boolean - Specifies whether the right file has a line of content relevant - to the difference data line. Valid only when - changes.type is change. - - - changes.left + diff.display_as String - Textual contents of the relevant line in the left file. Valid + Indicates the type of this block. One of the anchor (no display, + create an anchor), raw (non-colored diff, display as produced), + sidebyside-1 (traditional side-by-side diff), + sidebyside-2 (newer side-by-side diff with intraline changes), + unified (colored unified diff). + + + diff.anchor + String + If diff.display_as is anchor, this variable specifies + the anchor name. + + + diff.changes + List/Container + Set of objects which contain information about a change in a single + object (file or property). Not present if diff.display_as is + anchor, otherwise has different format depending on + diff.display_as (applicable as indicated in brackets below). + + + diff.changes.raw + String + [raw] Diff text. Valid only if diff.changes.type is + raw. + + + diff.changes.type + String + [raw] The type of change. Values: binary-diff, + error, no-changes, raw. + + + diff.changes.have_left + Boolean + [sidebyside-1] Specifies whether the left file has a line of content relevant + to the difference data line. Valid only when + changes.type is change. + + + diff.changes.have_right + Boolean + [sidebyside-1] Specifies whether the right file has a line of content relevant + to the difference data line. Valid only when + changes.type is change. + + + diff.changes.left + String + [sidebyside-1] Textual contents of the relevant line in the left file. Valid only when changes.type is change, context, or remove. When changes.type is change, valid only when @@ -731,10 +769,10 @@ td { between missing lines and empty lines, which EZT does not support). - - changes.right + + diff.changes.right String - Textual contents of the relevant line in the right file. Valid + [sidebyside-1] Textual contents of the relevant line in the right file. Valid only when changes.type is add, change, or context. When changes.type is change, valid only when @@ -742,40 +780,264 @@ td { between missing lines and empty lines, which EZT does not support). - - changes.line_info_extra + + diff.changes.line_info_extra String - Additional line information for the current difference hunk. + [sidebyside-1] Additional line information for the current difference hunk. Valid only when changes.type is header. - - changes.line_info_left + + diff.changes.line_info_left String - First line number represented by the current hunk in the left + [sidebyside-1] First line number represented by the current hunk in the left file. Valid only when changes.type is header. - - changes.line_info_right + + diff.changes.line_info_right String - First line number represented by the current hunk in the right + [sidebyside-1] First line number represented by the current hunk in the right file. Valid only when changes.type is header. - - changes.line_number + + diff.changes.line_number String - Line number (1-based) of the line. + [sidebyside-1] Line number (1-based) of the line. - - changes.type + + diff.changes.type String - The type of change. Value values: add, - change, context, header, + [sidebyside-1] The type of change. Values: add, binary-diff, + change, context, error, header, no-changes, remove. + + diff.changes.columns + List + [sidebyside-2] List of two columns for left and right parts of the diff. + + + diff.changes.columns.line_number + String + [sidebyside-2] Line number in the left/right column. + + + diff.changes.columns.segments + List + [sidebyside-2] Left/right line, broken into change segments. + + + diff.changes.columns.segments.text + String + [sidebyside-2] Text of this segment. + + + diff.changes.columns.segments.type + String + [sidebyside-2] Not set if the segment is the same in both left and right sides; + otherwise, one of the add, remove or change. + + + diff.changes.gap + Boolean + [sidebyside-2] If true, indicates that change blocks are non-contiguous + and that the template should display some sort of ellipsis before the + current block. + + + diff.changes.type + String + [sidebyside-2] The type of change. Values: binary-diff, + error, intraline, no-changes. + + + diff.changes.segments + List + [unified] Left/right line, broken into change segments. + + + diff.changes.segments.text + String + [unified] Text of this segment. + + + diff.changes.segments.type + String + [unified] Not set if the segment is the same in both left and right sides; + otherwise, one of the add, remove or change. + + + diff.changes.type + String + [unified] The type of change. Values: add, binary-diff, + error, no-changes, remove or empty string + if the line was not changed (context line). + + + diff.left + Container + Container object for grouping information about the left file. + + + diff.left.ago + String + Text description of the time elapsed since left.date. + + + diff.left.annotate_href + String + URL of the ViewVC annotation view for the left file. + Valid only when entries.pathtype is file. + + + diff.left.author + String + Author of the revision of the left file. + + + diff.left.date + String + Date (in UTC if not otherwise configured) in which the left file + revision was created. + + + diff.left.download_href + String + URL to download the HEAD revision of the left file. + + + diff.left.download_text_href + String + URL to download the HEAD revision of the left file as + text/plain. + + + diff.left.log + String + Log message of the left file revision. + + + diff.left.path + String + Path of the left file. + + + diff.left.prefer_markup + Boolean + Indicates whether to make the default file link a link to the markup + page instead of the checkout page. + + + diff.left.rev + String + Revision of the left file. + + + diff.left.revision_href + String + URL of the Subversion revision view for the left file's + current revision. Valid only when roottype is + svn. + + + diff.left.size + String + Size of the left file revision, in bytes. Subversion only. + + + diff.left.tag + String + Tag of the left file. + + + diff.left.view_href + String + This is a URL for the markup view of the left file. + + + diff.right + Container + Container object for grouping information about the right file. + + + diff.right.ago + String + Text description of the time elapsed since right.date. + + + diff.right.annotate_href + String + URL of the ViewVC annotation view for the right file. + Valid only when entries.pathtype is file. + + + diff.right.author + String + Author of the revision of the right file. + + + diff.right.date + String + Date (in UTC if not otherwise configured) in which the right file + revision was created. + + + diff.right.download_href + String + URL to download the HEAD revision of the right file. + + + diff.right.download_text_href + String + URL to download the HEAD revision of the right file as + text/plain. + + + diff.right.log + String + Log message of the right file revision. + + + diff.right.path + String + Path of the right file. + + + diff.right.prefer_markup + Boolean + Indicates whether to make the default file link a link to the markup + page instead of the checkout page. + + + diff.right.rev + String + Revision of the right file. + + + diff.right.revision_href + String + URL of the Subversion revision view for the right file's + current revision. Valid only when roottype is + svn. + + + diff.right.size + String + Size of the right file revision, in bytes. Subversion only. + + + diff.right.tag + String + Tag of the right file. + + + diff.right.view_href + String + This is a URL for the markup view of the right file. + diff_format String - Difference dislay format: Valid values are c + Difference display format: Valid values are c (context), f (full human-readable), h (human-readable, or colored), l (long human-readable), s (side-by-side), u @@ -792,172 +1054,14 @@ td { Hidden field name/value pairs for the diff format selection form. - left - Container - Container object for grouping information about the left file. - - - left.ago - String - Text description of the time elapsed since left.date. - - - left.annotate_href - String - URL of the ViewVC annotation view for the left file. - Valid only when entries.pathtype is file. - - - left.author - String - Author of the revision of the left file. - - - left.date - String - Date (in UTC if not otherwise configured) in which the left file - revision was created. - - - left.download_href - String - URL to download the HEAD revision of the left file. - - - left.download_text_href - String - URL to download the HEAD revision of the left file as - text/plain. - - - left.log - String - Log message of the left file revision. - - - left.path - String - Path of the left file. - - - left.prefer_markup + hide_legend Boolean - Indicates whether to make the default file link a link to the markup - page instead of the checkout page. - - - left.rev - String - Revision of the left file. - - - left.revision_href - String - URL of the Subversion revision view for the left file's - current revision. Valid only when roottype is - svn. - - - left.size - String - Size of the left file revision, in bytes. Subversion only. - - - left.tag - String - Tag of the left file. - - - left.view_href - String - This is a URL for the markup view of the left file. + Indicates whether the display format requires displaying a legend - raw_diff + patch_href String - Raw difference text. Valid only when diff_format is - c, s, or u. - - - right - Container - Container object for grouping information about the right file. - - - right.author - String - Author of the revision of the right file. - - - right.annotate_href - String - URL of the ViewVC annotation view for the right file. - Valid only when entries.pathtype is file. - - - right.author - String - Author of the revision of the right file. - - - right.date - String - Date (in UTC if not otherwise configured) in which the right file - revision was created. - - - right.download_href - String - URL to download the HEAD revision of the right file. - - - right.download_text_href - String - URL to download the HEAD revision of the right file as - text/plain. - - - right.log - String - Log message of the right file revision. - - - right.path - String - Path of the right file. - - - right.prefer_markup - Boolean - Indicates whether to make the default file link a link to the markup - page instead of the checkout page. - - - right.rev - String - Revision of the right file. - - - right.revision_href - String - URL of the Subversion revision view for the right file's - current revision. Valid only when roottype is - svn. - - - right.size - String - Size of the right file revision, in bytes. Subversion only. - - - right.tag - String - Tag of the right file. - - - right.view_href - String - This is a URL for the markup view of the right file. + URL of the patch view for the file. From 2b5e7b51a0ff8182b4971ed9d6ec8703aef78ba4 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 26 Oct 2011 19:11:41 +0000 Subject: [PATCH 210/353] On the 'property-diff' branch: rename the 'diff' template data dictionary item to 'diffs' for consistency with other multi-value items. Yes, I know it makes the template usage itself weird ... "diffs.changes" instead of "diff.changes", but... * lib/viewvc.py (view_diff): Store the desc.changes in the 'diffs' data dictionary item, not the 'diff' item. * templates/diff.ezt * templates/include/diff_display.ezt Replace uses of 'diff' with 'diffs'. Selectively, of course. git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/property-diff@2643 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 2 +- templates/diff.ezt | 4 +- templates/include/diff_display.ezt | 118 ++++++++++++++--------------- 3 files changed, 62 insertions(+), 62 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index a2d41372..5d7fbdbf 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3533,7 +3533,7 @@ def view_diff(request): data = common_template_data(request) data.merge(ezt.TemplateData({ - 'diff' : desc.changes, + 'diffs' : desc.changes, 'diff_format' : desc.diff_format, 'hide_legend' : ezt.boolean(desc.hide_legend), 'patch_href' : request.get_url(view_func=view_patch, diff --git a/templates/diff.ezt b/templates/diff.ezt index 39016d8f..f6df9e39 100644 --- a/templates/diff.ezt +++ b/templates/diff.ezt @@ -6,8 +6,8 @@ [include "include/header.ezt" "diff"] [include "include/file_header.ezt"] -[if-any diff] - [for diff] +[if-any diffs] + [for diffs] [include "include/diff_display.ezt"] [end] [end] diff --git a/templates/include/diff_display.ezt b/templates/include/diff_display.ezt index 88cec806..d41a56f6 100644 --- a/templates/include/diff_display.ezt +++ b/templates/include/diff_display.ezt @@ -1,5 +1,5 @@ -[is diff.display_as "anchor"] -

+[is diffs.display_as "anchor"] +

[else] [define msg_no_changes]
- No changes -
 [end] [define msg_binary]
- Binary content differs -
 [end] @@ -7,23 +7,23 @@ Even if you have GNU diff installed, the rcsdiff program must be configured and compiled with the GNU diff location. -

 [end] - [define left_view_href][if-any diff.left.prefer_markup][diff.left.view_href][else][if-any diff.left.download_href][diff.left.download_href][end][end][end] - [define right_view_href][if-any diff.right.prefer_markup][diff.right.view_href][else][if-any diff.right.download_href][diff.right.download_href][end][end][end] + [define left_view_href][if-any diffs.left.prefer_markup][diffs.left.view_href][else][if-any diffs.left.download_href][diffs.left.download_href][end][end][end] + [define right_view_href][if-any diffs.right.prefer_markup][diffs.right.view_href][else][if-any diffs.right.download_href][diffs.right.download_href][end][end][end] - [define left_header][is diff.left.path diff.right.path][else][diff.left.path]
[end] - [if-any diff.propname]Property: [diff.propname]
[end] - Revision [if-any left_view_href][end][diff.left.rev][if-any left_view_href][end][if-any diff.left.author] by [diff.left.author][end], - [diff.left.date] - [if-any diff.left.tag]
Tag: [diff.left.tag][end][end] + [define left_header][is diffs.left.path diffs.right.path][else][diffs.left.path]
[end] + [if-any diffs.propname]Property: [diffs.propname]
[end] + Revision [if-any left_view_href][end][diffs.left.rev][if-any left_view_href][end][if-any diffs.left.author] by [diffs.left.author][end], + [diffs.left.date] + [if-any diffs.left.tag]
Tag: [diffs.left.tag][end][end] - [define right_header][is diff.right.path diff.left.path][else][diff.right.path]
[end] - [if-any diff.propname]Property: [diff.propname]
[end] - Revision [if-any right_view_href][end][diff.right.rev][if-any right_view_href][end][if-any diff.right.author] by [diff.right.author][end], - [diff.right.date] - [if-any diff.right.tag]
Tag: [diff.right.tag][end][end] + [define right_header][is diffs.right.path diffs.left.path][else][diffs.right.path]
[end] + [if-any diffs.propname]Property: [diffs.propname]
[end] + Revision [if-any right_view_href][end][diffs.right.rev][if-any right_view_href][end][if-any diffs.right.author] by [diffs.right.author][end], + [diffs.right.date] + [if-any diffs.right.tag]
Tag: [diffs.right.tag][end][end] [end] -[is diff.display_as "raw"] +[is diffs.display_as "raw"] @@ -34,23 +34,23 @@ - [is diff.changes.type "no-changes"] + [is diffs.changes.type "no-changes"] [else] - [is diff.changes.type "binary-diff"] + [is diffs.changes.type "binary-diff"] [else] - + [end] [end]
 [left_header]
 [right_header]
[msg_no_changes]
[msg_binary]
[diff.changes.raw]
[diffs.changes.raw]
[end] -[is diff.display_as "sidebyside-1"] +[is diffs.display_as "sidebyside-1"] @@ -58,54 +58,54 @@ - [for diff.changes] - [is diff.changes.type "header"] - + [for diffs.changes] + [is diffs.changes.type "header"] + [else] - [is diff.changes.type "add"] + [is diffs.changes.type "add"] - + - + [else] - [is diff.changes.type "remove"] + [is diffs.changes.type "remove"] - + [else] - [is diff.changes.type "change"] + [is diffs.changes.type "change"] - [if-any diff.changes.have_right] - + [if-any diffs.changes.have_right] + [else] [end] - [if-any diff.changes.have_left] - + [if-any diffs.changes.have_left] + [else] [end] - [if-any diff.changes.have_right] - + [if-any diffs.changes.have_right] + [else] [end] [else] - [is diff.changes.type "no-changes"] + [is diffs.changes.type "no-changes"] @@ -113,7 +113,7 @@ [else] - [is diff.changes.type "binary-diff"] + [is diffs.changes.type "binary-diff"] @@ -121,7 +121,7 @@ [else] - [is diff.changes.type "error"] + [is diffs.changes.type "error"] @@ -130,9 +130,9 @@ [else] - - - + + + [end] [end] @@ -145,7 +145,7 @@
[right_header]
# - Line [diff.changes.line_info_left]  - [diff.changes.line_info_extra] + Line [diffs.changes.line_info_left]  + [diffs.changes.line_info_extra] - Line [diff.changes.line_info_right]  - [diff.changes.line_info_extra] + Line [diffs.changes.line_info_right]  + [diffs.changes.line_info_extra]
[if-any diff.right.annotate_href][diff.changes.line_number][else][diff.changes.line_number][end][if-any diffs.right.annotate_href][diffs.changes.line_number][else][diffs.changes.line_number][end]   [diff.changes.right] [diffs.changes.right]
 [diff.changes.left] [diffs.changes.left]  
[if-any diff.right.annotate_href][diff.changes.line_number][else][diff.changes.line_number][end][if-any diffs.right.annotate_href][diffs.changes.line_number][else][diffs.changes.line_number][end] [diff.changes.left] [diffs.changes.left]  [diff.changes.right] [diffs.changes.right] 
 
[msg_no_changes]
 
[msg_binary]
 
[if-any diff.right.annotate_href][diff.changes.line_number][else][diff.changes.line_number][end] [diff.changes.left] [diff.changes.right][if-any diffs.right.annotate_href][diffs.changes.line_number][else][diffs.changes.line_number][end] [diffs.changes.left] [diffs.changes.right]
[end] -[is diff.display_as "sidebyside-2"] +[is diffs.display_as "sidebyside-2"] @@ -156,26 +156,26 @@ - [for diff.changes] - [is diff.changes.type "no-changes"] + [for diffs.changes] + [is diffs.changes.type "no-changes"] [else] - [is diff.changes.type "binary-diff"] + [is diffs.changes.type "binary-diff"] [else] - [if-any diff.changes.gap] + [if-any diffs.changes.gap] [end] - [for diff.changes.columns] - [for diff.changes.columns.segments][if-any diff.changes.columns.segments.type][diff.changes.columns.segments.text][else][diff.changes.columns.segments.text][end][end] + [for diffs.changes.columns] + [for diffs.changes.columns.segments][if-any diffs.changes.columns.segments.type][diffs.changes.columns.segments.text][else][diffs.changes.columns.segments.text][end][end] [end] [end] @@ -185,7 +185,7 @@
[msg_no_changes]
[msg_binary]
[diff.changes.columns.line_number][diffs.changes.columns.line_number]
[end] -[is diff.display_as "unified"] +[is diffs.display_as "unified"] @@ -204,18 +204,18 @@ - [for diff.changes] - [is diff.changes.type "no-changes"] + [for diffs.changes] + [is diffs.changes.type "no-changes"] [else] - [is diff.changes.type "binary-diff"] + [is diffs.changes.type "binary-diff"] [else] - [if-any diff.changes.gap] + [if-any diffs.changes.gap] @@ -223,9 +223,9 @@ [end] - - - [for diff.changes.segments][if-any diff.changes.segments.type][diff.changes.segments.text][else][diff.changes.segments.text][end][end] + + + [for diffs.changes.segments][if-any diffs.changes.segments.type][diffs.changes.segments.text][else][diffs.changes.segments.text][end][end] [end] [end] From 753d2d532024ef05955ee9ce19b565ca5aa358ee Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 26 Oct 2011 19:18:20 +0000 Subject: [PATCH 211/353] On the 'property-diff' branch: * docs/template-authoring-guide.html Update the template authoring guide in light of the changes I made in r2643. git-svn-id: http://viewvc.tigris.org/svn/viewvc/branches/property-diff@2644 8cb11bc2-c004-0410-86c3-e597b4017df7 --- docs/template-authoring-guide.html | 120 ++++++++++++++--------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/docs/template-authoring-guide.html b/docs/template-authoring-guide.html index b1a074a1..9e700575 100644 --- a/docs/template-authoring-guide.html +++ b/docs/template-authoring-guide.html @@ -704,13 +704,13 @@ td { COMMON variable set - + - + - + - - + + diffs.display_as (applicable as indicated in brackets below). - + - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + From 00d96de4468d2c563548311bb45357081325c23d Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 27 Oct 2011 14:53:49 +0000 Subject: [PATCH 212/353] * CHANGES: Note the addition of prop-diff support. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2646 8cb11bc2-c004-0410-86c3-e597b4017df7 --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index 4e998575..763bc313 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ Version 1.2.0 (released ??-???-????) * bumped minimum support Python version to 2.4 + * implemented support for property diffs (issue #383) * allow user-configurable cvsgraph display (issue #336) * allow rNNNN syntax for Subversion revision numbers (issue #441) From 65137920a897b25e60306c27897c8dec88101ecd Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 27 Oct 2011 18:05:14 +0000 Subject: [PATCH 213/353] Begin the work of making the 'newvc' contributed template set into the new default for ViewVC 1.2. We'll keep the old templates around as a "classic" option. * lib/config.py, * conf/viewvc.conf.dist (Config.set_defaults): Set cfg.options.template_dir to "templates/default", and make the matching edit in the pristine configuration file. * templates/: Now just a container for... * templates/classic/, * templates/classic/*: ...the old default templates (which were 'templates' and 'templates/*'. * templates/default/, templates/default/*: ...and the new default, copied from the 'templates-contrib/1.1' area. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2647 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 7 +- lib/config.py | 2 +- templates/{ => classic}/diff.ezt | 0 templates/{ => classic}/dir_new.ezt | 0 templates/{ => classic}/directory.ezt | 0 templates/{ => classic}/docroot/help.css | 0 .../{ => classic}/docroot/help_dirview.html | 0 templates/{ => classic}/docroot/help_log.html | 0 .../{ => classic}/docroot/help_query.html | 0 .../{ => classic}/docroot/help_rootview.html | 0 .../{ => classic}/docroot/images/annotate.png | Bin .../{ => classic}/docroot/images/back.png | Bin .../docroot/images/back_small.png | Bin .../{ => classic}/docroot/images/broken.png | Bin .../{ => classic}/docroot/images/chalk.jpg | Bin .../docroot/images/cvsgraph_16x16.png | Bin .../docroot/images/cvsgraph_32x32.png | Bin .../{ => classic}/docroot/images/diff.png | Bin .../{ => classic}/docroot/images/dir.png | Bin .../{ => classic}/docroot/images/down.png | Bin .../{ => classic}/docroot/images/download.png | Bin .../{ => classic}/docroot/images/favicon.ico | Bin .../docroot/images/feed-icon-16x16.jpg | Bin .../{ => classic}/docroot/images/forward.png | Bin .../{ => classic}/docroot/images/list.png | Bin .../{ => classic}/docroot/images/lock.png | Bin .../{ => classic}/docroot/images/log.png | Bin .../{ => classic}/docroot/images/text.png | Bin templates/{ => classic}/docroot/images/up.png | Bin .../{ => classic}/docroot/images/view.png | Bin .../docroot/images/viewvc-logo.png | Bin templates/{ => classic}/docroot/styles.css | 0 templates/{ => classic}/error.ezt | 0 templates/{ => classic}/file.ezt | 0 templates/{ => classic}/graph.ezt | 0 .../{ => classic}/include/diff_display.ezt | 0 templates/{ => classic}/include/diff_form.ezt | 0 .../{ => classic}/include/dir_footer.ezt | 0 .../{ => classic}/include/dir_header.ezt | 0 .../{ => classic}/include/file_header.ezt | 0 templates/{ => classic}/include/footer.ezt | 0 templates/{ => classic}/include/header.ezt | 0 .../{ => classic}/include/log_footer.ezt | 0 .../{ => classic}/include/log_header.ezt | 0 templates/{ => classic}/include/paging.ezt | 0 .../{ => classic}/include/pathrev_form.ezt | 0 templates/{ => classic}/include/props.ezt | 0 templates/{ => classic}/include/sort.ezt | 0 templates/{ => classic}/log.ezt | 0 templates/{ => classic}/log_table.ezt | 0 templates/{ => classic}/query.ezt | 0 templates/{ => classic}/query_form.ezt | 0 templates/{ => classic}/query_results.ezt | 0 templates/{ => classic}/revision.ezt | 0 templates/{ => classic}/roots.ezt | 0 templates/{ => classic}/rss.ezt | 0 templates/default/diff.ezt | 128 +++++++ templates/default/directory.ezt | 139 +++++++ templates/default/docroot/help.css | 8 + templates/default/docroot/help_dirview.html | 126 +++++++ templates/default/docroot/help_log.html | 71 ++++ templates/default/docroot/help_query.html | 66 ++++ templates/default/docroot/help_rootview.html | 166 +++++++++ templates/default/docroot/images/back.png | Bin 0 -> 337 bytes .../default/docroot/images/back_small.png | Bin 0 -> 205 bytes templates/default/docroot/images/broken.png | Bin 0 -> 247 bytes templates/default/docroot/images/cvs-logo.png | Bin 0 -> 601 bytes templates/default/docroot/images/dir.png | Bin 0 -> 228 bytes templates/default/docroot/images/down.png | Bin 0 -> 167 bytes .../docroot/images/feed-icon-16x16.jpg | Bin 0 -> 1004 bytes templates/default/docroot/images/forward.png | Bin 0 -> 338 bytes templates/default/docroot/images/svn-logo.png | Bin 0 -> 1057 bytes templates/default/docroot/images/text.png | Bin 0 -> 226 bytes templates/default/docroot/images/up.png | Bin 0 -> 168 bytes .../default/docroot/images/viewvc-logo.png | Bin 0 -> 8376 bytes templates/default/docroot/scripts.js | 4 + templates/default/docroot/styles.css | 339 ++++++++++++++++++ templates/default/error.ezt | 51 +++ templates/default/file.ezt | 61 ++++ templates/default/graph.ezt | 15 + templates/default/include/diff_form.ezt | 70 ++++ templates/default/include/fileview.ezt | 74 ++++ templates/default/include/footer.ezt | 10 + templates/default/include/header.ezt | 71 ++++ templates/default/include/pathrev_form.ezt | 53 +++ templates/default/include/props.ezt | 25 ++ templates/default/log.ezt | 247 +++++++++++++ templates/default/markup.ezt | 18 + templates/default/query.ezt | 241 +++++++++++++ templates/default/query_form.ezt | 201 +++++++++++ templates/default/query_results.ezt | 86 +++++ templates/default/revision.ezt | 81 +++++ templates/default/roots.ezt | 40 +++ templates/default/rss.ezt | 17 + 94 files changed, 2415 insertions(+), 2 deletions(-) rename templates/{ => classic}/diff.ezt (100%) rename templates/{ => classic}/dir_new.ezt (100%) rename templates/{ => classic}/directory.ezt (100%) rename templates/{ => classic}/docroot/help.css (100%) rename templates/{ => classic}/docroot/help_dirview.html (100%) rename templates/{ => classic}/docroot/help_log.html (100%) rename templates/{ => classic}/docroot/help_query.html (100%) rename templates/{ => classic}/docroot/help_rootview.html (100%) rename templates/{ => classic}/docroot/images/annotate.png (100%) rename templates/{ => classic}/docroot/images/back.png (100%) rename templates/{ => classic}/docroot/images/back_small.png (100%) rename templates/{ => classic}/docroot/images/broken.png (100%) rename templates/{ => classic}/docroot/images/chalk.jpg (100%) rename templates/{ => classic}/docroot/images/cvsgraph_16x16.png (100%) rename templates/{ => classic}/docroot/images/cvsgraph_32x32.png (100%) rename templates/{ => classic}/docroot/images/diff.png (100%) rename templates/{ => classic}/docroot/images/dir.png (100%) rename templates/{ => classic}/docroot/images/down.png (100%) rename templates/{ => classic}/docroot/images/download.png (100%) rename templates/{ => classic}/docroot/images/favicon.ico (100%) rename templates/{ => classic}/docroot/images/feed-icon-16x16.jpg (100%) rename templates/{ => classic}/docroot/images/forward.png (100%) rename templates/{ => classic}/docroot/images/list.png (100%) rename templates/{ => classic}/docroot/images/lock.png (100%) rename templates/{ => classic}/docroot/images/log.png (100%) rename templates/{ => classic}/docroot/images/text.png (100%) rename templates/{ => classic}/docroot/images/up.png (100%) rename templates/{ => classic}/docroot/images/view.png (100%) rename templates/{ => classic}/docroot/images/viewvc-logo.png (100%) rename templates/{ => classic}/docroot/styles.css (100%) rename templates/{ => classic}/error.ezt (100%) rename templates/{ => classic}/file.ezt (100%) rename templates/{ => classic}/graph.ezt (100%) rename templates/{ => classic}/include/diff_display.ezt (100%) rename templates/{ => classic}/include/diff_form.ezt (100%) rename templates/{ => classic}/include/dir_footer.ezt (100%) rename templates/{ => classic}/include/dir_header.ezt (100%) rename templates/{ => classic}/include/file_header.ezt (100%) rename templates/{ => classic}/include/footer.ezt (100%) rename templates/{ => classic}/include/header.ezt (100%) rename templates/{ => classic}/include/log_footer.ezt (100%) rename templates/{ => classic}/include/log_header.ezt (100%) rename templates/{ => classic}/include/paging.ezt (100%) rename templates/{ => classic}/include/pathrev_form.ezt (100%) rename templates/{ => classic}/include/props.ezt (100%) rename templates/{ => classic}/include/sort.ezt (100%) rename templates/{ => classic}/log.ezt (100%) rename templates/{ => classic}/log_table.ezt (100%) rename templates/{ => classic}/query.ezt (100%) rename templates/{ => classic}/query_form.ezt (100%) rename templates/{ => classic}/query_results.ezt (100%) rename templates/{ => classic}/revision.ezt (100%) rename templates/{ => classic}/roots.ezt (100%) rename templates/{ => classic}/rss.ezt (100%) create mode 100644 templates/default/diff.ezt create mode 100644 templates/default/directory.ezt create mode 100644 templates/default/docroot/help.css create mode 100644 templates/default/docroot/help_dirview.html create mode 100644 templates/default/docroot/help_log.html create mode 100644 templates/default/docroot/help_query.html create mode 100644 templates/default/docroot/help_rootview.html create mode 100644 templates/default/docroot/images/back.png create mode 100644 templates/default/docroot/images/back_small.png create mode 100644 templates/default/docroot/images/broken.png create mode 100644 templates/default/docroot/images/cvs-logo.png create mode 100644 templates/default/docroot/images/dir.png create mode 100644 templates/default/docroot/images/down.png create mode 100644 templates/default/docroot/images/feed-icon-16x16.jpg create mode 100644 templates/default/docroot/images/forward.png create mode 100644 templates/default/docroot/images/svn-logo.png create mode 100644 templates/default/docroot/images/text.png create mode 100644 templates/default/docroot/images/up.png create mode 100644 templates/default/docroot/images/viewvc-logo.png create mode 100644 templates/default/docroot/scripts.js create mode 100644 templates/default/docroot/styles.css create mode 100644 templates/default/error.ezt create mode 100644 templates/default/file.ezt create mode 100644 templates/default/graph.ezt create mode 100644 templates/default/include/diff_form.ezt create mode 100644 templates/default/include/fileview.ezt create mode 100644 templates/default/include/footer.ezt create mode 100644 templates/default/include/header.ezt create mode 100644 templates/default/include/pathrev_form.ezt create mode 100644 templates/default/include/props.ezt create mode 100644 templates/default/log.ezt create mode 100644 templates/default/markup.ezt create mode 100644 templates/default/query.ezt create mode 100644 templates/default/query_form.ezt create mode 100644 templates/default/query_results.ezt create mode 100644 templates/default/revision.ezt create mode 100644 templates/default/roots.ezt create mode 100644 templates/default/rss.ezt diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index 4780aeb9..87b79a1d 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -568,7 +568,12 @@ ## SEE ALSO: the [templates] configuration section, where you can ## override templates on a per-view basis. ## -#template_dir = templates +## Example: +## template_dir = templates/classic +## template_dir = templates/default +## template_dir = templates-contrib/custom/templates +# +#template_dir = templates/default ## docroot: Web path to a directory that contains ViewVC static files ## (stylesheets, images, etc.) If set, static files will get diff --git a/lib/config.py b/lib/config.py index 11afc1c2..479aea0e 100644 --- a/lib/config.py +++ b/lib/config.py @@ -415,7 +415,7 @@ class Config: self.options.hr_ignore_keyword_subst = 1 self.options.hr_intraline = 0 self.options.allow_compress = 0 - self.options.template_dir = "templates" + self.options.template_dir = "templates/default" self.options.docroot = None self.options.show_subdir_lastmod = 0 self.options.show_roots_lastmod = 0 diff --git a/templates/diff.ezt b/templates/classic/diff.ezt similarity index 100% rename from templates/diff.ezt rename to templates/classic/diff.ezt diff --git a/templates/dir_new.ezt b/templates/classic/dir_new.ezt similarity index 100% rename from templates/dir_new.ezt rename to templates/classic/dir_new.ezt diff --git a/templates/directory.ezt b/templates/classic/directory.ezt similarity index 100% rename from templates/directory.ezt rename to templates/classic/directory.ezt diff --git a/templates/docroot/help.css b/templates/classic/docroot/help.css similarity index 100% rename from templates/docroot/help.css rename to templates/classic/docroot/help.css diff --git a/templates/docroot/help_dirview.html b/templates/classic/docroot/help_dirview.html similarity index 100% rename from templates/docroot/help_dirview.html rename to templates/classic/docroot/help_dirview.html diff --git a/templates/docroot/help_log.html b/templates/classic/docroot/help_log.html similarity index 100% rename from templates/docroot/help_log.html rename to templates/classic/docroot/help_log.html diff --git a/templates/docroot/help_query.html b/templates/classic/docroot/help_query.html similarity index 100% rename from templates/docroot/help_query.html rename to templates/classic/docroot/help_query.html diff --git a/templates/docroot/help_rootview.html b/templates/classic/docroot/help_rootview.html similarity index 100% rename from templates/docroot/help_rootview.html rename to templates/classic/docroot/help_rootview.html diff --git a/templates/docroot/images/annotate.png b/templates/classic/docroot/images/annotate.png similarity index 100% rename from templates/docroot/images/annotate.png rename to templates/classic/docroot/images/annotate.png diff --git a/templates/docroot/images/back.png b/templates/classic/docroot/images/back.png similarity index 100% rename from templates/docroot/images/back.png rename to templates/classic/docroot/images/back.png diff --git a/templates/docroot/images/back_small.png b/templates/classic/docroot/images/back_small.png similarity index 100% rename from templates/docroot/images/back_small.png rename to templates/classic/docroot/images/back_small.png diff --git a/templates/docroot/images/broken.png b/templates/classic/docroot/images/broken.png similarity index 100% rename from templates/docroot/images/broken.png rename to templates/classic/docroot/images/broken.png diff --git a/templates/docroot/images/chalk.jpg b/templates/classic/docroot/images/chalk.jpg similarity index 100% rename from templates/docroot/images/chalk.jpg rename to templates/classic/docroot/images/chalk.jpg diff --git a/templates/docroot/images/cvsgraph_16x16.png b/templates/classic/docroot/images/cvsgraph_16x16.png similarity index 100% rename from templates/docroot/images/cvsgraph_16x16.png rename to templates/classic/docroot/images/cvsgraph_16x16.png diff --git a/templates/docroot/images/cvsgraph_32x32.png b/templates/classic/docroot/images/cvsgraph_32x32.png similarity index 100% rename from templates/docroot/images/cvsgraph_32x32.png rename to templates/classic/docroot/images/cvsgraph_32x32.png diff --git a/templates/docroot/images/diff.png b/templates/classic/docroot/images/diff.png similarity index 100% rename from templates/docroot/images/diff.png rename to templates/classic/docroot/images/diff.png diff --git a/templates/docroot/images/dir.png b/templates/classic/docroot/images/dir.png similarity index 100% rename from templates/docroot/images/dir.png rename to templates/classic/docroot/images/dir.png diff --git a/templates/docroot/images/down.png b/templates/classic/docroot/images/down.png similarity index 100% rename from templates/docroot/images/down.png rename to templates/classic/docroot/images/down.png diff --git a/templates/docroot/images/download.png b/templates/classic/docroot/images/download.png similarity index 100% rename from templates/docroot/images/download.png rename to templates/classic/docroot/images/download.png diff --git a/templates/docroot/images/favicon.ico b/templates/classic/docroot/images/favicon.ico similarity index 100% rename from templates/docroot/images/favicon.ico rename to templates/classic/docroot/images/favicon.ico diff --git a/templates/docroot/images/feed-icon-16x16.jpg b/templates/classic/docroot/images/feed-icon-16x16.jpg similarity index 100% rename from templates/docroot/images/feed-icon-16x16.jpg rename to templates/classic/docroot/images/feed-icon-16x16.jpg diff --git a/templates/docroot/images/forward.png b/templates/classic/docroot/images/forward.png similarity index 100% rename from templates/docroot/images/forward.png rename to templates/classic/docroot/images/forward.png diff --git a/templates/docroot/images/list.png b/templates/classic/docroot/images/list.png similarity index 100% rename from templates/docroot/images/list.png rename to templates/classic/docroot/images/list.png diff --git a/templates/docroot/images/lock.png b/templates/classic/docroot/images/lock.png similarity index 100% rename from templates/docroot/images/lock.png rename to templates/classic/docroot/images/lock.png diff --git a/templates/docroot/images/log.png b/templates/classic/docroot/images/log.png similarity index 100% rename from templates/docroot/images/log.png rename to templates/classic/docroot/images/log.png diff --git a/templates/docroot/images/text.png b/templates/classic/docroot/images/text.png similarity index 100% rename from templates/docroot/images/text.png rename to templates/classic/docroot/images/text.png diff --git a/templates/docroot/images/up.png b/templates/classic/docroot/images/up.png similarity index 100% rename from templates/docroot/images/up.png rename to templates/classic/docroot/images/up.png diff --git a/templates/docroot/images/view.png b/templates/classic/docroot/images/view.png similarity index 100% rename from templates/docroot/images/view.png rename to templates/classic/docroot/images/view.png diff --git a/templates/docroot/images/viewvc-logo.png b/templates/classic/docroot/images/viewvc-logo.png similarity index 100% rename from templates/docroot/images/viewvc-logo.png rename to templates/classic/docroot/images/viewvc-logo.png diff --git a/templates/docroot/styles.css b/templates/classic/docroot/styles.css similarity index 100% rename from templates/docroot/styles.css rename to templates/classic/docroot/styles.css diff --git a/templates/error.ezt b/templates/classic/error.ezt similarity index 100% rename from templates/error.ezt rename to templates/classic/error.ezt diff --git a/templates/file.ezt b/templates/classic/file.ezt similarity index 100% rename from templates/file.ezt rename to templates/classic/file.ezt diff --git a/templates/graph.ezt b/templates/classic/graph.ezt similarity index 100% rename from templates/graph.ezt rename to templates/classic/graph.ezt diff --git a/templates/include/diff_display.ezt b/templates/classic/include/diff_display.ezt similarity index 100% rename from templates/include/diff_display.ezt rename to templates/classic/include/diff_display.ezt diff --git a/templates/include/diff_form.ezt b/templates/classic/include/diff_form.ezt similarity index 100% rename from templates/include/diff_form.ezt rename to templates/classic/include/diff_form.ezt diff --git a/templates/include/dir_footer.ezt b/templates/classic/include/dir_footer.ezt similarity index 100% rename from templates/include/dir_footer.ezt rename to templates/classic/include/dir_footer.ezt diff --git a/templates/include/dir_header.ezt b/templates/classic/include/dir_header.ezt similarity index 100% rename from templates/include/dir_header.ezt rename to templates/classic/include/dir_header.ezt diff --git a/templates/include/file_header.ezt b/templates/classic/include/file_header.ezt similarity index 100% rename from templates/include/file_header.ezt rename to templates/classic/include/file_header.ezt diff --git a/templates/include/footer.ezt b/templates/classic/include/footer.ezt similarity index 100% rename from templates/include/footer.ezt rename to templates/classic/include/footer.ezt diff --git a/templates/include/header.ezt b/templates/classic/include/header.ezt similarity index 100% rename from templates/include/header.ezt rename to templates/classic/include/header.ezt diff --git a/templates/include/log_footer.ezt b/templates/classic/include/log_footer.ezt similarity index 100% rename from templates/include/log_footer.ezt rename to templates/classic/include/log_footer.ezt diff --git a/templates/include/log_header.ezt b/templates/classic/include/log_header.ezt similarity index 100% rename from templates/include/log_header.ezt rename to templates/classic/include/log_header.ezt diff --git a/templates/include/paging.ezt b/templates/classic/include/paging.ezt similarity index 100% rename from templates/include/paging.ezt rename to templates/classic/include/paging.ezt diff --git a/templates/include/pathrev_form.ezt b/templates/classic/include/pathrev_form.ezt similarity index 100% rename from templates/include/pathrev_form.ezt rename to templates/classic/include/pathrev_form.ezt diff --git a/templates/include/props.ezt b/templates/classic/include/props.ezt similarity index 100% rename from templates/include/props.ezt rename to templates/classic/include/props.ezt diff --git a/templates/include/sort.ezt b/templates/classic/include/sort.ezt similarity index 100% rename from templates/include/sort.ezt rename to templates/classic/include/sort.ezt diff --git a/templates/log.ezt b/templates/classic/log.ezt similarity index 100% rename from templates/log.ezt rename to templates/classic/log.ezt diff --git a/templates/log_table.ezt b/templates/classic/log_table.ezt similarity index 100% rename from templates/log_table.ezt rename to templates/classic/log_table.ezt diff --git a/templates/query.ezt b/templates/classic/query.ezt similarity index 100% rename from templates/query.ezt rename to templates/classic/query.ezt diff --git a/templates/query_form.ezt b/templates/classic/query_form.ezt similarity index 100% rename from templates/query_form.ezt rename to templates/classic/query_form.ezt diff --git a/templates/query_results.ezt b/templates/classic/query_results.ezt similarity index 100% rename from templates/query_results.ezt rename to templates/classic/query_results.ezt diff --git a/templates/revision.ezt b/templates/classic/revision.ezt similarity index 100% rename from templates/revision.ezt rename to templates/classic/revision.ezt diff --git a/templates/roots.ezt b/templates/classic/roots.ezt similarity index 100% rename from templates/roots.ezt rename to templates/classic/roots.ezt diff --git a/templates/rss.ezt b/templates/classic/rss.ezt similarity index 100% rename from templates/rss.ezt rename to templates/classic/rss.ezt diff --git a/templates/default/diff.ezt b/templates/default/diff.ezt new file mode 100644 index 00000000..0072bbf7 --- /dev/null +++ b/templates/default/diff.ezt @@ -0,0 +1,128 @@ +[# Setup page definitions] + [define page_title]Diff of:[end] + [define help_href][docroot]/help_rootview.html[end] +[# end] +[include "include/header.ezt" "diff"] + +
+
+ [for diff_format_hidden_values][end] + + + (Generate patch) +
+ + +
+ + +[if-any raw_diff] +
[raw_diff]
+[else] + +[define change_right][end] +[define last_change_type][end] + +[# these should live in stylesheets] + +
[msg_no_changes]
[msg_binary]
[diff.changes.left_number][diff.changes.right_number][diffs.changes.left_number][diffs.changes.right_number]
diffdiffs List List of all blocks of differences between the two sides, including content and property differences.
diff.display_asdiffs.display_as String Indicates the type of this block. One of the anchor (no display, create an anchor), raw (non-colored diff, display as produced), @@ -719,47 +719,47 @@ td { unified (colored unified diff).
diff.anchordiffs.anchor StringIf diff.display_as is anchor, this variable specifies + If diffs.display_as is anchor, this variable specifies the anchor name.
diff.changesdiffs.changes List/Container Set of objects which contain information about a change in a single - object (file or property). Not present if diff.display_as is + object (file or property). Not present if diffs.display_as is anchor, otherwise has different format depending on - diff.display_as (applicable as indicated in brackets below).
diff.changes.rawdiffs.changes.raw String[raw] Diff text. Valid only if diff.changes.type is + [raw] Diff text. Valid only if diffs.changes.type is raw.
diff.changes.typediffs.changes.type String [raw] The type of change. Values: binary-diff, error, no-changes, raw.
diff.changes.have_leftdiffs.changes.have_left Boolean [sidebyside-1] Specifies whether the left file has a line of content relevant to the difference data line. Valid only when changes.type is change.
diff.changes.have_rightdiffs.changes.have_right Boolean [sidebyside-1] Specifies whether the right file has a line of content relevant to the difference data line. Valid only when changes.type is change.
diff.changes.leftdiffs.changes.left String [sidebyside-1] Textual contents of the relevant line in the left file. Valid only when changes.type is change, @@ -770,7 +770,7 @@ td { support).
diff.changes.rightdiffs.changes.right String [sidebyside-1] Textual contents of the relevant line in the right file. Valid only when changes.type is add, change, @@ -781,256 +781,256 @@ td { support).
diff.changes.line_info_extradiffs.changes.line_info_extra String [sidebyside-1] Additional line information for the current difference hunk. Valid only when changes.type is header.
diff.changes.line_info_leftdiffs.changes.line_info_left String [sidebyside-1] First line number represented by the current hunk in the left file. Valid only when changes.type is header.
diff.changes.line_info_rightdiffs.changes.line_info_right String [sidebyside-1] First line number represented by the current hunk in the right file. Valid only when changes.type is header.
diff.changes.line_numberdiffs.changes.line_number String [sidebyside-1] Line number (1-based) of the line.
diff.changes.typediffs.changes.type String [sidebyside-1] The type of change. Values: add, binary-diff, change, context, error, header, no-changes, remove.
diff.changes.columnsdiffs.changes.columns List [sidebyside-2] List of two columns for left and right parts of the diff.
diff.changes.columns.line_numberdiffs.changes.columns.line_number String [sidebyside-2] Line number in the left/right column.
diff.changes.columns.segmentsdiffs.changes.columns.segments List [sidebyside-2] Left/right line, broken into change segments.
diff.changes.columns.segments.textdiffs.changes.columns.segments.text String [sidebyside-2] Text of this segment.
diff.changes.columns.segments.typediffs.changes.columns.segments.type String [sidebyside-2] Not set if the segment is the same in both left and right sides; otherwise, one of the add, remove or change.
diff.changes.gapdiffs.changes.gap Boolean [sidebyside-2] If true, indicates that change blocks are non-contiguous and that the template should display some sort of ellipsis before the current block.
diff.changes.typediffs.changes.type String [sidebyside-2] The type of change. Values: binary-diff, error, intraline, no-changes.
diff.changes.segmentsdiffs.changes.segments List [unified] Left/right line, broken into change segments.
diff.changes.segments.textdiffs.changes.segments.text String [unified] Text of this segment.
diff.changes.segments.typediffs.changes.segments.type String [unified] Not set if the segment is the same in both left and right sides; otherwise, one of the add, remove or change.
diff.changes.typediffs.changes.type String [unified] The type of change. Values: add, binary-diff, error, no-changes, remove or empty string if the line was not changed (context line).
diff.leftdiffs.left Container Container object for grouping information about the left file.
diff.left.agodiffs.left.ago String Text description of the time elapsed since left.date.
diff.left.annotate_hrefdiffs.left.annotate_href String URL of the ViewVC annotation view for the left file. Valid only when entries.pathtype is file.
diff.left.authordiffs.left.author String Author of the revision of the left file.
diff.left.datediffs.left.date String Date (in UTC if not otherwise configured) in which the left file revision was created.
diff.left.download_hrefdiffs.left.download_href String URL to download the HEAD revision of the left file.
diff.left.download_text_hrefdiffs.left.download_text_href String URL to download the HEAD revision of the left file as text/plain.
diff.left.logdiffs.left.log String Log message of the left file revision.
diff.left.pathdiffs.left.path String Path of the left file.
diff.left.prefer_markupdiffs.left.prefer_markup Boolean Indicates whether to make the default file link a link to the markup page instead of the checkout page.
diff.left.revdiffs.left.rev String Revision of the left file.
diff.left.revision_hrefdiffs.left.revision_href String URL of the Subversion revision view for the left file's current revision. Valid only when roottype is svn.
diff.left.sizediffs.left.size String Size of the left file revision, in bytes. Subversion only.
diff.left.tagdiffs.left.tag String Tag of the left file.
diff.left.view_hrefdiffs.left.view_href String This is a URL for the markup view of the left file.
diff.rightdiffs.right Container Container object for grouping information about the right file.
diff.right.agodiffs.right.ago String Text description of the time elapsed since right.date.
diff.right.annotate_hrefdiffs.right.annotate_href String URL of the ViewVC annotation view for the right file. Valid only when entries.pathtype is file.
diff.right.authordiffs.right.author String Author of the revision of the right file.
diff.right.datediffs.right.date String Date (in UTC if not otherwise configured) in which the right file revision was created.
diff.right.download_hrefdiffs.right.download_href String URL to download the HEAD revision of the right file.
diff.right.download_text_hrefdiffs.right.download_text_href String URL to download the HEAD revision of the right file as text/plain.
diff.right.logdiffs.right.log String Log message of the right file revision.
diff.right.pathdiffs.right.path String Path of the right file.
diff.right.prefer_markupdiffs.right.prefer_markup Boolean Indicates whether to make the default file link a link to the markup page instead of the checkout page.
diff.right.revdiffs.right.rev String Revision of the right file.
diff.right.revision_hrefdiffs.right.revision_href String URL of the Subversion revision view for the right file's current revision. Valid only when roottype is svn.
diff.right.sizediffs.right.size String Size of the right file revision, in bytes. Subversion only.
diff.right.tagdiffs.right.tag String Tag of the right file.
diff.right.view_hrefdiffs.right.view_href String This is a URL for the markup view of the right file.
+[for changes] + [is changes.type "change"][else] + [if-any change_right][change_right][define change_right][end][end] + [end] + [is changes.type "header"] + + + + + [else] + [is changes.type "add"] + + + + + + [else] + [is changes.type "remove"] + + + + + + [else] + [is changes.type "change"] + [if-any changes.have_left] + + + + + + [end] + [define change_right][change_right] + [if-any changes.have_right] + + + + + [end] + [end] + [else] + [is changes.type "no-changes"] + + [else] + [is changes.type "binary-diff"] + + [else] + [is changes.type "error"] + + [else][# a line of context] + + + + + + [end][end][end][end][end][end][end] + [define last_change_type][changes.type][end] +[end] +[if-any change_right][change_right][end] +
# + Line [changes.line_info_left] | + Line [changes.line_info_right] +
[if-any right.annotate_href][changes.line_number][else][changes.line_number][end]+[changes.right]
[changes.line_number][changes.left]
[changes.line_number]<[changes.left]
[if-any right.annotate_href][changes.line_number][else][changes.line_number][end]>[changes.right]
- No changes -
- Binary file revisions differ -
- ViewVC depends on rcsdiff and GNU diff + to create this page. ViewVC cannot find GNU diff. Even if you + have GNU diff installed, the rcsdiff program must be configured + and compiled with the GNU diff location. -
[if-any right.annotate_href][changes.line_number][else][changes.line_number][end] [changes.right]
+ +

Diff Legend

+ + + + + + + + + + + + + + + + + +
Removed lines
+Added lines
<Changed lines
>Changed lines
+ +[end] + + + + +[include "include/footer.ezt"] diff --git a/templates/default/directory.ezt b/templates/default/directory.ezt new file mode 100644 index 00000000..67930728 --- /dev/null +++ b/templates/default/directory.ezt @@ -0,0 +1,139 @@ +[# setup page definitions] + [define page_title]Index of:[end] + [define help_href][docroot]/help_[if-any where]dir[else]root[end]view.html[end] +[# end] +[include "include/header.ezt" "directory"] + +[if-any where][else] + +[end] + + +[is picklist_len "0"][else][is picklist_len "1"][else] + + + + +[end][end] +
Jump to page:
+ [for dir_paging_hidden_values][end] + + +
+
+ +
+ + +
+[is roottype "svn"] +[if-any rev]r[rev][end] +[else] +[is num_dead "0"] +[else] + [if-any attic_showing] + Hide + [else] + Show + [end] + dead files +[end] +[end] +
+ + + + + + + + + + +[if-any up_href] + + + + [end] +[for entries] + [define click_href][is entries.pathtype "dir"][entries.view_href][else][if-any entries.prefer_markup][entries.view_href][else][entries.download_href][end][end][end] + + + + + + +[end] + + +
+ File + [is sortby "file"] + [is sortdir + [end] + + + Last Change + [is sortby "rev"] + [is sortdir + [end] + +
+ +  ../ +
+ [if-any click_href][end] + + [entries.name][is entries.pathtype "dir"]/[end][if-any click_href][end] + [is entries.state "dead"](dead)[end] + + [if-any entries.rev] + [if-any entries.log_href][entries.rev][else][entries.rev][end] + ([entries.ago] ago) + by [entries.author]: + [entries.log] + [is entries.pathtype "dir"][is roottype "cvs"] + (from [entries.log_file]/[entries.log_rev]) + [end][end] + [end] +
+ +
+[if-any search_re_action] +
+
+ [for search_re_hidden_values][end] + + +
+
+[if-any search_re] +
+
+ [for search_re_hidden_values][end] + +
+
+[end] +         +[end] +[include "include/pathrev_form.ezt"] +         +[files_shown] file[is files_shown "1"][else]s[end] shown +
+ +[include "include/props.ezt"] + + +
+ +[include "include/footer.ezt"] diff --git a/templates/default/docroot/help.css b/templates/default/docroot/help.css new file mode 100644 index 00000000..6680d84c --- /dev/null +++ b/templates/default/docroot/help.css @@ -0,0 +1,8 @@ +/************************************/ +/*** ViewVC Help CSS Stylesheet ***/ +/************************************/ +body { margin: 0.5em; } +img { border: none; } +table { width: 100%; } +td { vertical-align: top; } +col.menu { width:12em; } diff --git a/templates/default/docroot/help_dirview.html b/templates/default/docroot/help_dirview.html new file mode 100644 index 00000000..ea471d54 --- /dev/null +++ b/templates/default/docroot/help_dirview.html @@ -0,0 +1,126 @@ + + + + ViewVC Help: Directory View + + + + + + + + + +
+

ViewVC Help: Directory View

+
+

Help

+ General
+ Directory View
+ Log View
+ +

Internet

+ Home
+ Upgrading
+ Contributing
+ License
+
+ +

The directory listing view should be a familiar sight to any + computer user. It shows the path of the current directory being viewed + at the top of the page. Below that is a table summarizing the + directory contents, and then comes actual contents, a sortable list of + all files and subdirectories inside the current directory.

+ +

The summary table is made up of some or all + of the following rows:

+
    +
  • Files Shown + - Number of files shown in the directory listing. This might be less + than the actual number of files in the directory if a + regular expression search is in place, + hiding files which don't meet the search criteria. In CVS directory + listings, this row will also have a link to toggle display of + dead files, if any are + present.
  • + +
  • Directory + Revision - For Subversion directories only. + Shown as "# of #" where the first number is the most recent + repository revision where the directory (or a path underneath it) + was modified. The second number is just the latest repository + revision. Both numbers are links to + revision views
  • + +
  • Sticky + Revision/Tag - shows the current + sticky revision or + tag and contains form fields to set or clear it.
  • + +
  • Current Search - + If a regular expression search is in place, + shows the search string.
  • + +
  • Query - Provides + a link to a query form + for the directory
  • +
+ +

The actual directory list is a table with + filenames and directory names in one column and information about the + most recent revisions where each file or directory was modified in the + other columns. Column headers can be clicked to sort the directory + entries in order by a column, and clicked again to reverse the sort + order.

+ +

+ + File names are links to log views + showing a list of revisions where a file was modified. Revision + numbers are links to either + view + or download a file + (depending on its file type). The links are reversed for directories. + Directory revision numbers are links to log + views, while directory names are links showing the contents of those + directories. + + + + + Also, in CVS repositories with the graph view enabled, there + will be small icons next to file names which are links to revision + graphs.

+ +

Depending on how ViewVC is configured, there may be more options + at the bottom of directory pages:

+ +
    +
  • Regular expression + search - If enabled, will show a form field accepting + a search string (a + python regular + expression). Once submitted, only files that have at least + one occurance of the expression will show up in directory listings. +
  • +
  • Tarball download - + If enabled, will show a link to download a gzipped tar archive of + the directory contents.
  • +
+ +
+
+
ViewVC Users Mailinglist
+ + diff --git a/templates/default/docroot/help_log.html b/templates/default/docroot/help_log.html new file mode 100644 index 00000000..33000943 --- /dev/null +++ b/templates/default/docroot/help_log.html @@ -0,0 +1,71 @@ + + + + ViewVC Help: Log View + + + + + + + + + + +
+

ViewVC Help: Log View

+
+

Help

+ General
+ Directory View
+ Log View
+ +

Internet

+ Home
+ Upgrading
+ Contributing
+ License
+
+

+ The log view displays the revision history of the selected source + file or directory. For each revision the following information is + displayed: + +

    +
  • The revision number. In Subversion repositories, this is a + link to the revision + view
  • +
  • For files, links to + view, + download, and + annotate the + revision. For directories, a link to + list directory contents
  • +
  • A link to select the revision for diffs (see below)
  • +
  • The date and age of the change
  • +
  • The author of the modification
  • +
  • The CVS branch (usually MAIN, if not on a branch)
  • +
  • Possibly a list of CVS tags bound to the revision (if any)
  • +
  • The size of the change measured in added and removed lines of + code. (CVS only)
  • +
  • The size of the file in bytes at the time of the revision + (Subversion only)
  • +
  • Links to view diffs to the previous revision or possibly to + an arbitrary selected revision (if any, see above)
  • +
  • If the revision is the result of a copy, the path and revision + copied from
  • +
  • If the revision precedes a copy or rename, the path at the + time of the revision
  • +
  • And last but not least, the commit log message which should tell + about the reason for the change.
  • +
+

+ At the bottom of the page you will find a form which allows + to request diffs between arbitrary revisions. +

+
+
+
ViewVC Users Mailinglist
+ + diff --git a/templates/default/docroot/help_query.html b/templates/default/docroot/help_query.html new file mode 100644 index 00000000..96e6e438 --- /dev/null +++ b/templates/default/docroot/help_query.html @@ -0,0 +1,66 @@ + + + + ViewVC Help: Query The Commit Database + + + + + + + + + +
+

ViewVC Help: Query The Commit Database

+
+

Other Help:

+ General
+ Directory View
+ Classic Log View
+ Alternative Log View
+ Query Database + +

Internet

+ Home
+ Upgrading
+ Contributing
+ License
+
+ +

+ Select your parameters for querying the CVS commit database in the + form at the top of the page. You + can search for multiple matches by typing a comma-seperated list + into the text fields. Regular expressions, and wildcards are also + supported. Blank text input fields are treated as wildcards. +

+

+ Any of the text entry fields can take a comma-seperated list of + search arguments. For example, to search for all commits from + authors jpaint and gstein, just type: jpaint, + gstein in the Author input box. If you are searching + for items containing spaces or quotes, you will need to quote your + request. For example, the same search above with quotes is: + "jpaint", "gstein". +

+

+ Wildcard and regular expression searches are entered in a similar + way to the quoted requests. You must quote any wildcard or + regular expression request, and a command character preceeds the + first quote. The command character l(lowercase L) is for wildcard + searches, and the wildcard character is a percent (%). The + command character for regular expressions is r, and is + passed directly to MySQL, so you'll need to refer to the MySQL + manual for the exact regex syntax. It is very similar to Perl. A + wildard search for all files with a .py extention is: + l"%.py" in the File input box. The same search done + with a regular expression is: r".*\.py". +

+

+ All search types can be mixed, as long as they are seperated by + commas. +

+
+ diff --git a/templates/default/docroot/help_rootview.html b/templates/default/docroot/help_rootview.html new file mode 100644 index 00000000..1e15ccad --- /dev/null +++ b/templates/default/docroot/help_rootview.html @@ -0,0 +1,166 @@ + + + + ViewVC Help: General + + + + + + + + + +
+

ViewVC Help: General

+
+

Help

+ General
+ Directory View
+ Log View
+ +

Internet

+ Home
+ Upgrading
+ Contributing
+ License
+
+ +

ViewVC is a WWW interface for CVS and Subversion + repositories. It allows you to browse the files and directories in a + repository while showing you metadata from the repository history: log + messages, modification dates, author names, revision numbers, copy + history, and so on. It provides several different views of repository + data to help you find the information you are looking for:

+ + + +

Multiple Repositories

+ +

A single installation of ViewVC is often used to provide access to + more than one repository. In these installations, ViewVC shows a + Project Root drop down box in the top right corner of every + generated page to allow for quick access to any repository.

+ +

Sticky Revision and Tag

+ +

By default, ViewVC will show the files and directories and revisions + that currently exist in the repository. But it's also possible to browse + the contents of a repository at a point in its past history by choosing + a "sticky tag" (in CVS) or a "sticky revision" (in Subversion) from the + forms at the top of directory and log pages. They're called sticky + because once they're chosen, they stick around when you navigate to + other pages, until you reset them. When they're set, directory and log + pages only show revisions preceding the specified point in history. In + CVS, when a tag refers to a branch or a revision on a branch, only + revisions from the branch history are shown, including branch points and + their preceding revisions.

+ +

Dead Files

+ +

In CVS directory listings, ViewVC can optionally display dead files. + Dead files are files which used to be in a directory but are currently + deleted, or files which just don't exist in the currently selected + sticky tag. Dead files cannot be + shown in Subversion repositories. The only way to see a deleted file in + a Subversion directory is to navigate to a sticky revision where the + file previously existed.

+ +

Artificial Tags

+ +

In CVS Repositories, ViewVC adds artificial tags HEAD and + MAIN to tag listings and accepts them in place of revision + numbers and real tag names in all URLs. MAIN acts like a branch + tag pointing at the default branch, while HEAD acts like a + revision tag pointing to the latest revision on the default branch. The + default branch is usually just the trunk, but may be set to other + branches inside individual repository files. CVS will always check out + revisions from a file's default branch when no other branch is specified + on the command line.

+ +

More Information

+ +

More information about ViewVC is available from + viewvc.org. + See the links below for guides to CVS and Subversion

+ +

Documentation about CVS

+
+

+ Open Source + Development with CVS
+ CVS + User's Guide
+ Another CVS tutorial
+ Yet another CVS tutorial (a little old, but nice)
+ An old but very useful FAQ about CVS +

+
+ +

Documentation about Subversion

+
+

+ Version Control with + Subversion
+

+
+ +
+
+
ViewVC Users Mailinglist
+ + diff --git a/templates/default/docroot/images/back.png b/templates/default/docroot/images/back.png new file mode 100644 index 0000000000000000000000000000000000000000..65f463189df49999722b880f7438f27f4c9e319e GIT binary patch literal 337 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#R|IeH`Gc7I6*w`2- zwpDWP2Oz~*666=m;PC858ivL>4nJa0`PlBg3pY5H=O z_A8uXY#gkO>T~7+g~Cc)BTAg}b8}PkN*F>iGK&=wi%JxLRA!z+Nk*zdL1|J>X0k#` zer{rBo}PktY8g<%qclAuwOB_X8^p_SNX;zKOU}>LQ3y^gC`rvtN-a__w6rw!dGX~4 z(1u7)7srr_Td8L*ayA(7uw3Afba=reyRb-4;p{)-n@1`f_pE=cI_HGB>>6H)kZ(&J zGK)04zWyxOd`IH;%d7fl&#XSVXhqh{)|rtNf@_2MPu}18d)GeIGRdj&dFh-IDi5mv RyaHOn;OXk;vd$@?2>^bGagzW5 literal 0 HcmV?d00001 diff --git a/templates/default/docroot/images/back_small.png b/templates/default/docroot/images/back_small.png new file mode 100644 index 0000000000000000000000000000000000000000..a057c3f8b38885f081fa20b24ff6ebbd7948da09 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^4e$wZ{r~@ePft%&R1{F4rKQEt z&`?oPk$aSW-rm7L(vV4`t0 zZ4N`CiuCNpOf>~(#xp`@W+?|!b{JSRNVxUrc`@GJuRh0)ty{QI!S&cN vM*+7@g+Un#A<-H)JQgUacX&26Ih_!@hljQC0!qCAg>jC6&7I;J!Gca%qgD@k*tT_@u zLG}_)Usv|4TzsO^?3~}rd4NLEo-U3d9M_W*8X5x>0vHT^oSmEJCiDofY8Tv)70p>|W zK~yNueUiItQvnplzjN-z&{!V?TQvc3(ISXgMd}bbSO=|LM5(w5u1;F!^kE=AEn zEQoYy2|iHBBE?d~hBVZojY1!}eI#velbd@!hfuXP`r8g1_>PlojNMU&6lMRE7|r}5UUu2~tV7d=!Y^x4LX;sP zVdA`dF|7iT{NU``(y?g&y+|jwo+&hCNT}^kYWE;ST#{J)7?-uX8{=o|3s8dF+HoT6 zOlfNZfQkrq9gfg$g!v9x6*j3;Lto!sx1~umYPHH7UteLoN4!tY?C_QwpwJz#s(|6a zZoTwQ0Z2OxSQ6wH%;50sMjD8dHet;_g`Fn=~`KmGjDas?qX3B@tSM%B+BpFzO)CL O$>8bg=d#Wzp$P!8%Sc@S literal 0 HcmV?d00001 diff --git a/templates/default/docroot/images/down.png b/templates/default/docroot/images/down.png new file mode 100644 index 0000000000000000000000000000000000000000..5644d63bbf7d8ee10ddbf3896191c6efc9cef1ae GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4@NBt2Bi?12$S;_| z;n|He5GTpo-G!lpRn`N@;VkfoEM{Qf76M_$OLy!300r4gJbhi+uds{qb1J_`Wl{nP zNqM?BhE&{2PB_5ujbGvkzrhD{gAK+8298G=vuI=H%w(=K}(Mey}1a#RK7?>VxzCA7BvVU=UysU}h9#U=n0x7G(T?gmDqjf$WSR z0Azpx3oA1d8zTcd2PYRdBhcB*$g)5IpsU%yk^&4&Ku0mLFtM>S0|};LMkZ!K76w*D zAw$PNHsM62!bTCJi3{09H##XF47&KxSS;y-N>S5CRcDjnNsBfm7auZpQJ=hcvzd5E zO3C3%k2uttIk_YxTc)_WE!h%wIaEXH)8o%at~~jYTG~2w>DHrHpMFg%Yn!%g+p%lU zzL~p+r7lRZ2ajB-H%V;?0LOG%r8?+%jd! z7E~v@g&`b`)6ICC{QnjM4>Q=Af(-Ty-^C}|OkVu+@abLcv;MqY{BzQ;cc1>1?ftxO zzKXfw(W8N#^R9fF+!eOwU{%S>dD@FFC0%>@e8p8~&9Bm@xhC}MuaXbtOKChk`R&}L zwe7^k;YH0td;zKpGRXRds+*Tu+LU4(zNoX4jLe_2Z97vA_*wp%oKSAdw-R(i1SC^{AnGn@YN|Q)8YE(9p6{FT)S)aMQO(IdG!V* z{I)NCZJ$uHbZJ)k^zC)I-NBzkS8NacvS3%+^s-}p75b~rom!mtcXR&At1rJ+q%S)t xyf02CX(uOtNaY)gH4SF|>1AoPY!O*sg*%uz+k$J(_%DjtZezmv>_5Z*n*i+Te`Ejv literal 0 HcmV?d00001 diff --git a/templates/default/docroot/images/forward.png b/templates/default/docroot/images/forward.png new file mode 100644 index 0000000000000000000000000000000000000000..d8185ac944c0feee051eccbffee32eac22bfca06 GIT binary patch literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^B0wz0!VDyh@)w!{DgFST5Z5#R|IeH`Gc7I6*w`2- zwpDWP2Oz~*666=m;PC858ivL>4nJa0`PlBg3pY5H=O z_A8uXY#cIAeN5tjLSZGY5hc#~xw)x%B@7`MnZ*i;MI{PADl<=^BqLR!pfo8bGg%=e zKQ}QmPfx)+wG1fXQJS8STCAgx4dP`uq-K`rCFkerCP}+_EY!FlaVpXxVk1ODh>1aCbRm*}3l;D&M8p__ z1O&whXr;`eAQoh3p=BtIl2+)*>pYj&fzAWX0-Vsu`D zE=bTtDY_&@c{1Cw+{TyNej)Z11>g`U9YPi0T+=v3+D)l`Q*Lmr8(oOWtuVP&7LUg2 z(E=M@J?b^sd?vfk?C@C}eyh{JvFS%K0n`<+xdL`~z~K%!JwcZ@=<)^KzL3Ws^7=#m zU^oDT!a>YdD7+O0wy=mqBH#!9$3NOYBxvvKq{A?bZ8-vMFB=r>1_GbYK)@VVd?}j@ zJ&#GHfM!=IrLYWwViT~$3D&DZU`QyZUd|$j2&8x%@j!V=5g0M3kpN zB7>E7Uzv3MTJ%0;qR^Xj>}B~%lO9JbU6yhR=%@RgWwlxoXHaeK$2X661(->^1=l%r0h-@K0#|asNa#qKAwt*8@a63n1}Tj z&px6yCZ3_d?N^XYdd6H)5p+APqq>ZoSJKlGl}bP0l+XkKb96#n literal 0 HcmV?d00001 diff --git a/templates/default/docroot/images/up.png b/templates/default/docroot/images/up.png new file mode 100644 index 0000000000000000000000000000000000000000..625819f95daa9695a34e940f950fcf662be44af8 GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp@Ak4@NBt2Bi?12$S;_| z;n|He5GTpo-G!lpRn`N@;VkfoEM{Qf76M_$OLy!300r4gJbhi+uds{qa~RD&Cp-}- zB<<>$9(nR7-m=$^d0dGb{!7n_9(Wa!rFDV@ZCU_CWU)#(_1<=bLVg!;3g{R^P zsFKKzsDEw=_7i%US)?}yqJt)QagkyymW3xK0_v^*BLJ;eVX0vmP?{<*VE%}4@bb1u z*9+WbwdK!UaTHLQ?jg!1^SMcP_z40@xZ60+jL@~apnfzV58Z0|S7Dj%5=c5VeT=dB zT_p4PO^1*nE(irgYCbp=qhFwN;0%^u)Q7U@S>flx=IDN0NlUgEa;BD#dm_HSNPMlQ z2IXqqlk_^^Tt_ftBHP(hOxONnm%OmE|6THxGj$s7)@;a-vg#_@jR_6Md@I3GfIs*8C9sUr zOkc5d7mZzdhx&MEv2vUmuVrK>F}a?dUg|u5RHelMg1zJ=%IDgN#aEP^C^o%bTZFjkGI6sn|;0?xJXZc{%_rTd>vx}TzN?tOe z;c`3LbyjKnnbX`26ZdW-@Nh>QM`C#rYL$Db6;IES1i4n2uv&jIn83li<&QxQPO4x_n7iw zDlKEYez>61voj=e=MR;0d3EUr$&89p)@yNP(2aij1^&h*$3|(gm}oc!VnA5DUw`erE6>#)$}B*vkv{o0iFgUmLvlj!;| zax=zDe6FmQgZZ@%Yo7Ghwl*OrzI0`r9vQR}8Pw5Vf)*uI9UxFIC8=Qe8-Xp!oVCoO zV7-}mMRW2{em|o0Z; zX?gj9)6?o9i`pf`+vMS;B@tFuR(^hdCMG6s?s(TU!smBWqF)Fr-(4E5p0~!zo@ID_ zQaaO(j4M&k)VMo7J}xdU9vd6m*w`2v8j6U(;^N|pku&Ee&o3z08_gsmCGAg_G5YeW zb^0{}B&gl=eHZK-3Yn_$QcLCOi$aizx7%dL;fuAe*@Wo(4aClsvj=3_s*VCw&25=2 z!`pae3~!r{+=>)@d4vqSkMhCvvvj43nfqAu9nXTAG>VCf%gM}4>UWu#&-M29b~W`j zPS1kFpUX=(o7uC<1FaHOG&D5CYTJWTz(XcWRVTN@Y}x0N_6JU`q@~402x8Iw_H^U= z8gk~y%*yWc}&s$==>x!(*bHjMH#odb)?R+4t_e z<8g;8D^>&?J2Rub8vBko@>43OEpG;&{TweZFJ{A?N5{igFE1e_|KM3394#Fk$kV-h zUJ3BV&+6)(wigZd^N^EOzwN<<<73COpo|aJV^c++Mn*CdP8P*4@#GC60lX5E~3U69BXOd9Nki25_vr5D3tp$oSYN4BMVNC+B5|B?t3!L%_>3&^L*UbebFcx;i?mtzKID2~$&=KfBf; zEirNh6JO$DW51&(nWjBIKXVxT@x2%oAQao-`2RxVd)jqa)$v>+@uXNa-vc|py1Kf! zXz{(P-DCLr^=o!^HUR;F%}+D(;?h$15v&gS?(TKK?N9xRP$pAsF5`CgnX|`7U+_S- zsBef4Y^wMkVRIC_wk#*tK!Zi1L1{wQ6#TIkafSmN<;Lp-o=`xjb;kerHaePz7ex) zT!J;L@Tx>9lY>lpLUHlJP%@yJkKU&zWo2cTmzRDI*D3lqur{>jIg zYCn|7B(-yRaG-v%UjA}b72rimMMERub?(pl%6*yWMjnx=ge3T-% ztG8KYeNklC$*s;C$ioC--`6{lRueJsz>*VTnp#>6+TZ;B#eMl?HLBXKGt}RgOnYti zV&Ub!rV(e?HY%9>Pru<+%nK0MX2%s_f=I!lFBNk!R094Fh(>4{DGIN})JD)y-IeP~ z{e{D{c*M!br!RT=^>|@D!a`UebDj(kDCEMpk6RH|hGL#A;5}vz$|TdosZ$hdsG7Bu z+HkuaqH=1b)7+aZkWUy-D~2yFE^cg?61e}cOTpX^3JTIS_WK;3AYDfE<_$DCIXNML zfS8z3+X0~RmA~%h=H{HK@7UNBe>0+r{eT0(H_+Gj`~($r={Bp$?Ss1s1A+AX)Zg11 z92!breseW%tjkI)g?Kz}Ia$~e;^$|sRn@69ES-k0$MXvabX?6DOc-A>ZbDiFoK}4w zuD{_GyU;mdi==;Gu_6Jjn;jBFjk4}o+9{=`RwKW)t@G;Mfjroud@ze-tlQ(F==?WX zatoJYjnrf%b|4#gdgjIp7Fw8je0(e{WXuy*gNhER@(^gS0N^MpD%vMRJ1eGdxOrH6 z@wc!DZp4w*aO!x1eEvL}CmjYb$`i~wCtKLvZmr#qf`X!TM?^$K;(ni@WEu-0>K|t1 zS~qGX?X=br(4meUBe#|Q!J77R#nHphPpp1StSC1Zgv%VeMMpq&a25)AsWGkhKhb2;^Tnj$nm1 z#VZGV4PLRW_y*%5NV-$xV#6#NwW6V+!2l8eGmu_?#r8Tj?SvPSjReY+XhAJP60&W< z$VJ#_lJ@5_V@P(1tGb4bSEP?H-PJMct{0ho1@9%hq-#Iuq2*j9)H=Bfn zgi62>2NP4hRQmuUF(u_1UXoK>RCFfZ;JP<kK6j)E0^Hs)Gm6fDtngDXzYirMG zUT)=OW&5CFK4V!zbylO436+Sojx`IOnx6g}B*1U{f-r;`*S(hC>8}KVvh0OyJoJm! zr#@ATM;g4^V$)An8(X#{)RnqwsIpz8-lV44r$(Ao#t)w58$%=VWDG?`YO|Yt+h)X7 zsFaZCXk*jl_rTwQl&ju)KKyPQh2T9eEKS`1u?Zi>%E{@!n{Le-`NL*T6u&_qv9oh^ zz2tNuZdvms7Azz+?FN8T_RLy*Zhl@`)ZNXEm!Ch9_k5;QOQ)QKw6daNhhuARFEt}$ zSnh*jqOGlMb91xQEHM6&D~al0hMzw(b+4_P5Td$V?rS7K99LWK1Ul|wx=aF5ie~Ll zkddEn2P9HbQeKIf)qFWPI9Ra0P!N3gN{Y{}nJE8sb9;;%}@}wz-zL9 z1`KE!OnS>Q0gvwu)(V;;mJpr^ai|}>D79Yyo2n{amHz*jtoL_Q3%cVdU`LJGeT7t}_r`PfIOmUMN|KVD{V`O@N=2HbGGUK& zDvN*J-{r3#DTXbQl1dvV4D!8qILO!`3VYnP+21fHF8UYgeP(eHTQ~XuRWXz$)Vjcs z_?Fm&AzY9(s zpPikJiHoDcK__^T1Jr~!*GGIUXjF56MP8%s@6Nl6y%26j&UlS@#%7yIdOAsIH29Ff zI=D_k2y*mAQBl#rfXX5eS_@n&%+#O_WgMECnmRpoHd1?BUpE1`UR5;~Gr;F=Cl$8% z(Z(DVw7t7qru`OZqfR-1YByc!0BtF$?l2nv@MshM@!*m&*hbHT!P|&;VJzMgSQ6v3 z*ouj41R=u7NNgHxnu0IMF`vY>HG~!0$y@FoN1c#BY;}zUdW;+|;bkZobs{J-usfPvs-lk!BzGJZV{gQk(Ck9JjM8zYkQZmIIGAQ>i z{9Oh_;)?CRZ$c&>`d0@q*GH{|z&G4yApLS~XDJ!hzs+73Rs_Za9&3Iqmx#p%d)R@V zQsf6PD_zC|qgfq{mJaLn>$teMJ&xhMdyLPt9H0(75u zlX(uOvfog#4O7uzC59*Ty$zWU#}cN87Soaqx5m>eef)SGz16hBCuFi2F>Qw_F-8qn zC=E~J0S1y(ARZo`QN0ZTrMhZyaFb^-sW^#?aCWu4RD10Gy|>zZz317ckn1j>s=kX$ zeBT}f1V9KF;?Ulux<{`#Wx|cwOzF7t7vNP@wq3s7tel)2b!!6ygM@P8QTE3kxLbc; zpRAl5kT-k#`bPa|0oO4(Imw-kUJ4DX@eDv@8A!Y5wJSm)bY@d_$($Um+rAG1fQwO% zF=9M(OCfHafy|hF@Me1|K(39?=;i*;emjyS2px3GDlO_-6|YIaV;L=H4x}n46eF)4 zlBVT^{KVDUg@rG9RX`%bdm|eDkL=XOn{r)bKjaT(vJx5%J16IAyPrta!;fE&!CRg# zE;UklUurF|SZ2OI-nyiY^c}JrG&$3qALMF;q!T*3`ftSuh`&6#u6nk|Q^lGaN$X2^ z94`Zz?<^&Zf_XweT$bL4{77XWXzPD-Y#4q+xEsPefq>ePhTh? z38*HcHp;ut#XeytKhUsc@?k40D@T4rh-AQ(!QB=Skd~EWXTc-(8khrrCT=W>Vj>I% z15^Ptxv`u(T|B@O6|uQ1H_|Mw(%phqBw|AUCTh;56FtNk|LsA|u0e6u=~ z32-wZbFX{24gNSZ`#toh!?S9cbKwn`bmpSsBkKT6xdZB$!+ z<8a)xgioDyA8cbqe($zr1d=p6m0~Iit#M4-hD{8d7-OsVc@c`^9e(NXe*%b55Wub_ ziZj?4Q0)fUxmn6=h%l|IL*tiw-H!WYbylCgND?nEFQ7qyLO=%L;NZ;6%|!}YB7p#z z63i!kVydArne=Q09{8lBq>va4;~GifAR1Ej-;a39F5~-CI&z)1^NgL9RY6H9Q8TZ^ zE2eDr@G6u48{sQr$<(`R#FEz?NtMH5eMEsT4O}vbZb?Pt@BxpZVI0e-v+tlBTLH%p z52QYO+V`t`ufOuZr&ye+R0Y#NR;5`V!(NWrM|6ZJjb4Fh9G!Py{yh*cip-eENV9Sx zc#M2ct@o8(f}2F+(pN35x^GK=DhwI{z`HN~`L=1p$-xm4N~@m_^sUw#7qw5HuwT8B zxADqrL+*9rU@6x#3d^yJ_aU!|CI7W5*Tm7aFzN+FC#}5AoB} ze7CvH0VZrYcINrKo2~03vcLT^o#G~pHTN`l*=hHwP%DHYp_Gm+ckaz7ap+I~!rOY? z_IQW&JYyKC9kqNk&Tm=rqT1 zqyyHT+4ksz!~9Xcky_)4^3}U(F~5ELRziX%-I%avCF=@>B(19I1dyy(2jx}b*J#w- z?-Bo#HgW}BG$g+Z`*LKx37E{;joS@{b3?`s@)hUp8npD82U~a7qbqQGdU`sZu9p%M z69+<7OieeebNon&iBY$<a6=4QTr z;9b2~;AjcJ;pbK>KmRCPTk~>D&G14&Cn1{@_ttZGAgoRKG~fMCfYD#s@W9$O>lwZF(Fn)cD*S!;fv**w_H^ z4(K-*6BF7?vKpjOzE>__UHsv~+&+m*8gRyblk>wN+T%wd-}{}>v3c*T zGp;L#UX0^{b}PGzE4!G%411$*rO4a(4Cg1tX&yR3qv1UBzIR8 zQ&VK*t2)?`*FAbqb#5+gg^ozkVYZ*6FfXs$-dHvuyIQxfzAoDEegC25;En!bpslT~ zu0An23CwwT?F=Uapu@$%aRw(aDxzax4D|N{c7}wQSVm5+n<>a_D@znD8nNopvI5v; zt2(I7(_tC{4@5gAAtCUcPnHcf4y=8AZ+74}7|6EwIb3CO?tAfve=`0$;fB=qupO|n z--dsfqsx86N1oB~Vbb^b`c3GDL_Ar(@+a=3&R(eoecW$etG1F7^1;4;p}L~ATVxaO z{~7JCcLfoL^&r_-FCoB^(rRFB!fJ|BP9~s=3?wYO2WgR)m*+@%5Fjp}wF6vUh*VJ8 z8$*BRGFr-oi{6Y3dHwEPm@`wZ4R@$%^?Ulb&iR@a+F)C^(f60BK01Sr=su!C#CX~B zKjx9UHKc}-p@m=yijVDV6*`B9hauJ?;3?|2h4|{=X5)se&J%QCQ9P+giPu~ z$RT~(xv84qhEE#QwnR3COD_zkLE#O_T>~$>LTgLVvW8o)>SOK|JK#S=Rg` z4HV*6Xv$QIm_ng4BLd*(7si%0+kThm_@=lrk>B~ivtj>(kIQM8M5m-HNbha&5=V1MB z68XQMC>UWs{X{dxYHiYj!OZ*TDC2iT!vQAdAqdcpLvdEA6lM4gi`(SX559u-Y6Q*r zI_3$((GKbZ=lcfyl(2#gJvwXUU}nq;+!?DTaSfXZ*WCELO(7-dJh@30_T>h|q;Uy| z#?9B3P-dsDD(ymDqu#&afy6UjO$B-ta{)%4PTj(y76;Ij(0&kUZqz?4V+5kei9&+M z@q~y?R6dyukvXnPnZ$zu?eM1C{&n7}8&M~FZe{5F###dTO9u+a45LvOJ>j zGNkc6wBv#95|Vd}9mCR{m1L#xpNdVESUHK)2Z1-}SNMfWRwJHQh!=hlbd3#XKmEC^ z&*F<9846&Dt8)-x@TAL(u%b*XE0z9<1L{1;z?^1jA}NLrMe%MCvYn`ns+@ntGwsDDF%v2A| zTuaMZh5d&^gN$n=lnta-AAf6?v0>HUE}R_)#@#eslJpt;v{pV=yr-A#5QnSYBjNjQDuqWfwvg zImy84Iwmq$$26h^;`LnjldgO{D5l%Vrc%>h^WyEBFQhAJ%> zGJhR0OY5b);N-#>gI&v$C%6{B`$J@#wSdn9*#Gw}0E(7(N;-S(qfFo~EfwZVCkNHE t= 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ +} + + +/*** Changed Paths Listing ***/ +.vc_changedpaths { + margin: 1em 0 1em 2em; +} + + +/*** Properties Listing ***/ +.vc_properties { + margin: 1em 0 1em 2em; +} +.vc_properties td, .vc_properties th { + padding: 0.2em; +} + + +/*** File Content Markup Styles ***/ +.vc_summary { + background-color: #eeeeee; +} +#vc_file td { + border-right-style: solid; + border-right-color: #505050; + text-decoration: none; + font-weight: normal; + font-style: normal; + padding: 1px 5px; +} +.vc_file_line_number { + border-right-width: 1px; + background-color: #eeeeee; + color: #505050; + text-align: right; +} +.vc_file_line_author, .vc_file_line_rev { + border-right-width: 1px; + text-align: right; +} +.vc_file_line_text { + border-right-width: 0px; + background-color: white; + font-family: monospace; + text-align: left; + white-space: pre; + width: 100%; +} +.pygments-c { color: #408080; font-style: italic } /* Comment */ +.pygments-err { border: 1px solid #FF0000 } /* Error */ +.pygments-k { color: #008000; font-weight: bold } /* Keyword */ +.pygments-o { color: #666666 } /* Operator */ +.pygments-cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.pygments-cp { color: #BC7A00 } /* Comment.Preproc */ +.pygments-c1 { color: #408080; font-style: italic } /* Comment.Single */ +.pygments-cs { color: #408080; font-style: italic } /* Comment.Special */ +.pygments-gd { color: #A00000 } /* Generic.Deleted */ +.pygments-ge { font-style: italic } /* Generic.Emph */ +.pygments-gr { color: #FF0000 } /* Generic.Error */ +.pygments-gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.pygments-gi { color: #00A000 } /* Generic.Inserted */ +.pygments-go { color: #808080 } /* Generic.Output */ +.pygments-gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.pygments-gs { font-weight: bold } /* Generic.Strong */ +.pygments-gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.pygments-gt { color: #0040D0 } /* Generic.Traceback */ +.pygments-kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.pygments-kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.pygments-kp { color: #008000 } /* Keyword.Pseudo */ +.pygments-kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.pygments-kt { color: #B00040 } /* Keyword.Type */ +.pygments-m { color: #666666 } /* Literal.Number */ +.pygments-s { color: #BA2121 } /* Literal.String */ +.pygments-na { color: #7D9029 } /* Name.Attribute */ +.pygments-nb { color: #008000 } /* Name.Builtin */ +.pygments-nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.pygments-no { color: #880000 } /* Name.Constant */ +.pygments-nd { color: #AA22FF } /* Name.Decorator */ +.pygments-ni { color: #999999; font-weight: bold } /* Name.Entity */ +.pygments-ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.pygments-nf { color: #0000FF } /* Name.Function */ +.pygments-nl { color: #A0A000 } /* Name.Label */ +.pygments-nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.pygments-nt { color: #008000; font-weight: bold } /* Name.Tag */ +.pygments-nv { color: #19177C } /* Name.Variable */ +.pygments-ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.pygments-w { color: #bbbbbb } /* Text.Whitespace */ +.pygments-mf { color: #666666 } /* Literal.Number.Float */ +.pygments-mh { color: #666666 } /* Literal.Number.Hex */ +.pygments-mi { color: #666666 } /* Literal.Number.Integer */ +.pygments-mo { color: #666666 } /* Literal.Number.Oct */ +.pygments-sb { color: #BA2121 } /* Literal.String.Backtick */ +.pygments-sc { color: #BA2121 } /* Literal.String.Char */ +.pygments-sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.pygments-s2 { color: #BA2121 } /* Literal.String.Double */ +.pygments-se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.pygments-sh { color: #BA2121 } /* Literal.String.Heredoc */ +.pygments-si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.pygments-sx { color: #008000 } /* Literal.String.Other */ +.pygments-sr { color: #BB6688 } /* Literal.String.Regex */ +.pygments-s1 { color: #BA2121 } /* Literal.String.Single */ +.pygments-ss { color: #19177C } /* Literal.String.Symbol */ +.pygments-bp { color: #008000 } /* Name.Builtin.Pseudo */ +.pygments-vc { color: #19177C } /* Name.Variable.Class */ +.pygments-vg { color: #19177C } /* Name.Variable.Global */ +.pygments-vi { color: #19177C } /* Name.Variable.Instance */ +.pygments-il { color: #666666 } /* Literal.Number.Integer.Long */ + + +/*** Diff Styles ***/ +.vc_diff_plusminus { width: 1em; } +.vc_diff_remove, .vc_diff_add, .vc_diff_changes1, .vc_diff_changes2 { + font-family: monospace; + white-space: pre; +} +.vc_diff_remove { background: rgb(100%,60%,60%); } +.vc_diff_add { background: rgb(60%,100%,60%); } +.vc_diff_changes1 { background: rgb(100%,100%,70%); color: rgb(50%,50%,50%); text-decoration: line-through; } +.vc_diff_changes2 { background: rgb(100%,100%,0%); } +.vc_diff_nochange, .vc_diff_binary, .vc_diff_error { + font-family: sans-serif; + font-size: smaller; +} + +/*** Intraline Diff Styles ***/ +.vc_idiff_add { + background-color: #aaffaa; +} +.vc_idiff_change { + background-color:#ffff77; +} +.vc_idiff_remove { + background-color:#ffaaaa; +} +.vc_idiff_empty { + background-color:#e0e0e0; +} + +table.vc_idiff col.content { + width: 50%; +} +table.vc_idiff tbody { + font-family: monospace; + /* unfortunately, white-space: pre-wrap isn't widely supported ... */ + white-space: -moz-pre-wrap; /* Mozilla based browsers */ + white-space: -pre-wrap; /* Opera 4 - 6 */ + white-space: -o-pre-wrap; /* Opera >= 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ +} +table.vc_idiff tbody th { + background-color:#e0e0e0; + text-align:right; +} + + +/*** Query Form ***/ +.vc_query_form { +} diff --git a/templates/default/error.ezt b/templates/default/error.ezt new file mode 100644 index 00000000..e1d61af7 --- /dev/null +++ b/templates/default/error.ezt @@ -0,0 +1,51 @@ + + + + +ViewVC Exception + + +

An Exception Has Occurred

+ +[if-any msg] +

[msg]

+[end] + +[if-any status] +

HTTP Response Status

+

[status]

+
+[end] + +[if-any msg][else] +

Python Traceback

+

+[stacktrace]
+

+[end] + +[# Here follows a bunch of space characters, present to ensure that + our error message is larger than 512 bytes so that IE's "Friendly + Error Message" won't show. For more information, see + http://oreillynet.com/onjava/blog/2002/09/internet_explorer_subverts_err.html] + + + + + + + + + + + + + + + + + + + + diff --git a/templates/default/file.ezt b/templates/default/file.ezt new file mode 100644 index 00000000..218b47d6 --- /dev/null +++ b/templates/default/file.ezt @@ -0,0 +1,61 @@ +[# setup page definitions] + [define page_title]Annotation of:[end] + [define help_href][docroot]/help_rootview.html[end] +[# end] +[include "include/header.ezt" "annotate"] +[include "include/fileview.ezt"] + +
+ + +[define last_rev]0[end] +[define rowclass]vc_row_odd[end] + +[if-any lines] +
+ + + +[is annotation "annotated"] + + +[end] + + +[for lines] + [is lines.rev last_rev] + [else] + [is rowclass "vc_row_even"] + [define rowclass]vc_row_odd[end] + [else] + [define rowclass]vc_row_even[end] + [end] + [end] + + + +[is annotation "annotated"] + + +[end] + + + [define last_rev][lines.rev][end] +[end] +
LineUserRevFile contents
[lines.line_number][is lines.rev last_rev] [else][lines.author][end][is lines.rev last_rev] [else][if-any lines.diff_href][end][lines.rev][if-any lines.diff_href][end][end][lines.text]
+
+ +[else] +[if-any image_src_href] +
+ +
+[end] +[end] + +[include "include/props.ezt"] + + +
+ +[include "include/footer.ezt"] diff --git a/templates/default/graph.ezt b/templates/default/graph.ezt new file mode 100644 index 00000000..1896793d --- /dev/null +++ b/templates/default/graph.ezt @@ -0,0 +1,15 @@ +[# setup page definitions] + [define page_title]Graph of:[end] + [define help_href][docroot]/help_rootview.html[end] +[# end] + +[include "include/header.ezt" "graph"] + +
+[imagemap] +Revisions of [where] +
+ +[include "include/footer.ezt"] diff --git a/templates/default/include/diff_form.ezt b/templates/default/include/diff_form.ezt new file mode 100644 index 00000000..239e95d8 --- /dev/null +++ b/templates/default/include/diff_form.ezt @@ -0,0 +1,70 @@ + +
+

This form allows you to request diffs between any two + revisions of this file. + For each of the two "sides" of the diff, +[if-any tags] + select a symbolic revision name using the selection box, or choose + 'Use Text Field' and enter a numeric revision. +[else] + enter a numeric revision. +[end] +

+ +
+ + + + + + + + + + +
  + [for diff_select_hidden_values][end] + Diffs between +[if-any tags] + + +[else] + +[end] + + and +[if-any tags] + + +[else] + +[end] +
  + Type of Diff should be a + + +
+
+
diff --git a/templates/default/include/fileview.ezt b/templates/default/include/fileview.ezt new file mode 100644 index 00000000..fc718719 --- /dev/null +++ b/templates/default/include/fileview.ezt @@ -0,0 +1,74 @@ + + + + + + + + + + +[if-any orig_path] + + + + +[end] +[if-any branches] + + + + +[end] +[if-any tags] + + + + +[end] +[if-any branch_points] + + + + +[end] +[is roottype "cvs"][if-any changed] + + + + +[end][end] +[is roottype "svn"][if-any size] + + + +[end][end] +[if-any lockinfo] + + +[end] +[is state "dead"] + + + + +[end] +[if-any annotation] +[is annotation "binary"] + + + +[end] +[is annotation "error"] + + + +[end] +[end] +[if-any log] + + + + +[end] +
Revision:[if-any revision_href][rev][else][rev][end] [if-any vendor_branch] (vendor branch)[end]
Committed:[if-any date][date] [end][if-any ago]([ago] ago) [end][if-any author]by [author][end]
Original Path:[orig_path]
Branch:[branches]
CVS Tags:[tags]
Branch point for:[branch_points]
Changes since [prev]:[changed] lines
File size:[size] byte(s)
Lock status:[lockinfo]
State:FILE REMOVED
Unable to calculate annotation data on binary file contents.
Error occurred while calculating annotation data.
Log Message:
[log]
diff --git a/templates/default/include/footer.ezt b/templates/default/include/footer.ezt new file mode 100644 index 00000000..753ddf89 --- /dev/null +++ b/templates/default/include/footer.ezt @@ -0,0 +1,10 @@ + + + + + + diff --git a/templates/default/include/header.ezt b/templates/default/include/header.ezt new file mode 100644 index 00000000..3b08eaff --- /dev/null +++ b/templates/default/include/header.ezt @@ -0,0 +1,71 @@ + + + + + + + [[]ViewVC] [page_title] [if-any rootname][rootname][if-any where]/[where][end][end] + + + + [if-any rss_href] + + [end] + + + + +
+ +
+[if-any username]Logged in as: [username] |[end] +ViewVC Help +
+ + + +
+[is pathtype "dir"] + View Directory + [if-any log_href] + | Revision Log + [end] + [if-any queryform_href] + | Commit Query + [end] + [if-any tarball_href] + | Download Tarball + [end] +[end] +[is pathtype "file"] + [if-any view_href] + View File | + [end] + Revision Log + [if-any annotate_href] + | Show Annotations + [end] + [if-any graph_href] + | Revision Graph + [end] + [if-any download_href] + | Download File + [end] +[end] +[if-any revision_href] + | View Changeset +[end] +[if-any roots_href] + | Root Listing +[end] +
+ +
+[if-any roots_href]root[end][if-any nav_path]/[for nav_path][if-any nav_path.href][end][if-index nav_path last][end][nav_path.name][if-index nav_path last][end][if-any nav_path.href][end][if-index nav_path last][else]/[end][end][end] +
+ +
+ +
diff --git a/templates/default/include/pathrev_form.ezt b/templates/default/include/pathrev_form.ezt new file mode 100644 index 00000000..301e610b --- /dev/null +++ b/templates/default/include/pathrev_form.ezt @@ -0,0 +1,53 @@ +
+
+[for pathrev_hidden_values][end] +[is roottype "cvs"] + [define pathrev_selected][pathrev][end] + +[else] + +[end] + +
+
+ +[if-any pathrev] +
+
+[for pathrev_clear_hidden_values][end] +[if-any lastrev] + [is pathrev lastrev][else][end] + (Current path doesn't exist after revision [lastrev]) +[else] + +[end] +
+
+[end] diff --git a/templates/default/include/props.ezt b/templates/default/include/props.ezt new file mode 100644 index 00000000..b8e0ea58 --- /dev/null +++ b/templates/default/include/props.ezt @@ -0,0 +1,25 @@ +[if-any properties] +

Properties

+
+ + + + + + + + +[for properties] + + + [if-any properties.undisplayable] + + [else] + + [end] + +[end] + +
NameValue
[properties.name]Property value is undisplayable.[properties.value]
+
+[end] diff --git a/templates/default/log.ezt b/templates/default/log.ezt new file mode 100644 index 00000000..fd42b15b --- /dev/null +++ b/templates/default/log.ezt @@ -0,0 +1,247 @@ +[# setup page definitions] + [define page_title]Log of:[end] + [define help_href][docroot]/help_log.html[end] +[# end] +[include "include/header.ezt" "log"] + + + +[if-any default_branch] + + + + +[end] + +[is pathtype "file"] +[if-any view_href] + + + + +[end] + +[if-any tag_view_href] + + + + +[end] +[end] + + + + + + +[is picklist_len "0"][else][is picklist_len "1"][else] + + + + +[end][end] + + + + + + +
Default branch:[for default_branch][default_branch.name][if-index default_branch last][else], [end] +[end]
Links to HEAD: + (view) + [if-any download_href](download)[end] + [if-any download_text_href](as text)[end] + [if-any annotate_href](annotate)[end] +
Links to [pathrev]: + (view) + [if-any tag_download_href](download)[end] + [if-any tag_download_text_href](as text)[end] + [if-any tag_annotate_href](annotate)[end] +
Sticky [is roottype "cvs"]Tag[else]Revision[end]:[include "include/pathrev_form.ezt"]
Jump to page:
+ [for log_paging_hidden_values][end] + + +
+
Sort logs by:
+
+ + [for logsort_hidden_values][end] + + +
+
+
+ +
+ + +[define first_revision][end] +[define last_revision][end] + +[for entries] + +[if-index entries first][define first_revision][entries.rev][end][end] +[if-index entries last] +[define last_revision][entries.rev][end] +
+[else] +
+[end] + + [is entries.state "dead"] + Revision [entries.rev] + [else] + + [for entries.tag_names] + [end] + [for entries.branch_names] + [end] + + Revision [is roottype "svn"][entries.rev][else][entries.rev][end] - + [if-any entries.view_href] + [is pathtype "file"] + (view) + [else] + Directory Listing + [end] + [end] + [if-any entries.download_href](download)[end] + [if-any entries.download_text_href](as text)[end] + [if-any entries.annotate_href](annotate)[end] + + [is pathtype "file"] + [# if you don't want to allow select for diffs then remove this section] + [is entries.rev rev_selected] + - [[]selected] + [else] + - [[]select for diffs] + [end] + [end] + [end] + + [if-any entries.vendor_branch] + (vendor branch) + [end] + +
+ + [is roottype "svn"] + [if-index entries last]Added[else]Modified[end] + [end] + + [if-any entries.date][entries.date][else](unknown date)[end] + [if-any entries.ago]([entries.ago] ago)[end] + by [if-any entries.author][entries.author][else](unknown author)[end] + + [if-any entries.orig_path] +
Original Path: [entries.orig_path] + [end] + + [if-any entries.branches] +
Branch: + [for entries.branches] + [entries.branches.name][if-index entries.branches last][else],[end] + [end] + [end] + + [if-any entries.tags] +
CVS Tags: + [for entries.tags] + [entries.tags.name][if-index entries.tags last][else],[end] + [end] + [end] + + [if-any entries.branch_points] +
Branch point for: + [for entries.branch_points] + [entries.branch_points.name][if-index entries.branch_points last][else],[end] + [end] + [end] + + [if-any entries.prev] + [if-any entries.changed] + [is roottype "cvs"] +
Changes since [entries.prev]: [entries.changed] lines + [end] + [end] + [end] + + [if-any entries.lockinfo] +
Lock status: [entries.lockinfo] + [end] + + [is roottype "svn"] + [if-any entries.size] +
File length: [entries.size] byte(s) + [end] + + [if-any entries.copy_path] +
Copied from: [entries.copy_path] revision [entries.copy_rev] + [end] + [end] + + [is entries.state "dead"] +
FILE REMOVED + [else] + [is pathtype "file"] + [if-any entries.prev] +
Diff to previous [entries.prev] + [if-any human_readable] + [else] + (colored) + [end] + [end] + + [is roottype "cvs"] + [if-any entries.branch_point] + , to branch point [entries.branch_point] + [if-any human_readable] + [else] + (colored) + [end] + [end] + + [if-any entries.next_main] + , to next main [entries.next_main] + [if-any human_readable] + [else] + (colored) + [end] + [end] + [end] + + [if-any entries.diff_to_sel_href] + [if-any entries.prev], [else]
Diff[end] + to selected [rev_selected] + [if-any human_readable] + [else] + (colored) + [end] + [end] + [end] + [end] + +
[entries.log]
+
+[end] + + +
+ +[is pathtype "file"] + [include "include/diff_form.ezt"] +[end] + +[include "include/footer.ezt"] diff --git a/templates/default/markup.ezt b/templates/default/markup.ezt new file mode 100644 index 00000000..af048fdb --- /dev/null +++ b/templates/default/markup.ezt @@ -0,0 +1,18 @@ +[# setup page definitions] + [define page_title]View of:[end] + [define help_href][docroot]/help_rootview.html[end] +[# end] +[include "include/header.ezt" "markup"] +[include "include/fileview.ezt"] + +
+ + +
[markup]
+ +[include "include/props.ezt"] + + +
+ +[include "include/footer.ezt"] diff --git a/templates/default/query.ezt b/templates/default/query.ezt new file mode 100644 index 00000000..fa33c004 --- /dev/null +++ b/templates/default/query.ezt @@ -0,0 +1,241 @@ + + + + + Checkin Database Query + + + + + +[# setup page definitions] + [define help_href][docroot]/help_query.html[end] +[# end] + +

+ Select your parameters for querying the CVS commit database. You + can search for multiple matches by typing a comma-seperated list + into the text fields. Regular expressions, and wildcards are also + supported. Blank text input fields are treated as wildcards. +

+

+ Any of the text entry fields can take a comma-seperated list of + search arguments. For example, to search for all commits from + authors jpaint and gstein, just type: jpaint, + gstein in the Author input box. If you are searching + for items containing spaces or quotes, you will need to quote your + request. For example, the same search above with quotes is: + "jpaint", "gstein". +

+

+ + Wildcard and regular expression searches are entered in a similar + way to the quoted requests. You must quote any wildcard or + regular expression request, and a command charactor preceeds the + first quote. The command charactor l is for wildcard + searches, and the wildcard charactor is a percent (%). The + command charactor for regular expressions is r, and is + passed directly to MySQL, so you'll need to refer to the MySQL + manual for the exact regex syntax. It is very similar to Perl. A + wildard search for all files with a .py extention is: + l"%.py" in the File input box. The same search done + with a regular expression is: r".*\.py". +

+

+ All search types can be mixed, as long as they are seperated by + commas. +

+ +
+ +
+ + + + + +
+ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + +
CVS Repository: + +
CVS Branch: + +
Directory: + +
File: + +
Author: + +
+ +
+ + + + + + + + + +
Sort By: + +
+ + + + + + + + + + + + + + + + + + + + + + + + +
Date:
In the last + hours +
In the last day
In the last week
In the last month
Since the beginning of time
+
+ +
+
+ +
+
+ +
+ +[is query "skipped"] +[else] +

[num_commits] matches found.

+ +[if-any commits] + + + + + + + + + +[# uncommment, if you want a separate Description column: (also see below) + +] + + +[for commits] + + [for commits.files] + + + + + + + + +[# uncommment, if you want a separate Description column: + {if-index commits.files first{ + + {end} + + (substitute brackets for the braces) +] + +[# and also take the following out in the "Description column"-case:] + [if-index commits.files last] + + + + + [end] +[# ---] + [end] + +[end] + + + + + + + + +[# uncommment, if you want a separate Description column: + +] + +
RevisionFileBranch+/-DateAuthorDescription
+ [if-any commits.files.rev][commits.files.rev][else] [end] + [commits.files.link] + [if-any commits.files.branch][commits.files.branch][else] [end] + + [is commits.files.type "Add"][end] + [is commits.files.type "Change"][end] + [is commits.files.type "Remove"][end] + [commits.files.plus]/[commits.files.minus] + [is commits.files.type "Add"][end] + [is commits.files.type "Change"][end] + [is commits.files.type "Remove"][end] + + [if-any commits.files.date][commits.files.date][else] [end] + + [if-any commits.files.author][commits.files.author][else] [end] + + {commits.log} +
 Log:
+
[commits.log]
       
+[end] +[end] +[include "include/footer.ezt"] diff --git a/templates/default/query_form.ezt b/templates/default/query_form.ezt new file mode 100644 index 00000000..8060d0ba --- /dev/null +++ b/templates/default/query_form.ezt @@ -0,0 +1,201 @@ +[# setup page definitions] + [define page_title]Query on:[end] + [define help_href][docroot]/help_rootview.html[end] +[# end] +[include "include/header.ezt" "query"] + +
+ +
+ [for query_hidden_values][end] + + [is roottype "cvs"] + [# For subversion, the branch field is not used ] + + + + + [end] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Branch: + + + + + +
Subdirectory: + + (You can list multiple directories separated by commas.) +
File: + + + + + +
Who: + + + + + +
Comment: + + + + + +
Sort By: + +
Date: + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + hours +
+ + + and + +
+ (use the form yyyy-mm-dd hh:mm:ss) +
+
Limit: + Show at most + + changed files per commit. (Use 0 to show all files.) +
+
+ +
+ +[include "include/footer.ezt"] diff --git a/templates/default/query_results.ezt b/templates/default/query_results.ezt new file mode 100644 index 00000000..75945b94 --- /dev/null +++ b/templates/default/query_results.ezt @@ -0,0 +1,86 @@ +[# setup page definitions] + [define page_title]Query results in:[end] + [define help_href][docroot]/help_rootview.html[end] +[# end] + +[include "include/header.ezt"] + +

[english_query]

+[# ] +

Modify query

+

Show commands which could be used to back out these changes

+ +

+[plus_count]/-[minus_count] lines changed.

+ +[if-any commits] + + + + + +[if-any show_branch] + +[end] + + + +[# uncommment, if you want a separate Description column: (also see below) + +] + + +[for commits] + [for commits.files] + + + + +[if-any show_branch] + +[end] + + + + + [end] + [if-any commits.limited_files] + + + + [end] + + + + + +[end] +
RevisionFileBranch+/-DateAuthorDescription
+ [define rev_href][if-any commits.files.prefer_markup][commits.files.view_href][else][if-any commits.files.download_href][commits.files.download_href][end][end][end] + [if-any commits.files.rev][if-any rev_href][end][commits.files.rev][if-any rev_href][end][else] [end] + + [commits.files.dir]/ + [commits.files.file] + + [if-any commits.files.branch][commits.files.branch][else] [end] + + [# only show a diff link for changes ] + [is commits.files.type "Add"][end] + [is commits.files.type "Change"][end] + [is commits.files.type "Remove"][end] + [commits.files.plus]/[commits.files.minus] + [is commits.files.type "Add"][end] + [is commits.files.type "Change"][end] + [is commits.files.type "Remove"][end] + + [if-any commits.files.date][commits.files.date][else] [end] + + [if-any commits.files.author][commits.files.author][else] [end] +
  + Only first [commits.num_files] files shown. + Show all files or + adjust limit. +
 Log:
+
[commits.log]
+[end] + +[include "include/footer.ezt"] diff --git a/templates/default/revision.ezt b/templates/default/revision.ezt new file mode 100644 index 00000000..0331e0c3 --- /dev/null +++ b/templates/default/revision.ezt @@ -0,0 +1,81 @@ +[# setup page definitions] + [define page_title]Revision [rev] of:[end] + [define help_href][docroot]/help_rootview.html[end] +[# end] +[include "include/header.ezt" "revision"] + + +
+ + + + + + + + + + + + + + + + + +
Jump to revision: + [for jump_rev_hidden_values][end] + + + [if-any prev_href] + Previous[end] + [if-any next_href] Next[end] +
Author:[if-any author][author][else](unknown author)[end]
Date:[if-any date][date][else](unknown date)[end] + [if-any ago]([ago] ago)[end]
Log Message:
[log]
+
+ + + +[include "include/footer.ezt"] diff --git a/templates/default/roots.ezt b/templates/default/roots.ezt new file mode 100644 index 00000000..5a85e0e8 --- /dev/null +++ b/templates/default/roots.ezt @@ -0,0 +1,40 @@ +[# setup page definitions] + [define page_title]Repository Listing[end] + [define help_href][docroot]/help_rootview.html[end] +[# end] + +[include "include/header.ezt" "directory"] + +
+ + + + + + +[is cfg.options.show_roots_lastmod "1"] + +[end] + + + + +[if-any roots] +[for roots] + + +[is cfg.options.show_roots_lastmod "1"] + +[end] + +[end] +[end] + + +
NameLast Change
[roots.name][if-any roots.rev][roots.rev] ([roots.ago] ago) + by [roots.author]: [roots.log][end]
+ + +
+ +[include "include/footer.ezt"] diff --git a/templates/default/rss.ezt b/templates/default/rss.ezt new file mode 100644 index 00000000..7accf6e2 --- /dev/null +++ b/templates/default/rss.ezt @@ -0,0 +1,17 @@ + + + + [rss_link_href] + [rootname] checkins[if-any where] (in [where])[end] + + [is roottype "svn"]Subversion[else]CVS[end] commits to the[if-any where] [where] directory of the[end] [rootname] repository + + [for commits] + [if-any commits.rev][commits.rev]: [end][[commits.author]] [commits.short_log] + [if-any commits.rss_url][commits.rss_url][end] + [commits.author] + [if-any commits.rss_date][commits.rss_date][else](unknown date)[end] + <pre>[format "xml"][commits.log][end]</pre> + [end] + + From dc1763b37b3edf6b19bd6137e34caf63d301e926 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 27 Oct 2011 18:10:37 +0000 Subject: [PATCH 214/353] * lib/config.py, * conf/viewvc.conf.dist Use the "classic" templates until the "default" ones can be updated to reflect recent improvements (such as the property-diff stuff). git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2649 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 2 +- lib/config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index 87b79a1d..03d0f3b7 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -573,7 +573,7 @@ ## template_dir = templates/default ## template_dir = templates-contrib/custom/templates # -#template_dir = templates/default +#template_dir = templates/classic ## docroot: Web path to a directory that contains ViewVC static files ## (stylesheets, images, etc.) If set, static files will get diff --git a/lib/config.py b/lib/config.py index 479aea0e..98b514cb 100644 --- a/lib/config.py +++ b/lib/config.py @@ -415,7 +415,7 @@ class Config: self.options.hr_ignore_keyword_subst = 1 self.options.hr_intraline = 0 self.options.allow_compress = 0 - self.options.template_dir = "templates/default" + self.options.template_dir = "templates/classic" self.options.docroot = None self.options.show_subdir_lastmod = 0 self.options.show_roots_lastmod = 0 From 6e81b5eb1ea7a89af301a0de5b9c4893501f48bb Mon Sep 17 00:00:00 2001 From: stilor Date: Thu, 27 Oct 2011 18:20:06 +0000 Subject: [PATCH 215/353] * docs/template-authoring-guide.html * templates/classic/include/diff_display.ezt * lib/viewvc.py Rename 'display_as' to 'diff_block_format', as discussed on ML. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2650 8cb11bc2-c004-0410-86c3-e597b4017df7 --- docs/template-authoring-guide.html | 8 ++++---- lib/viewvc.py | 14 +++++++------- templates/classic/include/diff_display.ezt | 10 +++++----- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/template-authoring-guide.html b/docs/template-authoring-guide.html index 9e700575..c1bd216c 100644 --- a/docs/template-authoring-guide.html +++ b/docs/template-authoring-guide.html @@ -710,7 +710,7 @@ td { and property differences. - diffs.display_as + diffs.diff_block_format String Indicates the type of this block. One of the anchor (no display, create an anchor), raw (non-colored diff, display as produced), @@ -721,16 +721,16 @@ td { diffs.anchor String - If diffs.display_as is anchor, this variable specifies + If diffs.diff_block_format is anchor, this variable specifies the anchor name. diffs.changes List/Container Set of objects which contain information about a change in a single - object (file or property). Not present if diffs.display_as is + object (file or property). Not present if diffs.diff_block_format is anchor, otherwise has different format depending on - diffs.display_as (applicable as indicated in brackets below). + diffs.diff_block_format (applicable as indicated in brackets below). diffs.changes.raw diff --git a/lib/viewvc.py b/lib/viewvc.py index 5d7fbdbf..de071022 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3346,20 +3346,20 @@ class DiffDescription: self.hide_legend = 0 if self.human_readable: self.line_differ = self._line_idiff_sidebyside - self.display_as = 'sidebyside-2' + self.diff_block_format = 'sidebyside-2' else: self.line_differ = self._line_idiff_unified - self.display_as = 'unified' + self.diff_block_format = 'unified' else: if self.human_readable: - self.display_as = 'sidebyside-1' + self.diff_block_format = 'sidebyside-1' self.fp_differ = self._fp_vclib_hr else: - self.display_as = 'raw' + self.diff_block_format = 'raw' self.fp_differ = self._fp_vclib_raw def anchor(self, anchor_name): - self.changes.append(_item(display_as='anchor', anchor=anchor_name)) + self.changes.append(_item(diff_block_format='anchor', anchor=anchor_name)) def get_content_diff(self, left, right): options = {} @@ -3394,7 +3394,7 @@ class DiffDescription: if is_undisplayable(val_left) or is_undisplayable(val_right): self.changes.append(_item(left=left, right=right, - display_as=self.display_as, + diff_block_format=self.diff_block_format, changes=[ _item(type=_RCSDIFF_IS_BINARY) ], propname=name)) continue @@ -3411,7 +3411,7 @@ class DiffDescription: self.changes.append(_item(left=left, right=right, changes=changes, - display_as=self.display_as, + diff_block_format=self.diff_block_format, propname=propname)) def _line_idiff_sidebyside(self, lines_left, lines_right, options): diff --git a/templates/classic/include/diff_display.ezt b/templates/classic/include/diff_display.ezt index d41a56f6..08293ea4 100644 --- a/templates/classic/include/diff_display.ezt +++ b/templates/classic/include/diff_display.ezt @@ -1,4 +1,4 @@ -[is diffs.display_as "anchor"] +[is diffs.diff_block_format "anchor"]

[else] [define msg_no_changes]
- No changes -
 [end] @@ -23,7 +23,7 @@ [if-any diffs.right.tag]
Tag: [diffs.right.tag][end][end] [end] -[is diffs.display_as "raw"] +[is diffs.diff_block_format "raw"] @@ -50,7 +50,7 @@
 [left_header]
[end] -[is diffs.display_as "sidebyside-1"] +[is diffs.diff_block_format "sidebyside-1"] @@ -145,7 +145,7 @@
[end] -[is diffs.display_as "sidebyside-2"] +[is diffs.diff_block_format "sidebyside-2"] @@ -185,7 +185,7 @@
[end] -[is diffs.display_as "unified"] +[is diffs.diff_block_format "unified"] From 4341dab5b7d91678ddafaeefeb538fef7cb7d68f Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 27 Oct 2011 20:59:38 +0000 Subject: [PATCH 216/353] * templates/default/revision.ezt, * templates/default/log.ezt, * templates/default/graph.ezt, * templates/default/diff.ezt, * templates/default/include/diff_display.ezt Take a stab at updating the new default templates to handle the property diff stuff. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2651 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/diff.ezt | 80 +-------- templates/default/graph.ezt | 74 ++++++++ templates/default/include/diff_display.ezt | 188 +++++++++++++++++++++ templates/default/log.ezt | 16 +- templates/default/revision.ezt | 4 +- 5 files changed, 275 insertions(+), 87 deletions(-) create mode 100644 templates/default/include/diff_display.ezt diff --git a/templates/default/diff.ezt b/templates/default/diff.ezt index 0072bbf7..1899952e 100644 --- a/templates/default/diff.ezt +++ b/templates/default/diff.ezt @@ -23,83 +23,14 @@
-[if-any raw_diff] -
[raw_diff]
-[else] - -[define change_right][end] -[define last_change_type][end] - -[# these should live in stylesheets] - -
-[for changes] - [is changes.type "change"][else] - [if-any change_right][change_right][define change_right][end][end] - [end] - [is changes.type "header"] - - - - - [else] - [is changes.type "add"] - - - - - - [else] - [is changes.type "remove"] - - - - - - [else] - [is changes.type "change"] - [if-any changes.have_left] - - - - - +[if-any diffs] + [for diffs] + [include "include/diff_display.ezt"] [end] - [define change_right][change_right] - [if-any changes.have_right] - - - - - [end] - [end] - [else] - [is changes.type "no-changes"] - - [else] - [is changes.type "binary-diff"] - - [else] - [is changes.type "error"] - - [else][# a line of context] - - - - - - [end][end][end][end][end][end][end] - [define last_change_type][changes.type][end] [end] -[if-any change_right][change_right][end] -
# - Line [changes.line_info_left] | - Line [changes.line_info_right] -
[if-any right.annotate_href][changes.line_number][else][changes.line_number][end]+[changes.right]
[changes.line_number][changes.left]
[changes.line_number]<[changes.left]
[if-any right.annotate_href][changes.line_number][else][changes.line_number][end]>[changes.right]
- No changes -
- Binary file revisions differ -
- ViewVC depends on rcsdiff and GNU diff - to create this page. ViewVC cannot find GNU diff. Even if you - have GNU diff installed, the rcsdiff program must be configured - and compiled with the GNU diff location. -
[if-any right.annotate_href][changes.line_number][else][changes.line_number][end] [changes.right]
+[if-any hide_legend] +[else]

Diff Legend

@@ -119,7 +50,6 @@
Changed lines
- [end] diff --git a/templates/default/graph.ezt b/templates/default/graph.ezt index 1896793d..6a1bddb9 100644 --- a/templates/default/graph.ezt +++ b/templates/default/graph.ezt @@ -12,4 +12,78 @@ alt="Revisions of [where]" />
+[define graph_disp_opts][end] +[if-any opt_gflip][define graph_disp_opts]1[end][end] +[if-any opt_gbbox][define graph_disp_opts]1[end][end] +[if-any opt_gleft][define graph_disp_opts]1[end][end] + +[define graph_user_opts][end] +[if-any graph_disp_opts][define graph_user_opts]1[end][end] +[if-any opt_gshow][define graph_user_opts]1[end][end] +[if-any opt_gmaxtag][define graph_user_opts]1[end][end] + +[if-any graph_user_opts] + +
+
+[for graph_hidden_values][end] + +[is graph_disp_opts "1"] +

Graph display options:

+ +[if-any opt_gflip] + + + + +[end] +[if-any opt_gbbox] + + + + +[end] +[if-any opt_gleft] + + + + +[end] +
+[end] + +[if-any opt_gshow] +

Revision display options:

+ + + + + + + + + + + + + +
+[end] + +[if-any opt_gmaxtag] +

Tag limitation:

+ + + + + +
+[end] + + + +
+
+[end] + [include "include/footer.ezt"] diff --git a/templates/default/include/diff_display.ezt b/templates/default/include/diff_display.ezt new file mode 100644 index 00000000..a98d1545 --- /dev/null +++ b/templates/default/include/diff_display.ezt @@ -0,0 +1,188 @@ +[is diffs.display_as "anchor"] +

+[else] + [define msg_no_changes]- No changes -[end] + [define msg_binary]- Binary content differs -[end] + [define msg_error]- ViewVC depends on rcsdiff and GNU diff to create + this page. ViewVC cannot find GNU diff. Even if you have GNU diff + installed, the rcsdiff program must be configured and compiled with + the GNU diff location. -[end] + + [define left_view_href][if-any diffs.left.prefer_markup][diffs.left.view_href][else][if-any diffs.left.download_href][diffs.left.download_href][end][end][end] + [define right_view_href][if-any diffs.right.prefer_markup][diffs.right.view_href][else][if-any diffs.right.download_href][diffs.right.download_href][end][end][end] + + [define left_item][diffs.left.path] ([if-any diffs.propname]property [diffs.propname][else]file contents[end])[end] + [define right_item][diffs.right.path] ([if-any diffs.propname]property [diffs.propname][else]file contents[end])[end] + + [is left_item right_item] + [define common_header][left_item][end] + [define left_header]Revision [if-any left_view_href][end][diffs.left.rev][if-any left_view_href][end][if-any diffs.left.author] by [diffs.left.author][end], [diffs.left.date] [if-any diffs.left.tag]
Tag: [diffs.left.tag][end][end] + [define right_header]Revision [if-any right_view_href][end][diffs.right.rev][if-any right_view_href][end][if-any diffs.right.author] by [diffs.right.author][end], [diffs.right.date] [if-any diffs.right.tag]
Tag: [diffs.right.tag][end][end] + [else] + [define common_header][end] + [define left_header][left_item], Revision [if-any left_view_href][end][diffs.left.rev][if-any left_view_href][end][if-any diffs.left.author] by [diffs.left.author][end], [diffs.left.date] [if-any diffs.left.tag]
Tag: [diffs.left.tag][end][end] + [define right_header][right_item], Revision [if-any right_view_href][end][diffs.right.rev][if-any right_view_href][end][if-any diffs.right.author] by [diffs.right.author][end], [diffs.right.date] [if-any diffs.right.tag]
Tag: [diffs.right.tag][end][end] + [end] + +

Comparing[if-any common_header] [common_header][else][end]:
+ [left_header] vs.
+ [right_header]

+[end] + +[is diffs.display_as "raw"] + + [is diffs.changes.type "no-changes"] + + + + [else] + [is diffs.changes.type "binary-diff"] + + + + [else] + + [end][end] +
[msg_no_changes]
[msg_binary]
[diffs.changes.raw]
+[end] + +[is diffs.display_as "sidebyside-1"] + [define change_right][end] + [define last_change_type][end] + + + [for diffs.changes] + [is diffs.changes.type "change"][else][if-any change_right][change_right][define change_right][end][end][end] + [is diffs.changes.type "header"] + + + + + [else] + [is diffs.changes.type "add"] + + + + + + [else] + [is diffs.changes.type "remove"] + + + + + + [else] + [is diffs.changes.type "change"] + [if-any diffs.changes.have_left] + + + + + + [end] + [define change_right][change_right] + [if-any diffs.changes.have_right] + + + + + + [end] + [end] + [else] + [is diffs.changes.type "no-changes"] + + [else] + [is diffs.changes.type "binary-diff"] + + [else] + [is diffs.changes.type "error"] + + [else][# a line of context] + + + + + + [end][end][end][end][end][end][end] + [define last_change_type][diffs.changes.type][end] + [end] + [if-any change_right][change_right][end] +
# + Line [diffs.changes.line_info_left] | + Line [diffs.changes.line_info_right] +
[if-any diffs.right.annotate_href][diffs.changes.line_number][else][diffs.changes.line_number][end]+[diffs.changes.right]
[diffs.changes.line_number][diffs.changes.left]
[diffs.changes.line_number]<[diffs.changes.left]
[if-any diffs.right.annotate_href][diffs.changes.line_number][else][diffs.changes.line_number][end]>[diffs.changes.right]
[msg_no_changes]
[msg_binary]
[msg_error]
[if-any diffs.right.annotate_href][diffs.changes.line_number][else][diffs.changes.line_number][end] [diffs.changes.right]
+[end] + +[is diffs.display_as "sidebyside-2"] + + + + + [for diffs.changes] + [is diffs.changes.type "no-changes"] + + + + [else] + [is diffs.changes.type "binary-diff"] + + + + [else] + [if-any diffs.changes.gap] + + + + + [end] + + [for diffs.changes.columns] + [for diffs.changes.columns.segments][if-any diffs.changes.columns.segments.type][diffs.changes.columns.segments.text][else][diffs.changes.columns.segments.text][end][end] + [end] + + [end] + [end] + [end] + +
[msg_no_changes]
[msg_binary]
[diffs.changes.columns.line_number]
+[end] + +[is diffs.display_as "unified"] + + + + + + + + [for diffs.changes] + [is diffs.changes.type "no-changes"] + + + + [else] + [is diffs.changes.type "binary-diff"] + + + + [else] + [if-any diffs.changes.gap] + + + + + + [end] + + + + [for diffs.changes.segments][if-any diffs.changes.segments.type][diffs.changes.segments.text][else][diffs.changes.segments.text][end][end] + + [end] + [end] + [end] + +
[msg_no_changes]
[msg_binary]
[diffs.changes.left_number][diffs.changes.right_number]
+[end] diff --git a/templates/default/log.ezt b/templates/default/log.ezt index fd42b15b..dffdeed4 100644 --- a/templates/default/log.ezt +++ b/templates/default/log.ezt @@ -121,13 +121,11 @@ [if-any entries.download_text_href](as text)[end] [if-any entries.annotate_href](annotate)[end] - [is pathtype "file"] - [# if you don't want to allow select for diffs then remove this section] - [is entries.rev rev_selected] - - [[]selected] - [else] - - [[]select for diffs] - [end] + [# if you don't want to allow select for diffs then remove this section] + [is entries.rev rev_selected] + - [[]selected] + [else] + - [[]select for diffs] [end] [end] @@ -195,8 +193,7 @@ [is entries.state "dead"]
FILE REMOVED [else] - [is pathtype "file"] - [if-any entries.prev] + [if-any entries.diff_to_prev_href]
Diff to previous [entries.prev] [if-any human_readable] [else] @@ -230,7 +227,6 @@ (colored) [end] [end] - [end] [end]
[entries.log]
diff --git a/templates/default/revision.ezt b/templates/default/revision.ezt index 0331e0c3..23f47c21 100644 --- a/templates/default/revision.ezt +++ b/templates/default/revision.ezt @@ -63,8 +63,8 @@ [if-any changes.is_copy]
(Copied from [changes.copy_path], r[changes.copy_rev])[end] [if-any changes.log_href][end][changes.action][if-any changes.log_href][end] - [if-any changes.text_mods], [if-any changes.diff_href][end]text changed[if-any changes.diff_href][end][end] - [if-any changes.prop_mods], props changed[end] + [if-any changes.text_mods], [if-any changes.diff_href][end]text changed[if-any changes.diff_href][end][end] + [if-any changes.prop_mods], [if-any changes.diff_href][end]props changed[if-any changes.diff_href][end][end] [end] From 43f001ef2537c5c43d6971952ecacc17fb45b0f7 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 27 Oct 2011 21:14:02 +0000 Subject: [PATCH 217/353] * templates/default/file.ezt, * templates/default/log.ezt, * templates/default/docroot/styles.css, More markup changes to the default templates. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2652 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/docroot/styles.css | 9 +++++++++ templates/default/file.ezt | 9 +++++++-- templates/default/log.ezt | 10 ++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/templates/default/docroot/styles.css b/templates/default/docroot/styles.css index a45f9c18..28ad125f 100644 --- a/templates/default/docroot/styles.css +++ b/templates/default/docroot/styles.css @@ -141,6 +141,7 @@ address { font-style: normal; display: inline; } /*** Table Headers ***/ .vc_header, .vc_header_sort { + padding: 2px 5px; text-align: left; vertical-align: top; border-bottom: 1px solid black; @@ -181,6 +182,11 @@ address { font-style: normal; display: inline; } } +/*** Revision Log View ***/ +#vc_revision_log { + margin: 1em 0 1em 2em; +} + /*** Changed Paths Listing ***/ .vc_changedpaths { margin: 1em 0 1em 2em; @@ -200,6 +206,9 @@ address { font-style: normal; display: inline; } .vc_summary { background-color: #eeeeee; } +#vc_file { + margin: 1em 0 1em 2em; +} #vc_file td { border-right-style: solid; border-right-color: #505050; diff --git a/templates/default/file.ezt b/templates/default/file.ezt index 218b47d6..5a80f206 100644 --- a/templates/default/file.ezt +++ b/templates/default/file.ezt @@ -8,6 +8,8 @@
+

File Contents

+ [define last_rev]0[end] [define rowclass]vc_row_odd[end] @@ -15,12 +17,15 @@
- [is annotation "annotated"] + + +[else] + + [end] - [for lines] [is lines.rev last_rev] diff --git a/templates/default/log.ezt b/templates/default/log.ezt index dffdeed4..f167838b 100644 --- a/templates/default/log.ezt +++ b/templates/default/log.ezt @@ -87,9 +87,12 @@
+

Revision History

+ +
+ [define first_revision][end] [define last_revision][end] - [for entries] [if-index entries first][define first_revision][entries.rev][end][end] @@ -229,14 +232,17 @@ [end] [end] -
[entries.log]
+
[entries.log]
[end] +
+ [is pathtype "file"] +

Compare Revisions

[include "include/diff_form.ezt"] [end] From a69597e29c5e826ca90764073b1f01f0ef9d4d2f Mon Sep 17 00:00:00 2001 From: cmpilato Date: Fri, 28 Oct 2011 19:24:37 +0000 Subject: [PATCH 218/353] Finish issue #470 ("No links to repository root logs"). * lib/viewvc.py (view_roots): Generate a log_href -- the revision log for the root directory of the repository -- where it makes sense to do so. * templates/classic/roots.ezt, * templates/default/roots.ezt Markup the last-modified-revision as a link to the log view where we can. * docs/template-authoring-guide.html Note the additional data dictionary item. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2653 8cb11bc2-c004-0410-86c3-e597b4017df7 --- docs/template-authoring-guide.html | 6 ++++++ lib/viewvc.py | 15 +++++++++++---- templates/classic/roots.ezt | 2 +- templates/default/roots.ezt | 2 +- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/docs/template-authoring-guide.html b/docs/template-authoring-guide.html index c1bd216c..73812990 100644 --- a/docs/template-authoring-guide.html +++ b/docs/template-authoring-guide.html @@ -2352,6 +2352,12 @@ td { + + + + + diff --git a/lib/viewvc.py b/lib/viewvc.py index de071022..2c6919fa 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1929,20 +1929,27 @@ 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) - lastmod = allroots[rootname][2] + 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 roots.append(_item(name=request.server.escape(rootname), - type=allroots[rootname][1], - path=allroots[rootname][0], + type=root_type, + path=root_path, 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)) + href=href, + log_href=log_href)) data = common_template_data(request) data.merge(ezt.TemplateData({ diff --git a/templates/classic/roots.ezt b/templates/classic/roots.ezt index 40ca51ee..b14d5800 100644 --- a/templates/classic/roots.ezt +++ b/templates/classic/roots.ezt @@ -27,7 +27,7 @@ [roots.name] [is cfg.options.show_roots_lastmod "1"] - + diff --git a/templates/default/roots.ezt b/templates/default/roots.ezt index 5a85e0e8..08cf1779 100644 --- a/templates/default/roots.ezt +++ b/templates/default/roots.ezt @@ -24,7 +24,7 @@ [is cfg.options.show_roots_lastmod "1"] - [end] From 441da057cc4cbdb8ea9ad40e3aa976013f6570fd Mon Sep 17 00:00:00 2001 From: stilor Date: Fri, 28 Oct 2011 20:37:01 +0000 Subject: [PATCH 219/353] * lib/viewvc.py (DiffSource): Do not switch to flush state. Such switch causes changes to be displayed as removal and readdition. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2656 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 2c6919fa..0b24ede0 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3009,10 +3009,8 @@ class DiffSource: if line[0] == '\\': # \ No newline at end of file - - # move into the flushing state. note: it doesn't matter if we really - # have data to flush or not; that will be figured out later - self.state = 'flush-' + self.state + # Just skip. This code used to move to flush state, but that resulted in + # changes being displayed as removals-and-readditions. return None diff_code = line[0] From ccb53d164ed3566ed32f3b20c3a3cebfe20e81fb Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 31 Oct 2011 21:39:33 +0000 Subject: [PATCH 220/353] *** THIS REVISION WAS REVERTED IN r2684 *** Finish issue #495 ("Syntax highlight/colorize scripts without extensions"). * lib/viewvc.py (markup_stream_pygments): Failing all else, use the Pygments guess_lexer() function to guess a file's content type from the first line of its text. (Most of this patch is compensation for the first that if this heuristic codepath is traversed, we've eaten a line of text from the file object that we don't expect to have been eaten. Patch by: Chris Mayo (Tweaked by me.) git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2657 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 0b24ede0..83a3ac7a 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1573,13 +1573,15 @@ def markup_stream_pygments(request, cfg, blame_data, fp, filename, blame_data = blame_source lexer = None use_pygments = cfg.options.enable_syntax_coloration + first_line = None 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 + get_lexer_for_filename, \ + guess_lexer if not encoding: encoding = 'guess' if cfg.options.detect_encoding: @@ -1600,7 +1602,12 @@ def markup_stream_pygments(request, cfg, blame_data, fp, filename, tabsize=cfg.options.tabsize, stripnl=False) except ClassNotFound: - use_pygments = 0 + try: + first_line = fp.readline() + lexer = guess_lexer(first_line) + use_pygments = 1 + except ClassNotFound: + use_pygments = 0 except ImportError: use_pygments = 0 @@ -1623,7 +1630,11 @@ def markup_stream_pygments(request, cfg, blame_data, fp, filename, lines = [] line_no = 0 while 1: - line = fp.readline() + if first_line is not None: + line = first_line + first_line = None + else: + line = fp.readline() if not line: break line_no = line_no + 1 @@ -1656,7 +1667,7 @@ def markup_stream_pygments(request, cfg, blame_data, fp, filename, self.blame_data.append(item) self.line_no = self.line_no + 1 ps = PygmentsSink(blame_source) - highlight(fp.read(), lexer, + highlight((first_line or '') + fp.read(), lexer, HtmlFormatter(nowrap=True, classprefix="pygments-", encoding='utf-8'), ps) From 8cdccc1ea526e387083d0be636ba9832131ce462 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 1 Nov 2011 13:40:01 +0000 Subject: [PATCH 221/353] Fix a bug which prevented certain directory diff displays. * lib/viewvc.py (diff_side_item): Pass the option to repos.itemlog() which says to include directory logs even for revisions in which the directory itself was not explicitly modified (props changed). git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2659 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 83a3ac7a..9db08beb 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3267,9 +3267,11 @@ def view_patch(request): def diff_side_item(request, path_comp, rev, sym): '''Prepare information about left/right side of the diff. Prepare two flavors, for content and for property diffs.''' + # TODO: Is the slice necessary, or is limit enough? + options = {'svn_show_all_dir_logs': 1} log_entry = request.repos.itemlog(path_comp, rev, vclib.SORTBY_REV, - 0, 1, {})[-1] + 0, 1, options)[-1] ago = log_entry.date is not None \ and html_time(request, log_entry.date, 1) or None path_joined = _path_join(path_comp) From a6be4da9781c244bb05c8174429c85bb5b1ad3d6 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 1 Nov 2011 14:12:58 +0000 Subject: [PATCH 222/353] * templates/default/log.ezt, * templates/default/docroot/styles.css Layout/style tweaks to the new default template set. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2660 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/docroot/styles.css | 13 +++- templates/default/log.ezt | 100 +++++++++++---------------- 2 files changed, 53 insertions(+), 60 deletions(-) diff --git a/templates/default/docroot/styles.css b/templates/default/docroot/styles.css index 28ad125f..44079d22 100644 --- a/templates/default/docroot/styles.css +++ b/templates/default/docroot/styles.css @@ -184,8 +184,19 @@ address { font-style: normal; display: inline; } /*** Revision Log View ***/ #vc_revision_log { - margin: 1em 0 1em 2em; } +.vc_log_block_even { + border-left: 10px solid #d0d775; + padding-left: 1em; + background-color: rgb(95%,95%,95%); +} +.vc_log_block_odd { + border-left: 10px solid #94bd5e; + padding-left: 1em; + background-color: rgb(90%,90%,90%); +} + + /*** Changed Paths Listing ***/ .vc_changedpaths { diff --git a/templates/default/log.ezt b/templates/default/log.ezt index f167838b..550b68ac 100644 --- a/templates/default/log.ezt +++ b/templates/default/log.ezt @@ -40,48 +40,6 @@ [end] [end] - - - - - -[is picklist_len "0"][else][is picklist_len "1"][else] - - - - -[end][end] - - - - - -
Line# User RevContent#ContentFile contents
String Log message of last modification to the root.
roots.log_hrefStringURL of log revision view for the top-most (root) directory of + the root (repository).
roots.name String  [roots.rev] [if-any roots.log_href][roots.rev][else][roots.rev][end]  [roots.ago]  [roots.author]  [roots.short_log]
[roots.name][if-any roots.rev][roots.rev] ([roots.ago] ago) + [if-any roots.rev][if-any roots.log_href][roots.rev][else][roots.rev][end] ([roots.ago] ago) by [roots.author]: [roots.log][end]
Sticky [is roottype "cvs"]Tag[else]Revision[end]:[include "include/pathrev_form.ezt"]
Jump to page:
- [for log_paging_hidden_values][end] - - -
-
Sort logs by:
-
- - [for logsort_hidden_values][end] - - -
-
-
@@ -94,26 +52,20 @@ [define first_revision][end] [define last_revision][end] [for entries] - [if-index entries first][define first_revision][entries.rev][end][end] -[if-index entries last] -[define last_revision][entries.rev][end] -
+[if-index entries last][define last_revision][entries.rev][end][end] + +
+ +[is entries.state "dead"] + Revision [entries.rev] [else] -
-[end] + + [for entries.tag_names][end] + [for entries.branch_names][end] - [is entries.state "dead"] - Revision [entries.rev] - [else] - - [for entries.tag_names] - [end] - [for entries.branch_names] - [end] - - Revision [is roottype "svn"][entries.rev][else][entries.rev][end] - - [if-any entries.view_href] + Revision [is roottype "svn"][entries.rev][else][entries.rev][end] - + [if-any entries.view_href] [is pathtype "file"] (view) [else] @@ -238,6 +190,36 @@
+
+[is picklist_len "0"][else][is picklist_len "1"][else] +
+
+[for log_paging_hidden_values][end] + + +
+
+[end][end] +         +
+
+[for logsort_hidden_values][end] + + +
+
+         +[include "include/pathrev_form.ezt"] +
+
From b566f297b33da0f5c55a01c87c262f3066a62e4f Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 1 Nov 2011 14:14:40 +0000 Subject: [PATCH 223/353] * templates/default/include/diff_display.ezt Track recent rename of diffs.display_as to diffs.diff_block_format. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2661 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/include/diff_display.ezt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/default/include/diff_display.ezt b/templates/default/include/diff_display.ezt index a98d1545..7083619e 100644 --- a/templates/default/include/diff_display.ezt +++ b/templates/default/include/diff_display.ezt @@ -1,4 +1,4 @@ -[is diffs.display_as "anchor"] +[is diffs.diff_block_format "anchor"]

[else] [define msg_no_changes]- No changes -[end] @@ -29,7 +29,7 @@ [right_header] [end] -[is diffs.display_as "raw"] +[is diffs.diff_block_format "raw"] [is diffs.changes.type "no-changes"] @@ -46,7 +46,7 @@
[end] -[is diffs.display_as "sidebyside-1"] +[is diffs.diff_block_format "sidebyside-1"] [define change_right][end] [define last_change_type][end] @@ -115,7 +115,7 @@ [end] -[is diffs.display_as "sidebyside-2"] +[is diffs.diff_block_format "sidebyside-2"] @@ -149,7 +149,7 @@
[end] -[is diffs.display_as "unified"] +[is diffs.diff_block_format "unified"] From 94d9f0ef494a4e7669d74763e6e07fab8fa5999f Mon Sep 17 00:00:00 2001 From: cmpilato Date: Tue, 1 Nov 2011 18:45:27 +0000 Subject: [PATCH 224/353] * templates/default/log.ezt, * templates/default/include/pathrev_form.ezt, * templates/default/directory.ezt, * templates/default/diff.ezt, * templates/default/docroot/styles.css Still more template stylistic tweaks. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2662 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/diff.ezt | 4 +- templates/default/directory.ezt | 83 +++++++++---------- templates/default/docroot/styles.css | 1 + templates/default/include/pathrev_form.ezt | 8 +- templates/default/log.ezt | 92 +++++++++++----------- 5 files changed, 94 insertions(+), 94 deletions(-) diff --git a/templates/default/diff.ezt b/templates/default/diff.ezt index 1899952e..391d14a5 100644 --- a/templates/default/diff.ezt +++ b/templates/default/diff.ezt @@ -4,8 +4,8 @@ [# end] [include "include/header.ezt" "diff"] -
-
+ +
[for diff_format_hidden_values][end]
-[is picklist_len "0"][else][is picklist_len "1"][else] - - - - -[end][end] -
Jump to page: - [for dir_paging_hidden_values][end] - - - -
-

+
+[include "include/pathrev_form.ezt"] +
[is roottype "svn"] +
[if-any rev]r[rev][end] -[else] -[is num_dead "0"] -[else] - [if-any attic_showing] - Hide - [else] - Show - [end] - dead files -[end] +
[end]
@@ -108,27 +85,51 @@
+[is picklist_len "0"][else][is picklist_len "1"][else] +
+
+[for dir_paging_hidden_values][end] + + +
+
+[end][end] [if-any search_re_action]
-
- [for search_re_hidden_values][end] - - -
+
+ [for search_re_hidden_values][end] + + +
[if-any search_re]
-
- [for search_re_hidden_values][end] - -
+
+ [for search_re_hidden_values][end] + +
+
[end] -         [end] -[include "include/pathrev_form.ezt"] -         -[files_shown] file[is files_shown "1"][else]s[end] shown +[is num_dead "0"] +[else] +
+ [if-any attic_showing] + Hide + [else] + Show + [end] + dead files +
+[end] +
+ [files_shown] file[is files_shown "1"][else]s[end] shown +
[include "include/props.ezt"] diff --git a/templates/default/docroot/styles.css b/templates/default/docroot/styles.css index 44079d22..17822c29 100644 --- a/templates/default/docroot/styles.css +++ b/templates/default/docroot/styles.css @@ -44,6 +44,7 @@ table.fixed td { form { margin: 0; } address { font-style: normal; display: inline; } .inline { display: inline; } +.lpad { margin-left: 2em; } /*** Icons ***/ .vc_icon { diff --git a/templates/default/include/pathrev_form.ezt b/templates/default/include/pathrev_form.ezt index 301e610b..4625dec8 100644 --- a/templates/default/include/pathrev_form.ezt +++ b/templates/default/include/pathrev_form.ezt @@ -1,5 +1,5 @@ -
-
+ +
[for pathrev_hidden_values][end] [is roottype "cvs"] [define pathrev_selected][pathrev][end] @@ -39,8 +39,8 @@ [if-any pathrev] -
-
+ +
[for pathrev_clear_hidden_values][end] [if-any lastrev] [is pathrev lastrev][else][end] diff --git a/templates/default/log.ezt b/templates/default/log.ezt index 550b68ac..247caf36 100644 --- a/templates/default/log.ezt +++ b/templates/default/log.ezt @@ -4,49 +4,9 @@ [# end] [include "include/header.ezt" "log"] - - -[if-any default_branch] - - - - -[end] - -[is pathtype "file"] -[if-any view_href] - - - - -[end] - -[if-any tag_view_href] - - - - -[end] -[end] - -
Default branch:[for default_branch][default_branch.name][if-index default_branch last][else], [end] -[end]
Links to HEAD: - (view) - [if-any download_href](download)[end] - [if-any download_text_href](as text)[end] - [if-any annotate_href](annotate)[end] -
Links to [pathrev]: - (view) - [if-any tag_download_href](download)[end] - [if-any tag_download_text_href](as text)[end] - [if-any tag_annotate_href](annotate)[end] -
-
-

Revision History

-
[define first_revision][end] @@ -192,8 +152,8 @@
[is picklist_len "0"][else][is picklist_len "1"][else] -
- + +
[for log_paging_hidden_values][end] -
+ [end][end] -         -
-
+ +
[for logsort_hidden_values][end]
-         +
[include "include/pathrev_form.ezt"]
+
+

Convenience Links

+ +[if-any default_branch] + + Default branch: + [for default_branch][default_branch.name][if-index default_branch last][else], [end] +[end] + +[end] + +[is pathtype "file"] +[if-any view_href] + + Links to HEAD: + + (view) + [if-any download_href](download)[end] + [if-any download_text_href](as text)[end] + [if-any annotate_href](annotate)[end] + + +[end] + +[if-any tag_view_href] + + Links to [pathrev]: + + (view) + [if-any tag_download_href](download)[end] + [if-any tag_download_text_href](as text)[end] + [if-any tag_annotate_href](annotate)[end] + + +[end] +[end] + + + [is pathtype "file"]

Compare Revisions

[include "include/diff_form.ezt"] From a592e3b0bc6e5f3e8568bab1e5cc63ea6b8a7c62 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Thu, 3 Nov 2011 14:39:40 +0000 Subject: [PATCH 225/353] Bump latest version number. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2666 8cb11bc2-c004-0410-86c3-e597b4017df7 --- www/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/index.html b/www/index.html index 0aa3659b..b3f12cfa 100644 --- a/www/index.html +++ b/www/index.html @@ -30,13 +30,13 @@

Latest Release(s)

-

The most recent stable release of ViewVC is: 1.1.11

+

The most recent stable release of ViewVC is: 1.1.12

From 85df9e6ba4400936002bd42648080f13d6829e22 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 23 Jan 2012 17:51:58 +0000 Subject: [PATCH 256/353] * tools/bump-copyright-years New tool for bumping copyright years. I'm tired of trying to micromanage these things. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2719 8cb11bc2-c004-0410-86c3-e597b4017df7 --- tools/bump-copyright-years | 76 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100755 tools/bump-copyright-years diff --git a/tools/bump-copyright-years b/tools/bump-copyright-years new file mode 100755 index 00000000..4d9fcc15 --- /dev/null +++ b/tools/bump-copyright-years @@ -0,0 +1,76 @@ +#!/usr/bin/env python +# +# Copyright (C) 2012 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 +# distribution or at http://viewvc.org/license-1.html. +# +# For more information, visit http://viewvc.org/ +# +# ----------------------------------------------------------------------- +# +# bump-copyright-years: internal tool for bumping copyright years +# +# ----------------------------------------------------------------------- +# +import sys +import os +import time +import re + +_copyright_re = re.compile(r'Copyright (\(C\)|©) ([0-9]{4}-)?([0-9]{4}) The ViewCVS Group') + +def replace_end_year(path, year): + updated = False + lines = open(path, 'r').readlines() + for i in range(len(lines)): + line = lines[i] + new_line = None + m = _copyright_re.search(line) + if not m: + continue + if m.group(2): + new_line = line[:m.start(3)] + year + line[m.end(3):] + elif m.group(3) != year: + new_line = line[:m.end(3)] + '-' + year + line[m.end(3):] + if new_line is not None: + print "In file '%s'..." % (path) + print " replaced: " + line + print " with: " + new_line + updated = True + lines[i] = new_line + if updated: + open(path, 'w').write(''.join(lines)) + +def bump_years_recursive(target_dir, year): + children = os.listdir(target_dir) + for child in children: + child_path = os.path.join(target_dir, child) + if os.path.isfile(child_path): + replace_end_year(child_path, year) + elif os.path.isdir(child_path): + bump_years_recursive(child_path, year) + +def update_license(license_file, long_date): + pass + +def bump_years(target_dir): + year = time.strftime('%Y') + long_date = time.strftime('%B %d, %Y') + bump_years_recursive(target_dir, year) + update_license(os.path.join(target_dir, 'LICENSE.html'), long_date) + +if __name__ == "__main__": + try: + target_dir = sys.argv[1] + except: + sys.stderr.write("""\ +Usage: bump-copyright-years VIEWVC_DIRECTORY + +Recursively update the copyright years associated with files carrying +'The ViewCVS Group' copyright in and under VIEWVC_DIRECTORY to include +the current year. +""") + sys.exit(1) + bump_years(target_dir) From 9e9b82218cd6cdcf8f7c679c530eb8c8bdee5167 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 23 Jan 2012 17:52:47 +0000 Subject: [PATCH 257/353] Bump copyright years. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2720 8cb11bc2-c004-0410-86c3-e597b4017df7 --- bin/asp/query.asp | 2 +- bin/asp/viewvc.asp | 2 +- bin/cgi/query.cgi | 2 +- bin/cgi/viewvc.cgi | 2 +- bin/cvsdbadmin | 2 +- bin/loginfo-handler | 2 +- bin/make-database | 2 +- bin/mod_python/handler.py | 2 +- bin/mod_python/query.py | 2 +- bin/mod_python/viewvc.py | 2 +- bin/standalone.py | 2 +- bin/svndbadmin | 2 +- bin/wsgi/query.fcgi | 2 +- bin/wsgi/query.wsgi | 2 +- bin/wsgi/viewvc.fcgi | 2 +- bin/wsgi/viewvc.wsgi | 2 +- lib/accept.py | 2 +- lib/blame.py | 2 +- lib/common.py | 2 +- lib/config.py | 2 +- lib/cvsdb.py | 2 +- lib/dbi.py | 2 +- lib/debug.py | 2 +- lib/idiff.py | 2 +- lib/popen.py | 2 +- lib/query.py | 2 +- lib/sapi.py | 2 +- lib/vcauth/__init__.py | 2 +- lib/vcauth/forbidden/__init__.py | 2 +- lib/vcauth/forbiddenre/__init__.py | 2 +- lib/vcauth/svnauthz/__init__.py | 2 +- lib/vclib/__init__.py | 2 +- lib/vclib/ccvs/__init__.py | 2 +- lib/vclib/ccvs/bincvs.py | 2 +- lib/vclib/ccvs/blame.py | 2 +- lib/vclib/ccvs/ccvs.py | 2 +- lib/vclib/ccvs/rcsparse/__init__.py | 2 +- lib/vclib/ccvs/rcsparse/common.py | 2 +- lib/vclib/ccvs/rcsparse/debug.py | 2 +- lib/vclib/ccvs/rcsparse/default.py | 2 +- lib/vclib/ccvs/rcsparse/texttools.py | 2 +- lib/vclib/svn/__init__.py | 2 +- lib/vclib/svn/svn_ra.py | 2 +- lib/vclib/svn/svn_repos.py | 2 +- lib/viewvc.py | 2 +- lib/win32popen.py | 2 +- misc/tparse/tparse.cpp | 2 +- misc/tparse/tparse.h | 2 +- misc/tparse/tparsemodule.cpp | 2 +- misc/tparse/tparsemodule.h | 2 +- tools/make-release | 2 +- viewvc-install | 2 +- 52 files changed, 52 insertions(+), 52 deletions(-) diff --git a/bin/asp/query.asp b/bin/asp/query.asp index 75b1a864..794ee8f6 100644 --- a/bin/asp/query.asp +++ b/bin/asp/query.asp @@ -3,7 +3,7 @@ # -*-python-*- # -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/asp/viewvc.asp b/bin/asp/viewvc.asp index 57fa1b64..4880017d 100644 --- a/bin/asp/viewvc.asp +++ b/bin/asp/viewvc.asp @@ -3,7 +3,7 @@ # -*-python-*- # -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/cgi/query.cgi b/bin/cgi/query.cgi index 1e95efc6..e8c8eb0b 100644 --- a/bin/cgi/query.cgi +++ b/bin/cgi/query.cgi @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/cgi/viewvc.cgi b/bin/cgi/viewvc.cgi index b90e118d..e7154cb7 100644 --- a/bin/cgi/viewvc.cgi +++ b/bin/cgi/viewvc.cgi @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/cvsdbadmin b/bin/cvsdbadmin index 43f8a33e..3aa2bac9 100755 --- a/bin/cvsdbadmin +++ b/bin/cvsdbadmin @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/loginfo-handler b/bin/loginfo-handler index d90fb16a..b7613be6 100755 --- a/bin/loginfo-handler +++ b/bin/loginfo-handler @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/make-database b/bin/make-database index d508973e..5861cb0c 100755 --- a/bin/make-database +++ b/bin/make-database @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/mod_python/handler.py b/bin/mod_python/handler.py index 6ccabe9d..a50f0b52 100644 --- a/bin/mod_python/handler.py +++ b/bin/mod_python/handler.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/mod_python/query.py b/bin/mod_python/query.py index 555ab2a2..4ee10409 100644 --- a/bin/mod_python/query.py +++ b/bin/mod_python/query.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/mod_python/viewvc.py b/bin/mod_python/viewvc.py index d148f6f5..c53aca74 100644 --- a/bin/mod_python/viewvc.py +++ b/bin/mod_python/viewvc.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/standalone.py b/bin/standalone.py index 9af30db1..1befcee2 100755 --- a/bin/standalone.py +++ b/bin/standalone.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/svndbadmin b/bin/svndbadmin index cfc2fd6d..11853d12 100755 --- a/bin/svndbadmin +++ b/bin/svndbadmin @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 2004-2008 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2004-2012 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 diff --git a/bin/wsgi/query.fcgi b/bin/wsgi/query.fcgi index dd49f6a8..7407ce77 100644 --- a/bin/wsgi/query.fcgi +++ b/bin/wsgi/query.fcgi @@ -1,7 +1,7 @@ #!/usr/bin/python # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/wsgi/query.wsgi b/bin/wsgi/query.wsgi index bd6c2a35..10a6978e 100644 --- a/bin/wsgi/query.wsgi +++ b/bin/wsgi/query.wsgi @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/wsgi/viewvc.fcgi b/bin/wsgi/viewvc.fcgi index 09f7a1dd..9224e23f 100644 --- a/bin/wsgi/viewvc.fcgi +++ b/bin/wsgi/viewvc.fcgi @@ -1,7 +1,7 @@ #!/usr/bin/python # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/bin/wsgi/viewvc.wsgi b/bin/wsgi/viewvc.wsgi index ac0474ad..ba376b49 100644 --- a/bin/wsgi/viewvc.wsgi +++ b/bin/wsgi/viewvc.wsgi @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/accept.py b/lib/accept.py index 3d464f88..0f2a118b 100644 --- a/lib/accept.py +++ b/lib/accept.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/blame.py b/lib/blame.py index 6766318f..eefb8cd9 100644 --- a/lib/blame.py +++ b/lib/blame.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. # Copyright (C) 2000 Curt Hagenlocher # # By using this file, you agree to the terms and conditions set forth in diff --git a/lib/common.py b/lib/common.py index 34a5fac8..1659a6f6 100644 --- a/lib/common.py +++ b/lib/common.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/config.py b/lib/config.py index 98b514cb..302b9596 100644 --- a/lib/config.py +++ b/lib/config.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/cvsdb.py b/lib/cvsdb.py index 69d71958..e3fe750c 100644 --- a/lib/cvsdb.py +++ b/lib/cvsdb.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/dbi.py b/lib/dbi.py index db1fcb43..775534cb 100644 --- a/lib/dbi.py +++ b/lib/dbi.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/debug.py b/lib/debug.py index df7e07b0..b6ce420c 100644 --- a/lib/debug.py +++ b/lib/debug.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/idiff.py b/lib/idiff.py index 35c7aab4..f839fc06 100644 --- a/lib/idiff.py +++ b/lib/idiff.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/popen.py b/lib/popen.py index e780feb8..e7b6f4f9 100644 --- a/lib/popen.py +++ b/lib/popen.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/query.py b/lib/query.py index 7c3a647a..3ab47f17 100644 --- a/lib/query.py +++ b/lib/query.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/sapi.py b/lib/sapi.py index 28d0f3b3..7344d6a3 100644 --- a/lib/sapi.py +++ b/lib/sapi.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vcauth/__init__.py b/lib/vcauth/__init__.py index c66bd540..f6dc2608 100644 --- a/lib/vcauth/__init__.py +++ b/lib/vcauth/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 2006-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2006-2012 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 diff --git a/lib/vcauth/forbidden/__init__.py b/lib/vcauth/forbidden/__init__.py index ed3f5934..c92cd5fe 100644 --- a/lib/vcauth/forbidden/__init__.py +++ b/lib/vcauth/forbidden/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 2006-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2006-2012 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 diff --git a/lib/vcauth/forbiddenre/__init__.py b/lib/vcauth/forbiddenre/__init__.py index 19e9d85d..1bbaf171 100644 --- a/lib/vcauth/forbiddenre/__init__.py +++ b/lib/vcauth/forbiddenre/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 2008-2010 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2008-2012 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 diff --git a/lib/vcauth/svnauthz/__init__.py b/lib/vcauth/svnauthz/__init__.py index 62efe5be..97a42f5f 100644 --- a/lib/vcauth/svnauthz/__init__.py +++ b/lib/vcauth/svnauthz/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 2006-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2006-2012 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 diff --git a/lib/vclib/__init__.py b/lib/vclib/__init__.py index 0171b526..4783bbb7 100644 --- a/lib/vclib/__init__.py +++ b/lib/vclib/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/ccvs/__init__.py b/lib/vclib/ccvs/__init__.py index 3eb718fc..e6d2bad0 100644 --- a/lib/vclib/ccvs/__init__.py +++ b/lib/vclib/ccvs/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/ccvs/bincvs.py b/lib/vclib/ccvs/bincvs.py index 59d108fa..8472b52a 100644 --- a/lib/vclib/ccvs/bincvs.py +++ b/lib/vclib/ccvs/bincvs.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/ccvs/blame.py b/lib/vclib/ccvs/blame.py index 1fca053a..007395e1 100644 --- a/lib/vclib/ccvs/blame.py +++ b/lib/vclib/ccvs/blame.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. # Copyright (C) 2000 Curt Hagenlocher # # By using this file, you agree to the terms and conditions set forth in diff --git a/lib/vclib/ccvs/ccvs.py b/lib/vclib/ccvs/ccvs.py index 12ecd06c..2201eeed 100644 --- a/lib/vclib/ccvs/ccvs.py +++ b/lib/vclib/ccvs/ccvs.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/ccvs/rcsparse/__init__.py b/lib/vclib/ccvs/rcsparse/__init__.py index 049f36cd..67f28b7c 100644 --- a/lib/vclib/ccvs/rcsparse/__init__.py +++ b/lib/vclib/ccvs/rcsparse/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/ccvs/rcsparse/common.py b/lib/vclib/ccvs/rcsparse/common.py index a4911f1a..5baf9a69 100644 --- a/lib/vclib/ccvs/rcsparse/common.py +++ b/lib/vclib/ccvs/rcsparse/common.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/ccvs/rcsparse/debug.py b/lib/vclib/ccvs/rcsparse/debug.py index cfeaf2b6..baf93659 100644 --- a/lib/vclib/ccvs/rcsparse/debug.py +++ b/lib/vclib/ccvs/rcsparse/debug.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/ccvs/rcsparse/default.py b/lib/vclib/ccvs/rcsparse/default.py index 5face4ca..e65c34a0 100644 --- a/lib/vclib/ccvs/rcsparse/default.py +++ b/lib/vclib/ccvs/rcsparse/default.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/ccvs/rcsparse/texttools.py b/lib/vclib/ccvs/rcsparse/texttools.py index 03387194..da7ce396 100644 --- a/lib/vclib/ccvs/rcsparse/texttools.py +++ b/lib/vclib/ccvs/rcsparse/texttools.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2008 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/svn/__init__.py b/lib/vclib/svn/__init__.py index f1d59cb4..91ff862b 100644 --- a/lib/vclib/svn/__init__.py +++ b/lib/vclib/svn/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/svn/svn_ra.py b/lib/vclib/svn/svn_ra.py index b4f20d0e..d8b437d5 100644 --- a/lib/vclib/svn/svn_ra.py +++ b/lib/vclib/svn/svn_ra.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/vclib/svn/svn_repos.py b/lib/vclib/svn/svn_repos.py index 0d1305af..5abb845a 100644 --- a/lib/vclib/svn/svn_repos.py +++ b/lib/vclib/svn/svn_repos.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/viewvc.py b/lib/viewvc.py index 3ac57d17..2b6a0a1c 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2011 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/lib/win32popen.py b/lib/win32popen.py index 4c30ec23..16f7948b 100644 --- a/lib/win32popen.py +++ b/lib/win32popen.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/misc/tparse/tparse.cpp b/misc/tparse/tparse.cpp index 4da238c7..c9366379 100644 --- a/misc/tparse/tparse.cpp +++ b/misc/tparse/tparse.cpp @@ -1,5 +1,5 @@ /* -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/misc/tparse/tparse.h b/misc/tparse/tparse.h index 4e53f747..53d3011a 100644 --- a/misc/tparse/tparse.h +++ b/misc/tparse/tparse.h @@ -1,5 +1,5 @@ /* -# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/misc/tparse/tparsemodule.cpp b/misc/tparse/tparsemodule.cpp index 79d0b40a..edc74245 100644 --- a/misc/tparse/tparsemodule.cpp +++ b/misc/tparse/tparsemodule.cpp @@ -1,5 +1,5 @@ /* -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/misc/tparse/tparsemodule.h b/misc/tparse/tparsemodule.h index 9fb77569..a4cd8c27 100644 --- a/misc/tparse/tparsemodule.h +++ b/misc/tparse/tparsemodule.h @@ -1,5 +1,5 @@ /* -# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/tools/make-release b/tools/make-release index 1654b86a..942a73ac 100755 --- a/tools/make-release +++ b/tools/make-release @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (C) 1999-2007 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 diff --git a/viewvc-install b/viewvc-install index 4fda25ff..ab75d7a9 100755 --- a/viewvc-install +++ b/viewvc-install @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- Mode: python -*- # -# Copyright (C) 1999-2009 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2012 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 From ad0c0dd5fae3ed3e455dd42653f50a80f714cdf0 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 23 Jan 2012 17:57:10 +0000 Subject: [PATCH 258/353] * tools/bump-copyright-years (replace_end_year): Remove debugging print statements, and simplify code. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2721 8cb11bc2-c004-0410-86c3-e597b4017df7 --- tools/bump-copyright-years | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/tools/bump-copyright-years b/tools/bump-copyright-years index 4d9fcc15..ff827a46 100755 --- a/tools/bump-copyright-years +++ b/tools/bump-copyright-years @@ -31,17 +31,13 @@ def replace_end_year(path, year): if not m: continue if m.group(2): - new_line = line[:m.start(3)] + year + line[m.end(3):] + lines[i] = line[:m.start(3)] + year + line[m.end(3):] + open(path, 'w').write(''.join(lines)) + break elif m.group(3) != year: - new_line = line[:m.end(3)] + '-' + year + line[m.end(3):] - if new_line is not None: - print "In file '%s'..." % (path) - print " replaced: " + line - print " with: " + new_line - updated = True - lines[i] = new_line - if updated: - open(path, 'w').write(''.join(lines)) + lines[i] = line[:m.end(3)] + '-' + year + line[m.end(3):] + open(path, 'w').write(''.join(lines)) + break def bump_years_recursive(target_dir, year): children = os.listdir(target_dir) From 7043120d2ca9b5a15bad834b5ebe19eb19c0b237 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 23 Jan 2012 18:31:20 +0000 Subject: [PATCH 259/353] * tools/bump-copyright-years (update_license): Remove. (bump_years): Print reminder about amending the change history section of the LICENSE.html file. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2722 8cb11bc2-c004-0410-86c3-e597b4017df7 --- tools/bump-copyright-years | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tools/bump-copyright-years b/tools/bump-copyright-years index ff827a46..87864e63 100755 --- a/tools/bump-copyright-years +++ b/tools/bump-copyright-years @@ -48,14 +48,17 @@ def bump_years_recursive(target_dir, year): elif os.path.isdir(child_path): bump_years_recursive(child_path, year) -def update_license(license_file, long_date): - pass - def bump_years(target_dir): year = time.strftime('%Y') long_date = time.strftime('%B %d, %Y') bump_years_recursive(target_dir, year) - update_license(os.path.join(target_dir, 'LICENSE.html'), long_date) + sys.stdout.write("""\ +Copyright years bumped. Don't forget to add the following line to +the primary license file at '%s': + +
  • %s — copyright years updated
  • + +""" % (os.path.join(target_dir, 'LICENSE.html'), long_date)) if __name__ == "__main__": try: From 86449bdec7fa80cf7c0660534a9a01da1176d383 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Mon, 23 Jan 2012 18:51:45 +0000 Subject: [PATCH 260/353] Bump pointer to latest version. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2726 8cb11bc2-c004-0410-86c3-e597b4017df7 --- www/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/index.html b/www/index.html index b3f12cfa..d2bf38a2 100644 --- a/www/index.html +++ b/www/index.html @@ -30,13 +30,13 @@

    Latest Release(s)

    -

    The most recent stable release of ViewVC is: 1.1.12

    +

    The most recent stable release of ViewVC is: 1.1.13

    From adfa50c9b4f1a62d4e5eb61aef1ee9aefacb3d1d Mon Sep 17 00:00:00 2001 From: cmpilato Date: Fri, 22 Jun 2012 20:22:49 +0000 Subject: [PATCH 292/353] * lib/vclib/svn/svn_ra.py (RemoteSubversionRepository.itemlog): Only fetch lock and size information for files, not directories. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2781 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/svn/svn_ra.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/vclib/svn/svn_ra.py b/lib/vclib/svn/svn_ra.py index 4656ffb1..a2662683 100644 --- a/lib/vclib/svn/svn_ra.py +++ b/lib/vclib/svn/svn_ra.py @@ -312,14 +312,18 @@ class RemoteSubversionRepository(vclib.Repository): rev = self._getrev(rev) url = self._geturl(path) - # Use ls3 to fetch the lock status and size (as of REV) for this item. - lockinfo = None - basename = path_parts and path_parts[-1] or "" - dirents, locks = list_directory(url, _rev2optrev(rev), - _rev2optrev(rev), 0, self.ctx) - if locks.has_key(basename): - lockinfo = locks[basename].owner - size_in_rev = dirents[basename].size + # If this is a file, fetch the lock status and size (as of REV) + # for this item. + lockinfo = size_in_rev = None + if path_type == vclib.FILE: + basename = path_parts[-1] + list_url = self._geturl(self._getpath(path_parts[:-1])) + dirents, locks = list_directory(list_url, _rev2optrev(rev), + _rev2optrev(rev), 0, self.ctx) + if locks.has_key(basename): + lockinfo = locks[basename].owner + if dirents.has_key(basename): + size_in_rev = dirents[basename].size # Special handling for the 'svn_latest_log' scenario. ### FIXME: Don't like this hack. We should just introduce From 00feefc3dced7fe4465d67b97f7d8f2f16d1f4fe Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 5 Sep 2012 12:55:19 +0000 Subject: [PATCH 293/353] Finish issue #510 ("Block the expensive display of binary files"). Add a new configuration option 'binary_mime_types' which accepts a comma-delimited list of MIME content type patterns ('text/plain', or 'image/*', etc.) against which versioned file MIME types are compared for the purposes of deciding whether to allow their display in the 'markup', 'annotate', 'diff' and 'patch' views. * conf/viewvc.conf.dist (binary_mime_types): Describe new option. * lib/config.py (_force_multi_value): Add 'binary_file_types' to the list of multi-value options. (Config.set_defaults): Initialize cfg.options.binary_mime_types. * lib/viewvc.py (is_binary_file_mime_type): New function. (get_file_view_info): Use is_binary_file_mime_type() to determine whether to return links to content-ful views of the input file. (markup_or_annotate, view_diff): Use is_binary_file_mime_type() to deny display of so-deemed binary files. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2784 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 18 ++++++++++++++++++ lib/config.py | 2 ++ lib/viewvc.py | 36 +++++++++++++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index e4a75344..bda07f49 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -383,6 +383,24 @@ ## #allowed_views = annotate, diff, markup, roots +## Comma-delimited list of MIME content types (with support for fnmatch- +## style glob characters) which are considered not-human-readable and for +## which ViewVC will neither generate links to, nor support the direct +## display of, non-checkout views which carry the file's content (the +## 'markup', 'annotate', 'diff', and 'patch' views). +## +## NOTE: Handling of this option is given priority over ViewVC's +## longstanding support for showing web-friendly file formats -- even +## binary ones such as "image/jpeg" and "image/gif" -- in the 'markup' +## view. Thus, if you add "image/*" to this list, 'markup'-view +## display of JPEG, GIF, and PNG images will be disabled. +## +## Example: +## binary_mime_types = application/octet-stream, image/*, application/pdf, +## application/vnd*, application/msword, audio/* +# +#binary_mime_types = + ## authorizer: The name of the ViewVC authorizer plugin to use when ## authorizing access to repository contents. This value must be the ## name of a Python module addressable as vcauth.MODULENAME (most diff --git a/lib/config.py b/lib/config.py index 05b329c8..b3c066b9 100644 --- a/lib/config.py +++ b/lib/config.py @@ -111,6 +111,7 @@ class Config: _force_multi_value = ( # Configuration values with multiple, comma-separated values. 'allowed_views', + 'binary_mime_types', 'custom_log_formatting', 'cvs_roots', 'kv_files', @@ -399,6 +400,7 @@ class Config: self.options.mangle_email_addresses = 0 self.options.custom_log_formatting = [] self.options.default_file_view = "log" + self.options.binary_mime_types = [] self.options.http_expiration_time = 600 self.options.generate_etags = 1 self.options.svn_ignore_mimetype = 0 diff --git a/lib/viewvc.py b/lib/viewvc.py index d449db43..66ef8c5c 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -26,6 +26,7 @@ import sys import os import calendar import copy +import fnmatch import gzip import mimetypes import re @@ -1023,6 +1024,15 @@ def default_view(mime_type, cfg): return view_markup return view_checkout +def is_binary_file_mime_type(mime_type, cfg): + """Return True iff MIME_TYPE is set and matches one of the binary + file mime type patterns in CFG.""" + if mime_type: + for pattern in cfg.options.binary_mime_types: + if fnmatch.fnmatch(mime_type, pattern): + return True + return False + def get_file_view_info(request, where, rev=None, mime_type=None, pathrev=-1): """Return an object holding common hrefs and a viewability flag used for various views of FILENAME at revision REV whose MIME type is @@ -1083,7 +1093,12 @@ def get_file_view_info(request, where, rev=None, mime_type=None, pathrev=-1): params={'revision': rev}, escape=1) - prefer_markup = default_view(mime_type, request.cfg) == view_markup + is_binary_file = is_binary_file_mime_type(mime_type, request.cfg) + if is_binary_file: + download_text_href = annotate_href = view_href = None + prefer_markup = False + else: + prefer_markup = default_view(mime_type, request.cfg) == view_markup return _item(view_href=view_href, download_href=download_href, @@ -1839,6 +1854,11 @@ def markup_or_annotate(request, is_annotate): revision = None mime_type, encoding = calculate_mime_type(request, path, rev) + # Is this display blocked by 'binary_mime_types' configuration? + if is_binary_file_mime_type(mime_type, cfg): + raise debug.ViewVCException('Display of binary file content disabled ' + 'by configuration', '403 Forbidden') + # Is this a viewable image type? if is_viewable_image(mime_type) \ and 'co' in cfg.options.allowed_views: @@ -3359,6 +3379,13 @@ def view_patch(request): query_dict = request.query_dict p1, p2, rev1, rev2, sym1, sym2 = setup_diff(request) + mime_type1, encoding1 = calculate_mime_type(request, p1, rev1) + mime_type2, encoding2 = calculate_mime_type(request, p2, rev2) + if is_binary_file_mime_type(mime_type1, cfg) or \ + is_binary_file_mime_type(mime_type2, cfg): + raise debug.ViewVCException('Display of binary file content disabled ' + 'by configuration', '403 Forbidden') + # In the absence of a format dictation in the CGI params, we'll let # use the configured diff format, allowing 'c' to mean 'c' and # anything else to mean 'u'. @@ -3649,6 +3676,13 @@ def view_diff(request): p1, p2, rev1, rev2, sym1, sym2 = setup_diff(request) + mime_type1, encoding1 = calculate_mime_type(request, p1, rev1) + mime_type2, encoding2 = calculate_mime_type(request, p2, rev2) + if is_binary_file_mime_type(mime_type1, cfg) or \ + is_binary_file_mime_type(mime_type2, cfg): + raise debug.ViewVCException('Display of binary file content disabled ' + 'by configuration', '403 Forbidden') + # since templates are in use and subversion allows changes to the dates, # we can't provide a strong etag if check_freshness(request, None, '%s-%s' % (rev1, rev2), weak=1): From ace5d55f0e32d191ba71c1dac009f6cc53c083c1 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 5 Sep 2012 15:52:27 +0000 Subject: [PATCH 294/353] * bin/cgi/query.cgi, * bin/cgi/viewvc.cgi Add some commented-out logic for renice-ing the ViewVC CGI process. Inspired by: Karl Berry git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2786 8cb11bc2-c004-0410-86c3-e597b4017df7 --- bin/cgi/query.cgi | 16 +++++++++++++++- bin/cgi/viewvc.cgi | 15 ++++++++++++--- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/bin/cgi/query.cgi b/bin/cgi/query.cgi index e8c8eb0b..1520a5dd 100644 --- a/bin/cgi/query.cgi +++ b/bin/cgi/query.cgi @@ -34,7 +34,7 @@ CONF_PATHNAME = None ######################################################################### # -# Adjust sys.path to include our library directory +# Adjust sys.path to include our library directory. # import sys @@ -47,6 +47,20 @@ else: "../../../lib"))) ######################################################################### +# +# If admins want nicer processes, here's the place to get them. +# + +#try: +# os.nice(20) # bump the nice level of this process +#except: +# pass + + +######################################################################### +# +# Go do the work. +# import sapi import viewvc diff --git a/bin/cgi/viewvc.cgi b/bin/cgi/viewvc.cgi index e7154cb7..60875873 100644 --- a/bin/cgi/viewvc.cgi +++ b/bin/cgi/viewvc.cgi @@ -34,7 +34,7 @@ CONF_PATHNAME = None ######################################################################### # -# Adjust sys.path to include our library directory +# Adjust sys.path to include our library directory. # import sys @@ -47,12 +47,21 @@ else: "../../../lib"))) ######################################################################### +# +# If admins want nicer processes, here's the place to get them. +# + +#try: +# os.nice(20) # bump the nice level of this process +#except: +# pass -### add code for checking the load average ######################################################################### +# +# Go do the work. +# -# go do the work import sapi import viewvc From 4590ebbd6b1d79cdd9102045c177fa63256f7fbe Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 3 Oct 2012 14:22:48 +0000 Subject: [PATCH 295/353] Fix issue #512 ("'Select for diffs' does not work across pages"). * lib/viewvc.py (view_log): Preserve the 'log_pagestart' query value when generating the 'select for diff' links so that clicking the link returns you to the same page (modulo repagination due to new commits in the race window ... but let's not think about that). Also, preserve the 'r1' query parameter when generating the paging form. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2788 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 66ef8c5c..f93dec2f 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -2686,7 +2686,8 @@ def view_log(request): if selected_rev != entry.rev: entry.sel_for_diff_href = \ request.get_url(view_func=view_log, - params={'r1': entry.rev}, + params={'r1': entry.rev, + 'log_pagestart': log_pagestart}, escape=1) if entry.prev is not None: entry.diff_to_prev_href = \ @@ -2827,7 +2828,9 @@ def view_log(request): if cfg.options.log_pagesize: data['log_paging_action'], data['log_paging_hidden_values'] = \ - request.get_form(params={'log_pagestart': None}) + request.get_form(params={'log_pagestart': None, + 'r1': selected_rev, + }) data['log_pagestart'] = int(request.query_dict.get('log_pagestart',0)) data['entries'] = paging_sws(data, 'entries', data['log_pagestart'], 'rev', cfg.options.log_pagesize, From f4945fd7d91b39f9a7b61e3292e839993de1f228 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 3 Oct 2012 14:33:38 +0000 Subject: [PATCH 296/353] Oops! Fix the diff view I broke in r2784. * lib/viewvc.py (view_diff): Add 'cfg' convenience variable (to avoid a stack trace caused by using such a thing a few lines later). git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2790 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/viewvc.py b/lib/viewvc.py index f93dec2f..0266bd35 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3677,6 +3677,7 @@ def view_diff(request): raise debug.ViewVCException('Diff generation is disabled', '403 Forbidden') + cfg = request.cfg p1, p2, rev1, rev2, sym1, sym2 = setup_diff(request) mime_type1, encoding1 = calculate_mime_type(request, p1, rev1) From 4a98f512f7c9b8f7cc323f8ec3fd31616cdb473d Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 24 Oct 2012 13:22:14 +0000 Subject: [PATCH 297/353] * conf/viewvc.conf.dist Show the default value of 'hr_funout' as 1 (which matches the programmatic default). git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2791 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index bda07f49..34c24a4b 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -571,7 +571,7 @@ ## (Only works well for C source files, otherwise diff's heuristic falls short.) ## ('-p' option to diff) ## -#hr_funout = 0 +#hr_funout = 1 ## hr_ignore_white: Ignore whitespace (indendation and stuff) for human ## readable diffs. From de517ae29cc34a57084faf82fd5cab44e3dc25e4 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 24 Oct 2012 13:26:36 +0000 Subject: [PATCH 298/353] Fix issue #515 ("XSS bug in diff view (CVE-2012-4533)"). MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * lib/viewvc.py (DiffSource._get_row): Pass the "extra" line information through the formatter code so that, at a minimum, it's HTML-escaped. Patch by: Nicolás Alvarez git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2792 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 0266bd35..1f2b1fbb 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3165,7 +3165,7 @@ class DiffSource: return _item(type='header', line_info_left=match.group(1), line_info_right=match.group(2), - line_info_extra=match.group(3)) + line_info_extra=self._format_text(match.group(3))) if line[0] == '\\': # \ No newline at end of file From a8d3373025f458e372454de2b14e3fe94a66be43 Mon Sep 17 00:00:00 2001 From: cmpilato Date: Wed, 24 Oct 2012 16:57:59 +0000 Subject: [PATCH 299/353] Fix issue #514 (Simple file view has page title with "Annotation of:"). * templates/classic/file.ezt, * templates/default/file.ezt Set the page's attribute to "Annotation of ..." or "Contents of ...", depending on whether the output is annotated. Patch by: John McNally <jmcnally{__AT__}collab.net> git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2796 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/classic/file.ezt | 6 +++++- templates/default/file.ezt | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/templates/classic/file.ezt b/templates/classic/file.ezt index 8aad128b..b35e64db 100644 --- a/templates/classic/file.ezt +++ b/templates/classic/file.ezt @@ -9,7 +9,11 @@ [# ------------------------------------------------------------------------- ] [# setup page definitions] - [define page_title]Contents of /[where][end] + [is annotation "annotated"] + [define page_title]Annotation of /[where][end] + [else] + [define page_title]Contents of /[where][end] + [end] [define help_href][docroot]/help_rootview.html[end] [# end] diff --git a/templates/default/file.ezt b/templates/default/file.ezt index 0a3abe4c..1b5f6ba2 100644 --- a/templates/default/file.ezt +++ b/templates/default/file.ezt @@ -9,7 +9,11 @@ [# ------------------------------------------------------------------------- ] [# setup page definitions] - [define page_title]Annotation of:[end] + [is annotation "annotated"] + [define page_title]Annotation of:[end] + [else] + [define page_title]Contents of:[end] + [end] [define help_href][docroot]/help_rootview.html[end] [# end] [include "include/header.ezt" "annotate"] From 64b0994f2f772119b45412f3d2db194bbaa2e9f8 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 24 Oct 2012 18:21:47 +0000 Subject: [PATCH 300/353] Bump most stable release version. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2804 8cb11bc2-c004-0410-86c3-e597b4017df7 --- www/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/index.html b/www/index.html index 5180638c..91a64382 100644 --- a/www/index.html +++ b/www/index.html @@ -30,13 +30,13 @@ <h2>Latest Release(s)</h2> -<p>The most recent stable release of ViewVC is: <strong>1.1.15</strong></p> +<p>The most recent stable release of ViewVC is: <strong>1.1.16</strong></p> <ul> <li><a href="http://www.viewvc.org/download.html" >Download or checkout</a> this release</li> <li>See the - <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.15/CHANGES" + <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.16/CHANGES" >CHANGES</a> in this release.</li> <li>Read the <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/trunk/docs/release-notes/1.1.0.html" From 06910f29e38f5f93c8f110ac0535731e471c7f90 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 24 Oct 2012 18:46:52 +0000 Subject: [PATCH 301/353] * CHANGES Include 1.1.16 and 1.0.13 changes, too. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2806 8cb11bc2-c004-0410-86c3-e597b4017df7 --- CHANGES | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGES b/CHANGES index 1c24cb16..c88fd7b4 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,14 @@ Version 1.2.0 (released ??-???-????) * allow user-configurable cvsgraph display (issue #336) * allow rNNNN syntax for Subversion revision numbers (issue #441) +Version 1.1.16 (released 24-Oct-2012) + + * security fix: escape "extra" diff info to avoid XSS attack (issue #515) + * add 'binary_mime_types' configuration option and handling (issue #510) + * fix 'select for diffs' persistence across log pages (issue #512) + * remove lock status and filesize check on directories in remote SVN views + * fix bogus 'Annotation of' page title for non-annotated view (issue #514) + Version 1.1.15 (released 22-Jun-2012) * security fix: complete authz support for remote SVN views (issue #353) @@ -180,6 +188,13 @@ Version 1.1.0 (released 13-May-2009) * fix exception in rev-sorted remote Subversion directory views (issue #409) * allow setting of page sizes for log and dir views individually (issue #402) +Version 1.0.13 (released 24-Oct-2012) + + * security fix: escape "extra" diff info to avoid XSS attack (issue #515) + * security fix: remove user-reachable override of cvsdb row limit + * fix obscure "unexpected NULL parent pool" Subversion bindings error + * fix svndbadmin failure on deleted paths under Subversion 1.7 (issue #499) + Version 1.0.12 (released 02-Jun-2010) * fix exception caused by trying to HTML-escape non-string data (issue #454) From e8f975475e4e860ba1d711502129ca4f36f38f81 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 24 Oct 2012 18:50:57 +0000 Subject: [PATCH 302/353] Update link to the CHANGES file. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2807 8cb11bc2-c004-0410-86c3-e597b4017df7 --- www/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/index.html b/www/index.html index 91a64382..a618b130 100644 --- a/www/index.html +++ b/www/index.html @@ -79,7 +79,7 @@ <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" + href="http://viewvc.tigris.org/source/browse/viewvc/trunk/CHANGES?view=markup&pathrev=HEAD" >CHANGES</a> file.</p> </div> From dcb7e17dc60efc48e52979a3a3b276b648f3ed43 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 25 Oct 2012 13:46:15 +0000 Subject: [PATCH 303/353] Fix issue #516 ("Regression: UnboundLocalError: local variable 'log_pagestart' referenced before assignment"). * lib/viewvc.py (view_log): Initialize the 'log_pagestart' variable. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2808 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/viewvc.py b/lib/viewvc.py index 1f2b1fbb..16d2c85e 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -2563,6 +2563,7 @@ def view_log(request): sortby = vclib.SORTBY_DEFAULT first = last = 0 + log_pagestart = None if cfg.options.log_pagesize: log_pagestart = int(request.query_dict.get('log_pagestart', 0)) total = cfg.options.log_pagesextra * cfg.options.log_pagesize From 6fcc2b5992e8b54cedd4614e4ea47c8fcb990356 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 25 Oct 2012 14:05:24 +0000 Subject: [PATCH 304/353] Bump most recent reported release. Again. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2811 8cb11bc2-c004-0410-86c3-e597b4017df7 --- www/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/index.html b/www/index.html index a618b130..f31a80c2 100644 --- a/www/index.html +++ b/www/index.html @@ -30,13 +30,13 @@ <h2>Latest Release(s)</h2> -<p>The most recent stable release of ViewVC is: <strong>1.1.16</strong></p> +<p>The most recent stable release of ViewVC is: <strong>1.1.17</strong></p> <ul> <li><a href="http://www.viewvc.org/download.html" >Download or checkout</a> this release</li> <li>See the - <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.16/CHANGES" + <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.17/CHANGES" >CHANGES</a> in this release.</li> <li>Read the <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/trunk/docs/release-notes/1.1.0.html" From cea54da382b91f9fda5bb4a39ceafec61aa538bd Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 25 Oct 2012 14:06:06 +0000 Subject: [PATCH 305/353] * CHANGES Merge 1.1.17 changes. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2812 8cb11bc2-c004-0410-86c3-e597b4017df7 --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index c88fd7b4..94c238df 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,10 @@ Version 1.2.0 (released ??-???-????) * allow user-configurable cvsgraph display (issue #336) * allow rNNNN syntax for Subversion revision numbers (issue #441) +Version 1.1.17 (released 25-Oct-2012) + + * fix exception caused by uninitialized variable usage (issue #516) + Version 1.1.16 (released 24-Oct-2012) * security fix: escape "extra" diff info to avoid XSS attack (issue #515) From d01846793769496b3bab321c04ab625d3adf916b Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 25 Oct 2012 19:16:18 +0000 Subject: [PATCH 306/353] Revert r2649, as the default templates *should* support the property diff stuff now if I recall correctly. * conf/viewvc.conf.dist, * lib/config.py Use "templates/default" now for the default templates. Duh. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2815 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 2 +- lib/config.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index 34c24a4b..cc6cd9a3 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -617,7 +617,7 @@ ## template_dir = templates/default ## template_dir = templates-contrib/custom/templates # -#template_dir = templates/classic +#template_dir = templates/default ## docroot: Web path to a directory that contains ViewVC static files ## (stylesheets, images, etc.) If set, static files will get diff --git a/lib/config.py b/lib/config.py index b3c066b9..401d1114 100644 --- a/lib/config.py +++ b/lib/config.py @@ -419,7 +419,7 @@ class Config: self.options.hr_ignore_keyword_subst = 1 self.options.hr_intraline = 0 self.options.allow_compress = 0 - self.options.template_dir = "templates/classic" + self.options.template_dir = "templates/default" self.options.docroot = None self.options.show_subdir_lastmod = 0 self.options.show_roots_lastmod = 0 From 0d1da3c79b5f39b79732ee76e8e17081d21cc405 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 25 Oct 2012 19:56:52 +0000 Subject: [PATCH 307/353] * templates/default/include/diff_display.ezt Show the "extra" diff info stuff, too. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2816 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/include/diff_display.ezt | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/default/include/diff_display.ezt b/templates/default/include/diff_display.ezt index 7083619e..ca52891c 100644 --- a/templates/default/include/diff_display.ezt +++ b/templates/default/include/diff_display.ezt @@ -59,6 +59,7 @@ <th colspan="2" class="vc_header"> <strong>Line [diffs.changes.line_info_left]</strong> | <strong>Line [diffs.changes.line_info_right]</strong> + [if-any diffs.changes.line_info_extra]| <strong>[diffs.changes.line_info_extra]</strong>[end] </th> </tr> [else] From 19818e269cda77626b36fb6b477f9838215353ac Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 25 Oct 2012 20:14:16 +0000 Subject: [PATCH 308/353] * lib/viewvc.py (view_patch): Honor the "show functions" option when generating patches, too. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2817 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 16d2c85e..cd4c6a96 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3402,9 +3402,14 @@ def view_patch(request): else: raise debug.ViewVCException('Diff format %s not understood' % format, '400 Bad Request') + + # Set some diff options. (Are there other options folks might want? + # Maybe not. For a patch, perhaps the precise change is ideal.) + diff_options = {} + diff_options['funout'] = cfg.options.hr_funout try: - fp = request.repos.rawdiff(p1, rev1, p2, rev2, diff_type) + fp = request.repos.rawdiff(p1, rev1, p2, rev2, diff_type, diff_options) except vclib.InvalidRevision: raise debug.ViewVCException('Invalid path(s) or revision(s) passed ' 'to diff', '400 Bad Request') From b57831ade86fd8aa75d88b64204898271d9e194a Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 25 Oct 2012 20:21:13 +0000 Subject: [PATCH 309/353] Fix the handling of diff options throughout. * lib/viewvc.py (DiffDescription.__init__): Don't set self.diff_options. (DiffDescription.get_content_diff, DiffDescription.get_prop_diff): Rename local variable 'options' to 'diff_options', and actually populate *it* rather than the otherwise unused (and now removed) 'diff_options' class variable. (DiffDescription._get_diff, DiffDescription._line_idiff_sidebyside, DiffDescription._line_idiff_unified, DiffDescription._content_fp, DiffDescription._prop_fp): Rename 'options' to 'diff_options'. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2818 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index cd4c6a96..6eff03bd 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3481,7 +3481,6 @@ class DiffDescription: query_dict = request.query_dict self.diff_format = query_dict.get('diff_format', cfg.options.diff_format) - self.diff_options = {} self.human_readable = 0 self.hide_legend = 0 self.line_differ = None @@ -3545,25 +3544,25 @@ class DiffDescription: self.changes.append(_item(diff_block_format='anchor', anchor=anchor_name)) def get_content_diff(self, left, right): - options = {} + diff_options = {} if self.context != -1: - options['context'] = self.context + diff_options['context'] = self.context if self.human_readable: cfg = self.request.cfg - self.diff_options['funout'] = cfg.options.hr_funout - self.diff_options['ignore_white'] = cfg.options.hr_ignore_white - self.diff_options['ignore_keyword_subst'] = \ + diff_options['funout'] = cfg.options.hr_funout + diff_options['ignore_white'] = cfg.options.hr_ignore_white + diff_options['ignore_keyword_subst'] = \ cfg.options.hr_ignore_keyword_subst self._get_diff(left, right, self._content_lines, self._content_fp, - options, None) + diff_options, None) def get_prop_diff(self, left, right): - options = {} + diff_options = {} if self.context != -1: - options['context'] = self.context + diff_options['context'] = self.context if self.human_readable: cfg = self.request.cfg - self.diff_options['ignore_white'] = cfg.options.hr_ignore_white + diff_options['ignore_white'] = cfg.options.hr_ignore_white for name in self._uniq(left.properties.keys() + right.properties.keys()): # Skip non-utf8 property names if is_undisplayable(name): @@ -3581,27 +3580,30 @@ class DiffDescription: changes=[ _item(type=_RCSDIFF_IS_BINARY) ], propname=name)) continue - self._get_diff(left, right, self._prop_lines, self._prop_fp, options, name) + self._get_diff(left, right, self._prop_lines, self._prop_fp, + diff_options, name) - def _get_diff(self, left, right, get_lines, get_fp, options, propname): + def _get_diff(self, left, right, get_lines, get_fp, diff_options, propname): if self.fp_differ is not None: - fp = get_fp(left, right, propname, options) + fp = get_fp(left, right, propname, diff_options) changes = self.fp_differ(left, right, fp, propname) else: lines_left = get_lines(left, propname) lines_right = get_lines(right, propname) - changes = self.line_differ(lines_left, lines_right, options) + changes = self.line_differ(lines_left, lines_right, diff_options) self.changes.append(_item(left=left, right=right, changes=changes, diff_block_format=self.diff_block_format, propname=propname)) - def _line_idiff_sidebyside(self, lines_left, lines_right, options): - return idiff.sidebyside(lines_left, lines_right, options.get("context", 5)) + def _line_idiff_sidebyside(self, lines_left, lines_right, diff_options): + return idiff.sidebyside(lines_left, lines_right, + diff_options.get("context", 5)) - def _line_idiff_unified(self, lines_left, lines_right, options): - return idiff.unified(lines_left, lines_right, options.get("context", 2)) + def _line_idiff_unified(self, lines_left, lines_right, diff_options): + return idiff.unified(lines_left, lines_right, + diff_options.get("context", 2)) def _fp_vclib_hr(self, left, right, fp, propname): date1, date2, flag, headers = \ @@ -3634,18 +3636,19 @@ class DiffDescription: f.close() return lines - def _content_fp(self, left, right, propname, options): + def _content_fp(self, left, right, propname, diff_options): return self.request.repos.rawdiff(left.path_comp, left.rev, - right.path_comp, right.rev, self.diff_type, options) + right.path_comp, right.rev, + self.diff_type, diff_options) def _prop_lines(self, side, propname): val = side.properties.get(propname, '') return val.splitlines() - def _prop_fp(self, left, right, propname, options): + def _prop_fp(self, left, right, propname, diff_options): fn_left = self._temp_file(left.properties.get(propname)) fn_right = self._temp_file(right.properties.get(propname)) - diff_args = vclib._diff_args(self.diff_type, options) + diff_args = vclib._diff_args(self.diff_type, diff_options) info_left = self._property_path(left, propname), \ left.log_entry.date, left.rev info_right = self._property_path(right, propname), \ From f48add83f7d3ee999dc582312f9b3afc7fdb2a5c Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Fri, 4 Jan 2013 19:01:54 +0000 Subject: [PATCH 310/353] Bump copyright years. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2820 8cb11bc2-c004-0410-86c3-e597b4017df7 --- LICENSE.html | 3 ++- bin/asp/query.asp | 2 +- bin/asp/viewvc.asp | 2 +- bin/cgi/query.cgi | 2 +- bin/cgi/viewvc.cgi | 2 +- bin/cvsdbadmin | 2 +- bin/loginfo-handler | 2 +- bin/make-database | 2 +- bin/mod_python/handler.py | 2 +- bin/mod_python/query.py | 2 +- bin/mod_python/viewvc.py | 2 +- bin/standalone.py | 2 +- bin/svndbadmin | 2 +- bin/wsgi/query.fcgi | 2 +- bin/wsgi/query.wsgi | 2 +- bin/wsgi/viewvc.fcgi | 2 +- bin/wsgi/viewvc.wsgi | 2 +- lib/accept.py | 2 +- lib/blame.py | 2 +- lib/common.py | 2 +- lib/config.py | 2 +- lib/cvsdb.py | 2 +- lib/dbi.py | 2 +- lib/debug.py | 2 +- lib/idiff.py | 2 +- lib/popen.py | 2 +- lib/query.py | 2 +- lib/sapi.py | 2 +- lib/vcauth/__init__.py | 2 +- lib/vcauth/forbidden/__init__.py | 2 +- lib/vcauth/forbiddenre/__init__.py | 2 +- lib/vcauth/svnauthz/__init__.py | 2 +- lib/vclib/__init__.py | 2 +- lib/vclib/ccvs/__init__.py | 2 +- lib/vclib/ccvs/bincvs.py | 2 +- lib/vclib/ccvs/blame.py | 2 +- lib/vclib/ccvs/ccvs.py | 2 +- lib/vclib/ccvs/rcsparse/__init__.py | 2 +- lib/vclib/ccvs/rcsparse/common.py | 2 +- lib/vclib/ccvs/rcsparse/debug.py | 2 +- lib/vclib/ccvs/rcsparse/default.py | 2 +- lib/vclib/ccvs/rcsparse/texttools.py | 2 +- lib/vclib/svn/__init__.py | 2 +- lib/vclib/svn/svn_ra.py | 2 +- lib/vclib/svn/svn_repos.py | 2 +- lib/viewvc.py | 2 +- lib/win32popen.py | 2 +- misc/tparse/tparse.cpp | 2 +- misc/tparse/tparse.h | 2 +- misc/tparse/tparsemodule.cpp | 2 +- misc/tparse/tparsemodule.h | 2 +- tools/bump-copyright-years | 2 +- tools/make-release | 2 +- viewvc-install | 2 +- 54 files changed, 55 insertions(+), 54 deletions(-) diff --git a/LICENSE.html b/LICENSE.html index 910ecb38..d15d9b8d 100644 --- a/LICENSE.html +++ b/LICENSE.html @@ -15,7 +15,7 @@ <blockquote> -<p><strong>Copyright © 1999-2012 The ViewCVS Group. All rights +<p><strong>Copyright © 1999-2013 The ViewCVS Group. All rights reserved.</strong></p> <p>By using ViewVC, you agree to the terms and conditions set forth @@ -63,6 +63,7 @@ <li>March 29, 2010 — copyright years updated</li> <li>February 18, 2011 — copyright years updated</li> <li>January 23, 2012 — copyright years updated</li> + <li>January 04, 2013 — copyright years updated</li> </ul> </body> diff --git a/bin/asp/query.asp b/bin/asp/query.asp index 794ee8f6..110a04a6 100644 --- a/bin/asp/query.asp +++ b/bin/asp/query.asp @@ -3,7 +3,7 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/asp/viewvc.asp b/bin/asp/viewvc.asp index 4880017d..c78672b0 100644 --- a/bin/asp/viewvc.asp +++ b/bin/asp/viewvc.asp @@ -3,7 +3,7 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/cgi/query.cgi b/bin/cgi/query.cgi index 1520a5dd..c7bd0b21 100644 --- a/bin/cgi/query.cgi +++ b/bin/cgi/query.cgi @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/cgi/viewvc.cgi b/bin/cgi/viewvc.cgi index 60875873..a6da9307 100644 --- a/bin/cgi/viewvc.cgi +++ b/bin/cgi/viewvc.cgi @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/cvsdbadmin b/bin/cvsdbadmin index 3aa2bac9..7a34a220 100755 --- a/bin/cvsdbadmin +++ b/bin/cvsdbadmin @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/loginfo-handler b/bin/loginfo-handler index b7613be6..7edde4e2 100755 --- a/bin/loginfo-handler +++ b/bin/loginfo-handler @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/make-database b/bin/make-database index 5861cb0c..d845eb65 100755 --- a/bin/make-database +++ b/bin/make-database @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/mod_python/handler.py b/bin/mod_python/handler.py index a50f0b52..37f495f1 100644 --- a/bin/mod_python/handler.py +++ b/bin/mod_python/handler.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/mod_python/query.py b/bin/mod_python/query.py index 4ee10409..116879e3 100644 --- a/bin/mod_python/query.py +++ b/bin/mod_python/query.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/mod_python/viewvc.py b/bin/mod_python/viewvc.py index c53aca74..4ecbaf5e 100644 --- a/bin/mod_python/viewvc.py +++ b/bin/mod_python/viewvc.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/standalone.py b/bin/standalone.py index 1befcee2..8023c182 100755 --- a/bin/standalone.py +++ b/bin/standalone.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/svndbadmin b/bin/svndbadmin index 11853d12..caf21e7a 100755 --- a/bin/svndbadmin +++ b/bin/svndbadmin @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 2004-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2004-2013 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 diff --git a/bin/wsgi/query.fcgi b/bin/wsgi/query.fcgi index 7407ce77..5e37308e 100644 --- a/bin/wsgi/query.fcgi +++ b/bin/wsgi/query.fcgi @@ -1,7 +1,7 @@ #!/usr/bin/python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/wsgi/query.wsgi b/bin/wsgi/query.wsgi index 10a6978e..f68382a9 100644 --- a/bin/wsgi/query.wsgi +++ b/bin/wsgi/query.wsgi @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/wsgi/viewvc.fcgi b/bin/wsgi/viewvc.fcgi index 9224e23f..28ba336d 100644 --- a/bin/wsgi/viewvc.fcgi +++ b/bin/wsgi/viewvc.fcgi @@ -1,7 +1,7 @@ #!/usr/bin/python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/bin/wsgi/viewvc.wsgi b/bin/wsgi/viewvc.wsgi index ba376b49..d27d5cf5 100644 --- a/bin/wsgi/viewvc.wsgi +++ b/bin/wsgi/viewvc.wsgi @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/accept.py b/lib/accept.py index 0f2a118b..01076b4d 100644 --- a/lib/accept.py +++ b/lib/accept.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/blame.py b/lib/blame.py index eefb8cd9..ab023b80 100644 --- a/lib/blame.py +++ b/lib/blame.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/common.py b/lib/common.py index 1659a6f6..66d5a71a 100644 --- a/lib/common.py +++ b/lib/common.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/config.py b/lib/config.py index 401d1114..a3c29a20 100644 --- a/lib/config.py +++ b/lib/config.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/cvsdb.py b/lib/cvsdb.py index e3fe750c..1903cb01 100644 --- a/lib/cvsdb.py +++ b/lib/cvsdb.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/dbi.py b/lib/dbi.py index 775534cb..626e4b76 100644 --- a/lib/dbi.py +++ b/lib/dbi.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/debug.py b/lib/debug.py index b6ce420c..c17fac15 100644 --- a/lib/debug.py +++ b/lib/debug.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/idiff.py b/lib/idiff.py index f839fc06..0dfd60d1 100644 --- a/lib/idiff.py +++ b/lib/idiff.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/popen.py b/lib/popen.py index e7b6f4f9..e6ab1328 100644 --- a/lib/popen.py +++ b/lib/popen.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/query.py b/lib/query.py index 3ab47f17..76b2cae7 100644 --- a/lib/query.py +++ b/lib/query.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/sapi.py b/lib/sapi.py index 7344d6a3..585f3ca0 100644 --- a/lib/sapi.py +++ b/lib/sapi.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vcauth/__init__.py b/lib/vcauth/__init__.py index f6dc2608..2f78571f 100644 --- a/lib/vcauth/__init__.py +++ b/lib/vcauth/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2006-2013 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 diff --git a/lib/vcauth/forbidden/__init__.py b/lib/vcauth/forbidden/__init__.py index c92cd5fe..46b52f7a 100644 --- a/lib/vcauth/forbidden/__init__.py +++ b/lib/vcauth/forbidden/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2006-2013 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 diff --git a/lib/vcauth/forbiddenre/__init__.py b/lib/vcauth/forbiddenre/__init__.py index 1bbaf171..a50d37d5 100644 --- a/lib/vcauth/forbiddenre/__init__.py +++ b/lib/vcauth/forbiddenre/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 2008-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2008-2013 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 diff --git a/lib/vcauth/svnauthz/__init__.py b/lib/vcauth/svnauthz/__init__.py index ab9a7079..7c7bceba 100644 --- a/lib/vcauth/svnauthz/__init__.py +++ b/lib/vcauth/svnauthz/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 2006-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2006-2013 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 diff --git a/lib/vclib/__init__.py b/lib/vclib/__init__.py index 4783bbb7..34b53422 100644 --- a/lib/vclib/__init__.py +++ b/lib/vclib/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/ccvs/__init__.py b/lib/vclib/ccvs/__init__.py index e6d2bad0..e3c03159 100644 --- a/lib/vclib/ccvs/__init__.py +++ b/lib/vclib/ccvs/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/ccvs/bincvs.py b/lib/vclib/ccvs/bincvs.py index 8472b52a..281f6561 100644 --- a/lib/vclib/ccvs/bincvs.py +++ b/lib/vclib/ccvs/bincvs.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/ccvs/blame.py b/lib/vclib/ccvs/blame.py index 007395e1..f1adae37 100644 --- a/lib/vclib/ccvs/blame.py +++ b/lib/vclib/ccvs/blame.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/ccvs/ccvs.py b/lib/vclib/ccvs/ccvs.py index 2201eeed..292999cc 100644 --- a/lib/vclib/ccvs/ccvs.py +++ b/lib/vclib/ccvs/ccvs.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/ccvs/rcsparse/__init__.py b/lib/vclib/ccvs/rcsparse/__init__.py index 67f28b7c..10fe244c 100644 --- a/lib/vclib/ccvs/rcsparse/__init__.py +++ b/lib/vclib/ccvs/rcsparse/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/ccvs/rcsparse/common.py b/lib/vclib/ccvs/rcsparse/common.py index 5baf9a69..4df15e5a 100644 --- a/lib/vclib/ccvs/rcsparse/common.py +++ b/lib/vclib/ccvs/rcsparse/common.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/ccvs/rcsparse/debug.py b/lib/vclib/ccvs/rcsparse/debug.py index baf93659..f3687e28 100644 --- a/lib/vclib/ccvs/rcsparse/debug.py +++ b/lib/vclib/ccvs/rcsparse/debug.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/ccvs/rcsparse/default.py b/lib/vclib/ccvs/rcsparse/default.py index e65c34a0..942aab59 100644 --- a/lib/vclib/ccvs/rcsparse/default.py +++ b/lib/vclib/ccvs/rcsparse/default.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/ccvs/rcsparse/texttools.py b/lib/vclib/ccvs/rcsparse/texttools.py index da7ce396..65c4b167 100644 --- a/lib/vclib/ccvs/rcsparse/texttools.py +++ b/lib/vclib/ccvs/rcsparse/texttools.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/svn/__init__.py b/lib/vclib/svn/__init__.py index 4d044b45..862b548e 100644 --- a/lib/vclib/svn/__init__.py +++ b/lib/vclib/svn/__init__.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/svn/svn_ra.py b/lib/vclib/svn/svn_ra.py index a2662683..bd7a57c1 100644 --- a/lib/vclib/svn/svn_ra.py +++ b/lib/vclib/svn/svn_ra.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/vclib/svn/svn_repos.py b/lib/vclib/svn/svn_repos.py index 628fb1e9..189c83f6 100644 --- a/lib/vclib/svn/svn_repos.py +++ b/lib/vclib/svn/svn_repos.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/viewvc.py b/lib/viewvc.py index 6eff03bd..cbd5b700 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/lib/win32popen.py b/lib/win32popen.py index 16f7948b..f210008e 100644 --- a/lib/win32popen.py +++ b/lib/win32popen.py @@ -1,6 +1,6 @@ # -*-python-*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/misc/tparse/tparse.cpp b/misc/tparse/tparse.cpp index c9366379..2bb08220 100644 --- a/misc/tparse/tparse.cpp +++ b/misc/tparse/tparse.cpp @@ -1,5 +1,5 @@ /* -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/misc/tparse/tparse.h b/misc/tparse/tparse.h index 53d3011a..a98a90cc 100644 --- a/misc/tparse/tparse.h +++ b/misc/tparse/tparse.h @@ -1,5 +1,5 @@ /* -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/misc/tparse/tparsemodule.cpp b/misc/tparse/tparsemodule.cpp index edc74245..8bc28755 100644 --- a/misc/tparse/tparsemodule.cpp +++ b/misc/tparse/tparsemodule.cpp @@ -1,5 +1,5 @@ /* -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/misc/tparse/tparsemodule.h b/misc/tparse/tparsemodule.h index a4cd8c27..8236610a 100644 --- a/misc/tparse/tparsemodule.h +++ b/misc/tparse/tparsemodule.h @@ -1,5 +1,5 @@ /* -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/tools/bump-copyright-years b/tools/bump-copyright-years index 87864e63..895d1584 100755 --- a/tools/bump-copyright-years +++ b/tools/bump-copyright-years @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (C) 2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 2012-2013 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 diff --git a/tools/make-release b/tools/make-release index 942a73ac..a3029f34 100755 --- a/tools/make-release +++ b/tools/make-release @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 diff --git a/viewvc-install b/viewvc-install index ab75d7a9..6af30c68 100755 --- a/viewvc-install +++ b/viewvc-install @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- Mode: python -*- # -# Copyright (C) 1999-2012 The ViewCVS Group. All Rights Reserved. +# Copyright (C) 1999-2013 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 From bb4a748eda7dc79f7a9ff010aa510fc8549b62dc Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Tue, 29 Jan 2013 15:57:57 +0000 Subject: [PATCH 311/353] Fix issue #519 ("Stack trace while accessing a BDB repository if last commit deleted a file or directory"). * lib/vclib/svn/svn_repos.py (_get_change_copyinfo): Only call svn_fs_copied_from() on "add" and "replace" change items (which might actually be copies). This avoids raising an exception caused by running svn_fs_copied_from() on a missing (via deletion) root/path pair. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2827 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/svn/svn_repos.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/vclib/svn/svn_repos.py b/lib/vclib/svn/svn_repos.py index 189c83f6..1b604fb1 100644 --- a/lib/vclib/svn/svn_repos.py +++ b/lib/vclib/svn/svn_repos.py @@ -644,11 +644,19 @@ class LocalSubversionRepository(vclib.Repository): return found_readable, found_unreadable, changedpaths.values() def _get_change_copyinfo(fsroot, path, change): + # If we know the copyfrom info, return it... if hasattr(change, 'copyfrom_known') and change.copyfrom_known: copyfrom_path = change.copyfrom_path copyfrom_rev = change.copyfrom_rev - else: + # ...otherwise, if this change could be a copy (that is, it + # contains an add action), query the copyfrom info ... + elif (change.change_kind == fs.path_change_add or + change.change_kind == fs.path_change_replace): copyfrom_rev, copyfrom_path = fs.copied_from(fsroot, path) + # ...else, there's no copyfrom info. + else: + copyfrom_rev = core.SVN_INVALID_REVNUM + copyfrom_path = None return copyfrom_path, copyfrom_rev def _simple_auth_check(fsroot): From 281ed5ca840521da109894df8db76b5687543b45 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 31 Jan 2013 19:49:49 +0000 Subject: [PATCH 312/353] Correct a royally botched CHANGES entry. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2830 8cb11bc2-c004-0410-86c3-e597b4017df7 --- CHANGES | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 94c238df..6bd05564 100644 --- a/CHANGES +++ b/CHANGES @@ -31,7 +31,7 @@ Version 1.1.14 (released 12-Jun-2012) * 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) + * add support for custom revision log markup rules (issue #246) Version 1.1.13 (released 23-Jan-2012) From 572554fa897844b6fe5596d05ec9c1a53c70d1c7 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Fri, 22 Feb 2013 16:34:10 +0000 Subject: [PATCH 313/353] * lib/viewvc.py (markup_stream): Strip EOL characters from the ends of marked-up lines. Templates can re-add line breaks, but they can't easily strip them. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2832 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index cbd5b700..f410cc9d 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1725,7 +1725,7 @@ def markup_stream(request, cfg, blame_data, file_lines, filename, if not pygments_lexer: lines = [] for i in range(len(file_lines)): - line = file_lines[i] + line = file_lines[i].rstrip('\n\r') line = sapi.escape(line.expandtabs(cfg.options.tabsize)) line = markup_escaped_urls(line) if blame_data: @@ -1749,7 +1749,7 @@ def markup_stream(request, cfg, blame_data, file_lines, filename, self.line_no = 0 def write(self, buf): ### FIXME: Don't bank on write() being called once per line - buf = markup_escaped_urls(buf) + buf = markup_escaped_urls(buf.rstrip('\n\r')) if self.has_blame_data: self.blame_data[self.line_no].text = buf else: From 3d3f677b3ced5ac5ec23da85c4c9afbfcf68cc39 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Fri, 22 Feb 2013 16:44:51 +0000 Subject: [PATCH 314/353] * templates/default/file.ezt Reduce a bit of redundancy. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2834 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/file.ezt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/templates/default/file.ezt b/templates/default/file.ezt index 1b5f6ba2..c9c1b27c 100644 --- a/templates/default/file.ezt +++ b/templates/default/file.ezt @@ -121,15 +121,12 @@ <div id="vc_file"> <table cellspacing="0" cellpadding="0"> <tr> -[is annotation "annotated"] <th class="vc_header">#</th> +[is annotation "annotated"] <th class="vc_header">User</th> <th class="vc_header">Rev</th> -<th class="vc_header">Content</th> -[else] -<th class="vc_header">#</th> -<th class="vc_header">Content</th> [end] +<th class="vc_header">Content</th> </tr> [for lines] [is lines.rev last_rev] From bbe8b428771fd3d6dba6176a7f17f783585e8771 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Fri, 22 Feb 2013 16:48:33 +0000 Subject: [PATCH 315/353] * templates/default/docroot/styles.css Highlight file content lines in yellow when hovered over. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2835 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/docroot/styles.css | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/templates/default/docroot/styles.css b/templates/default/docroot/styles.css index e4371bbd..f9f153a6 100644 --- a/templates/default/docroot/styles.css +++ b/templates/default/docroot/styles.css @@ -166,6 +166,9 @@ address { font-style: normal; display: inline; } .vc_row_odd { background-color: rgb(90%,90%,90%); } +.vc_row_odd:hover, .vc_row_even:hover { + background-color: yellow !important; +} /*** Directory View ***/ @@ -253,6 +256,9 @@ address { font-style: normal; display: inline; } white-space: pre; width: 100%; } +tr:hover .vc_file_line_text { + background-color: yellow; +} .pygments-c { color: #408080; font-style: italic } /* Comment */ .pygments-err { border: 1px solid #FF0000 } /* Error */ .pygments-k { color: #008000; font-weight: bold } /* Keyword */ From 41858c6f8933f9c281d27760807e247b732f08bc Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Fri, 22 Feb 2013 16:56:26 +0000 Subject: [PATCH 316/353] * templates/default/docroot/styles.css Follow up to r2835, removing an unnecessary "!important" CSS declaration. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2836 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/docroot/styles.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/default/docroot/styles.css b/templates/default/docroot/styles.css index f9f153a6..ba10dacd 100644 --- a/templates/default/docroot/styles.css +++ b/templates/default/docroot/styles.css @@ -167,7 +167,7 @@ address { font-style: normal; display: inline; } background-color: rgb(90%,90%,90%); } .vc_row_odd:hover, .vc_row_even:hover { - background-color: yellow !important; + background-color: yellow; } From 07ac7f5e542f4f2d1231cd823e4e0336550fa5db Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 25 Feb 2013 20:01:45 +0000 Subject: [PATCH 317/353] Mark busted ,v files with no revisions as "absent" in the rcsparse- driven CVS backend, fixing an inconsistency between rcsparse-based and binary-based parsing. * lib/vclib/ccvs/ccvs.py (InfoSink.__init__): Init new 'saw_revision' flag. (InfoSink.define_revision): Set 'saw_revision'. (InfoSink.parse_completed): If 'saw_revision' is not set, set the 'absent' flag. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2837 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/ccvs/ccvs.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/vclib/ccvs/ccvs.py b/lib/vclib/ccvs/ccvs.py index 292999cc..073248c3 100644 --- a/lib/vclib/ccvs/ccvs.py +++ b/lib/vclib/ccvs/ccvs.py @@ -195,6 +195,7 @@ class InfoSink(MatchingSink): self.matching_rev = None self.perfect_match = 0 self.lockinfo = { } + self.saw_revision = False def define_tag(self, name, revision): MatchingSink.define_tag(self, name, revision) @@ -208,10 +209,17 @@ class InfoSink(MatchingSink): self.entry.absent = 1 raise rcsparse.RCSStopParser + def parse_completed(self): + if not self.saw_revision: + #self.entry.errors.append("No revisions exist on %s" % (view_tag or "MAIN")) + self.entry.absent = 1 + def set_locker(self, rev, locker): self.lockinfo[rev] = locker def define_revision(self, revision, date, author, state, branches, next): + self.saw_revision = True + if self.perfect_match: return From 3edd7de4d1e3f7af4f3f865f1d5c3713ed8b43f3 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 25 Feb 2013 20:35:56 +0000 Subject: [PATCH 318/353] Fix issue #347 ("ccvs module handling of "dead" files doesn't jive with that of bincvs logic"). * lib/vclib/ccvs/ccvs.py (InfoSink.define_revision): Tweak the revision matching logic a bit to include branch points as valid revisions when examining branch tags. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2839 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/ccvs/ccvs.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lib/vclib/ccvs/ccvs.py b/lib/vclib/ccvs/ccvs.py index 073248c3..0c19c59d 100644 --- a/lib/vclib/ccvs/ccvs.py +++ b/lib/vclib/ccvs/ccvs.py @@ -227,14 +227,18 @@ class InfoSink(MatchingSink): rev = Revision(revision, date, author, state == "dead") rev.lockinfo = self.lockinfo.get(revision) - # perfect match if revision number matches tag number or if revision is on - # trunk and tag points to trunk. imperfect match if tag refers to a branch - # and this revision is the highest revision so far found on that branch + # perfect match if revision number matches tag number or if + # revision is on trunk and tag points to trunk. imperfect match + # if tag refers to a branch and either a) this revision is the + # highest revision so far found on that branch, or b) this + # revision is the branchpoint. perfect = ((rev.number == tag.number) or (not tag.number and len(rev.number) == 2)) - if perfect or (tag.is_branch and tag.number == rev.number[:-1] and - (not self.matching_rev or - rev.number > self.matching_rev.number)): + if perfect or (tag.is_branch and \ + ((tag.number == rev.number[:-1] and + (not self.matching_rev or + rev.number > self.matching_rev.number)) or + (rev.number == tag.number[:-1]))): self.matching_rev = rev self.perfect_match = perfect From 9b57e7d6a6f0129ab8d10857c148b39a598048a1 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 25 Feb 2013 20:51:01 +0000 Subject: [PATCH 319/353] Fix issue #521 ("make-database does not allow the database port to be specified"). * bin/make-database (__main__): Add a --port option and handling thereof, passing the value off to 'mysql'. Patch by: Grant Bremer <gbremer{__AT__}tigris.org> git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2841 8cb11bc2-c004-0410-86c3-e597b4017df7 --- bin/make-database | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bin/make-database b/bin/make-database index d845eb65..524eb147 100755 --- a/bin/make-database +++ b/bin/make-database @@ -256,6 +256,9 @@ Options: --hostname=ARG Use ARG as the hostname for the MySQL connection. [Default: localhost] + --port=ARG Use ARG as the port for the MySQL connection. + [Default: 3306] + --password=ARG Use ARG as the password for the MySQL connection. --username=ARG Use ARG as the username for the MySQL connection. @@ -274,10 +277,11 @@ Options: if __name__ == "__main__": try: # Parse the command-line options, if any. - dbname = version = hostname = username = password = None + dbname = version = hostname = port = username = password = None opts, args = getopt.getopt(sys.argv[1:], '', [ 'dbname=', 'help', 'hostname=', + 'port=', 'password=', 'username=', 'version=', @@ -291,6 +295,8 @@ if __name__ == "__main__": dbname = value elif name == '--hostname': hostname = value + elif name == '--port': + port = value elif name == '--username': username = value elif name == '--password': @@ -304,6 +310,8 @@ if __name__ == "__main__": # Prompt for information not provided via command-line options. if hostname is None: hostname = raw_input("MySQL Hostname [default: localhost]: ") or "" + if port is None: + port = raw_input("MySQL Port [default: 3306]: ") or "" if username is None: username = raw_input("MySQL User: ") if password is None: @@ -320,6 +328,7 @@ if __name__ == "__main__": dscript = dscript + DATABASE_SCRIPT_VERSION_1 host_option = hostname and "--host=%s" % (hostname) or "" + host_option = port and (host_option + " --port=%s") % (port) or host_option if sys.platform == "win32": cmd = "mysql --user=%s --password=%s %s "\ % (username, password, host_option) From 8854a7304049aee4e2c961ee9c1e4d97870830ab Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Tue, 26 Feb 2013 16:15:35 +0000 Subject: [PATCH 320/353] * bin/make-database Use "ENGINE=MyISAM" rather than "TYPE=MyISAM" throughout. The latter syntax was deprecated in MySQL 5.0 and dropped in 5.5. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2842 8cb11bc2-c004-0410-86c3-e597b4017df7 --- bin/make-database | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/bin/make-database b/bin/make-database index 524eb147..5b36ad08 100755 --- a/bin/make-database +++ b/bin/make-database @@ -41,7 +41,7 @@ CREATE TABLE branches ( branch varchar(64) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE branch (branch) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS checkins; CREATE TABLE checkins ( @@ -64,7 +64,7 @@ CREATE TABLE checkins ( KEY dirid (dirid), KEY fileid (fileid), KEY branchid (branchid) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS descs; CREATE TABLE descs ( @@ -73,7 +73,7 @@ CREATE TABLE descs ( hash bigint(20) DEFAULT '0' NOT NULL, PRIMARY KEY (id), KEY hash (hash) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS dirs; CREATE TABLE dirs ( @@ -81,7 +81,7 @@ CREATE TABLE dirs ( dir varchar(255) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE dir (dir) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS files; CREATE TABLE files ( @@ -89,7 +89,7 @@ CREATE TABLE files ( file varchar(255) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE file (file) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS people; CREATE TABLE people ( @@ -97,7 +97,7 @@ CREATE TABLE people ( who varchar(128) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE who (who) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS repositories; CREATE TABLE repositories ( @@ -105,7 +105,7 @@ CREATE TABLE repositories ( repository varchar(64) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE repository (repository) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS tags; CREATE TABLE tags ( @@ -119,7 +119,7 @@ CREATE TABLE tags ( KEY dirid (dirid), KEY fileid (fileid), KEY branchid (branchid) -) TYPE=MyISAM; +) ENGINE=MyISAM; """ ## ------------------------------------------------------------------------ @@ -133,7 +133,7 @@ CREATE TABLE branches ( branch varchar(64) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE branch (branch) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS commits; CREATE TABLE commits ( @@ -157,7 +157,7 @@ CREATE TABLE commits ( KEY fileid (fileid), KEY branchid (branchid), KEY descid (descid) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS descs; CREATE TABLE descs ( @@ -166,7 +166,7 @@ CREATE TABLE descs ( hash bigint(20) DEFAULT '0' NOT NULL, PRIMARY KEY (id), KEY hash (hash) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS dirs; CREATE TABLE dirs ( @@ -174,7 +174,7 @@ CREATE TABLE dirs ( dir varchar(255) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE dir (dir) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS files; CREATE TABLE files ( @@ -182,7 +182,7 @@ CREATE TABLE files ( file varchar(255) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE file (file) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS people; CREATE TABLE people ( @@ -190,7 +190,7 @@ CREATE TABLE people ( who varchar(128) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE who (who) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS repositories; CREATE TABLE repositories ( @@ -198,7 +198,7 @@ CREATE TABLE repositories ( repository varchar(64) binary DEFAULT '' NOT NULL, PRIMARY KEY (id), UNIQUE repository (repository) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS tags; CREATE TABLE tags ( @@ -212,7 +212,7 @@ CREATE TABLE tags ( KEY dirid (dirid), KEY fileid (fileid), KEY branchid (branchid) -) TYPE=MyISAM; +) ENGINE=MyISAM; DROP TABLE IF EXISTS metadata; CREATE TABLE metadata ( @@ -220,7 +220,7 @@ CREATE TABLE metadata ( value text, PRIMARY KEY (name), UNIQUE name (name) -) TYPE=MyISAM; +) ENGINE=MyISAM; INSERT INTO metadata (name, value) VALUES ('version', '1'); """ From b8a7f32fb429bf417a759113468339bc18ff5054 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Tue, 26 Feb 2013 16:43:12 +0000 Subject: [PATCH 321/353] When querying the commits database, explicitly name columns in case someone has a modified/customized database with additional or reordered columns. * lib/cvsdb.py (CheckinDatabase.CheckCommit, CheckinDatabase.PurgeRepository): Name columns in SELECT statement rather than using '*'. Patch by: Grant Bremer <gbremer{__AT__}tigris.org> (Tweaked by me.) git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2843 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/cvsdb.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/cvsdb.py b/lib/cvsdb.py index 1903cb01..4028cf47 100644 --- a/lib/cvsdb.py +++ b/lib/cvsdb.py @@ -519,7 +519,10 @@ class CheckinDatabase: if file_id == None: return None - sql = "SELECT * FROM %s WHERE "\ + sql = "SELECT type, ci_when, whoid, repositoryid, dirid, fileid, " \ + "revision, stickytag, branchid, addedlines, removedlines, " \ + "descid "\ + " FROM %s WHERE "\ " repositoryid=%%s "\ " AND dirid=%%s"\ " AND fileid=%%s"\ @@ -569,7 +572,10 @@ class CheckinDatabase: self.sql_purge('descs', 'id', 'descid', 'commits') self.sql_purge('people', 'id', 'whoid', 'commits') else: - sql = "SELECT * FROM checkins WHERE repositoryid=%s" + sql = "SELECT type, ci_when, whoid, repositoryid, dirid, " \ + "fileid, revision, stickytag, branchid, addedlines, " \ + "removedlines, descid "\ + " FROM checkins WHERE repositoryid=%s" sql_args = (rep_id, ) cursor = self.db.cursor() cursor.execute(sql, sql_args) From 63563517d730e5d8f0fd00298fd787863dc2ed75 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Tue, 26 Feb 2013 16:51:03 +0000 Subject: [PATCH 322/353] * bin/make-database Be less sloppy about what this script reports as default behavior around hostnames and ports. If a hostname isn't supplied, "localhost" isn't strictly passed to 'mysql'; same for the port. And on UNIX, the lack of an explicit hostname (or an explicit "localhost" one) will cause 'mysql' to use a UNIX socket rather than a TCP/IP one, regardless of what the provided port is. So it's not strictly accurate to imply that by not providing a hostname and port, 'make-database' will use "localhost/3306" for that information. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2844 8cb11bc2-c004-0410-86c3-e597b4017df7 --- bin/make-database | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/bin/make-database b/bin/make-database index 5b36ad08..bdd9c492 100755 --- a/bin/make-database +++ b/bin/make-database @@ -246,6 +246,10 @@ options.) This script will use the 'mysql' program to create the database for you. You will then need to set the appropriate parameters in the [cvsdb] section of your viewvc.conf file. +NOTE: If a hostname or port is supplied at the command line or during +interactive prompting, this script will pass '--protocol=TCP' to +'mysql'. + Options: --dbname=ARG Use ARG as the ViewVC database name to create. @@ -254,10 +258,8 @@ Options: --help Show this usage message. --hostname=ARG Use ARG as the hostname for the MySQL connection. - [Default: localhost] --port=ARG Use ARG as the port for the MySQL connection. - [Default: 3306] --password=ARG Use ARG as the password for the MySQL connection. @@ -309,9 +311,9 @@ if __name__ == "__main__": # Prompt for information not provided via command-line options. if hostname is None: - hostname = raw_input("MySQL Hostname [default: localhost]: ") or "" + hostname = raw_input("MySQL Hostname (leave blank for default): ") if port is None: - port = raw_input("MySQL Port [default: 3306]: ") or "" + port = raw_input("MySQL Port (leave blank for default): ") if username is None: username = raw_input("MySQL User: ") if password is None: @@ -319,7 +321,7 @@ if __name__ == "__main__": if dbname is None: dbname = raw_input("ViewVC Database Name [default: ViewVC]: ") or "ViewVC" - # Create the database + # Create the database. dscript = DATABASE_SCRIPT_COMMON.replace("<dbname>", dbname) if version == "1.0": print BONSAI_COMPAT @@ -327,17 +329,22 @@ if __name__ == "__main__": else: dscript = dscript + DATABASE_SCRIPT_VERSION_1 - host_option = hostname and "--host=%s" % (hostname) or "" - host_option = port and (host_option + " --port=%s") % (port) or host_option + # Calculate command arguments. + cmd_args = "--user=%s --password=%s" % (username, password) + if hostname or port: + cmd_args = cmd_args + " --protocol=TCP" + if hostname: + cmd_args = cmd_args + " --host=%s" % (hostname) + if port: + cmd_args = cmd_args + " --port=%s" % (port) + if sys.platform == "win32": - cmd = "mysql --user=%s --password=%s %s "\ - % (username, password, host_option) + cmd = "mysql %s" % (cmd_args) mysql = os.popen(cmd, "w") # popen2.Popen3 is not provided on windows mysql.write(dscript) status = mysql.close() else: - cmd = "{ mysql --user=%s --password=%s %s ; } 2>&1" \ - % (username, password, host_option) + cmd = "{ mysql %s ; } 2>&1" % (cmd_args) pipes = popen2.Popen3(cmd) pipes.tochild.write(dscript) pipes.tochild.close() From 345e7ceb8d0330817c9a67aba595ad719559c616 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 28 Feb 2013 19:26:50 +0000 Subject: [PATCH 323/353] Bump the advertised latest release. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2849 8cb11bc2-c004-0410-86c3-e597b4017df7 --- www/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/index.html b/www/index.html index f31a80c2..4e0802e8 100644 --- a/www/index.html +++ b/www/index.html @@ -30,13 +30,13 @@ <h2>Latest Release(s)</h2> -<p>The most recent stable release of ViewVC is: <strong>1.1.17</strong></p> +<p>The most recent stable release of ViewVC is: <strong>1.1.18</strong></p> <ul> <li><a href="http://www.viewvc.org/download.html" >Download or checkout</a> this release</li> <li>See the - <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.17/CHANGES" + <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.18/CHANGES" >CHANGES</a> in this release.</li> <li>Read the <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/trunk/docs/release-notes/1.1.0.html" From 33eeb417639ef3fef8332ee5cd9c48abbea5af16 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 28 Feb 2013 19:34:22 +0000 Subject: [PATCH 324/353] * CHANGES: Merge in 1.1.18's changes. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2851 8cb11bc2-c004-0410-86c3-e597b4017df7 --- CHANGES | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGES b/CHANGES index 6bd05564..c05784aa 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,16 @@ Version 1.2.0 (released ??-???-????) * allow user-configurable cvsgraph display (issue #336) * allow rNNNN syntax for Subversion revision numbers (issue #441) +Version 1.1.18 (released 28-Feb-2013) + + * fix exception raised by BDB-backed SVN repositories (issue #519) + * hide revision-less files when rcsparse is in use + * include branchpoints in branch views using rcsparse (issue #347) + * miscellaneous cvsdb improvements: + - add --port option to make-database (issue #521) + - explicitly name columns in queries (issue #522) + - update MySQL syntax to avoid discontinued "TYPE=" terms + Version 1.1.17 (released 25-Oct-2012) * fix exception caused by uninitialized variable usage (issue #516) From 819915112edb59dd30146c56184d00eccd28a47f Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Fri, 1 Mar 2013 15:52:29 +0000 Subject: [PATCH 325/353] * templates/default/docroot/styles.css Revert r2835. Not liking the yellow. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2852 8cb11bc2-c004-0410-86c3-e597b4017df7 --- templates/default/docroot/styles.css | 6 ------ 1 file changed, 6 deletions(-) diff --git a/templates/default/docroot/styles.css b/templates/default/docroot/styles.css index ba10dacd..e4371bbd 100644 --- a/templates/default/docroot/styles.css +++ b/templates/default/docroot/styles.css @@ -166,9 +166,6 @@ address { font-style: normal; display: inline; } .vc_row_odd { background-color: rgb(90%,90%,90%); } -.vc_row_odd:hover, .vc_row_even:hover { - background-color: yellow; -} /*** Directory View ***/ @@ -256,9 +253,6 @@ address { font-style: normal; display: inline; } white-space: pre; width: 100%; } -tr:hover .vc_file_line_text { - background-color: yellow; -} .pygments-c { color: #408080; font-style: italic } /* Comment */ .pygments-err { border: 1px solid #FF0000 } /* Error */ .pygments-k { color: #008000; font-weight: bold } /* Keyword */ From eaeb5278028bf570353a8dcf5099b21c239e1e65 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 4 Mar 2013 16:51:38 +0000 Subject: [PATCH 326/353] * lib/viewvc.py Fix spelling error ('typefrag' should be 'typeflag') throughout. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2853 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index f410cc9d..d30c2127 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3740,7 +3740,7 @@ def view_diff(request): def generate_tarball_header(out, name, size=0, mode=None, mtime=0, - uid=0, gid=0, typefrag=None, linkname='', + uid=0, gid=0, typeflag=None, linkname='', uname='viewvc', gname='viewvc', devmajor=1, devminor=0, prefix=None, magic='ustar', version='00', chksum=None): @@ -3750,11 +3750,11 @@ def generate_tarball_header(out, name, size=0, mode=None, mtime=0, else: mode = 0644 - if not typefrag: + if not typeflag: if name[-1:] == '/': - typefrag = '5' # directory + typeflag = '5' # directory else: - typefrag = '0' # regular file + typeflag = '0' # regular file if not prefix: prefix = '' @@ -3775,7 +3775,7 @@ def generate_tarball_header(out, name, size=0, mode=None, mtime=0, '%011o' % mtime) block2 = struct.pack('c 100s 6s 2s 32s 32s 8s 8s 155s', - typefrag, + typeflag, linkname, magic, version, From 701ba244547dd900a2f7905364010608666afe56 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 4 Mar 2013 16:52:19 +0000 Subject: [PATCH 327/353] * lib/viewvc.py (generate_tarball_header): Indentation fixes only. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2854 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index d30c2127..4d8ba6a8 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3767,23 +3767,23 @@ def generate_tarball_header(out, name, size=0, mode=None, mtime=0, out.write('\0' * (511 - ((len(name) + 511) % 512))) block1 = struct.pack('100s 8s 8s 8s 12s 12s', - name, - '%07o' % mode, - '%07o' % uid, - '%07o' % gid, - '%011o' % size, - '%011o' % mtime) + name, + '%07o' % mode, + '%07o' % uid, + '%07o' % gid, + '%011o' % size, + '%011o' % mtime) block2 = struct.pack('c 100s 6s 2s 32s 32s 8s 8s 155s', - typeflag, - linkname, - magic, - version, - uname, - gname, - '%07o' % devmajor, - '%07o' % devminor, - prefix) + typeflag, + linkname, + magic, + version, + uname, + gname, + '%07o' % devmajor, + '%07o' % devminor, + prefix) if not chksum: dummy_chksum = ' ' From ab923539dd11e83eb88d4ac1b4982428d1c67160 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 4 Mar 2013 19:37:31 +0000 Subject: [PATCH 328/353] Finish issue #487 ("Preserve Subversion symlinks in generated tarballs") for local Subversion repositories. * lib/vclib/svn/svn_repos.py (LocalSubversionRepository.get_symlink_target): New function. * lib/viewvc.py (generate_tarball_header): Add the ability to generate private headers for long symlink names, too. (generate_tarball): Use the Repository object's get_symlink_target() function (if available) to determine whether a versioned object is a symlink, and use that information to preserve symlinks in generated tarballs. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2855 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/svn/svn_repos.py | 29 ++++++++++++++++++++++ lib/viewvc.py | 51 ++++++++++++++++++++++++++++---------- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/lib/vclib/svn/svn_repos.py b/lib/vclib/svn/svn_repos.py index 1b604fb1..919a0d5a 100644 --- a/lib/vclib/svn/svn_repos.py +++ b/lib/vclib/svn/svn_repos.py @@ -923,3 +923,32 @@ class LocalSubversionRepository(vclib.Repository): return peg_revision, path finally: pass + + def get_symlink_target(self, path_parts, rev): + """Return the target of the symbolic link versioned at PATH_PARTS + in REV, or None if that object is not a symlink.""" + + path = self._getpath(path_parts) + rev = self._getrev(rev) + path_type = self.itemtype(path_parts, rev) # does auth-check + fsroot = self._getroot(rev) + + # Symlinks must be files with the svn:special property set on them + # and with file contents which read "link SOME_PATH". + if path_type != vclib.FILE: + return None + props = fs.node_proplist(fsroot, path) + if not props.has_key(core.SVN_PROP_SPECIAL): + return None + pathspec = '' + ### FIXME: We're being a touch sloppy here, only checking the first line + ### of the file. + stream = fs.file_contents(fsroot, path) + try: + pathspec, eof = core.svn_stream_readline(stream, '\n') + finally: + core.svn_stream_close(stream) + if pathspec[:5] != 'link ': + return None + return pathspec[5:] + diff --git a/lib/viewvc.py b/lib/viewvc.py index 4d8ba6a8..ccf9d95e 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3751,7 +3751,9 @@ def generate_tarball_header(out, name, size=0, mode=None, mtime=0, mode = 0644 if not typeflag: - if name[-1:] == '/': + if linkname: + typeflag = '2' # symbolic link + elif name[-1:] == '/': typeflag = '5' # directory else: typeflag = '0' # regular file @@ -3759,13 +3761,20 @@ def generate_tarball_header(out, name, size=0, mode=None, mtime=0, if not prefix: prefix = '' - # generate a GNU tar extension header for long names. + # generate a GNU tar extension header for a long name. if len(name) >= 100: generate_tarball_header(out, '././@LongLink', len(name), - 0644, 0, 0, 0, 'L') + 0, 0, 0, 0, 'L') out.write(name) out.write('\0' * (511 - ((len(name) + 511) % 512))) + # generate a GNU tar extension header for a long symlink name. + if len(linkname) >= 100: + generate_tarball_header(out, '././@LongLink', len(linkname), + 0, 0, 0, 0, 'K') + out.write(linkname) + out.write('\0' * (511 - ((len(linkname) + 511) % 512))) + block1 = struct.pack('100s 8s 8s 8s 12s 12s', name, '%07o' % mode, @@ -3861,17 +3870,33 @@ def generate_tarball(out, request, reldir, stack, dir_mtime=None): else: mode = 0644 - ### FIXME: Read the whole file into memory? Bad... better to do - ### 2 passes. - fp = request.repos.openfile(rep_path + [file.name], request.pathrev, {})[0] - contents = fp.read() - fp.close() + # Is this thing a symlink? + # + ### FIXME: A better solution would be to have vclib returning + ### symlinks with a new vclib.SYMLINK path type. + symlink_target = None + if hasattr(request.repos, 'get_symlink_target'): + symlink_target = request.repos.get_symlink_target(rep_path + [file.name], + request.pathrev) - generate_tarball_header(out, tar_dir + file.name, - len(contents), mode, - file.date is not None and file.date or 0) - out.write(contents) - out.write('\0' * (511 - ((len(contents) + 511) % 512))) + # If the object is a symlink, generate the appropriate header. + # Otherwise, we're dealing with a regular file. + if symlink_target: + generate_tarball_header(out, tar_dir + file.name, 0, mode, + file.date is not None and file.date or 0, + typeflag='2', linkname=symlink_target) + else: + ### FIXME: Read the whole file into memory? Bad... better to do + ### 2 passes. + fp = request.repos.openfile(rep_path + [file.name], request.pathrev, {})[0] + contents = fp.read() + fp.close() + + generate_tarball_header(out, tar_dir + file.name, + len(contents), mode, + file.date is not None and file.date or 0) + out.write(contents) + out.write('\0' * (511 - ((len(contents) + 511) % 512))) # Recurse into subdirectories, skipping busted and unauthorized (or # configured-to-be-hidden) ones. From 388c55e564f0f11f5666b803570da792e27fd064 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 4 Mar 2013 19:57:35 +0000 Subject: [PATCH 329/353] * lib/vclib/svn/svn_ra.py (cat_to_tempfile): Renamed from temp_checkout(). Callers updated. (RemoteSubversionRepository.openfile): Use cat_to_tempfile() now, and try to head off a race condition that could leave tempfiles lying about. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2857 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/svn/svn_ra.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/vclib/svn/svn_ra.py b/lib/vclib/svn/svn_ra.py index bd7a57c1..071633aa 100644 --- a/lib/vclib/svn/svn_ra.py +++ b/lib/vclib/svn/svn_ra.py @@ -131,7 +131,7 @@ class LogCollector: if this_path: self.path = this_path -def temp_checkout(svnrepos, path, rev): +def cat_to_tempfile(svnrepos, path, rev): """Check out file revision to temporary file""" temp = tempfile.mktemp() stream = core.svn_stream_from_aprfile(temp) @@ -258,13 +258,10 @@ class RemoteSubversionRepository(vclib.Repository): raise vclib.Error("Path '%s' is not a file." % path) rev = self._getrev(rev) url = self._geturl(path) - tmp_file = tempfile.mktemp() - stream = core.svn_stream_from_aprfile(tmp_file) ### rev here should be the last history revision of the URL - client.svn_client_cat(core.Stream(stream), url, _rev2optrev(rev), self.ctx) - core.svn_stream_close(stream) + fp = SelfCleanFP(cat_to_tempfile(self, path, rev)) lh_rev, c_rev = self._get_last_history_rev(path_parts, rev) - return SelfCleanFP(tmp_file), lh_rev + return fp, lh_rev def listdir(self, path_parts, rev, options): path = self._getpath(path_parts) @@ -441,8 +438,8 @@ class RemoteSubversionRepository(vclib.Repository): return date try: - temp1 = temp_checkout(self, p1, r1) - temp2 = temp_checkout(self, p2, r2) + temp1 = cat_to_tempfile(self, p1, r1) + temp2 = cat_to_tempfile(self, p2, r2) info1 = p1, _date_from_rev(r1), r1 info2 = p2, _date_from_rev(r2), r2 return vclib._diff_fp(temp1, temp2, info1, info2, self.diff_cmd, args) From af996b9b49122f84a66477881096aebb0bc2d272 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 4 Mar 2013 20:23:09 +0000 Subject: [PATCH 330/353] Finish issue #487 ("Preserve Subversion symlinks in generated tarballs") for remote Subversion repositories, too. * lib/vclib/svn/svn_ra.py (RemoteSubversionRepository.get_symlink_target): New function. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2858 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/svn/svn_ra.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/vclib/svn/svn_ra.py b/lib/vclib/svn/svn_ra.py index 071633aa..fdd7efab 100644 --- a/lib/vclib/svn/svn_ra.py +++ b/lib/vclib/svn/svn_ra.py @@ -735,3 +735,33 @@ class RemoteSubversionRepository(vclib.Repository): else: peg_revision = mid return peg_revision, path + + def get_symlink_target(self, path_parts, rev): + """Return the target of the symbolic link versioned at PATH_PARTS + in REV, or None if that object is not a symlink.""" + + path = self._getpath(path_parts) + path_type = self.itemtype(path_parts, rev) # does auth-check + rev = self._getrev(rev) + url = self._geturl(path) + + # Symlinks must be files with the svn:special property set on them + # and with file contents which read "link SOME_PATH". + if path_type != vclib.FILE: + return None + pairs = client.svn_client_proplist2(url, _rev2optrev(rev), + _rev2optrev(rev), 0, self.ctx) + props = pairs and pairs[0][1] or {} + if not props.has_key(core.SVN_PROP_SPECIAL): + return None + pathspec = '' + ### FIXME: We're being a touch sloppy here, first by grabbing the + ### whole file and then by checking only the first line + ### of it. + fp = SelfCleanFP(cat_to_tempfile(self, path, rev)) + pathspec = fp.readline() + fp.close() + if pathspec[:5] != 'link ': + return None + return pathspec[5:] + From decb5e375bbf00f2319dee55fc3063b420509206 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 18 Mar 2013 18:38:51 +0000 Subject: [PATCH 331/353] * lib/viewvc.py Drop in some more timestamp debugging sections. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2860 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/viewvc.py b/lib/viewvc.py index ccf9d95e..64f58f3f 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -227,9 +227,12 @@ class Request: cfg.overlay_root_options(self.rootname) # Setup an Authorizer for this rootname and username + debug.t_start('setup-authorizer') self.auth = setup_authorizer(cfg, self.username) + debug.t_end('setup-authorizer') # Create the repository object + debug.t_start('select-repos') try: if roottype == 'cvs': self.rootpath = vclib.ccvs.canonicalize_rootpath(rootpath) @@ -252,6 +255,7 @@ class Request: raise vclib.ReposNotFound() except vclib.ReposNotFound: pass + debug.t_end('select-repos') if self.repos is None: raise debug.ViewVCException( 'The root "%s" is unknown. If you believe the value is ' @@ -259,7 +263,9 @@ class Request: % self.rootname, "404 Not Found") if self.repos: + debug.t_start('select-repos') self.repos.open() + debug.t_end('select-repos') type = self.repos.roottype() if type == vclib.SVN: self.roottype = 'svn' @@ -391,7 +397,9 @@ class Request: if needs_redirect: self.server.redirect(self.get_url()) else: + debug.t_start('view-func') self.view_func(self) + debug.t_end('view-func') def get_url(self, escape=0, partial=0, prefix=0, **args): """Constructs a link to another ViewVC page just like the get_link From b67254fcf2a70688e640690c239e60da512c3635 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 20 Mar 2013 13:15:34 +0000 Subject: [PATCH 332/353] Optimize the mapping of a single root name to a root path by avoiding a potentially costly directory listing within the root parent paths. This has been shown to reduce the initial ViewVC startup overhead by 400% in some situations where disk I/O is especially sluggish. * lib/vclib/ccvs/__init__.py (find_root_in_parent): New function. * lib/vclib/svn/__init__.py (find_root_in_parent): New function. * lib/viewvc.py (find_root_in_parents): Use the new find_root_in_parent() functions offered by the vclib implementations rather than the more expensive full root expansion stuffs. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2862 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/ccvs/__init__.py | 17 +++++++++++++++++ lib/vclib/svn/__init__.py | 14 ++++++++++++++ lib/viewvc.py | 12 ++++++------ 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/lib/vclib/ccvs/__init__.py b/lib/vclib/ccvs/__init__.py index e3c03159..e6d3c9e6 100644 --- a/lib/vclib/ccvs/__init__.py +++ b/lib/vclib/ccvs/__init__.py @@ -40,6 +40,23 @@ def expand_root_parent(parent_path): return roots +def find_root_in_parent(parent_path, rootname): + """Search PARENT_PATH for a root named ROOTNAME, returning the + canonicalized ROOTPATH of the root if found; return None if no such + root is found.""" + + assert os.path.isabs(parent_path) + # Is PARENT_PATH itself a CVS repository? If so, we allow ROOTNAME + # to be any subdir within it. Otherwise, we expect + # PARENT_PATH/ROOTNAME to be a CVS repository. + rootpath = os.path.join(parent_path, rootname) + if os.path.exists(os.path.join(parent_path, "CVSROOT", "config")): + return canonicalize_rootpath(rootpath) + if os.path.exists(os.path.join(rootpath, "CVSROOT", "config")): + return canonicalize_rootpath(rootpath) + return None + + def CVSRepository(name, rootpath, authorizer, utilities, use_rcsparse): rootpath = canonicalize_rootpath(rootpath) if use_rcsparse: diff --git a/lib/vclib/svn/__init__.py b/lib/vclib/svn/__init__.py index 862b548e..16edf805 100644 --- a/lib/vclib/svn/__init__.py +++ b/lib/vclib/svn/__init__.py @@ -77,6 +77,20 @@ def expand_root_parent(parent_path): return roots +def find_root_in_parent(parent_path, rootname): + """Search PARENT_PATH for a root named ROOTNAME, returning the + canonicalized ROOTPATH of the root if found; return None if no such + root is found.""" + + if not re.search(_re_url, parent_path): + assert os.path.isabs(parent_path) + rootpath = os.path.join(parent_path, rootname) + format_path = os.path.join(rootpath, "format") + if os.path.exists(format_path): + return canonicalize_rootpath(rootpath) + return None + + def SubversionRepository(name, rootpath, authorizer, utilities, config_dir): rootpath = canonicalize_rootpath(rootpath) if re.search(_re_url, rootpath): diff --git a/lib/viewvc.py b/lib/viewvc.py index 64f58f3f..e0c9ce73 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -4838,14 +4838,14 @@ def find_root_in_parents(cfg, rootname, roottype): continue pp = os.path.normpath(pp[:pos].strip()) + rootpath = None if roottype == 'cvs': - roots = vclib.ccvs.expand_root_parent(pp) + rootpath = vclib.ccvs.find_root_in_parent(pp, rootname) elif roottype == 'svn': - roots = vclib.svn.expand_root_parent(pp) - else: - roots = {} - if roots.has_key(rootname): - return roots[rootname] + rootpath = vclib.svn.find_root_in_parent(pp, rootname) + + if rootpath is not None: + return rootpath return None def locate_root(cfg, rootname): From 814bee3e4ae04dd0447ba4b795f4b409667b598f Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Fri, 12 Apr 2013 15:05:28 +0000 Subject: [PATCH 333/353] Over in Subversion-land, I finally got around to exposing the svn_cmdline_create_auth_baton() function via the SWIG Python bindings. So now use it if it's available! * lib/vclib/svn/svn_ra.py (setup_client_ctx): New compatability-sensitive function. (RemoteSubversionRepository.open): Use setup_client_ctx() now. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2864 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/svn/svn_ra.py | 51 +++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/lib/vclib/svn/svn_ra.py b/lib/vclib/svn/svn_ra.py index fdd7efab..bba3495b 100644 --- a/lib/vclib/svn/svn_ra.py +++ b/lib/vclib/svn/svn_ra.py @@ -78,6 +78,40 @@ def client_log(url, start_rev, end_rev, log_limit, include_changes, client.svn_client_log2([url], start_rev, end_rev, log_limit, include_changes, not cross_copies, cb_convert, ctx) + +def setup_client_ctx(config_dir): + # Ensure that the configuration directory exists. + core.svn_config_ensure(config_dir) + + # Fetch the configuration (and 'config' bit thereof). + cfg = core.svn_config_get_config(config_dir) + config = cfg.get(core.SVN_CONFIG_CATEGORY_CONFIG) + + # Here's the compat-sensitive part: try to use + # svn_cmdline_create_auth_baton(), and fall back to making our own + # if that fails. + try: + auth_baton = core.svn_cmdline_create_auth_baton(1, None, None, config_dir, + 1, 1, config, None) + except AttributeError: + auth_baton = core.svn_auth_open([ + client.svn_client_get_simple_provider(), + client.svn_client_get_username_provider(), + client.svn_client_get_ssl_server_trust_file_provider(), + client.svn_client_get_ssl_client_cert_file_provider(), + client.svn_client_get_ssl_client_cert_pw_file_provider(), + ]) + if config_dir is not None: + core.svn_auth_set_parameter(auth_baton, + core.SVN_AUTH_PARAM_CONFIG_DIR, + config_dir) + + # Create, setup, and return the client context baton. + ctx = client.svn_client_create_context() + ctx.config = cfg + ctx.auth_baton = auth_baton + return ctx + ### END COMPATABILITY CODE ### @@ -192,21 +226,8 @@ class RemoteSubversionRepository(vclib.Repository): def open(self): # Setup the client context baton, complete with non-prompting authstuffs. - # TODO: svn_cmdline_setup_auth_baton() is mo' better (when available) - core.svn_config_ensure(self.config_dir) - self.ctx = client.svn_client_create_context() - self.ctx.auth_baton = core.svn_auth_open([ - client.svn_client_get_simple_provider(), - client.svn_client_get_username_provider(), - client.svn_client_get_ssl_server_trust_file_provider(), - client.svn_client_get_ssl_client_cert_file_provider(), - client.svn_client_get_ssl_client_cert_pw_file_provider(), - ]) - self.ctx.config = core.svn_config_get_config(self.config_dir) - if self.config_dir is not None: - core.svn_auth_set_parameter(self.ctx.auth_baton, - core.SVN_AUTH_PARAM_CONFIG_DIR, - self.config_dir) + self.ctx = setup_client_ctx(self.config_dir) + ra_callbacks = ra.svn_ra_callbacks_t() ra_callbacks.auth_baton = self.ctx.auth_baton self.ra_session = ra.svn_ra_open(self.rootpath, ra_callbacks, None, From 1ca3dc41951fbae6594cea02100692f3279c69b9 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 15 Apr 2013 19:04:40 +0000 Subject: [PATCH 334/353] Fix issue #524 ("Give administrators a way to limit the size of files processed by markup and annotate views"). This introduces a new 'max_filesize_kbytes' configuration option for limiting markup and annotate operations on really big files (whose contents unfortunately must be read fully into memory sometimes). By default, a 512-kilobyte limit will be in place. * lib/vclib/__init__.py (Repository.filesize): New. * lib/vclib/svn/svn_repos.py (LocalSubversionRepository.filesize): New function. * lib/vclib/svn/svn_ra.py (RemoteSubversionRepository.filesize): New function. * lib/vclib/ccvs/bincvs.py (BaseCVSRepository.filesize): New function (returns -1 aka "not implemented") * conf/viewvc.conf.dist (max_filesize_kbytes): New configuration option. * lib/config.py (Config.set_defaults): Set default value for new 'max_filesize_kbytes' configuration option. * lib/viewvc.py (assert_viewable_filesize): New helper function. (markup_or_annotate): Use assert_viewable_filesize() and the new repos.filesize() API to honor the new 'max_filesize_kbytes' configuration option. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2866 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 9 +++++++++ lib/config.py | 1 + lib/vclib/__init__.py | 14 ++++++++++++++ lib/vclib/ccvs/bincvs.py | 5 +++++ lib/vclib/svn/svn_ra.py | 9 +++++++++ lib/vclib/svn/svn_repos.py | 7 +++++++ lib/viewvc.py | 33 +++++++++++++++++++++++++++++++-- 7 files changed, 76 insertions(+), 2 deletions(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index cc6cd9a3..9f5d71a0 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -502,6 +502,15 @@ ## #svn_ignore_mimetype = 0 +## max_filesize_kbytes: Limit ViewVC's processing of file contents in +## "markup" and "annotate" views to only those files which are smaller +## than this setting, expressed in kilobytes. Set to 0 to disable +## this safeguard. +## +## NOTE: The "co" and "tar" views are unaffected by this setting. +## +#max_filesize_kbytes = 512 + ## svn_config_dir: Path of the Subversion runtime configuration ## directory ViewVC should consult for various things, including cached ## remote authentication credentials. If unset, Subversion will use diff --git a/lib/config.py b/lib/config.py index a3c29a20..61db979f 100644 --- a/lib/config.py +++ b/lib/config.py @@ -405,6 +405,7 @@ class Config: self.options.generate_etags = 1 self.options.svn_ignore_mimetype = 0 self.options.svn_config_dir = None + self.options.max_filesize_kbytes = 512 self.options.use_rcsparse = 0 self.options.sort_by = 'file' self.options.sort_group_dirs = 1 diff --git a/lib/vclib/__init__.py b/lib/vclib/__init__.py index 34b53422..74e83e8e 100644 --- a/lib/vclib/__init__.py +++ b/lib/vclib/__init__.py @@ -206,7 +206,21 @@ class Repository: rev is the revision of the item to return information about """ + + def filesize(self, path_parts, rev): + """Return the size of a versioned file's contents if it can be + obtained without a brute force measurement; -1 otherwise. + + NOTE: Callers that require a filesize answer when this function + returns -1 may obtain it by measuring the data returned via + openfile(). + The 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 + """ + # ====================================================================== class DirEntry: diff --git a/lib/vclib/ccvs/bincvs.py b/lib/vclib/ccvs/bincvs.py index 281f6561..4f04c970 100644 --- a/lib/vclib/ccvs/bincvs.py +++ b/lib/vclib/ccvs/bincvs.py @@ -151,6 +151,11 @@ class BaseCVSRepository(vclib.Repository): raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts))) rcsfile = self.rcsfile(path_parts, 1) return os.access(rcsfile, os.X_OK) + + def filesize(self, path_parts, rev): + if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check + raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts))) + return -1 class BinCVSRepository(BaseCVSRepository): diff --git a/lib/vclib/svn/svn_ra.py b/lib/vclib/svn/svn_ra.py index bba3495b..c54a977e 100644 --- a/lib/vclib/svn/svn_ra.py +++ b/lib/vclib/svn/svn_ra.py @@ -474,6 +474,15 @@ class RemoteSubversionRepository(vclib.Repository): props = self.itemprops(path_parts, rev) # does authz-check return props.has_key(core.SVN_PROP_EXECUTABLE) + def filesize(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) + rev = self._getrev(rev) + dirents, locks = self._get_dirents(path_parts[:-1], rev) + dirent = dirents.get(path_parts[-1], None) + return dirent.size + def _getpath(self, path_parts): return '/'.join(path_parts) diff --git a/lib/vclib/svn/svn_repos.py b/lib/vclib/svn/svn_repos.py index 919a0d5a..ba7462fe 100644 --- a/lib/vclib/svn/svn_repos.py +++ b/lib/vclib/svn/svn_repos.py @@ -568,6 +568,13 @@ class LocalSubversionRepository(vclib.Repository): props = self.itemprops(path_parts, rev) # does authz-check return props.has_key(core.SVN_PROP_EXECUTABLE) + def filesize(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) + fsroot = self._getroot(self._getrev(rev)) + return fs.file_length(fsroot, path) + ##--- helpers ---## def _revinfo(self, rev, include_changed_paths=0): diff --git a/lib/viewvc.py b/lib/viewvc.py index e0c9ce73..a0b59fc5 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1854,6 +1854,15 @@ def calculate_mime_type(request, path_parts, rev): pass return guess_mime(path_parts[-1]), None +def assert_viewable_filesize(cfg, filesize): + if cfg.options.max_filesize_kbytes \ + and filesize != -1 \ + and filesize > (1024 * cfg.options.max_filesize_kbytes): + raise debug.ViewVCException('Display of files larger than %d KB ' + 'disallowed by configuration' + % (cfg.options.max_filesize_kbytes), + '403 Forbidden') + def markup_or_annotate(request, is_annotate): cfg = request.cfg path, rev = _orig_path(request, is_annotate and 'annotate' or 'revision') @@ -1881,11 +1890,16 @@ def markup_or_annotate(request, is_annotate): # Not a viewable image. else: - blame_data = None + filesize = request.repos.filesize(path, rev) + + # If configuration disallows display of large files, try to honor + # that request. + assert_viewable_filesize(cfg, filesize) # 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_data = None if is_annotate: try: blame_source, revision = request.repos.annotate(path, rev, False) @@ -1913,7 +1927,22 @@ def markup_or_annotate(request, is_annotate): if check_freshness(request, None, revision, weak=1): fp.close() return - file_lines = fp.readlines() + + # If we're limiting by filesize but couldn't pull off the cheap + # check above, we'll try to do so line by line here (while + # building our file_lines array). + if cfg.options.max_filesize_kbytes and filesize == -1: + file_lines = [] + filesize = 0 + while 1: + line = fp.readline() + if not line: + break + filesize = filesize + len(line) + assert_viewable_filesize(cfg, filesize) + file_lines.append(line) + else: + file_lines = fp.readlines() fp.close() # Do we have a differing number of file content lines and From 801eaff7641870348df61b26217c0e42bacb7b7c Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 15 Apr 2013 19:06:30 +0000 Subject: [PATCH 335/353] Fix an ancient code concern by no longer reading file content fully into memory when generating tarballs. * lib/viewvc.py (generate_tarball): Avoid reading file contents fully into memory. Rather, query the filesize from the vclib provider and chunk the output. If the filesize must be calculated, use two chunked passes over those contents (one to measure, one to write to the tarball). git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2867 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index a0b59fc5..52afb779 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -3923,17 +3923,34 @@ def generate_tarball(out, request, reldir, stack, dir_mtime=None): file.date is not None and file.date or 0, typeflag='2', linkname=symlink_target) else: - ### FIXME: Read the whole file into memory? Bad... better to do - ### 2 passes. + filesize = request.repos.filesize(rep_path + [file.name], request.pathrev) + + if filesize == -1: + # Bummer. We have to calculate the filesize manually. + fp = request.repos.openfile(rep_path + [file.name], request.pathrev, {})[0] + filesize = 0 + while 1: + chunk = retry_read(fp) + if not chunk: + break + filesize = filesize + len(chunk) + fp.close() + + # Write the tarball header... + generate_tarball_header(out, tar_dir + file.name, filesize, mode, + file.date is not None and file.date or 0) + + # ...the file's contents ... fp = request.repos.openfile(rep_path + [file.name], request.pathrev, {})[0] - contents = fp.read() + while 1: + chunk = retry_read(fp) + if not chunk: + break + out.write(chunk) fp.close() - generate_tarball_header(out, tar_dir + file.name, - len(contents), mode, - file.date is not None and file.date or 0) - out.write(contents) - out.write('\0' * (511 - ((len(contents) + 511) % 512))) + # ... and then add the block padding. + out.write('\0' * (511 - (filesize + 511) % 512)) # Recurse into subdirectories, skipping busted and unauthorized (or # configured-to-be-hidden) ones. From 0ca6106034f26abb6ce1e6b67fcbfa98f650e764 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Tue, 16 Apr 2013 18:15:50 +0000 Subject: [PATCH 336/353] Fix issue #525 ("Tarball output is double-compressed when allow_compress=1"). * lib/viewvc.py (get_writeready_server_file): Add 'allow_compress' parameter, and handling to give callers the power to disable response-level compression. (download_tarball): When calling get_writeready_server_file(), disable compression (if any) since we're doing our own gzipping herein. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2870 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 52afb779..82021077 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -908,7 +908,7 @@ def get_view_template(cfg, view_name, language="en"): return template def get_writeready_server_file(request, content_type=None, encoding=None, - content_length=None): + content_length=None, allow_compress=True): """Return a file handle to a response body stream, after outputting any queued special headers (on REQUEST.server) and (optionally) a 'Content-Type' header whose value is CONTENT_TYPE and character set @@ -917,10 +917,14 @@ def get_writeready_server_file(request, content_type=None, encoding=None, If CONTENT_LENGTH is provided and compression is not in use, also generate a 'Content-Length' header for this response. + Callers my use ALLOW_COMPRESS to disable compression where it would + otherwise be allowed. (Such as when transmitting an + already-compressed response.) + After this function is called, it is too late to add new headers to the response.""" - if request.gzip_compress_level: + if allow_compress and request.gzip_compress_level: request.server.addheader('Content-Encoding', 'gzip') elif content_length is not None: request.server.addheader('Content-Length', content_length) @@ -932,7 +936,7 @@ def get_writeready_server_file(request, content_type=None, encoding=None, else: request.server.header() - if request.gzip_compress_level: + if allow_compress and request.gzip_compress_level: fp = gzip.GzipFile('', 'wb', request.gzip_compress_level, request.server.file()) else: @@ -3974,6 +3978,10 @@ def download_tarball(request): raise debug.ViewVCException('Tarball generation is disabled', '403 Forbidden') + # If debugging, we just need to open up the specified tar path for + # writing. Otherwise, we get a writeable server output stream -- + # disabling any default compression thereupon -- and wrap that in + # our own gzip stream wrapper. if debug.TARFILE_PATH: fp = open(debug.TARFILE_PATH, 'w') else: @@ -3982,11 +3990,9 @@ def download_tarball(request): tarfile = "%s-%s" % (tarfile, request.path_parts[-1]) request.server.addheader('Content-Disposition', 'attachment; filename="%s.tar.gz"' % (tarfile)) - server_fp = get_writeready_server_file(request, 'application/x-gzip') + server_fp = get_writeready_server_file(request, 'application/x-gzip', + allow_compress=False) request.server.flush() - - # Try to use the Python gzip module, if available; otherwise, - # we'll use the configured 'gzip' binary. fp = gzip.GzipFile('', 'wb', 9, server_fp) ### FIXME: For Subversion repositories, we can get the real mtime of the From a2090ce90bdf01ea071eb0cf42821f37aa710f4c Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 17 Apr 2013 15:23:42 +0000 Subject: [PATCH 337/353] Make some additional dents on issue #11 ("Universal UTF-8 output from ViewVC"). Use the 'chardet' module where available and enabled by configuration to detect source file content encoding, and transcode the output to UTF-8. We supported this already via Pygments when 'enable_syntax_coloration' was set; now we can also support this when it isn't. * lib/viewvc.py (detect_encoding, transcode_text): New helper functions. (markup_stream): Use the new helper functions to attempt to transcode text into UTF-8 even when syntax coloration is *not* in use. * conf/viewvc.conf.dist (detect_encoding): Remove notation about this only being used when 'enable_syntax_coloration' is also enabled. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2872 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 3 +-- lib/viewvc.py | 49 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index 9f5d71a0..79e06101 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -706,8 +706,7 @@ ## detect_encoding: Should we attempt to detect versioned file ## character encodings? [Requires 'chardet' module, and is currently -## used only by the syntax coloration logic -- if enabled -- for the -## 'markup' and 'annotate' views; see 'enable_syntax_coloration'.] +## used only for the 'markup' and 'annotate' views.] ## #detect_encoding = 0 diff --git a/lib/viewvc.py b/lib/viewvc.py index 82021077..e2bad07f 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1666,6 +1666,37 @@ def markup_escaped_urls(s): return re.sub(_re_rewrite_escaped_url, _url_repl, s) +def detect_encoding(text_block): + # Does the TEXT_BLOCK start with a BOM? + for bom, encoding in [('\xef\xbb\xbf', 'utf-8'), + ('\xff\xfe', 'utf-16'), + ('\xfe\xff', 'utf-16be'), + ('\xff\xfe\0\0', 'utf-32'), + ('\0\0\xfe\xff', 'utf-32be'), + ]: + if text_block.startswith(bom): + return encoding + + # If no recognized BOM, see if chardet can help us. + try: + import chardet + return chardet.detect(text_block).get('encoding') + except: + pass + + # By default ... we have no idea. + return None + +def transcode_text(text, encoding=None): + """If ENCODING is provided and not 'utf-8', transcode TEXT from + ENCODING to UTF-8.""" + + if not encoding or encoding == 'utf-8': + return text + return unicode(text, encoding, + errors='replace').encode('utf-8', + errors='replace') + 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 @@ -1735,9 +1766,25 @@ def markup_stream(request, cfg, blame_data, file_lines, filename, # If we aren't highlighting, just return an amalgamation of the # BLAME_DATA (if any) and the FILE_LINES. if not pygments_lexer: + + # If allowed by configuration, try to detect the source encoding + # for this file. We'll assemble a block of data from the file + # contents to do so... 1024 bytes should be enough. + if not encoding and cfg.options.detect_encoding: + block_size = 0 + text_block = '' + for i in range(len(file_lines)): + text_block = text_block + file_lines[i] + if len(text_block) >= 1024: + break + encoding = detect_encoding(text_block) + + # Built output data comprised of marked-up and possibly-transcoded + # source text lines wrapped in (possibly dummy) vclib.Annotation + # objects. lines = [] for i in range(len(file_lines)): - line = file_lines[i].rstrip('\n\r') + line = transcode_text(file_lines[i].rstrip('\n\r'), encoding) line = sapi.escape(line.expandtabs(cfg.options.tabsize)) line = markup_escaped_urls(line) if blame_data: From 6406b106a1a59361a384d9939739c2a65fd3d23a Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 17 Apr 2013 17:59:41 +0000 Subject: [PATCH 338/353] More work on issue #11 ("Universal UTF-8 output from ViewVC"). * lib/viewvc.py (markup_stream): When transcoding, handle the whole body of file contents at once rather than trying to go line-by-line. Why? Because until transcoded, the concept of a "line" is rather meaningless. (NOTE: There is almost certainly some fallout to occur in the annotate view as a result of this work, since each VC system's annotation support also uses the naive concept of a line.) git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2873 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index e2bad07f..29b82cf7 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1783,8 +1783,9 @@ def markup_stream(request, cfg, blame_data, file_lines, filename, # source text lines wrapped in (possibly dummy) vclib.Annotation # objects. lines = [] + file_lines = transcode_text(''.join(file_lines), encoding).rstrip('\n').split('\n') for i in range(len(file_lines)): - line = transcode_text(file_lines[i].rstrip('\n\r'), encoding) + line = file_lines[i] line = sapi.escape(line.expandtabs(cfg.options.tabsize)) line = markup_escaped_urls(line) if blame_data: From 7026dcb4989b6316d39da57e04008101062a76cd Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 17 Apr 2013 18:16:48 +0000 Subject: [PATCH 339/353] Fix an exception recently introduced. * lib/vclib/svn/svn_ra.py (RemoteSubversionRepository.filesize): Recombine path_parts before calling _get_dirents(). git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2874 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/svn/svn_ra.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vclib/svn/svn_ra.py b/lib/vclib/svn/svn_ra.py index c54a977e..5d252307 100644 --- a/lib/vclib/svn/svn_ra.py +++ b/lib/vclib/svn/svn_ra.py @@ -479,7 +479,7 @@ class RemoteSubversionRepository(vclib.Repository): if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check raise vclib.Error("Path '%s' is not a file." % path) rev = self._getrev(rev) - dirents, locks = self._get_dirents(path_parts[:-1], rev) + dirents, locks = self._get_dirents(self._getpath(path_parts[:-1]), rev) dirent = dirents.get(path_parts[-1], None) return dirent.size From 4fd9cc08116cafd13e4e5199fd1f2fc7d2a880ad Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 18 Apr 2013 13:49:15 +0000 Subject: [PATCH 340/353] Fix some latent bugs whitespace handling. * lib/viewvc.py (markup_stream): Only expand tabs if the tabsize > 0. (DiffSource._format_text): Only strip EOL stuffs from the ends of lines -- preserve other whitespace forms. Also, only expand tabs if the tabsize > 0. * conf/viewvc.conf.dist (tabsize): Use the term "horizontal tab character" rather than "tabstop". The latter is the destination; the former is the character that tells the text flow to resume there. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2876 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 5 +++-- lib/viewvc.py | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index 79e06101..1682e716 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -699,8 +699,9 @@ ## #enable_syntax_coloration = 1 -## tabsize: The number of spaces into which tabstops are converted -## when viewing file contents. +## tabsize: The number of spaces into which horizontal tab characters +## are converted when viewing file contents. Set to 0 to preserve +## tab characters. ## #tabsize = 8 diff --git a/lib/viewvc.py b/lib/viewvc.py index 29b82cf7..36d4a318 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1786,8 +1786,9 @@ def markup_stream(request, cfg, blame_data, file_lines, filename, file_lines = transcode_text(''.join(file_lines), encoding).rstrip('\n').split('\n') for i in range(len(file_lines)): line = file_lines[i] - line = sapi.escape(line.expandtabs(cfg.options.tabsize)) - line = markup_escaped_urls(line) + if cfg.options.tabsize > 0: + line.expandtabs(cfg.options.tabsize) + line = markup_escaped_urls(sapi.escape(line)) if blame_data: blame_item = blame_data[i] blame_item.text = line @@ -3198,7 +3199,9 @@ class DiffSource: return item def _format_text(self, text): - text = text.rstrip().expandtabs(self.cfg.options.tabsize) + text = text.rstrip('\r\n') + if self.cfg.options.tabsize > 0: + text = expandtabs(self.cfg.options.tabsize) hr_breakable = self.cfg.options.hr_breakable # in the code below, "\x01" will be our stand-in for "&". We don't want From 1f58e4137602949c6b10c33447eb291ed8bc79a5 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Fri, 19 Apr 2013 20:31:15 +0000 Subject: [PATCH 341/353] Finish issue #46 ("ISO 8601 date/time format"). * lib/viewvc.py (make_time_string): If cfg.options.iso8601_timestamps is set, generate ISO-8601-compliant timestamp strings. * lib/config.py (Config.set_defaults): Initialize 'iso8601_timestamps' option value. * conf/viewvc.conf.dist (iso8601_timestamps): New option. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2880 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 4 ++++ lib/config.py | 1 + lib/viewvc.py | 19 ++++++++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index 1682e716..96c63e3f 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -683,6 +683,10 @@ ## #use_localtime = 0 +## iso8601_dates: Display timestamps using a standard ISO-8601 format. +## +#iso8601_timestamps = 0 + ## short_log_len: The length (in characters) to which the most recent ## log entry should be truncated when shown in the directory view. ## diff --git a/lib/config.py b/lib/config.py index 61db979f..5edcad0d 100644 --- a/lib/config.py +++ b/lib/config.py @@ -428,6 +428,7 @@ class Config: self.options.show_log_in_markup = 1 self.options.cross_copies = 1 self.options.use_localtime = 0 + self.options.iso8601_timestamps = 0 self.options.short_log_len = 80 self.options.enable_syntax_coloration = 1 self.options.tabsize = 8 diff --git a/lib/viewvc.py b/lib/viewvc.py index 36d4a318..11b1baaa 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1836,10 +1836,23 @@ def make_time_string(date, cfg): if date is None: return None if cfg.options.use_localtime: - localtime = time.localtime(date) - return time.asctime(localtime) + ' ' + time.tzname[localtime[8]] + tm = time.localtime(date) else: - return time.asctime(time.gmtime(date)) + ' UTC' + tm = time.gmtime(date) + if cfg.options.iso8601_timestamps: + if cfg.options.use_localtime: + if tm[8] and time.daylight: + tz = time.altzone + else: + tz = time.timezone + tz = float(tz) / 3600.0 + tz = str.format('{0:+06.2f}', tz).replace('.', ':') + else: + tz = 'Z' + return time.strftime('%Y-%m-%dT%H:%M:%S', tm) + tz + else: + return time.asctime(tm) + ' ' + \ + (cfg.options.use_localtime and time.tzname[tm[8]] or 'UTC') def make_rss_time_string(date, cfg): """Returns formatted date string in UTC, formatted for RSS. From a4ad1b13c2b5948a2d574a0685afaa47205f0014 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Fri, 19 Apr 2013 20:34:46 +0000 Subject: [PATCH 342/353] * lib/viewvc.py (make_time_string): A little syntax change to be more Pythonic. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2881 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 11b1baaa..ec69fc09 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1846,7 +1846,7 @@ def make_time_string(date, cfg): else: tz = time.timezone tz = float(tz) / 3600.0 - tz = str.format('{0:+06.2f}', tz).replace('.', ':') + tz = '{0:+06.2f}'.format(tz).replace('.', ':') else: tz = 'Z' return time.strftime('%Y-%m-%dT%H:%M:%S', tm) + tz From 3fbaffa2fd40e2495b6a18cb75bd0e8850cff574 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 22 Apr 2013 19:20:06 +0000 Subject: [PATCH 343/353] Bump latest advertised release. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2885 8cb11bc2-c004-0410-86c3-e597b4017df7 --- www/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/index.html b/www/index.html index 4e0802e8..9efed361 100644 --- a/www/index.html +++ b/www/index.html @@ -30,13 +30,13 @@ <h2>Latest Release(s)</h2> -<p>The most recent stable release of ViewVC is: <strong>1.1.18</strong></p> +<p>The most recent stable release of ViewVC is: <strong>1.1.19</strong></p> <ul> <li><a href="http://www.viewvc.org/download.html" >Download or checkout</a> this release</li> <li>See the - <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.18/CHANGES" + <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.19/CHANGES" >CHANGES</a> in this release.</li> <li>Read the <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/trunk/docs/release-notes/1.1.0.html" From 75e503a16b02463f0ba58fefaff3c6fcf7c26f40 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Mon, 22 Apr 2013 19:28:18 +0000 Subject: [PATCH 344/353] * CHANGES Merge in 1.1.19 changes. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2888 8cb11bc2-c004-0410-86c3-e597b4017df7 --- CHANGES | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGES b/CHANGES index c05784aa..8b5e0e86 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,20 @@ Version 1.2.0 (released ??-???-????) * allow user-configurable cvsgraph display (issue #336) * allow rNNNN syntax for Subversion revision numbers (issue #441) +Version 1.1.19 (released 22-Apr-2013) + + * improve root lookup performance (issue #523) + * new 'max_filesize_kbytes' config option and handling (issue #524) + * tarball generation improvements: + - preserve Subversion symlinks in generated tarballs (issue #487) + - reduce memory usage of tarball generation logic + - fix double compression of generated tarballs (issue #525) + * file content handling improvements: + - expanded support for encoding detection and transcoding (issue #11) + - fix tab-to-space conversion bugs in markup, annotate, and diff views + - fix handling of trailing whitespace in diff view + * add support for timestamp display in ISO8601 format (issue #46) + Version 1.1.18 (released 28-Feb-2013) * fix exception raised by BDB-backed SVN repositories (issue #519) From 16d7e0af8afd5450326fbba23f28189d2e850eff Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Tue, 23 Apr 2013 18:43:15 +0000 Subject: [PATCH 345/353] Fix issue #526 ("Subversion roots not longer accessible"). This is a big-time regression in root handling which unfortunately found its way into the 1.1.19 release. Reported by: Michael Theys <michael.th90{_AT_}gmail.com>, olli hauer <ohauer{_AT_}gmx.de> * lib/vclib/ccvs/__init__.py (expand_root_parent): Avoid unnecessary convenience variable. (find_root_in_parent): Don't return a rootpath that we've not checked for existence!! git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2891 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/ccvs/__init__.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/vclib/ccvs/__init__.py b/lib/vclib/ccvs/__init__.py index e6d3c9e6..df6782da 100644 --- a/lib/vclib/ccvs/__init__.py +++ b/lib/vclib/ccvs/__init__.py @@ -31,10 +31,9 @@ def expand_root_parent(parent_path): assert os.path.isabs(parent_path) roots = {} subpaths = os.listdir(parent_path) - cvsroot = os.path.exists(os.path.join(parent_path, "CVSROOT", "config")) for rootname in subpaths: rootpath = os.path.join(parent_path, rootname) - if cvsroot \ + if os.path.exists(os.path.join(parent_path, "CVSROOT", "config")) \ or (os.path.exists(os.path.join(rootpath, "CVSROOT", "config"))): roots[rootname] = canonicalize_rootpath(rootpath) return roots @@ -44,15 +43,16 @@ def find_root_in_parent(parent_path, rootname): """Search PARENT_PATH for a root named ROOTNAME, returning the canonicalized ROOTPATH of the root if found; return None if no such root is found.""" - assert os.path.isabs(parent_path) - # Is PARENT_PATH itself a CVS repository? If so, we allow ROOTNAME - # to be any subdir within it. Otherwise, we expect - # PARENT_PATH/ROOTNAME to be a CVS repository. rootpath = os.path.join(parent_path, rootname) + + # Is PARENT_PATH itself a CVS repository? If so, we allow ROOTNAME + # to be any subdir within it. if os.path.exists(os.path.join(parent_path, "CVSROOT", "config")): - return canonicalize_rootpath(rootpath) - if os.path.exists(os.path.join(rootpath, "CVSROOT", "config")): + if os.path.exists(rootpath): + return canonicalize_rootpath(rootpath) + # Otherwise, we expect PARENT_PATH/ROOTNAME to be a CVS repository. + elif os.path.exists(os.path.join(rootpath, "CVSROOT", "config")): return canonicalize_rootpath(rootpath) return None From ece31e7369ce0f4c7d1bc2dfea5a2b6495f7dac2 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Tue, 23 Apr 2013 18:49:10 +0000 Subject: [PATCH 346/353] * lib/vclib/ccvs/__init__.py (_is_cvsroot): New helper function. (expand_root_parent, find_root_in_parent): Rework these to now use _is_cvsroot(). git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2892 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/ccvs/__init__.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/vclib/ccvs/__init__.py b/lib/vclib/ccvs/__init__.py index df6782da..79237fd3 100644 --- a/lib/vclib/ccvs/__init__.py +++ b/lib/vclib/ccvs/__init__.py @@ -23,6 +23,10 @@ def canonicalize_rootpath(rootpath): return os.path.normpath(rootpath) +def _is_cvsroot(path): + return os.path.exists(os.path.join(path, "CVSROOT", "config")) + + def expand_root_parent(parent_path): # Each subdirectory of PARENT_PATH that contains a child # "CVSROOT/config" is added the set of returned roots. Or, if the @@ -33,8 +37,7 @@ def expand_root_parent(parent_path): subpaths = os.listdir(parent_path) for rootname in subpaths: rootpath = os.path.join(parent_path, rootname) - if os.path.exists(os.path.join(parent_path, "CVSROOT", "config")) \ - or (os.path.exists(os.path.join(rootpath, "CVSROOT", "config"))): + if _is_cvsroot(parent_path) or _is_cvsroot(rootpath): roots[rootname] = canonicalize_rootpath(rootpath) return roots @@ -43,16 +46,13 @@ def find_root_in_parent(parent_path, rootname): """Search PARENT_PATH for a root named ROOTNAME, returning the canonicalized ROOTPATH of the root if found; return None if no such root is found.""" + # Is PARENT_PATH itself a CVS repository? If so, we allow ROOTNAME + # to be any subdir within it. Otherwise, we expect + # PARENT_PATH/ROOTNAME to be a CVS repository. assert os.path.isabs(parent_path) rootpath = os.path.join(parent_path, rootname) - - # Is PARENT_PATH itself a CVS repository? If so, we allow ROOTNAME - # to be any subdir within it. - if os.path.exists(os.path.join(parent_path, "CVSROOT", "config")): - if os.path.exists(rootpath): - return canonicalize_rootpath(rootpath) - # Otherwise, we expect PARENT_PATH/ROOTNAME to be a CVS repository. - elif os.path.exists(os.path.join(rootpath, "CVSROOT", "config")): + if (_is_cvsroot(parent_path) and os.path.exists(rootpath)) \ + or _is_cvsroot(rootpath): return canonicalize_rootpath(rootpath) return None From d2e7f4aff28234e3507c9e785eff83b2e0b7dc8d Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Tue, 23 Apr 2013 18:53:15 +0000 Subject: [PATCH 347/353] * lib/vclib/ccvs/__init__.py (find_root_in_parent): Minor comment tweak only. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2893 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/vclib/ccvs/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vclib/ccvs/__init__.py b/lib/vclib/ccvs/__init__.py index 79237fd3..d75617af 100644 --- a/lib/vclib/ccvs/__init__.py +++ b/lib/vclib/ccvs/__init__.py @@ -47,7 +47,7 @@ def find_root_in_parent(parent_path, rootname): canonicalized ROOTPATH of the root if found; return None if no such root is found.""" # Is PARENT_PATH itself a CVS repository? If so, we allow ROOTNAME - # to be any subdir within it. Otherwise, we expect + # to be any subdir within it. Otherwise, we expect # PARENT_PATH/ROOTNAME to be a CVS repository. assert os.path.isabs(parent_path) rootpath = os.path.join(parent_path, rootname) From a1fd08948a6e593747e57558e2885df1692e623d Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Tue, 23 Apr 2013 20:17:01 +0000 Subject: [PATCH 348/353] * lib/viewvc.py (markup_stream, DiffSource._format_text): Fix still more buglets around tab-to-space conversion. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2895 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index ec69fc09..51966747 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1787,7 +1787,7 @@ def markup_stream(request, cfg, blame_data, file_lines, filename, for i in range(len(file_lines)): line = file_lines[i] if cfg.options.tabsize > 0: - line.expandtabs(cfg.options.tabsize) + line = line.expandtabs(cfg.options.tabsize) line = markup_escaped_urls(sapi.escape(line)) if blame_data: blame_item = blame_data[i] @@ -3214,7 +3214,7 @@ class DiffSource: def _format_text(self, text): text = text.rstrip('\r\n') if self.cfg.options.tabsize > 0: - text = expandtabs(self.cfg.options.tabsize) + text = text.expandtabs(self.cfg.options.tabsize) hr_breakable = self.cfg.options.hr_breakable # in the code below, "\x01" will be our stand-in for "&". We don't want From 89d478a933b3b864a36bbdd2b20343e2ffd8ff35 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 24 Apr 2013 13:31:36 +0000 Subject: [PATCH 349/353] Bump latest advertised release. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2899 8cb11bc2-c004-0410-86c3-e597b4017df7 --- www/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/www/index.html b/www/index.html index 9efed361..abd54d91 100644 --- a/www/index.html +++ b/www/index.html @@ -30,13 +30,13 @@ <h2>Latest Release(s)</h2> -<p>The most recent stable release of ViewVC is: <strong>1.1.19</strong></p> +<p>The most recent stable release of ViewVC is: <strong>1.1.20</strong></p> <ul> <li><a href="http://www.viewvc.org/download.html" >Download or checkout</a> this release</li> <li>See the - <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.19/CHANGES" + <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/tags/1.1.20/CHANGES" >CHANGES</a> in this release.</li> <li>Read the <a href="http://viewvc.tigris.org/source/browse/*checkout*/viewvc/trunk/docs/release-notes/1.1.0.html" From 9e97bd332de19026d4ef6bf8533fd7e4e2c2ffa9 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 24 Apr 2013 14:12:41 +0000 Subject: [PATCH 350/353] * CHANGES Merge 1.1.20 changes. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2901 8cb11bc2-c004-0410-86c3-e597b4017df7 --- CHANGES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES b/CHANGES index 8b5e0e86..d59618c8 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,11 @@ Version 1.2.0 (released ??-???-????) * allow user-configurable cvsgraph display (issue #336) * allow rNNNN syntax for Subversion revision numbers (issue #441) +Version 1.1.20 (released 24-Apr-2013) + + * fix tab-to-space handling regression in markup view + * fix regression in root lookup handling (issue #526) + Version 1.1.19 (released 22-Apr-2013) * improve root lookup performance (issue #523) From aa724feae4ae5669fe77dd0a6cd499f6f74ecdad Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Thu, 25 Apr 2013 14:52:58 +0000 Subject: [PATCH 351/353] Fix issue #527 ("ViewVC markup/annotate views raise exceptions depending on Python version"). * lib/viewvc.py (transcode_text): Avoid using keyword arguments with unicode() and .encode(), support for which wasn't added until Python 2.7. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2902 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 51966747..2ac7443d 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1693,9 +1693,11 @@ def transcode_text(text, encoding=None): if not encoding or encoding == 'utf-8': return text - return unicode(text, encoding, - errors='replace').encode('utf-8', - errors='replace') + try: + return unicode(text, encoding, 'replace').encode('utf-8', 'replace') + except: + pass + return text def markup_stream(request, cfg, blame_data, file_lines, filename, mime_type, encoding, colorize): From 0ac2f63f710eea3f9882e189771cf6c267d430d4 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 1 May 2013 15:49:29 +0000 Subject: [PATCH 352/353] * conf/viewvc.conf.dist: Minor comment formatting tweak. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2904 8cb11bc2-c004-0410-86c3-e597b4017df7 --- conf/viewvc.conf.dist | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conf/viewvc.conf.dist b/conf/viewvc.conf.dist index 96c63e3f..dfdf6761 100644 --- a/conf/viewvc.conf.dist +++ b/conf/viewvc.conf.dist @@ -889,7 +889,8 @@ #port = 3306 ## database_name: ViewVC database name. -##database_name = ViewVC +## +#database_name = ViewVC ## user: Username of user with read/write privileges to the database ## specified by the 'database_name' configuration option. From 4251b529879bd76213fbc3ab1348189cd1ad52e2 Mon Sep 17 00:00:00 2001 From: cmpilato <cmpilato@8cb11bc2-c004-0410-86c3-e597b4017df7> Date: Wed, 10 Jul 2013 16:29:13 +0000 Subject: [PATCH 353/353] Fix buglet in (unused) ViewVCHtmlFormatter.get_result() function. * lib/viewvc.py (ViewVCHtmlFormatter.get_result): Remove some unnecessary statements, and fix the fact that this was disregarding the 'maxlen' parameter. git-svn-id: http://viewvc.tigris.org/svn/viewvc/trunk@2905 8cb11bc2-c004-0410-86c3-e597b4017df7 --- lib/viewvc.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/viewvc.py b/lib/viewvc.py index 2ac7443d..060cd8a3 100644 --- a/lib/viewvc.py +++ b/lib/viewvc.py @@ -1294,10 +1294,7 @@ class ViewVCHtmlFormatter: the number of visible characters in the result string, and a boolean flag indicating whether or not S was truncated. """ - out = '' - out_len = 0 - tokens = self.tokenize_text(s) - return tokens.get_result() + return self.tokenize_text(s).get_result(maxlen) def tokenize_text(self, s): """Return a ViewVCHtmlFormatterTokens object containing the tokens