dev 2.1.153 → 2.1.154

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/lib/apps/git.rb +207 -208
  3. data/lib/apps/msbuild.rb +90 -90
  4. data/lib/apps/nbench.rb +2 -1
  5. data/lib/apps/nuget.rb +57 -59
  6. data/lib/apps/svn.rb +137 -143
  7. data/lib/apps/wix.rb +47 -50
  8. data/lib/apps/xcodebuild.rb +13 -11
  9. data/lib/apps/zip.rb +25 -25
  10. data/lib/apps.rb +3 -1
  11. data/lib/base/array.rb +66 -64
  12. data/lib/base/command.rb +237 -238
  13. data/lib/base/dir.rb +73 -76
  14. data/lib/base/environment.rb +94 -99
  15. data/lib/base/file.rb +35 -33
  16. data/lib/base/gemspec.rb +47 -45
  17. data/lib/base/giturl.rb +88 -90
  18. data/lib/base/hash.rb +20 -15
  19. data/lib/base/history.rb +36 -33
  20. data/lib/base/internet.rb +22 -20
  21. data/lib/base/project.rb +410 -423
  22. data/lib/base/projects.rb +231 -246
  23. data/lib/base/source.rb +22 -20
  24. data/lib/base/string.rb +6 -4
  25. data/lib/base/text.rb +16 -14
  26. data/lib/base/timeout.rb +29 -28
  27. data/lib/base/timer.rb +23 -19
  28. data/lib/base/version.rb +68 -72
  29. data/lib/base.rb +5 -3
  30. data/lib/commands.rb +47 -43
  31. data/lib/dev.config.rb +3 -2
  32. data/lib/dev.rb +65 -66
  33. data/lib/tasks/add.rb +34 -40
  34. data/lib/tasks/analyze.rb +17 -15
  35. data/lib/tasks/build.rb +101 -103
  36. data/lib/tasks/clean.rb +6 -4
  37. data/lib/tasks/clobber.rb +20 -18
  38. data/lib/tasks/commit.rb +42 -44
  39. data/lib/tasks/default.rb +41 -39
  40. data/lib/tasks/doc.rb +10 -8
  41. data/lib/tasks/info.rb +8 -7
  42. data/lib/tasks/package.rb +23 -20
  43. data/lib/tasks/publish.rb +20 -25
  44. data/lib/tasks/pull.rb +9 -9
  45. data/lib/tasks/push.rb +11 -13
  46. data/lib/tasks/setup.rb +180 -183
  47. data/lib/tasks/test.rb +121 -107
  48. data/lib/tasks/update.rb +13 -11
  49. data/lib/tasks.rb +38 -42
  50. metadata +7 -9
  51. data/bin/dev +0 -3
data/lib/base/command.rb CHANGED
@@ -1,17 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  puts DELIMITER if defined?(DEBUG)
2
4
  puts __FILE__ if defined?(DEBUG)
3
5
 
4
- require 'time'
5
- require 'open3'
6
- require_relative('timeout.rb')
7
- require_relative('timer.rb')
8
- require_relative('array.rb')
9
- require_relative('hash.rb')
10
- require_relative('string.rb')
11
- require_relative('environment.rb')
12
- require_relative('dir.rb')
13
- BUFFER_SIZE=1024 if(!defined?(BUFFER_SIZE))
14
-
6
+ require "time"
7
+ require "open3"
8
+ require_relative("timeout")
9
+ require_relative("timer")
10
+ require_relative("array")
11
+ require_relative("hash")
12
+ require_relative("string")
13
+ require_relative("environment")
14
+ require_relative("dir")
15
+ BUFFER_SIZE = 1024 unless defined?(BUFFER_SIZE)
16
+
15
17
  # = Command
16
18
  #
17
19
  # execution of system commands
@@ -33,43 +35,41 @@ BUFFER_SIZE=1024 if(!defined?(BUFFER_SIZE))
33
35
  # - :end_time
34
36
  #
35
37
  class Command < Hash
