Beispiel #1
0
 def openfile(self, path_parts, rev=None):
     path = self.rcsfile(path_parts, 1)
     sink = COSink(rev)
     rcsparse.Parser().parse(open(path, 'rb'), sink)
     revision = sink.last and sink.last.string
     return cStringIO.StringIO(string.join(sink.sstext.text,
                                           "\n")), revision
def pass1(ctx):
    cd = CollectData(ctx.cvsroot, DATAFILE)
    p = rcsparse.Parser()
    stats = [0]
    os.path.walk(ctx.cvsroot, visit_file, (cd, p, stats))
    if ctx.verbose:
        print 'processed', stats[0], 'files'
    def parse_cvs_file(self, rcs_pathname):
        try:
            rcsfile = open(rcs_pathname, 'r')
        except:
            try:
                dirname, fname = os.path.split(rcs_pathname)
                rcs_pathname = os.path.join(dirname, "Attic", fname)
                rcsfile = open(rcs_pathname, 'r')
            except:
                ### should use a better error
                raise RuntimeError, (
                    'error: %s appeared to be under CVS control, '
                    'but the RCS file is inaccessible.' % rcs_pathname)

        rcsparse.Parser().parse(rcsfile, self)
Beispiel #4
0
    def dirlogs(self, path_parts, rev, entries, options):
        """see vclib.Repository.dirlogs docstring

    rev can be a tag name or None. if set only information from revisions
    matching the tag will be retrieved

    Option values recognized by this implementation:

      cvs_subdirs
        boolean. true to fetch logs of the most recently modified file in each
        subdirectory

    Option values returned by this implementation:

      cvs_tags, cvs_branches
        lists of tag and branch names encountered in the directory
    """
        subdirs = options.get('cvs_subdirs', 0)

        dirpath = self._getpath(path_parts)
        alltags = {  # all the tags seen in the files of this dir
            'MAIN': '',
            'HEAD': '1.1'
        }

        for entry in entries:
            entry.rev = entry.date = entry.author = entry.dead = entry.log = None
            path = _log_path(entry, dirpath, subdirs)
            if path:
                entry.path = path
                try:
                    rcsparse.Parser().parse(open(path, 'rb'),
                                            InfoSink(entry, rev, alltags))
                except IOError, e:
                    entry.errors.append("rcsparse error: %s" % e)
                except RuntimeError, e:
                    entry.errors.append("rcsparse error: %s" % e)
                except rcsparse.RCSStopParser:
                    pass
Beispiel #5
0
    def itemlog(self, path_parts, rev, options):
        """see vclib.Repository.itemlog docstring

    rev parameter can be a revision number, a branch number, a tag name,
    or None. If None, will return information about all revisions, otherwise,
    will only return information about the specified revision or branch.

    Option values returned by this implementation:

      cvs_tags
        dictionary of Tag objects for all tags encountered
    """
        path = self.rcsfile(path_parts, 1)
        sink = TreeSink()
        rcsparse.Parser().parse(open(path, 'rb'), sink)
        filtered_revs = _file_log(sink.revs.values(), sink.tags,
                                  sink.default_branch, rev)
        for rev in filtered_revs:
            if rev.prev and len(rev.number) == 2:
                rev.changed = rev.prev.next_changed
        options['cvs_tags'] = sink.tags

        return filtered_revs
