Re-update to rcsparse r2495 to get all the goodness of the new update script.
[cvs2svn.git] / cvs2svn_lib / keyword_expander.py
blobe180e1d1ef68bbaf2939a18c8a32958608b144c3
1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2007-2010 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """Expand RCS/CVS keywords."""
20 import re
21 import time
23 from cvs2svn_lib.context import Ctx
26 class _KeywordExpander:
27 """A class whose instances provide substitutions for CVS keywords.
29 This class is used via its __call__() method, which should be called
30 with a match object representing a match for a CVS keyword string.
31 The method returns the replacement for the matched text.
33 The __call__() method works by calling the method with the same name
34 as that of the CVS keyword (converted to lower case).
36 Instances of this class can be passed as the REPL argument to
37 re.sub()."""
39 date_fmt_old = "%Y/%m/%d %H:%M:%S" # CVS 1.11, rcs
40 date_fmt_new = "%Y-%m-%d %H:%M:%S" # CVS 1.12
42 date_fmt = date_fmt_new
44 @classmethod
45 def use_old_date_format(klass):
46 """Class method to ensure exact compatibility with CVS 1.11
47 output. Use this if you want to verify your conversion and you're
48 using CVS 1.11."""
49 klass.date_fmt = klass.date_fmt_old
51 def __init__(self, cvs_rev):
52 self.cvs_rev = cvs_rev
54 def __call__(self, match):
55 return '$%s: %s $' % (
56 match.group(1), getattr(self, match.group(1).lower())(),
59 def author(self):
60 return Ctx()._metadata_db[self.cvs_rev.metadata_id].original_author
62 def date(self):
63 return time.strftime(self.date_fmt, time.gmtime(self.cvs_rev.timestamp))
65 def header(self):
66 return '%s %s %s %s Exp' % (
67 self.source(), self.cvs_rev.rev, self.date(), self.author(),
70 def id(self):
71 return '%s %s %s %s Exp' % (
72 self.rcsfile(), self.cvs_rev.rev, self.date(), self.author(),
75 def locker(self):
76 # Handle kvl like kv, as a converted repo is supposed to have no
77 # locks.
78 return ''
80 def log(self):
81 # Would need some special handling.
82 return 'not supported by cvs2svn'
84 def name(self):
85 # Cannot work, as just creating a new symbol does not check out
86 # the revision again.
87 return 'not supported by cvs2svn'
89 def rcsfile(self):
90 return self.cvs_rev.cvs_file.rcs_basename + ",v"
92 def revision(self):
93 return self.cvs_rev.rev
95 def source(self):
96 project = self.cvs_rev.cvs_file.project
97 return '%s/%s%s,v' % (
98 project.cvs_repository_root,
99 project.cvs_module,
100 self.cvs_rev.cvs_file.cvs_path,
103 def state(self):
104 # We check out only live revisions.
105 return 'Exp'
108 _kws = 'Author|Date|Header|Id|Locker|Log|Name|RCSfile|Revision|Source|State'
109 _kw_re = re.compile(r'\$(' + _kws + r'):[^$\n]*\$')
110 _kwo_re = re.compile(r'\$(' + _kws + r')(:[^$\n]*)?\$')
113 def expand_keywords(text, cvs_rev):
114 """Return TEXT with keywords expanded for CVS_REV.
116 E.g., '$Author$' -> '$Author: jrandom $'."""
118 return _kwo_re.sub(_KeywordExpander(cvs_rev), text)
121 def collapse_keywords(text):
122 """Return TEXT with keywords collapsed.
124 E.g., '$Author: jrandom $' -> '$Author$'."""
126 return _kw_re.sub(r'$\1$', text)