Index: cvs2svn_lib/checkout_internal.py =================================================================== --- cvs2svn_lib/checkout_internal.py (revision 4535) +++ cvs2svn_lib/checkout_internal.py (working copy) @@ -634,6 +634,10 @@ return time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(self.cvs_rev.timestamp)) + def freebsd(self): + return '%s %s %s %s Exp' % \ + (self.source(), self.cvs_rev.rev, self.date(), self.author()) + def header(self): return '%s %s %s %s Exp' % \ (self.source(), self.cvs_rev.rev, self.date(), self.author()) @@ -664,7 +668,7 @@ def source(self): project = self.cvs_rev.cvs_file.project - return project.cvs_repository_root + '/' + project.cvs_module + \ + return 'src/' + project.cvs_module + \ self.cvs_rev.cvs_file.cvs_path + ",v" def state(self): @@ -675,7 +679,7 @@ class InternalRevisionReader(RevisionReader): """A RevisionReader that reads the contents from an own delta store.""" - _kws = 'Author|Date|Header|Id|Locker|Log|Name|RCSfile|Revision|Source|State' + _kws = 'FreeBSD' _kw_re = re.compile(r'\$(' + _kws + r'):[^$\n]*\$') _kwo_re = re.compile(r'\$(' + _kws + r')(:[^$\n]*)?\$') Index: cvs2svn_lib/symbol_transform.py =================================================================== --- cvs2svn_lib/symbol_transform.py (revision 4535) +++ cvs2svn_lib/symbol_transform.py (working copy) @@ -216,3 +216,63 @@ cvs_path = new_cvs_path +class SubtreeRevisionSymbolMapper(SymbolTransform): + """A SymbolTransform that transforms symbols within a whole repo subtree. + + The user has to specify a CVS repository path (a filename or + directory) and a revision number. All symbols under that path with + the specified revision number will be renamed to the specified new + name (which can be None if the symbol should be ignored). The + mappings can be set via a constructor argument or by calling + __setitem__(). Only the most specific rule is applied.""" + + def __init__(self, items=[]): + """Initialize the mapper. + + ITEMS is a list of tuples (cvs_path, revision, new_name) + which will be set as mappings. cvs_path is a string naming a + directory within the CVS repository.""" + + # A map {revision : {cvs_path : new_name}}: + self._map = {} + + for (cvs_path, revision, new_name) in items: + self[cvs_path, revision] = new_name + + def __setitem__(self, (cvs_path, revision), new_name): + """Set a mapping for a particular subtree and revision number.""" + + try: + revision_map = self._map[revision] + except KeyError: + revision_map = {} + self._map[revision] = revision_map + + if cvs_path in revision_map: + Log().warn( + 'Overwriting symbol transform for\n' + ' directory=%r revision=%s' + % (cvs_path, revision,) + ) + revision_map[cvs_path] = new_name + + def transform(self, cvs_file, symbol_name, revision): + try: + revision_map = self._map[revision] + except KeyError: + # No rules for that revision number: + return symbol_name + + cvs_path = cvs_file.filename + while True: + try: + return revision_map[cvs_path] + except KeyError: + new_cvs_path = os.path.dirname(cvs_path) + if new_cvs_path == cvs_path: + # No rules found for that path; return symbol name unaltered. + return symbol_name + else: + cvs_path = new_cvs_path + + Index: cvs2svn_lib/svn_output_option.py =================================================================== --- cvs2svn_lib/svn_output_option.py (revision 4535) +++ cvs2svn_lib/svn_output_option.py (working copy) @@ -72,9 +72,22 @@ pass - def __init__(self): + def __init__(self, author_transforms=None): self._mirror = RepositoryMirror() + def to_utf8(s): + if isinstance(s, unicode): + return s.encode('utf8') + else: + return s + + self.author_transforms = {} + if author_transforms is not None: + for (cvsauthor, name) in author_transforms.iteritems(): + cvsauthor = to_utf8(cvsauthor) + name = to_utf8(name) + self.author_transforms[cvsauthor] = name + def register_artifacts(self, which_pass): # These artifacts are needed for SymbolingsReader: artifact_manager.register_temp_file_needed( @@ -122,11 +135,16 @@ Ctx().revision_reader.start() self.add_delegate(StdoutDelegate(svn_rev_count)) + def _get_author(self, svn_commit): + author = svn_commit.get_author() + name = self.author_transforms.get(author, author) + return name + def _get_revprops(self, svn_commit): """Return the Subversion revprops for this SVNCommit.""" return { - 'svn:author' : svn_commit.get_author(), + 'svn:author' : self._get_author(svn_commit), 'svn:log' : svn_commit.get_log_msg(), 'svn:date' : format_date(svn_commit.date), } @@ -602,8 +620,8 @@ class DumpfileOutputOption(SVNOutputOption): """Output the result of the conversion into a dumpfile.""" - def __init__(self, dumpfile_path): - SVNOutputOption.__init__(self) + def __init__(self, dumpfile_path, author_transforms=None): + SVNOutputOption.__init__(self, author_transforms) self.dumpfile_path = dumpfile_path def check(self): @@ -621,8 +639,8 @@ class RepositoryOutputOption(SVNOutputOption): """Output the result of the conversion into an SVN repository.""" - def __init__(self, target): - SVNOutputOption.__init__(self) + def __init__(self, target, author_transforms=None): + SVNOutputOption.__init__(self, author_transforms) self.target = target def check(self): @@ -649,8 +667,8 @@ class NewRepositoryOutputOption(RepositoryOutputOption): """Output the result of the conversion into a new SVN repository.""" - def __init__(self, target, fs_type=None, bdb_txn_nosync=None): - RepositoryOutputOption.__init__(self, target) + def __init__(self, target, fs_type=None, bdb_txn_nosync=None, author_transforms=None): + RepositoryOutputOption.__init__(self, target, author_transforms) self.fs_type = fs_type self.bdb_txn_nosync = bdb_txn_nosync @@ -724,8 +742,8 @@ class ExistingRepositoryOutputOption(RepositoryOutputOption): """Output the result of the conversion into an existing SVN repository.""" - def __init__(self, target): - RepositoryOutputOption.__init__(self, target) + def __init__(self, target, author_transforms=None): + RepositoryOutputOption.__init__(self, target, author_transforms) def check(self): RepositoryOutputOption.check(self)