Beispiel #6
0
    def parse_cvs_file(self, rcs_pathname, opt_rev=None, opt_m_timestamp=None):
        # Args in:  opt_rev - requested revision
        #           opt_m - time since modified
        # Args out: revision_map
        #           timestamp
        #           revision_deltatext

        # CheckHidden(rcs_pathname)
        try:
            rcsfile = open(rcs_pathname, 'rb')
        except:
            raise RuntimeError, (
                'error: %s appeared to be under CVS control, ' +
                'but the RCS file is inaccessible.') % rcs_pathname

        rcsparse.Parser().parse(rcsfile, self)
        rcsfile.close()

        if opt_rev in [None, '', 'HEAD']:
            # Explicitly specified topmost revision in tree
            revision = self.head_revision
        else:
            # Symbolic tag or specific revision number specified.
            revision = self.map_tag_to_revision(opt_rev)
            if revision == '':
                raise RuntimeError, 'error: -r: No such revision: ' + opt_rev

        # The primordial revision is not always 1.1!  Go find it.
        primordial = revision
        while self.prev_revision.get(primordial):
            primordial = self.prev_revision[primordial]

        # Don't display file at all, if -m option is specified and no
        # changes have been made in the specified file.
        if opt_m_timestamp and self.timestamp[revision] < opt_m_timestamp:
            return ''

        # Figure out how many lines were in the primordial, i.e. version 1.1,
        # check-in by moving backward in time from the head revision to the
        # first revision.
        line_count = 0
        if self.revision_deltatext.get(self.head_revision):
            tmp_array = self.deltatext_split(self.head_revision)
            line_count = len(tmp_array)

        skip = 0

        rev = self.prev_revision.get(self.head_revision)
        while rev:
            diffs = self.deltatext_split(rev)
            for command in diffs:
                dmatch = self.d_command.match(command)
                amatch = self.a_command.match(command)
                if skip > 0:
                    # Skip insertion lines from a prior "a" command
                    skip = skip - 1
                elif dmatch:
                    # "d" - Delete command
                    start_line = string.atoi(dmatch.group(1))
                    count = string.atoi(dmatch.group(2))
                    line_count = line_count - count
                elif amatch:
                    # "a" - Add command
                    start_line = string.atoi(amatch.group(1))
                    count = string.atoi(amatch.group(2))
                    skip = count
                    line_count = line_count + count
                else:
                    raise RuntimeError, 'error: illegal RCS file'

            rev = self.prev_revision.get(rev)

        # Now, play the delta edit commands *backwards* from the primordial
        # revision forward, but rather than applying the deltas to the text of
        # each revision, apply the changes to an array of revision numbers.
        # This creates a "revision map" -- an array where each element
        # represents a line of text in the given revision but contains only
        # the revision number in which the line was introduced rather than
        # the line text itself.
        #
        # Note: These are backward deltas for revisions on the trunk and
        # forward deltas for branch revisions.

        # Create initial revision map for primordial version.
        self.revision_map = [primordial] * line_count

        ancestors = [
            revision,
        ] + self.ancestor_revisions(revision)
        ancestors = ancestors[:-1]  # Remove "1.1"
        last_revision = primordial
        ancestors.reverse()
        for revision in ancestors:
            is_trunk_revision = self.trunk_rev.match(revision) is not None

            if is_trunk_revision:
                diffs = self.deltatext_split(last_revision)

                # Revisions on the trunk specify deltas that transform a
                # revision into an earlier revision, so invert the translation
                # of the 'diff' commands.
                for command in diffs:
                    if skip > 0:
                        skip = skip - 1
                    else:
                        dmatch = self.d_command.match(command)
                        amatch = self.a_command.match(command)
                        if dmatch:
                            start_line = string.atoi(dmatch.group(1))
                            count = string.atoi(dmatch.group(2))
                            temp = []
                            while count > 0:
                                temp.append(revision)
                                count = count - 1
                            self.revision_map = (
                                self.revision_map[:start_line - 1] + temp +
                                self.revision_map[start_line - 1:])
                        elif amatch:
                            start_line = string.atoi(amatch.group(1))
                            count = string.atoi(amatch.group(2))
                            del self.revision_map[start_line:start_line +
                                                  count]
                            skip = count
                        else:
                            raise RuntimeError, 'Error parsing diff commands'

            else:
                # Revisions on a branch are arranged backwards from those on
                # the trunk.  They specify deltas that transform a revision
                # into a later revision.
                adjust = 0
                diffs = self.deltatext_split(revision)
                for command in diffs:
                    if skip > 0:
                        skip = skip - 1
                    else:
                        dmatch = self.d_command.match(command)
                        amatch = self.a_command.match(command)
                        if dmatch:
                            start_line = string.atoi(dmatch.group(1))
                            count = string.atoi(dmatch.group(2))
                            adj_begin = start_line + adjust - 1
                            adj_end = start_line + adjust - 1 + count
                            del self.revision_map[adj_begin:adj_end]
                            adjust = adjust - count
                        elif amatch:
                            start_line = string.atoi(amatch.group(1))
                            count = string.atoi(amatch.group(2))
                            skip = count
                            temp = []
                            while count > 0:
                                temp.append(revision)
                                count = count - 1
                            self.revision_map = (
                                self.revision_map[:start_line + adjust] +
                                temp + self.revision_map[start_line + adjust:])
                            adjust = adjust + skip
                        else:
                            raise RuntimeError, 'Error parsing diff commands'

            last_revision = revision

        return revision