/
tagexpander.rb
125 lines (108 loc) · 2.86 KB
/
tagexpander.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# This file is part of fromcvs.
#
# fromcvs is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# fromcvs is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with fromcvs. If not, see <http://www.gnu.org/licenses/>.
#
module FromCVS
class TagExpander
def initialize(cvsroot)
@cvsroot = cvsroot
@keywords = {}
expandkw = []
self.methods.select{|m| m.to_s =~ /^expand_/}.each do |kw|
kw = kw.to_s
kw[/^expand_/] = ''
@keywords[kw] = kw
expandkw << kw
end
configs = %w{config options}
begin
until configs.empty? do
File.foreach(File.join(@cvsroot, 'CVSROOT', configs.shift)) do |line|
if m = /^\s*(?:LocalKeyword|tag)=(\w+)(?:=(\w+))?/.match(line)
@keywords[m[1]] = m[2] || 'Id'
elsif m = /^\s*(?:KeywordExpand|tagexpand)=(e|i)(\w+(?:,\w+)*)?/.match(line)
inc = m[1] == 'i'
keyws = (m[2] || '').split(',')
if inc
expandkw = keyws
else
expandkw -= keyws
end
end
end
end
rescue Errno::EACCES, Errno::ENOENT
retry
end
if expandkw.empty?
# produce unmatchable regexp
@kwre = Regexp.compile('$nonmatch')
else
@kwre = Regexp.compile('\$('+expandkw.join('|')+')(?::.*?)?\$')
end
end
def expand!(str, mode, rev)
str.gsub!(@kwre) do |s|
m = @kwre.match(s) # gsub passes String, not MatchData
case mode
when 'o', 'b'
s
when 'k'
"$#{m[1]}$"
when 'kv', nil
"$#{m[1]}: " + send("expand_#{@keywords[m[1]]}", rev) + ' $'
else
s
end
end
end
def expand_Author(rev)
rev.author
end
def expand_Date(rev)
rev.date.strftime('%Y/%m/%d %H:%M:%S')
end
def _expand_header(rev)
" #{rev.rev} " + expand_Date(rev) + " #{rev.author} #{rev.state}"
end
def expand_CVSHeader(rev)
rev.rcsfile + _expand_header(rev)
end
def expand_Header(rev)
File.join(@cvsroot, rev.rcsfile) + _expand_header(rev)
end
def expand_Id(rev)
File.basename(rev.rcsfile) + _expand_header(rev)
end
def expand_Name(rev)
if rev.syms
rev.syms[0]
else
""
end
end
def expand_RCSfile(rev)
File.basename(rev.rcsfile)
end
def expand_Revision(rev)
rev.rev
end
def expand_Source(rev)
File.join(@cvsroot, rev.rcsfile)
end
def expand_State(rev)
rev.state.to_s
end
end
end