36
- def initialize command
37
- self[:input] = ''
38
- self[:timeout] = 0
39
- self[:directory] = ''
40
- self[:exit_code] = 0
41
- self[:output] = ''
42
- self[:error] = ''
43
- self[:machine] = ''
44
- self[:user] = ''
45
- self[:start_time] = nil
46
- self[:end_time] = nil
47
-
48
- if(command.kind_of?(String))
49
- self[:input] = command
50
- end
51
-
52
- if(command.kind_of?(Hash))
53
- command.each{|k,v|self[k.to_sym]=v}
54
- self[:start_time]=Time.parse(self[:start_time]) if(self.has_key?(:start_time) && !self[:start_time].nil?)
55
- self[:end_time]=Time.parse(self[:end_time]) if(self.has_key?(:end_time) && !self[:end_time].nil?)
38
+ def initialize(command)
39
+ self[:input] = ""
40
+ self[:timeout] = 0
41
+ self[:directory] = ""
42
+ self[:exit_code] = 0
43
+ self[:output] = ""
44
+ self[:error] = ""
45
+ self[:machine] = ""
46
+ self[:user] = ""
47
+ self[:start_time] = nil
48
+ self[:end_time] = nil
49
+
50
+ self[:input] = command if command.is_a?(String)
51
+
52
+ if command.is_a?(Hash)
53
+ command.each { |k, v| self[k.to_sym] = v }
54
+ self[:start_time] = Time.parse(self[:start_time]) if key?(:start_time) && !self[:start_time].nil?
55
+ self[:end_time] = Time.parse(self[:end_time]) if key?(:end_time) && !self[:end_time].nil?
56
56
  end
57
- end
57
+ end
58
58
 
59
- def save filename
60
- File.open(filename,'w'){|f|f.write(to_json)}
59
+ def save(filename)
60
+ File.open(filename, "w") { |f| f.write(to_json) }
61
61
  end
62
62
 
63
- def open filename=''
64
- @filename=filename if filename.length > 0
65
- self.clear
66
- JSON.parse(IO.read(@filename)).each{|k,v| self[k.to_sym]=v}
67
- self[:start_time]=Time.parse(self[:start_time]) if(self.has_key?(:start_time))
68
- self[:end_time]=Time.parse(self[:end_time]) if(self.has_key?(:end_time))
63
+ def open(filename = "")
64
+ @filename = filename if filename.length.positive?
65
+ clear
66
+ JSON.parse(IO.read(@filename)).each { |k, v| self[k.to_sym] = v }
67
+ self[:start_time] = Time.parse(self[:start_time]) if key?(:start_time)
68
+ self[:end_time] = Time.parse(self[:end_time]) if key?(:end_time)
69
69
  end
70
70
 
71
71
  def quiet?
72
- (self.has_key?(:quiet) && self[:quiet])
72
+ (key?(:quiet) && self[:quiet])
73
73
  end
74
74
 
75
75
  def exit_code
@@ -79,255 +79,254 @@ class Command < Hash
79
79
  def output
80
80
  self[:output]
81
81
  end
82
+
82
83
  def error
83
84
  self[:error]
84
85
  end
86
+
85
87
  def self.executes?(command)
86
- cmd = Command.new({ :input => command, :quiet => true,:ignore_failure => true})
88
+ cmd = Command.new({ input: command, quiet: true, ignore_failure: true })
87
89
  cmd.execute
88
- if(cmd[:exit_code] == 0)
90
+ if (cmd[:exit_code]).zero?
89
91
  true
90
92
  else
91
93
  false
92
94
  end
93
95
  end
94
96
 
95
- # todo: add log of execution
96
- def execute value=nil
97
+ # TODO: add log of execution
98
+ def execute(value = nil)
99
+ puts (self[:input]).to_s if defined?(DEBUG)
97
100
 
98
- puts "#{self[:input]}" if defined?(DEBUG)
101
+ value.each { |k, v| self[k] = v } if !value.nil? && value.is_a?(Hash)
99
102
 
100
- if(!value.nil? && value.is_a?(Hash))
101
- value.each{|k,v|self[k]=v}
102
- end
103
+ pwd = Dir.pwd
104
+ self[:directory] = pwd if !key?(:directory) || self[:directory].length.zero?
103
105
 
104
- pwd=Dir.pwd
105
- self[:directory] = pwd if(!self.has_key?(:directory) || self[:directory].length==0)
106
-
107
- if(self[:timeout] > 0)
108
- puts "#{self[:input]} (#{self[:directory]}) timeout #{self[:timeout].to_s}" if(!quiet?)
106
+ if (self[:timeout]).positive?
107
+ puts "#{self[:input]} (#{self[:directory]}) timeout #{self[:timeout]}" unless quiet?
109
108
  else
