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."""
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
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
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
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())(),
60 return Ctx()._metadata
_db
[self
.cvs_rev
.metadata_id
].original_author
63 return time
.strftime(self
.date_fmt
, time
.gmtime(self
.cvs_rev
.timestamp
))
66 return '%s %s %s %s Exp' % (
67 self
.source(), self
.cvs_rev
.rev
, self
.date(), self
.author(),
71 return '%s %s %s %s Exp' % (
72 self
.rcsfile(), self
.cvs_rev
.rev
, self
.date(), self
.author(),
76 # Handle kvl like kv, as a converted repo is supposed to have no
81 # Would need some special handling.
82 return 'not supported by cvs2svn'
85 # Cannot work, as just creating a new symbol does not check out
87 return 'not supported by cvs2svn'
90 return self
.cvs_rev
.cvs_file
.rcs_basename
+ ",v"
93 return self
.cvs_rev
.rev
96 project
= self
.cvs_rev
.cvs_file
.project
98 project
.cvs_repository_root
,
100 '/'.join(self
.cvs_rev
.cvs_file
.get_path_components(rcs
=True)),
104 # We check out only live revisions.
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
)