3 # (Be in -*- python -*- mode.)
5 # ====================================================================
6 # Copyright (c) 2006-2008 CollabNet. All rights reserved.
8 # This software is licensed as described in the file COPYING, which
9 # you should have received as part of this distribution. The terms
10 # are also available at http://subversion.tigris.org/license-1.html.
11 # If newer versions of this license are posted there, you may use a
12 # newer version instead, at your option.
14 # This software consists of voluntary contributions made by many
15 # individuals. For exact contribution history, see the revision
16 # history and logs, available at http://cvs2svn.tigris.org/.
17 # ====================================================================
19 """Filter an RCS file."""
25 sys
.path
.insert(0, os
.path
.dirname(os
.path
.dirname(sys
.argv
[0])))
27 import cvs2svn_rcsparse
31 return '@' + s
.replace('@', '@@') + '@'
34 def format_date(date
):
35 date_tuple
= time
.gmtime(date
)
37 if 1900 <= year
<= 1999:
38 year
= '%02d' % (year
- 1900)
41 return year
+ time
.strftime('.%m.%d.%H.%M.%S', date_tuple
)
44 class WriteRCSFileSink(cvs2svn_rcsparse
.Sink
):
45 """A Sink that outputs reconstructed RCS file contents."""
47 def __init__(self
, f
):
48 """Create a Sink object that will write its output into F.
50 F should be a file-like object."""
54 self
.principal_branch
= None
62 def set_head_revision(self
, revision
):
65 def set_principal_branch(self
, branch_name
):
66 self
.principal_branch
= branch_name
68 def set_access(self
, accessors
):
69 self
.accessors
= accessors
71 def define_tag(self
, name
, revision
):
72 self
.symbols
.append((name
, revision
,))
74 def set_locker(self
, revision
, locker
):
75 self
.lockers
.append((revision
, locker
,))
77 def set_locking(self
, mode
):
80 def set_comment(self
, comment
):
81 self
.comment
= comment
83 def set_expansion(self
, mode
):
86 def admin_completed(self
):
87 self
.f
.write('head\t%s;\n' % self
.head
)
88 if self
.principal_branch
is not None:
89 self
.f
.write('branch\t%s;\n' % self
.principal_branch
)
90 self
.f
.write('access')
91 for accessor
in self
.accessors
:
92 self
.f
.write('\n\t%s' % accessor
)
94 self
.f
.write('symbols')
95 for (name
, revision
) in self
.symbols
:
96 self
.f
.write('\n\t%s:%s' % (name
, revision
))
99 for (revision
, locker
) in self
.lockers
:
100 self
.f
.write('\n\t%s:%s' % (locker
, revision
))
102 if self
.locking
is not None:
103 self
.f
.write(' %s;' % self
.locking
)
105 if self
.comment
is not None:
106 self
.f
.write('comment\t%s;\n' % at_quote(self
.comment
))
107 if self
.expansion
is not None:
108 self
.f
.write('expand\t%s;\n' % at_quote(self
.expansion
))
112 self
, revision
, timestamp
, author
, state
, branches
, next
115 '\n%s\ndate\t%s;\tauthor %s;\tstate %s;\n'
116 % (revision
, format_date(timestamp
), author
, state
,)
118 self
.f
.write('branches')
119 for branch
in branches
:
120 self
.f
.write('\n\t%s' % branch
)
122 self
.f
.write('next\t%s;\n' % (next
or ''))
124 def tree_completed(self
):
127 def set_description(self
, description
):
128 self
.f
.write('\n\ndesc\n%s\n' % at_quote(description
))
130 def set_revision_info(self
, revision
, log
, text
):
133 self
.f
.write('%s\n' % revision
)
134 self
.f
.write('log\n%s\n' % at_quote(log
))
135 self
.f
.write('text\n%s\n' % at_quote(text
))
137 def parse_completed(self
):
141 class FilterSink(cvs2svn_rcsparse
.Sink
):
142 """A Sink that passes callbacks through to another sink.
144 This is intended for use as a base class for other filter classes
145 that modify the data before passing it through."""
147 def __init__(self
, sink
):
148 """Create a Sink object that will write its output into SINK.
150 SINK should be a cvs2svn_rcsparse.Sink."""
154 def set_head_revision(self
, revision
):
155 self
.sink
.set_head_revision(revision
)
157 def set_principal_branch(self
, branch_name
):
158 self
.sink
.set_principal_branch(branch_name
)
160 def set_access(self
, accessors
):
161 self
.sink
.set_access(accessors
)
163 def define_tag(self
, name
, revision
):
164 self
.sink
.define_tag(name
, revision
)
166 def set_locker(self
, revision
, locker
):
167 self
.sink
.set_locker(revision
, locker
)
169 def set_locking(self
, mode
):
170 self
.sink
.set_locking(mode
)
172 def set_comment(self
, comment
):
173 self
.sink
.set_comment(comment
)
175 def set_expansion(self
, mode
):
176 self
.sink
.set_expansion(mode
)
178 def admin_completed(self
):
179 self
.sink
.admin_completed()
182 self
, revision
, timestamp
, author
, state
, branches
, next
184 self
.sink
.define_revision(
185 revision
, timestamp
, author
, state
, branches
, next
188 def tree_completed(self
):
189 self
.sink
.tree_completed()
191 def set_description(self
, description
):
192 self
.sink
.set_description(description
)
194 def set_revision_info(self
, revision
, log
, text
):
195 self
.sink
.set_revision_info(revision
, log
, text
)
197 def parse_completed(self
):
198 self
.sink
.parse_completed()
201 if __name__
== '__main__':
203 for path
in sys
.argv
[1:]:
204 if os
.path
.isfile(path
) and path
.endswith(',v'):
205 cvs2svn_rcsparse
.parse(
206 open(path
, 'rb'), WriteRCSFileSink(sys
.stdout
)
209 sys
.stderr
.write('%r is being ignored.\n' % path
)
211 cvs2svn_rcsparse
.parse(sys
.stdin
, WriteRCSFileSink(sys
.stdout
))