110
- puts "#{self[:input]} (#{self[:directory]})" if(!quiet?)
109
+ puts "#{self[:input]} (#{self[:directory]})" unless quiet?
111
110
  end
112
111
 
113
- self[:machine] = Command.machine
114
- self[:user] = Command.user
112
+ self[:machine] = Command.machine
113
+ self[:user] = Command.user
115
114
 
116
- self[:start_time]=Time.now
117
- timer=Timer.new
115
+ self[:start_time] = Time.now
116
+ timer = Timer.new
118
117
 
119
118
  Dir.chdir(self[:directory]) do
120
- if self[:input].include?('<%') && self[:input].include?('%>')
121
- ruby = self[:input].gsub("<%","").gsub("%>","")
122
-
123
- begin
124
- self[:output]=eval(ruby)
125
- rescue
126
- self[:exit_code]=1
127
- self[:error]="unable to eval(#{ruby})"
128
- end
129
-
130
- self[:elapsed] = timer.elapsed_str
131
- self[:end_time] = Time.now
132
- else
133
- begin
134
- if(self[:timeout] <= 0)
135
- self[:output],self[:error],status= Open3.capture3(self[:input])
136
- self[:exit_code]=status.to_i
137
- self[:elapsed] = timer.elapsed_str
138
- self[:end_time] = Time.now
119
+ if self[:input].include?("<%") && self[:input].include?("%>")
120
+ ruby = self[:input].gsub("<%", "").gsub("%>", "")
121
+
122
+ begin
123
+ self[:output] = eval(ruby)
124
+ rescue StandardError
125
+ self[:exit_code] = 1
126
+ self[:error] = "unable to eval(#{ruby})"
127
+ end
128
+
129
+ self[:elapsed] = timer.elapsed_str
130
+ self[:end_time] = Time.now
131
+ else
132
+ begin
133
+ if self[:timeout] <= 0
134
+ self[:output], self[:error], status = Open3.capture3(self[:input])
135
+ self[:exit_code] = status.to_i
136
+ self[:elapsed] = timer.elapsed_str
137
+ self[:end_time] = Time.now
139
138
  else
140
- require_relative 'timeout.rb'
141
- result=run_with_timeout(self[:directory],self[:input], self[:timeout],2)
142
- self[:output]=result[0]
143
- self[:exit_code]=result[1]
139
+ require_relative "timeout"
140
+ result = run_with_timeout(self[:directory], self[:input], self[:timeout], 2)
141
+ self[:output] = result[0]
142
+ self[:exit_code] = result[1]
144
143
  self[:elapsed] = timer.elapsed_str
145
144
  self[:end_time] = Time.now
146
-
147
- if(timer.elapsed >= self[:timeout])
148
- self[:exit_code]=1
149
- self[:error] = self[:error] + "timed out"
145
+
146
+ if timer.elapsed >= self[:timeout]
147
+ self[:exit_code] = 1
148
+ self[:error] = "#{self[:error]}timed out"
150
149
  end
151
150
  end
152
- rescue Exception => e
153
- self[:elapsed] = timer.elapsed_str
154
- self[:end_time] = Time.now
155
- self[:error] = "Exception: " + e.to_s
156
- self[:exit_code]=1
157
- end
158
- end
151
+ rescue Exception => e
152
+ self[:elapsed] = timer.elapsed_str
153
+ self[:end_time] = Time.now
154
+ self[:error] = "Exception: #{e}"
155
+ self[:exit_code] = 1
156
+ end
157
+ end
159
158
  end
160
-
161
159
 
162
- if(self[:exit_code] != 0)
163
- if(!quiet?)
164
- puts "exit_code=#{self[:exit_code]}"
165
- puts self[:output]
166
- puts self[:error]
160
+ if self[:exit_code] != 0
161
+ unless quiet?
162
+ puts "exit_code=#{self[:exit_code]}"
163
+ puts self[:output]
164
+ puts self[:error]
165
+ end
166
+ if !key?(:ignore_failure) || !self[:ignore_failure]
167
+ raise "#{self[:input]} failed\n#{self[:output]}\n#{self[:error]}"
167
168
  end
