metanorma-utils 1.11.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/utils/log.rb +48 -128
- data/lib/utils/log_html.rb +163 -0
- data/lib/utils/version.rb +1 -1
- data/metanorma-utils.gemspec +1 -1
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3356c5d36c4605ce33d895949bb01b4bc59c823ef73fa6974844746578347087
|
|
4
|
+
data.tar.gz: 13f3f9e75e204cb1c152186e9c0feae34b02542dde612626535d598022a8cd50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f90ebfb556dadc68dde7ed04ed93f44819e69a60fe0daab2775d9cb61726b12222cfe187456770f92399a250dd6d52b079a56f6ad6a2da0a253b72ca7a7a7c03
|
|
7
|
+
data.tar.gz: 25a38f448ca9883380623391f12f8ee6c83b1ed8f4556cab5f6eca39baea3fd79cbbdd8553cc42b265a2b64dbd2e1078a1e7c392a28f9f98a27479f0d0019b86
|
data/lib/utils/log.rb
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
require "htmlentities"
|
|
2
|
+
require_relative "log_html"
|
|
2
3
|
|
|
3
4
|
module Metanorma
|
|
4
5
|
module Utils
|
|
5
6
|
class Log
|
|
6
7
|
attr_writer :xml, :suppress_log
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
# messages: hash of message IDs to {error, severity, category}
|
|
10
|
+
# severity: 0: abort; 1: serious; 2: not serious; 3: info only
|
|
11
|
+
def initialize(messages = {})
|
|
9
12
|
@log = {}
|
|
10
13
|
@c = HTMLEntities.new
|
|
11
14
|
@mapid = {}
|
|
12
15
|
@suppress_log = { severity: 4, category: [] }
|
|
16
|
+
@msg = messages.each_value do |v|
|
|
17
|
+
v[:error] = v[:error]
|
|
18
|
+
.encode("UTF-8", invalid: :replace, undef: :replace)
|
|
19
|
+
end
|
|
13
20
|
end
|
|
14
21
|
|
|
15
|
-
def
|
|
16
|
-
|
|
22
|
+
def add_msg(messages)
|
|
23
|
+
@msg.merge!(messages)
|
|
17
24
|
end
|
|
18
25
|
|
|
19
26
|
def save_to(filename, dir = nil)
|
|
@@ -24,21 +31,28 @@ module Metanorma
|
|
|
24
31
|
@htmlfilename = "#{b}.html"
|
|
25
32
|
end
|
|
26
33
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@
|
|
30
|
-
@
|
|
31
|
-
|
|
32
|
-
@
|
|
34
|
+
def add_prep(id)
|
|
35
|
+
id = id.to_sym
|
|
36
|
+
@msg[id] or raise "Logging: Error #{id} is not defined!"
|
|
37
|
+
@novalid || suppress_log?(id) and return nil
|
|
38
|
+
@log[@msg[id][:category]] ||= []
|
|
39
|
+
@msg[id]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def add(id, loc, display: true, params: [])
|
|
43
|
+
m = add_prep(id) or return
|
|
44
|
+
msg = create_entry(loc, m[:error],
|
|
45
|
+
m[:severity], params)
|
|
46
|
+
@log[m[:category]] << msg
|
|
33
47
|
loc = loc.nil? ? "" : "(#{current_location(loc)}): "
|
|
34
|
-
suppress_display?(category, loc, msg, display) or
|
|
35
|
-
warn "#{category}: #{loc}#{msg}"
|
|
48
|
+
suppress_display?(m[:category], loc, msg, display) or
|
|
49
|
+
warn "#{m[:category]}: #{loc}#{msg[:error]}"
|
|
36
50
|
end
|
|
37
51
|
|
|
38
52
|
def abort_messages
|
|
39
53
|
@log.values.each_with_object([]) do |v, m|
|
|
40
54
|
v.each do |e|
|
|
41
|
-
e[:severity].zero? and m << e[:
|
|
55
|
+
e[:severity].zero? and m << e[:error]
|
|
42
56
|
end
|
|
43
57
|
end
|
|
44
58
|
end
|
|
@@ -51,9 +65,10 @@ module Metanorma
|
|
|
51
65
|
end
|
|
52
66
|
end
|
|
53
67
|
|
|
54
|
-
def suppress_log?(
|
|
55
|
-
category
|
|
56
|
-
|
|
68
|
+
def suppress_log?(id)
|
|
69
|
+
category = @msg[id][:category]
|
|
70
|
+
category && /^Fetching /.match?(@msg[id][:error]) ||
|
|
71
|
+
@suppress_log[:severity] <= @msg[id][:severity] ||
|
|
57
72
|
@suppress_log[:category].include?(category)
|
|
58
73
|
end
|
|
59
74
|
|
|
@@ -62,18 +77,30 @@ module Metanorma
|
|
|
62
77
|
!display
|
|
63
78
|
end
|
|
64
79
|
|
|
65
|
-
def create_entry(loc, msg, severity)
|
|
66
|
-
|
|
80
|
+
def create_entry(loc, msg, severity, params)
|
|
81
|
+
interpolated = interpolate_msg(msg, params)
|
|
67
82
|
item = { location: current_location(loc), severity: severity,
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
83
|
+
error: interpolated, context: context(loc),
|
|
84
|
+
line: line(loc, msg) }
|
|
85
|
+
if item[:error].include?(" :: ")
|
|
86
|
+
a = item[:error].split(" :: ", 2)
|
|
71
87
|
item[:context] = a[1]
|
|
72
|
-
item[:
|
|
88
|
+
item[:error] = a[0]
|
|
73
89
|
end
|
|
74
90
|
item
|
|
75
91
|
end
|
|
76
92
|
|
|
93
|
+
def interpolate_msg(msg, params)
|
|
94
|
+
# Count %s placeholders in the message
|
|
95
|
+
placeholder_count = msg.scan(/%s/).length
|
|
96
|
+
interpolation_params = if params.empty?
|
|
97
|
+
::Array.new(placeholder_count, "")
|
|
98
|
+
else
|
|
99
|
+
params
|
|
100
|
+
end
|
|
101
|
+
placeholder_count.zero? ? msg : (msg % interpolation_params)
|
|
102
|
+
end
|
|
103
|
+
|
|
77
104
|
def current_location(node)
|
|
78
105
|
if node.nil? then ""
|
|
79
106
|
elsif node.respond_to?(:id) && !node.id.nil? then "ID #{node.id}"
|
|
@@ -133,113 +160,6 @@ module Metanorma
|
|
|
133
160
|
end
|
|
134
161
|
ret.to_xml
|
|
135
162
|
end
|
|
136
|
-
|
|
137
|
-
def log_hdr(file)
|
|
138
|
-
<<~HTML
|
|
139
|
-
<html><head><title>#{file} errors</title>
|
|
140
|
-
<meta charset="UTF-8"/>
|
|
141
|
-
<style> pre { white-space: pre-wrap; }
|
|
142
|
-
thead th { font-weight: bold; background-color: aqua; }
|
|
143
|
-
.severity0 { font-weight: bold; background-color: lightpink }
|
|
144
|
-
.severity1 { font-weight: bold; }
|
|
145
|
-
.severity2 { }
|
|
146
|
-
.severity3 { font-style: italic; color: grey; }
|
|
147
|
-
</style>
|
|
148
|
-
</head><body><h1>#{file} errors</h1>
|
|
149
|
-
<ul>#{log_index}</ul>
|
|
150
|
-
HTML
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def log_index
|
|
154
|
-
@log.each_with_object([]) do |(k, v), m|
|
|
155
|
-
m << <<~HTML
|
|
156
|
-
<li><p><b><a href="##{to_ncname(k)}">#{k}</a></b>: #{index_severities(v)}</p></li>
|
|
157
|
-
HTML
|
|
158
|
-
end.join("\n")
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def index_severities(entries)
|
|
162
|
-
s = entries.each_with_object({}) do |e, m|
|
|
163
|
-
m[e[:severity]] ||= 0
|
|
164
|
-
m[e[:severity]] += 1
|
|
165
|
-
end.compact
|
|
166
|
-
s.keys.sort.map do |k|
|
|
167
|
-
"Severity #{k}: <b>#{s[k]}</b> errors"
|
|
168
|
-
end.join("; ")
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def write(file = nil)
|
|
172
|
-
(!file && @filename) or save_to(file || "metanorma", nil)
|
|
173
|
-
File.open(@filename, "w:UTF-8") do |f|
|
|
174
|
-
f.puts log_hdr(@filename)
|
|
175
|
-
@log.each_key { |key| write_key(f, key) }
|
|
176
|
-
f.puts "</body></html>\n"
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def write_key(file, key)
|
|
181
|
-
file.puts <<~HTML
|
|
182
|
-
<h2 id="#{to_ncname(key)}">#{key}</h2>\n<table border="1">
|
|
183
|
-
<thead><th width="5%">Line</th><th width="20%">ID</th>
|
|
184
|
-
<th width="30%">Message</th><th width="40%">Context</th><th width="5%">Severity</th></thead>
|
|
185
|
-
<tbody>
|
|
186
|
-
HTML
|
|
187
|
-
@log[key].sort_by { |a| [a[:line], a[:location], a[:message]] }
|
|
188
|
-
.each do |n|
|
|
189
|
-
write_entry(file, render_preproc_entry(n))
|
|
190
|
-
end
|
|
191
|
-
file.puts "</tbody></table>\n"
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
def render_preproc_entry(entry)
|
|
195
|
-
ret = entry.dup
|
|
196
|
-
ret[:line] = nil if ret[:line] == "000000"
|
|
197
|
-
ret[:location] = loc_link(entry)
|
|
198
|
-
ret[:message] = break_up_long_str(entry[:message], 10, 2)
|
|
199
|
-
.gsub(/`([^`]+)`/, "<code>\\1</code>")
|
|
200
|
-
ret[:context] = context_render(entry)
|
|
201
|
-
ret.compact
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
def context_render(entry)
|
|
205
|
-
entry[:context] or return nil
|
|
206
|
-
entry[:context].split("\n").first(5)
|
|
207
|
-
.join("\n").gsub("><", "> <")
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
def mapid(old, new)
|
|
211
|
-
@mapid[old] = new
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def loc_link(entry)
|
|
215
|
-
loc = entry[:location]
|
|
216
|
-
loc.nil? || loc.empty? and loc = "--"
|
|
217
|
-
loc, url = loc_to_url(loc)
|
|
218
|
-
loc &&= break_up_long_str(loc, 10, 2)
|
|
219
|
-
url and loc = "<a href='#{url}'>#{loc}</a>"
|
|
220
|
-
loc
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
def loc_to_url(loc)
|
|
224
|
-
/^ID /.match?(loc) or return [loc, nil]
|
|
225
|
-
loc.sub!(/^ID /, "")
|
|
226
|
-
loc = @mapid[loc] while @mapid[loc]
|
|
227
|
-
url = "#{@htmlfilename}##{to_ncname loc}"
|
|
228
|
-
[loc, url]
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
def break_up_long_str(str, threshold, punct)
|
|
232
|
-
Metanorma::Utils.break_up_long_str(str, threshold, punct)
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
def write_entry(file, entry)
|
|
236
|
-
entry[:context] &&= @c.encode(break_up_long_str(entry[:context], 40, 2))
|
|
237
|
-
file.print <<~HTML
|
|
238
|
-
<tr class="severity#{entry[:severity]}">
|
|
239
|
-
<td>#{entry[:line]}</td><th><code>#{entry[:location]}</code></th>
|
|
240
|
-
<td>#{entry[:message]}</td><td><pre>#{entry[:context]}</pre></td><td>#{entry[:severity]}</td></tr>
|
|
241
|
-
HTML
|
|
242
|
-
end
|
|
243
163
|
end
|
|
244
164
|
end
|
|
245
165
|
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
module Metanorma
|
|
2
|
+
module Utils
|
|
3
|
+
class Log
|
|
4
|
+
def to_ncname(tag)
|
|
5
|
+
::Metanorma::Utils.to_ncname(tag)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def log_hdr(file)
|
|
9
|
+
<<~HTML
|
|
10
|
+
<html><head><title>#{file} errors</title>
|
|
11
|
+
<meta charset="UTF-8"/>
|
|
12
|
+
<style> pre { white-space: pre-wrap; }
|
|
13
|
+
thead th { font-weight: bold; background-color: aqua; }
|
|
14
|
+
.severity0 { font-weight: bold; background-color: lightpink }
|
|
15
|
+
.severity1 { font-weight: bold; }
|
|
16
|
+
.severity2 { }
|
|
17
|
+
.severity3 { font-style: italic; color: grey; }
|
|
18
|
+
</style>
|
|
19
|
+
</head><body><h1>#{file} errors</h1>
|
|
20
|
+
<ul>#{log_index}</ul>
|
|
21
|
+
HTML
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def log_index
|
|
25
|
+
@log.each_with_object([]) do |(k, v), m|
|
|
26
|
+
m << <<~HTML
|
|
27
|
+
<li><p><b><a href="##{to_ncname(k)}">#{k}</a></b>: #{index_severities(v)}</p></li>
|
|
28
|
+
HTML
|
|
29
|
+
end.join("\n")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def index_severities(entries)
|
|
33
|
+
s = entries.each_with_object({}) do |e, m|
|
|
34
|
+
m[e[:severity]] ||= 0
|
|
35
|
+
m[e[:severity]] += 1
|
|
36
|
+
end.compact
|
|
37
|
+
s.keys.sort.map do |k|
|
|
38
|
+
"Severity #{k}: <b>#{s[k]}</b> errors"
|
|
39
|
+
end.join("; ")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def write(file = nil)
|
|
43
|
+
(!file && @filename) or save_to(file || "metanorma", nil)
|
|
44
|
+
File.open(@filename, "w:UTF-8") do |f|
|
|
45
|
+
f.puts log_hdr(@filename)
|
|
46
|
+
@log.each_key { |key| write_key(f, key) }
|
|
47
|
+
f.puts "</body></html>\n"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def write_key(file, key)
|
|
52
|
+
file.puts <<~HTML
|
|
53
|
+
<h2 id="#{to_ncname(key)}">#{key}</h2>\n<table border="1">
|
|
54
|
+
<thead><th width="5%">Line</th><th width="20%">ID</th>
|
|
55
|
+
<th width="30%">Message</th><th width="40%">Context</th><th width="5%">Severity</th></thead>
|
|
56
|
+
<tbody>
|
|
57
|
+
HTML
|
|
58
|
+
@log[key].sort_by { |a| [a[:line], a[:location], a[:error]] }
|
|
59
|
+
.each do |n|
|
|
60
|
+
write_entry(file, render_preproc_entry(n))
|
|
61
|
+
end
|
|
62
|
+
file.puts "</tbody></table>\n"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def render_preproc_entry(entry)
|
|
66
|
+
ret = entry.dup
|
|
67
|
+
ret[:line] = nil if ret[:line] == "000000"
|
|
68
|
+
ret[:location] = loc_link(entry)
|
|
69
|
+
ret[:error] = break_up_long_str(entry[:error], 10, 2)
|
|
70
|
+
.gsub(/`([^`]+)`/, "<code>\\1</code>")
|
|
71
|
+
ret[:context] = context_render(entry)
|
|
72
|
+
ret.compact
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def context_render(entry)
|
|
76
|
+
entry[:context] or return nil
|
|
77
|
+
entry[:context].split("\n").first(5)
|
|
78
|
+
.join("\n").gsub("><", "> <")
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def mapid(old, new)
|
|
82
|
+
@mapid[old] = new
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def loc_link(entry)
|
|
86
|
+
loc = entry[:location]
|
|
87
|
+
loc.nil? || loc.empty? and loc = "--"
|
|
88
|
+
loc, url = loc_to_url(loc)
|
|
89
|
+
loc &&= break_up_long_str(loc, 10, 2)
|
|
90
|
+
url and loc = "<a href='#{url}'>#{loc}</a>"
|
|
91
|
+
loc
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def loc_to_url(loc)
|
|
95
|
+
/^ID /.match?(loc) or return [loc, nil]
|
|
96
|
+
loc.sub!(/^ID /, "")
|
|
97
|
+
loc = @mapid[loc] while @mapid[loc]
|
|
98
|
+
url = "#{@htmlfilename}##{to_ncname loc}"
|
|
99
|
+
[loc, url]
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def break_up_long_str(str, threshold, punct)
|
|
103
|
+
Metanorma::Utils.break_up_long_str(str, threshold, punct)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def write_entry(file, entry)
|
|
107
|
+
entry[:context] &&= @c.encode(break_up_long_str(entry[:context], 40, 2))
|
|
108
|
+
file.print <<~HTML
|
|
109
|
+
<tr class="severity#{entry[:severity]}">
|
|
110
|
+
<td>#{entry[:line]}</td><th><code>#{entry[:location]}</code></th>
|
|
111
|
+
<td>#{entry[:error]}</td><td><pre>#{entry[:context]}</pre></td><td>#{entry[:severity]}</td></tr>
|
|
112
|
+
HTML
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def display_messages
|
|
116
|
+
grouped = group_messages_by_category
|
|
117
|
+
grouped.map { |cat, keys| format_category_section(cat, keys) }
|
|
118
|
+
.join("\n")
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def group_messages_by_category
|
|
122
|
+
sort_messages_by_category_and_key
|
|
123
|
+
.group_by { |k| @msg[k][:category] }
|
|
124
|
+
.sort_by { |cat, _| cat }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def format_category_section(category, keys)
|
|
128
|
+
lines = keys.map { |k| format_error_line(k) }
|
|
129
|
+
"#{category}:\n#{lines.join("\n")}"
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def format_error_line(key)
|
|
133
|
+
padded_key = key.to_s.ljust(12)
|
|
134
|
+
"\t#{padded_key}: #{@msg[key][:error]}"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def sort_messages_by_category_and_key
|
|
138
|
+
@msg.keys.sort do |a, b|
|
|
139
|
+
cat_cmp = @msg[a][:category] <=> @msg[b][:category]
|
|
140
|
+
a_parts = parse_message_key(a)
|
|
141
|
+
b_parts = parse_message_key(b)
|
|
142
|
+
cat_cmp.zero? ? compare_key_parts(a_parts, b_parts) : cat_cmp
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def parse_message_key(key)
|
|
147
|
+
match = key.to_s.match(/^(.+?)_(\d+)$/)
|
|
148
|
+
match ? [match[1], match[2].to_i] : [key.to_s, nil]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def compare_key_parts(a_parts, b_parts)
|
|
152
|
+
a_str, a_num = a_parts
|
|
153
|
+
b_str, b_num = b_parts
|
|
154
|
+
if a_num.nil? || b_num.nil?
|
|
155
|
+
a_str <=> b_str
|
|
156
|
+
else
|
|
157
|
+
str_cmp = a_str <=> b_str
|
|
158
|
+
str_cmp.zero? ? a_num <=> b_num : str_cmp
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
data/lib/utils/version.rb
CHANGED
data/metanorma-utils.gemspec
CHANGED
|
@@ -46,6 +46,6 @@ Gem::Specification.new do |spec|
|
|
|
46
46
|
spec.add_development_dependency "simplecov", "~> 0.15"
|
|
47
47
|
spec.add_development_dependency "timecop", "~> 0.9"
|
|
48
48
|
spec.add_development_dependency "webmock"
|
|
49
|
-
spec.add_development_dependency "canon"
|
|
49
|
+
spec.add_development_dependency "canon", "= 0.1.3"
|
|
50
50
|
# spec.metadata["rubygems_mfa_required"] = "true"
|
|
51
51
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: metanorma-utils
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: asciidoctor
|
|
@@ -280,16 +280,16 @@ dependencies:
|
|
|
280
280
|
name: canon
|
|
281
281
|
requirement: !ruby/object:Gem::Requirement
|
|
282
282
|
requirements:
|
|
283
|
-
- -
|
|
283
|
+
- - '='
|
|
284
284
|
- !ruby/object:Gem::Version
|
|
285
|
-
version:
|
|
285
|
+
version: 0.1.3
|
|
286
286
|
type: :development
|
|
287
287
|
prerelease: false
|
|
288
288
|
version_requirements: !ruby/object:Gem::Requirement
|
|
289
289
|
requirements:
|
|
290
|
-
- -
|
|
290
|
+
- - '='
|
|
291
291
|
- !ruby/object:Gem::Version
|
|
292
|
-
version:
|
|
292
|
+
version: 0.1.3
|
|
293
293
|
description: 'metanorma-utils provides utilities for the Metanorma stack
|
|
294
294
|
|
|
295
295
|
'
|
|
@@ -313,6 +313,7 @@ files:
|
|
|
313
313
|
- lib/utils/image.rb
|
|
314
314
|
- lib/utils/linestatus.rb
|
|
315
315
|
- lib/utils/log.rb
|
|
316
|
+
- lib/utils/log_html.rb
|
|
316
317
|
- lib/utils/main.rb
|
|
317
318
|
- lib/utils/namespace.rb
|
|
318
319
|
- lib/utils/version.rb
|