"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "lib/vclib/ccvs/ccvs.py" between
viewvc-1.1.28.tar.gz and viewvc-1.2.1.tar.gz

About: ViewVC is a browser interface for CVS and Subversion version control repositories.

ccvs.py  (viewvc-1.1.28):ccvs.py  (viewvc-1.2.1)
skipping to change at line 14 skipping to change at line 14
# #
# By using this file, you agree to the terms and conditions set forth in # 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 # the LICENSE.html file which can be found at the top level of the ViewVC
# distribution or at http://viewvc.org/license-1.html. # distribution or at http://viewvc.org/license-1.html.
# #
# For more information, visit http://viewvc.org/ # For more information, visit http://viewvc.org/
# #
# ----------------------------------------------------------------------- # -----------------------------------------------------------------------
import os import os
import string
import re import re
import cStringIO import cStringIO
import tempfile import tempfile
import vclib import vclib
import rcsparse import rcsparse
import blame import blame
### The functionality shared with bincvs should probably be moved to a ### The functionality shared with bincvs should probably be moved to a
### separate module ### separate module
from bincvs import BaseCVSRepository, Revision, Tag, _file_log, _log_path, _logs ort_date_cmp, _logsort_rev_cmp from bincvs import BaseCVSRepository, Revision, Tag, _file_log, _log_path, _logs ort_date_cmp, _logsort_rev_cmp, _path_join
class CCVSRepository(BaseCVSRepository): class CCVSRepository(BaseCVSRepository):
def dirlogs(self, path_parts, rev, entries, options): def dirlogs(self, path_parts, rev, entries, options):
"""see vclib.Repository.dirlogs docstring """see vclib.Repository.dirlogs docstring
rev can be a tag name or None. if set only information from revisions rev can be a tag name or None. if set only information from revisions
matching the tag will be retrieved matching the tag will be retrieved
Option values recognized by this implementation: Option values recognized by this implementation:
skipping to change at line 47 skipping to change at line 46
boolean. true to fetch logs of the most recently modified file in each boolean. true to fetch logs of the most recently modified file in each
subdirectory subdirectory
Option values returned by this implementation: Option values returned by this implementation:
cvs_tags, cvs_branches cvs_tags, cvs_branches
lists of tag and branch names encountered in the directory lists of tag and branch names encountered in the directory
""" """
if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check if self.itemtype(path_parts, rev) != vclib.DIR: # does auth-check
raise vclib.Error("Path '%s' is not a directory." raise vclib.Error("Path '%s' is not a directory."
% (string.join(path_parts, "/"))) % (part2path(path_parts)))
entries_to_fetch = [] entries_to_fetch = []
for entry in entries: for entry in entries:
if vclib.check_path_access(self, path_parts + [entry.name], None, rev): if vclib.check_path_access(self, path_parts + [entry.name], None, rev):
entries_to_fetch.append(entry) entries_to_fetch.append(entry)
subdirs = options.get('cvs_subdirs', 0) subdirs = options.get('cvs_subdirs', 0)
dirpath = self._getpath(path_parts) dirpath = self._getpath(path_parts)
alltags = { # all the tags seen in the files of this dir alltags = { # all the tags seen in the files of this dir
'MAIN' : '', 'MAIN' : '',
skipping to change at line 97 skipping to change at line 96
rev parameter can be a revision number, a branch number, a tag name, rev parameter can be a revision number, a branch number, a tag name,
or None. If None, will return information about all revisions, otherwise, or None. If None, will return information about all revisions, otherwise,
will only return information about the specified revision or branch. will only return information about the specified revision or branch.
Option values returned by this implementation: Option values returned by this implementation:
cvs_tags cvs_tags
dictionary of Tag objects for all tags encountered dictionary of Tag objects for all tags encountered
""" """
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts)))
% (string.join(path_parts, "/")))
path = self.rcsfile(path_parts, 1) path = self.rcsfile(path_parts, 1)
sink = TreeSink() sink = TreeSink()
rcsparse.parse(open(path, 'rb'), sink) rcsparse.parse(open(path, 'rb'), sink)
filtered_revs = _file_log(sink.revs.values(), sink.tags, sink.lockinfo, filtered_revs = _file_log(sink.revs.values(), sink.tags, sink.lockinfo,
sink.default_branch, rev) sink.default_branch, rev)
for rev in filtered_revs: for rev in filtered_revs:
if rev.prev and len(rev.number) == 2: if rev.prev and len(rev.number) == 2:
rev.changed = rev.prev.next_changed rev.changed = rev.prev.next_changed
options['cvs_tags'] = sink.tags options['cvs_tags'] = sink.tags
skipping to change at line 123 skipping to change at line 121
filtered_revs.sort(_logsort_rev_cmp) filtered_revs.sort(_logsort_rev_cmp)
if len(filtered_revs) < first: if len(filtered_revs) < first:
return [] return []
if limit: if limit:
return filtered_revs[first:first+limit] return filtered_revs[first:first+limit]
return filtered_revs return filtered_revs
def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}): def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
if self.itemtype(path_parts1, rev1) != vclib.FILE: # does auth-check if self.itemtype(path_parts1, rev1) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts1)))
% (string.join(path_parts1, "/")))
if self.itemtype(path_parts2, rev2) != vclib.FILE: # does auth-check if self.itemtype(path_parts2, rev2) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts2)))
% (string.join(path_parts2, "/")))
temp1 = tempfile.mktemp() fd1, temp1 = tempfile.mkstemp()
open(temp1, 'wb').write(self.openfile(path_parts1, rev1, {})[0].getvalue()) os.fdopen(fd1, 'wb').write(self.openfile(path_parts1, rev1, {})[0].getvalue(
temp2 = tempfile.mktemp() ))
open(temp2, 'wb').write(self.openfile(path_parts2, rev2, {})[0].getvalue()) fd2, temp2 = tempfile.mkstemp()
os.fdopen(fd2, 'wb').write(self.openfile(path_parts2, rev2, {})[0].getvalue(
))
r1 = self.itemlog(path_parts1, rev1, vclib.SORTBY_DEFAULT, 0, 0, {})[-1] r1 = self.itemlog(path_parts1, rev1, vclib.SORTBY_DEFAULT, 0, 0, {})[-1]
r2 = self.itemlog(path_parts2, rev2, vclib.SORTBY_DEFAULT, 0, 0, {})[-1] r2 = self.itemlog(path_parts2, rev2, vclib.SORTBY_DEFAULT, 0, 0, {})[-1]
info1 = (self.rcsfile(path_parts1, root=1, v=0), r1.date, r1.string) info1 = (self.rcsfile(path_parts1, root=1, v=0), r1.date, r1.string)
info2 = (self.rcsfile(path_parts2, root=1, v=0), r2.date, r2.string) info2 = (self.rcsfile(path_parts2, root=1, v=0), r2.date, r2.string)
diff_args = vclib._diff_args(type, options) diff_args = vclib._diff_args(type, options)
return vclib._diff_fp(temp1, temp2, info1, info2, return vclib._diff_fp(temp1, temp2, info1, info2,
self.utilities.diff or 'diff', diff_args) self.utilities.diff or 'diff', diff_args)
def annotate(self, path_parts, rev=None, include_text=False): def annotate(self, path_parts, rev=None, include_text=False):
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts)))
% (string.join(path_parts, "/")))
source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, include_text) source = blame.BlameSource(self.rcsfile(path_parts, 1), rev, include_text)
return source, source.revision return source, source.revision
def revinfo(self, rev): def revinfo(self, rev):
raise vclib.UnsupportedFeature raise vclib.UnsupportedFeature
def openfile(self, path_parts, rev, options): def openfile(self, path_parts, rev, options):
if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check if self.itemtype(path_parts, rev) != vclib.FILE: # does auth-check
raise vclib.Error("Path '%s' is not a file." raise vclib.Error("Path '%s' is not a file." % (_path_join(path_parts)))
% (string.join(path_parts, "/")))
path = self.rcsfile(path_parts, 1) path = self.rcsfile(path_parts, 1)
sink = COSink(rev) sink = COSink(rev)
rcsparse.parse(open(path, 'rb'), sink) rcsparse.parse(open(path, 'rb'), sink)
revision = sink.last and sink.last.string revision = sink.last and sink.last.string
return cStringIO.StringIO(string.join(sink.sstext.text, "\n")), revision return cStringIO.StringIO('\n'.join(sink.sstext.text)), revision
class MatchingSink(rcsparse.Sink): class MatchingSink(rcsparse.Sink):
"""Superclass for sinks that search for revisions based on tag or number""" """Superclass for sinks that search for revisions based on tag or number"""
def __init__(self, find): def __init__(self, find):
"""Initialize with tag name or revision number string to match against""" """Initialize with tag name or revision number string to match against"""
if not find or find == 'MAIN' or find == 'HEAD': if not find or find == 'MAIN' or find == 'HEAD':
self.find = None self.find = None
else: else:
self.find = find self.find = find
skipping to change at line 302 skipping to change at line 296
def set_revision_info(self, revision, log, text): def set_revision_info(self, revision, log, text):
# check revs.has_key(revision) # check revs.has_key(revision)
rev = self.revs[revision] rev = self.revs[revision]
rev.log = log rev.log = log
changed = None changed = None
added = 0 added = 0
deled = 0 deled = 0
if self.head != revision: if self.head != revision:
changed = 1 changed = 1
lines = string.split(text, '\n') lines = text.split('\n')
idx = 0 idx = 0
while idx < len(lines): while idx < len(lines):
command = lines[idx] command = lines[idx]
dmatch = self.d_command.match(command) dmatch = self.d_command.match(command)
idx = idx + 1 idx = idx + 1
if dmatch: if dmatch:
deled = deled + string.atoi(dmatch.group(2)) deled = deled + int(dmatch.group(2))
else: else:
amatch = self.a_command.match(command) amatch = self.a_command.match(command)
if amatch: if amatch:
count = string.atoi(amatch.group(2)) count = int(amatch.group(2))
added = added + count added = added + count
idx = idx + count idx = idx + count
elif command: elif command:
raise "error while parsing deltatext: %s" % command raise vclib.Error("error while parsing deltatext: %s" % command)
if len(rev.number) == 2: if len(rev.number) == 2:
rev.next_changed = changed and "+%i -%i" % (deled, added) rev.next_changed = changed and "+%i -%i" % (deled, added)
else: else:
rev.changed = changed and "+%i -%i" % (added, deled) rev.changed = changed and "+%i -%i" % (added, deled)
class StreamText: class StreamText:
d_command = re.compile('^d(\d+)\\s(\\d+)') d_command = re.compile('^d(\d+)\\s(\\d+)')
a_command = re.compile('^a(\d+)\\s(\\d+)') a_command = re.compile('^a(\d+)\\s(\\d+)')
def __init__(self, text): def __init__(self, text):
self.text = string.split(text, "\n") self.text = text.split('\n')
def command(self, cmd): def command(self, cmd):
adjust = 0 adjust = 0
add_lines_remaining = 0 add_lines_remaining = 0
diffs = string.split(cmd, "\n") diffs = cmd.split('\n')
if diffs[-1] == "": if diffs[-1] == "":
del diffs[-1] del diffs[-1]
if len(diffs) == 0: if len(diffs) == 0:
return return
if diffs[0] == "": if diffs[0] == "":
del diffs[0] del diffs[0]
for command in diffs: for command in diffs:
if add_lines_remaining > 0: if add_lines_remaining > 0:
# Insertion lines from a prior "a" command # Insertion lines from a prior "a" command
self.text.insert(start_line + adjust, command) self.text.insert(start_line + adjust, command)
add_lines_remaining = add_lines_remaining - 1 add_lines_remaining = add_lines_remaining - 1
adjust = adjust + 1 adjust = adjust + 1
continue continue
dmatch = self.d_command.match(command) dmatch = self.d_command.match(command)
amatch = self.a_command.match(command) amatch = self.a_command.match(command)
if dmatch: if dmatch:
# "d" - Delete command # "d" - Delete command
start_line = string.atoi(dmatch.group(1)) start_line = int(dmatch.group(1))
count = string.atoi(dmatch.group(2)) count = int(dmatch.group(2))
begin = start_line + adjust - 1 begin = start_line + adjust - 1
del self.text[begin:begin + count] del self.text[begin:begin + count]
adjust = adjust - count adjust = adjust - count
elif amatch: elif amatch:
# "a" - Add command # "a" - Add command
start_line = string.atoi(amatch.group(1)) start_line = int(amatch.group(1))
count = string.atoi(amatch.group(2)) count = int(amatch.group(2))
add_lines_remaining = count add_lines_remaining = count
else: else:
raise RuntimeError, 'Error parsing diff commands' raise RuntimeError, 'Error parsing diff commands'
def secondnextdot(s, start): def secondnextdot(s, start):
# find the position the second dot after the start index. # find the position the second dot after the start index.
return string.find(s, '.', string.find(s, '.', start) + 1) return s.find('.', s.find('.', start) + 1)
class COSink(MatchingSink): class COSink(MatchingSink):
def __init__(self, rev): def __init__(self, rev):
MatchingSink.__init__(self, rev) MatchingSink.__init__(self, rev)
def set_head_revision(self, revision): def set_head_revision(self, revision):
self.head = Revision(revision) self.head = Revision(revision)
self.last = None self.last = None
self.sstext = None self.sstext = None
 End of changes. 19 change blocks. 
29 lines changed or deleted 25 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)