168
- if(!self.has_key?(:ignore_failure) || !self[:ignore_failure])
169
- raise "#{self[:input]} failed\n#{self[:output]}\n#{self[:error]}"
170
- end
171
169
  end
172
- self
173
- end
170
+ self
171
+ end
174
172
 
175
- def self.machine
176
- if !ENV['COMPUTERNAME'].nil?
177
- return ENV['COMPUTERNAME']
178
- end
173
+ def self.machine
174
+ return ENV["COMPUTERNAME"] unless ENV["COMPUTERNAME"].nil?
179
175
 
180
- machine = `hostname`
181
- machine = machine.split('.')[0] if machine.include?('.')
182
- return machine.strip
183
- end
176
+ machine = `hostname`
177
+ machine = machine.split(".")[0] if machine.include?(".")
178
+ machine.strip
179
+ end
184
180
 
185
- def self.user
186
- ENV['USER'].nil? ? ENV['USERNAME'] : ENV['USER']
187
- end
188
-
189
- def self.home
190
- ["USERPROFILE","HOME"].each {|v|
191
- return ENV[v].gsub('\\','/') unless ENV[v].nil?
192
- }
193
- dir="~"
194
- dir=ENV["HOME"] unless ENV["HOME"].nil?
195
- dir=ENV["USERPROFILE"].gsub('\\','/') unless ENV["USERPROFILE"].nil?
196
- return dir
197
- end
181
+ def self.user
182
+ ENV["USER"].nil? ? ENV["USERNAME"] : ENV["USER"]
183
+ end
198
184
 
199
- def self.dev_root
200
- ["DEV_HOME","DEV_ROOT"].each {|v|
201
- return ENV[v].gsub('\\','/') unless ENV[v].nil?
202
- }
203
- dir=home
204
- return dir
185
+ def self.home
186
+ %w[USERPROFILE HOME].each do |v|
187
+ return ENV[v].gsub('\\', "/") unless ENV[v].nil?
205
188
  end
189
+ dir = "~"
190
+ dir = ENV["HOME"] unless ENV["HOME"].nil?
191
+ dir = ENV["USERPROFILE"].gsub('\\', "/") unless ENV["USERPROFILE"].nil?
192
+ dir
193
+ end
206
194
 
207
- def self.execute command, working_directory=''
208
- cmd = Command.new({ :input => command, :quiet => true}) if command.kind_of?(String)
209
- cmd[:directory] = working_directory if command.kind_of?(String)
210
- cmd = command if command.kind_of?(Command)
211
- cmd = Command.new(command) if command.kind_of?(Hash)
212
- cmd.execute
213
- cmd[:exit_code]
214
- cmd
195
+ def self.dev_root
196
+ %w[DEV_HOME DEV_ROOT].each do |v|
197
+ return ENV[v].gsub('\\', "/") unless ENV[v].nil?
215
198
  end
199
+ home
200
+ end
216
201
 
217
- def self.exit_code command
218
- cmd = Command.new(command)
219
- cmd[:ignore_failure]=true
220
- cmd[:quiet]=true
221
- cmd.execute
222
- cmd[:exit_code]
223
- end
202
+ def self.execute(command, working_directory = "")
203
+ cmd = Command.new({ input: command, quiet: true }) if command.is_a?(String)
204
+ cmd[:directory] = working_directory if command.is_a?(String)
205
+ cmd = command if command.is_a?(Command)
206
+ cmd = Command.new(command) if command.is_a?(Hash)
207
+ cmd.execute
208
+ cmd[:exit_code]
209
+ cmd
210
+ end
224
211
 
225
- def self.output command
226
- cmd = Command.new(command)
227
- cmd[:ignore_failure]=true
228
- cmd[:quiet]=true
229
- cmd.execute
230
- cmd[:output]
231
- end
212
+ def self.exit_code(command)
213
+ cmd = Command.new(command)
214
+ cmd[:ignore_failure] = true
215
+ cmd[:quiet] = true
216
+ cmd.execute
217
+ cmd[:exit_code]
218
+ end
219
+
220
+ def self.output(command)
221
+ cmd = Command.new(command)
222
+ cmd[:ignore_failure] = true
223
+ cmd[:quiet] = true
224
+ cmd.execute
225
+ cmd[:output]
226
+ end
227
+
228
+ def self.error(command)
229
+ cmd = Command.new(command)
230
+ cmd[:ignore_failure] = true
231
+ cmd[:quiet] = true
232
+ cmd.execute
233
+ cmd[:error]
234
+ end
232
235
 
233
- def self.error command
234
- cmd = Command.new(command)
235
- cmd[:ignore_failure]=true
236
- cmd[:quiet]=true
237
- cmd.execute
238
- cmd[:error]
236
+ def getFormattedTimeSpan(timespan)
237
+ result = ""
238
+ seconds = timespan.round
239
+ if seconds > 99
240
+ minutes = (seconds / 60).round
241
+ result = "#{minutes}m"
242
+ else
243
+ result = "#{seconds}s" # 99s
239
244
  end
245
+ result.fix(3)
246
+ end
240
247
 
241
- def getFormattedTimeSpan timespan
242
- result=''
243
- seconds = timespan.round
244
- if(seconds > 99)
245
- minutes=(seconds/60).round
246
- result="#{minutes}m"
247
- else
248
- result="#{seconds}s" # 99s
249
- end
250
- result.fix(3)
248
+ def summary(include_directory = false)
249
+ duration = ""
250
+ duration = getFormattedTimeSpan(self[:end_time] - self[:start_time])
251
+ if Environment.default.colorize?
252
+ require "ansi/code"
253
+ cduration = ANSI.reset + duration
254
+ # code=ANSI.green + '+ ' + ANSI.reset
255
+ # code=ANSI.red + '- ' + ANSI.reset if exit_code != 0
256
+ cinput = ANSI.reset + self[:input] + ANSI.reset
257
+ cinput = ANSI.red + self[:input] + ANSI.reset if exit_code != 0
258
+ cdirectory = ""
259
+ cdirectory = "(#{self[:directory]})" if include_directory
260
+ " #{cduration} #{cinput} #{cdirectory}"
261
+ else
262
+ code = " "
263
+ code = "X" if exit_code != 0
264
+ sdirectory = ""
265
+ sdirectory = "(#{self[:directory]})" if include_directory
266
+ "#{code} #{duration} #{self[:input]} #{sdirectory}"
251
267
  end
268
+ end
252
269
 
253
- def summary include_directory=false
254
- duration=""
255
- duration=getFormattedTimeSpan(self[:end_time]-self[:start_time])
256
- if(Environment.default.colorize?)
257
- require 'ansi/code'
258
- cduration = ANSI.reset + duration
259
- #code=ANSI.green + '+ ' + ANSI.reset
260
- #code=ANSI.red + '- ' + ANSI.reset if exit_code != 0
261
- cinput = ANSI.reset + self[:input] + ANSI.reset
262
- cinput = ANSI.red + self[:input] + ANSI.reset if exit_code != 0
263
- cdirectory = ''
264
- cdirectory = "(#{self[:directory]})" if include_directory
265
- " #{cduration} #{cinput} #{cdirectory}"
266
- else
267
- code=' '
268
- code='X' if exit_code != 0
269
- sdirectory = ''
270
- sdirectory = "(#{self[:directory]})" if include_directory
271
- "#{code} #{duration} #{self[:input]} #{sdirectory}"
272
- end
270
+ def format_property(name, value)
271
+ if Environment.default.colorize?
272
+ require "ansi/code"
273
+ "#{name}: " + ANSI.yellow + ANSI.bright + value.to_s.strip + ANSI.reset
274
+ else
275
+ "#{name}: #{value}"
273
276
  end
277
+ end
274
278
 
275
- def format_property name,value
276
- if(Environment.default.colorize?)
277
- require 'ansi/code'
278
- return "#{name}: " + ANSI.yellow + ANSI.bright + value.to_s.strip + ANSI.reset
279
- else
280
- return "#{name}: #{value}"
281
- end
282
- end
283
-
284
- def info
285
- result=format_property('input'.fix(15),self[:input]) + "\n"
286
- result=result + format_property('directory'.fix(15),self[:directory]) + "\n"
287
- result=result + format_property('exit_code'.fix(15),self[:exit_code]) + "\n"
288
- result=result + format_property('duration'.fix(15),getFormattedTimeSpan(self[:end_time]-self[:start_time])) + "\n"
289
- output=['']
290
- output=self[:output].strip.split("\n") if !self[:output].nil?
291
- if(output.length <= 1)
292
- result=result + format_property('output'.fix(15),output[0]) + "\n"
293
- #result=result + format_property('output'.fix(15),'') + "\n" if(output.length==0)
294
- #result=result + format_property('output'.fix(15),output) + "\n" if(output.length==1)
295
- else
296
- result=result + format_property('output'.fix(15),'') + "\n"
297
- output.each{|line|
298
- result=result + ' '.fix(16) + line + "\n"
299
- }
279
+ def info
280
+ result = "#{format_property("input".fix(15), self[:input])}\n"
281
+ result = "#{result}#{format_property("directory".fix(15), self[:directory])}\n"
282
+ result = "#{result}#{format_property("exit_code".fix(15), self[:exit_code])}\n"
283
+ result = result + format_property("duration".fix(15),
284
+ getFormattedTimeSpan(self[:end_time] - self[:start_time])) + "\n"
285
+ output = [""]
286
+ output = self[:output].strip.split("\n") unless self[:output].nil?
287
+ if output.length <= 1
288
+ result = "#{result}#{format_property("output".fix(15), output[0])}\n"
289
+ # result=result + format_property('output'.fix(15),'') + "\n" if(output.length==0)
290
+ # result=result + format_property('output'.fix(15),output) + "\n" if(output.length==1)
291
+ else
292
+ result = "#{result}#{format_property("output".fix(15), "")}\n"
293
+ output.each do |line|
294
+ result = "#{result}#{" ".fix(16)}#{line}\n"
300
295
  end
301
- error=['']
302
- error=self[:error].strip.split("\n") if !self[:error].nil?
303
- if(error.length <= 1)
304
- result=result + format_property('error'.fix(15),error[0]) + "\n"
305
- #result=result + format_property('error'.fix(15),'') + "\n" if(error.length==0)
306
- #result=result + format_property('error'.fix(15),error) + "\n" if(error.length==1)
307
- else
308
- result=result + format_property('error'.fix(15),'') + "\n"
309
- error.each{|line|
310
- result=result + ' '.fix(16) + line + "\n"
311
- }
296
+ end
297
+ error = [""]
298
+ error = self[:error].strip.split("\n") unless self[:error].nil?
299
+ if error.length <= 1
300
+ result = "#{result}#{format_property("error".fix(15), error[0])}\n"
301
+ # result=result + format_property('error'.fix(15),'') + "\n" if(error.length==0)
302
+ # result=result + format_property('error'.fix(15),error) + "\n" if(error.length==1)
303
+ else
304
+ result = "#{result}#{format_property("error".fix(15), "")}\n"
305
+ error.each do |line|
306
+ result = "#{result}#{" ".fix(16)}#{line}\n"
312
307
  end
313
308
  end
309
+ end
314
310
 
315
- def to_html
316
- if self[:exit_code] == 0
311
+ def to_html
312
+ if (self[:exit_code]).zero?
317
313
  [
318
- '<div><table><tr><td width="20"></td><td><pre>',
319
- self[:input],
320
- '</pre></td></tr></table></div>'
314
+ '<div><table><tr><td width="20"></td><td><pre>',
315
+ self[:input],
316
+ "</pre></td></tr></table></div>",
321
317
  ].join
322
- else
318
+ else
323
319
  [
324
- '<div><table><tr><td width="20"></td><td><pre>',
325
- self[:input],
320
+ '<div><table><tr><td width="20"></td><td><pre>',
321
+ self[:input],
326
322
  '</pre><table><tr><td width="20"></td><td><table>',
327
- map { |k, v| ["<tr><td><strong>#{k}</strong></td>", v.respond_to?(:to_html) ? v.to_html : "<td><span><pre>#{v}</pre></span></td></tr>"] },
328
- '</table>',
329
- '</td></tr></table></td></tr></table></div>'
323
+ map do |k, v|
324
+ ["<tr><td><strong>#{k}</strong></td>",
325
+ v.respond_to?(:to_html) ? v.to_html : "<td><span><pre>#{v}</pre></span></td></tr>"]
326
+ end,
327
+ "</table>",
328
+ "</td></tr></table></td></tr></table></div>",
330
329
  ].join
331
- end
332
330
  end
333
- end
331
+ end
332
+ end