td 0.11.9 → 0.11.10

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.
@@ -1,5 +1,8 @@
1
+ require 'td/command/options'
2
+
1
3
  module TreasureData
2
4
  module Command
5
+ include Options
3
6
 
4
7
  # TODO
5
8
  JOB_WAIT_MAX_RETRY_COUNT_ON_NETWORK_ERROR = 10
@@ -49,6 +52,7 @@ module Command
49
52
  op.on('--slow [SECONDS]', 'show slow queries (default threshold: 3600 seconds)', Integer) {|i|
50
53
  slower_than = i || 3600
51
54
  }
55
+
52
56
  set_render_format_option(op)
53
57
 
54
58
  max = op.cmd_parse
@@ -86,69 +90,29 @@ module Command
86
90
  :CPUTime => cpu_time.rjust(17),
87
91
  :ResultSize => (job.result_size ? Command.humanize_bytesize(job.result_size, 2) : ""),
88
92
  :Priority => priority,
89
- :Result => job.result_url
93
+ :Result => job.result_url,
94
+ :Duration => job.duration ? Time.at(job.duration).utc.strftime("%X") : nil
90
95
  }
91
96
  }
92
97
 
93
- puts cmd_render_table(rows,
94
- :fields => [:JobID, :Status, :Start, :Elapsed, :CPUTime, :ResultSize, :Priority, :Result, :Type, :Database, :Query],
98
+ $stdout.puts cmd_render_table(rows,
99
+ :fields => [:JobID, :Status, :Start, :Elapsed, :CPUTime, :ResultSize, :Priority, :Result, :Type, :Database, :Query, :Duration],
95
100
  :max_width => 1000,
96
101
  :render_format => op.render_format
97
102
  )
98
103
  end
99
104
 
100
105
  def job_show(op)
101
- verbose = nil
102
- wait = false
103
- output = nil
104
- format = nil
105
- render_opts = {:header => false}
106
- limit = nil
107
- exclude = false
108
-
109
- op.on('-v', '--verbose', 'show logs', TrueClass) {|b|
110
- verbose = b
111
- }
112
- op.on('-w', '--wait', 'wait for finishing the job', TrueClass) {|b|
113
- wait = b
114
- }
115
- op.on('-G', '--vertical', 'use vertical table to show results', TrueClass) {|b|
116
- render_opts[:vertical] = b
117
- }
118
- op.on('-o', '--output PATH', 'write result to the file') {|s|
119
- unless Dir.exist?(File.dirname(s))
120
- s = File.expand_path(s)
121
- end
122
- output = s
123
- format = 'tsv' if format.nil?
124
- }
125
- op.on('-f', '--format FORMAT', 'format of the result to write to the file (tsv, csv, json, msgpack, and msgpack.gz)') {|s|
126
- unless ['tsv', 'csv', 'json', 'msgpack', 'msgpack.gz'].include?(s)
127
- raise "Unknown format #{s.dump}. Supported formats are: tsv, csv, json, msgpack, and msgpack.gz"
128
- end
129
- format = s
130
- }
131
- op.on('-l', '--limit ROWS', 'limit the number of result rows shown when not outputting to file') {|s|
132
- unless s.to_i > 0
133
- raise "Invalid limit number. Must be a positive integer"
134
- end
135
- limit = s.to_i
136
- }
137
- op.on('-c', '--column-header', 'output of the columns\' header when the schema is available',
138
- ' for the table (only applies to tsv and csv formats)', TrueClass) {|b|
139
- render_opts[:header] = b;
140
- }
141
- op.on('-x', '--exclude', 'do not automatically retrieve the job result', TrueClass) {|b|
142
- exclude = b
143
- }
144
-
145
- op.on('--null STRING', "null expression in csv or tsv") {|s|
146
- render_opts[:null_expr] = s.to_s
147
- }
148
-
106
+ options = job_show_options(op)
149
107
  job_id = op.cmd_parse
150
108
 
151
- # parameter concurrency validation
109
+ verbose = options[:verbose]
110
+ wait = options[:wait]
111
+ output = options[:output]
112
+ format = options[:format]
113
+ render_opts = options[:render_opts]
114
+ limit = options[:limit]
115
+ exclude = options[:exclude]
152
116
 
153
117
  if output.nil? && format
154
118
  unless ['tsv', 'csv', 'json'].include?(format)
@@ -176,7 +140,7 @@ module Command
176
140
  job_id = op.cmd_parse
177
141
  client = get_client
178
142
 
179
- puts client.job_status(job_id)
143
+ $stdout.puts client.job_status(job_id)
180
144
  end
181
145
 
182
146
  def job_kill(op)
@@ -203,27 +167,27 @@ private
203
167
  client = get_client
204
168
  job = client.job(job_id)
205
169
 
206
- puts "JobID : #{job.job_id}"
170
+ $stdout.puts "JobID : #{job.job_id}"
207
171
  #puts "URL : #{job.url}"
208
- puts "Status : #{job.status}"
209
- puts "Type : #{job.type}"
210
- puts "Database : #{job.db_name}"
172
+ $stdout.puts "Status : #{job.status}"
173
+ $stdout.puts "Type : #{job.type}"
174
+ $stdout.puts "Database : #{job.db_name}"
211
175
  # exclude some fields from bulk_import_perform type jobs
212
176
  if [:hive, :pig, :impala, :presto].include?(job.type)
213
- puts "Priority : #{job_priority_name_of(job.priority)}"
214
- puts "Retry limit : #{job.retry_limit}"
215
- puts "Output : #{job.result_url}"
216
- puts "Query : #{job.query}"
177
+ $stdout.puts "Priority : #{job_priority_name_of(job.priority)}"
178
+ $stdout.puts "Retry limit : #{job.retry_limit}"
179
+ $stdout.puts "Output : #{job.result_url}"
180
+ $stdout.puts "Query : #{job.query}"
217
181
  elsif job.type == :bulk_import_perform
218
- puts "Destination : #{job.query}"
182
+ $stdout.puts "Destination : #{job.query}"
219
183
  end
220
184
  # if the job is done and is of type hive, show the Map-Reduce cumulated CPU time
221
185
  if job.finished?
222
186
  if [:hive].include?(job.type)
223
- puts "CPU time : #{Command.humanize_time(job.cpu_time, true)}"
187
+ $stdout.puts "CPU time : #{Command.humanize_time(job.cpu_time, true)}"
224
188
  end
225
189
  if [:hive, :pig, :impala, :presto].include?(job.type)
226
- puts "Result size : #{Command.humanize_bytesize(job.result_size, 2)}"
190
+ $stdout.puts "Result size : #{Command.humanize_bytesize(job.result_size, 2)}"
227
191
  end
228
192
  end
229
193
 
@@ -239,23 +203,23 @@ private
239
203
 
240
204
  if verbose
241
205
  if !job.debug['cmdout'].nil?
242
- puts ""
243
- puts "Output:"
206
+ $stdout.puts ""
207
+ $stdout.puts "Output:"
244
208
  job.debug['cmdout'].to_s.split("\n").each {|line|
245
- puts " " + line
209
+ $stdout.puts " " + line
246
210
  }
247
211
  end
248
212
  if !job.debug['stderr'].nil?
249
- puts ""
250
- puts "Details:"
213
+ $stdout.puts ""
214
+ $stdout.puts "Details:"
251
215
  job.debug['stderr'].to_s.split("\n").each {|line|
252
- puts " " + line
216
+ $stdout.puts " " + line
253
217
  }
254
218
  end
255
219
  end
256
220
  end
257
221
 
258
- puts "\rUse '-v' option to show detailed messages." + " " * 20 unless verbose
222
+ $stdout.puts "\rUse '-v' option to show detailed messages." + " " * 20 unless verbose
259
223
  end
260
224
 
261
225
  def wait_job(job, first_call = false)
@@ -281,7 +245,7 @@ private
281
245
  cmdout = job.debug['cmdout'].to_s.split("\n")[cmdout_lines..-1] || []
282
246
  stderr = job.debug['stderr'].to_s.split("\n")[stderr_lines..-1] || []
283
247
  (cmdout + stderr).each {|line|
284
- puts " "+line
248
+ $stdout.puts " "+line
285
249
  }
286
250
  cmdout_lines += cmdout.size
287
251
  stderr_lines += stderr.size
@@ -294,7 +258,7 @@ private
294
258
  max_cumul_retry_delay = 200
295
259
  cumul_retry_delay = 0
296
260
 
297
- puts "Result :"
261
+ $stdout.puts "Result :"
298
262
  begin
299
263
  show_result(job, output, limit, format, render_opts)
300
264
  rescue TreasureData::NotFoundError => e
@@ -320,7 +284,7 @@ private
320
284
  def show_result(job, output, limit, format, render_opts={})
321
285
  if output
322
286
  write_result(job, output, limit, format, render_opts)
323
- puts "\rwritten to #{output} in #{format} format" + " " * 50
287
+ $stdout.puts "\rwritten to #{output} in #{format} format" + " " * 50
324
288
  else
325
289
  # every format that is allowed on stdout
326
290
  render_result(job, limit, format, render_opts)
@@ -331,10 +295,19 @@ private
331
295
 
332
296
  # the next 3 formats allow writing to both a file and stdout
333
297
 
298
+
299
+ if output
300
+ if output.is_a?(String)
301
+ tempfile = "#{output}.tmp"
302
+ else # File or Tempfile
303
+ tempfile = "#{output.path}.tmp"
304
+ end
305
+ end
306
+
334
307
  case format
335
308
  when 'json'
336
309
  require 'yajl'
337
- open_file(output, "w") {|f|
310
+ open_file(tempfile || output, "w") {|f|
338
311
  f.write "["
339
312
  n_rows = 0
340
313
  unless output.nil?
@@ -352,13 +325,13 @@ private
352
325
  f.write "]"
353
326
  indicator.finish unless output.nil?
354
327
  }
355
- puts if output.nil?
328
+ $stdout.puts if output.nil?
356
329
 
357
330
  when 'csv'
358
331
  require 'yajl'
359
332
  require 'csv'
360
333
 
361
- open_file(output, "w") {|f|
334
+ open_file(tempfile || output, "w") {|f|
362
335
  writer = CSV.new(f)
363
336
  # output headers
364
337
  if render_opts[:header] && job.hive_result_schema
@@ -391,7 +364,7 @@ private
391
364
  when 'tsv'
392
365
  require 'yajl'
393
366
 
394
- open_file(output, "w") {|f|
367
+ open_file(tempfile || output, "w") {|f|
395
368
  # output headers
396
369
  if render_opts[:header] && job.hive_result_schema
397
370
  f.write job.hive_result_schema.map {|name, type| name}.join("\t") + "\n"
@@ -423,7 +396,7 @@ private
423
396
  raise ParameterConfigurationError,
424
397
  "Format 'msgpack' does not support writing to stdout"
425
398
  end
426
- open_file(output, "wb") {|f|
399
+ open_file(tempfile || output, "wb") {|f|
427
400
  indicator = Command::SizeBasedDownloadProgressIndicator.new(
428
401
  "NOTE: the job result is being written to #{output} in msgpack format",
429
402
  job.result_size, 0.1, 1)
@@ -438,7 +411,7 @@ private
438
411
  raise ParameterConfigurationError,
439
412
  "Format 'msgpack' does not support writing to stdout"
440
413
  end
441
- open_file(output, "wb") {|f|
414
+ open_file(tempfile || output, "wb") {|f|
442
415
  indicator = Command::SizeBasedDownloadProgressIndicator.new(
443
416
  "NOTE: the job result is being written to #{output} in msgpack.gz format",
444
417
  job.result_size, 0.1, 1)
@@ -451,6 +424,10 @@ private
451
424
  else
452
425
  raise "Unknown format #{format.inspect}"
453
426
  end
427
+
428
+ if tempfile && File.exists?(tempfile)
429
+ FileUtils.mv(tempfile, output.respond_to?(:path) ? output.path : output)
430
+ end
454
431
  end
455
432
 
456
433
  def open_file(output, mode)
@@ -485,15 +462,15 @@ private
485
462
  n_rows += 1
486
463
  break if !limit.nil? and n_rows == limit
487
464
  }
488
- print " " * 100, "\r" # make sure the previous WARNING is cleared over
465
+ $stdout.print " " * 100, "\r" # make sure the previous WARNING is cleared over
489
466
 
490
467
  render_opts[:max_width] = 10000
491
468
  if job.hive_result_schema
492
469
  render_opts[:change_fields] = job.hive_result_schema.map { |name,type| name }
493
470
  end
494
471
 
495
- print "\r" + " " * 50
496
- puts "\r" + cmd_render_table(rows, render_opts)
472
+ $stdout.print "\r" + " " * 50
473
+ $stdout.puts "\r" + cmd_render_table(rows, render_opts)
497
474
  else
498
475
  # display result in any of: json, csv, tsv.
499
476
  # msgpack and mspgpack.gz are not supported for stdout output
@@ -15,7 +15,7 @@ module List
15
15
  @cmd_requires_connectivity = req_conn
16
16
  end
17
17
 
18
- attr_accessor :message, :name, :cmd_requires_connectivity
18
+ attr_accessor :message, :name, :cmd_requires_connectivity, :argv
19
19
 
20
20
  def on(*argv)
21
21
  @has_options = true
@@ -46,8 +46,8 @@ module List
46
46
  end
47
47
 
48
48
  def cmd_usage(msg=nil)
49
- puts self.to_s
50
- puts "Error: #{msg}" if msg
49
+ $stdout.puts self.to_s
50
+ $stdout.puts "Error: #{msg}" if msg
51
51
  exit 1
52
52
  end
53
53
  end
@@ -118,7 +118,15 @@ module List
118
118
 
119
119
  def usage
120
120
  compile!
121
- "%-40s # %s" % [@usage_args, @description]
121
+ description_lines = @description.split("\n")
122
+ strout = "%-40s # %s" % [@usage_args, description_lines[0]]
123
+ if description_lines.length > 1
124
+ description_lines[1..-1].each {|lines|
125
+ strout += "\n"
126
+ strout += "%-40s # %s" % ["", lines]
127
+ }
128
+ end
129
+ strout
122
130
  end
123
131
 
124
132
  def group
@@ -181,9 +189,9 @@ module List
181
189
  next if HELP_EXCLUDE.any? {|pattern| pattern =~ c.name }
182
190
  if before_group != c.group
183
191
  before_group = c.group
184
- puts ""
192
+ $stdout.puts ""
185
193
  end
186
- puts "#{indent}#{c.usage}"
194
+ $stdout.puts "#{indent}#{c.usage}"
187
195
  }
188
196
  end
189
197
 
@@ -281,6 +289,10 @@ module List
281
289
  add_list 'sched:update', %w[name], 'Modify a schedule', ['sched:update sched1 -s "0 */2 * * *" -d my_db -t "Asia/Tokyo" -D 3600']
282
290
  add_list 'sched:history', %w[name max?], 'Show history of scheduled queries', ['sched sched1 --page 1']
283
291
  add_list 'sched:run', %w[name time], 'Run scheduled queries for the specified time', ['sched:run sched1 "2013-01-01 00:00:00" -n 6']
292
+ add_list 'sched:result', %w[name], "Show status and result of the last job ran.\n" +
293
+ "--last [N] option enables to show the result before N from the last.\n" +
294
+ "The other options are identical to those of the 'job:show' command.",
295
+ ['sched:result NAME | sched:result NAME --last | sched:result NAME --last 3']
284
296
 
285
297
  add_list 'query', %w[sql?], 'Issue a query', ['query -d example_db -w -r rset1 "select count(*) from table1"',
286
298
  'query -d example_db -w -r rset1 -q query.txt']
@@ -356,6 +368,7 @@ module List
356
368
  add_alias 'schedule:create', 'sched:create'
357
369
  add_alias 'schedule:delete', 'sched:delete'
358
370
  add_alias 'schedule:history', 'sched:history'
371
+ add_alias 'schedule:result', 'sched:result'
359
372
  add_alias 'schedule:hist', 'sched:history'
360
373
  add_alias 'sched:hist', 'sched:history'
361
374
  add_alias 'sched', 'sched:history'
@@ -0,0 +1,61 @@
1
+ module TreasureData
2
+ module Command
3
+ module Options
4
+
5
+ def job_show_options(op)
6
+ opts = {}
7
+ opts[:verbose] = nil
8
+ opts[:wait] = false
9
+ opts[:output] = nil
10
+ opts[:format] = nil
11
+ opts[:render_opts] = {:header => false}
12
+ opts[:limit] = nil
13
+ opts[:exclude] = false
14
+
15
+ op.on('-v', '--verbose', 'show logs', TrueClass) {|b|
16
+ opts[:verbose] = b
17
+ }
18
+ op.on('-w', '--wait', 'wait for finishing the job', TrueClass) {|b|
19
+ opts[:wait] = b
20
+ }
21
+ op.on('-G', '--vertical', 'use vertical table to show results', TrueClass) {|b|
22
+ opts[:render_opts][:vertical] = b
23
+ }
24
+ op.on('-o', '--output PATH', 'write result to the file') {|s|
25
+ unless Dir.exist?(File.dirname(s))
26
+ s = File.expand_path(s)
27
+ end
28
+ opts[:output] = s
29
+ opts[:format] ||= 'tsv'
30
+ }
31
+ op.on('-f', '--format FORMAT', 'format of the result to write to the file (tsv, csv, json, msgpack, and msgpack.gz)') {|s|
32
+ unless ['tsv', 'csv', 'json', 'msgpack', 'msgpack.gz'].include?(s)
33
+ raise "Unknown format #{s.dump}. Supported formats are: tsv, csv, json, msgpack, and msgpack.gz"
34
+ end
35
+ opts[:format] = s
36
+ }
37
+ op.on('-l', '--limit ROWS', 'limit the number of result rows shown when not outputting to file') {|s|
38
+ unless s.to_i > 0
39
+ raise "Invalid limit number. Must be a positive integer"
40
+ end
41
+ opts[:limit] = s.to_i
42
+ }
43
+ op.on('-c', '--column-header', 'output of the columns\' header when the schema is available',
44
+ ' for the table (only applies to tsv and csv formats)', TrueClass) {|b|
45
+ opts[:render_opts][:header] = b;
46
+ }
47
+ op.on('-x', '--exclude', 'do not automatically retrieve the job result', TrueClass) {|b|
48
+ opts[:exclude] = b
49
+ }
50
+
51
+ op.on('--null STRING', "null expression in csv or tsv") {|s|
52
+ opts[:render_opts][:null_expr] = s.to_s
53
+ }
54
+
55
+ # CAUTION: this opts is filled by op.cmd_parse
56
+ opts
57
+ end
58
+
59
+ end # module Options
60
+ end # module Command
61
+ end # module TreasureData
@@ -10,7 +10,7 @@ module Command
10
10
 
11
11
  begin
12
12
  system "stty -echo" # TODO termios
13
- print "Old password (typing will be hidden): "
13
+ $stdout.print "Old password (typing will be hidden): "
14
14
  old_password = STDIN.gets || ""
15
15
  old_password = old_password[0..-2] # strip \n
16
16
  rescue Interrupt
@@ -18,7 +18,7 @@ module Command
18
18
  exit 1
19
19
  ensure
20
20
  system "stty echo" # TODO termios
21
- print "\n"
21
+ $stdout.print "\n"
22
22
  end
23
23
 
24
24
  if old_password.empty?
@@ -29,7 +29,7 @@ module Command
29
29
  3.times do
30
30
  begin
31
31
  system "stty -echo" # TODO termios
32
- print "New password (typing will be hidden): "
32
+ $stdout.print "New password (typing will be hidden): "
33
33
  password = STDIN.gets || ""
34
34
  password = password[0..-2] # strip \n
35
35
  rescue Interrupt
@@ -37,7 +37,7 @@ module Command
37
37
  exit 1
38
38
  ensure
39
39
  system "stty echo" # TODO termios
40
- print "\n"
40
+ $stdout.print "\n"
41
41
  end
42
42
 
43
43
  if password.empty?
@@ -47,7 +47,7 @@ module Command
47
47
 
48
48
  begin
49
49
  system "stty -echo" # TODO termios
50
- print "Retype new password: "
50
+ $stdout.print "Retype new password: "
51
51
  password2 = STDIN.gets || ""
52
52
  password2 = password2[0..-2] # strip \n
53
53
  rescue Interrupt
@@ -55,14 +55,14 @@ module Command
55
55
  exit 1
56
56
  ensure
57
57
  system "stty echo" # TODO termios
58
- print "\n"
58
+ $stdout.print "\n"
59
59
  end
60
60
 
61
61
  if password == password2
62
62
  break
63
63
  end
64
64
 
65
- puts "Doesn't match."
65
+ $stdout.puts "Doesn't match."
66
66
  end
67
67
 
68
68
  client = get_client(:ssl => true)
@@ -16,6 +16,7 @@ module Command
16
16
  type = nil
17
17
  limit = nil
18
18
  exclude = false
19
+ pool_name = nil
19
20
 
20
21
  op.on('-d', '--database DB_NAME', 'use the database (required)') {|s|
21
22
  db_name = s
@@ -62,13 +63,13 @@ module Command
62
63
  op.on('-q', '--query PATH', 'use file instead of inline query') {|s|
63
64
  query = File.open(s) { |f| f.read.strip }
64
65
  }
65
- op.on('-T', '--type TYPE', 'set query type (hive, pig, impala, presto)') {|s|
66
+ op.on('-T', '--type TYPE', 'set query type (hive, pig, presto)') {|s|
66
67
  type = s.to_sym
67
68
  }
68
69
  op.on('--sampling DENOMINATOR', 'OBSOLETE - enable random sampling to reduce records 1/DENOMINATOR', Integer) {|i|
69
- puts "WARNING: the random sampling feature enabled through the '--sampling' option was removed and does no longer"
70
- puts " have any effect. It is left for backwards compatibility with older scripts using 'td'."
71
- puts
70
+ $stdout.puts "WARNING: the random sampling feature enabled through the '--sampling' option was removed and does no longer"
71
+ $stdout.puts " have any effect. It is left for backwards compatibility with older scripts using 'td'."
72
+ $stdout.puts
72
73
  }
73
74
  op.on('-l', '--limit ROWS', 'limit the number of result rows shown when not outputting to file') {|s|
74
75
  unless s.to_i > 0
@@ -77,11 +78,14 @@ module Command
77
78
  limit = s.to_i
78
79
  }
79
80
  op.on('-c', '--column-header', 'output of the columns\' header when the schema is available for the table (only applies to tsv and csv formats)', TrueClass) {|b|
80
- render_opts[:header] = b;
81
+ render_opts[:header] = b
81
82
  }
82
83
  op.on('-x', '--exclude', 'do not automatically retrieve the job result', TrueClass) {|b|
83
84
  exclude = b
84
85
  }
86
+ op.on('-O', '--pool-name NAME', 'specify resource pool by name') {|s|
87
+ pool_name = s
88
+ }
85
89
 
86
90
  sql = op.cmd_parse
87
91
 
@@ -130,17 +134,18 @@ module Command
130
134
 
131
135
  opts = {}
132
136
  opts['type'] = type if type
137
+ opts['pool_name'] = pool_name if pool_name
133
138
  job = client.query(db_name, sql, result_url, priority, retry_limit, opts)
134
139
 
135
- puts "Job #{job.job_id} is queued."
136
- puts "Use '#{$prog} " + Config.cl_options_string + "job:show #{job.job_id}' to show the status."
140
+ $stdout.puts "Job #{job.job_id} is queued."
141
+ $stdout.puts "Use '#{$prog} " + Config.cl_options_string + "job:show #{job.job_id}' to show the status."
137
142
  #puts "See #{job.url} to see the progress."
138
143
 
139
144
  if wait
140
145
  wait_job(job, true)
141
- puts "Status : #{job.status}"
146
+ $stdout.puts "Status : #{job.status}"
142
147
  if job.success? && !exclude
143
- puts "Result :"
148
+ $stdout.puts "Result :"
144
149
  begin
145
150
  show_result(job, output, limit, format, render_opts)
146
151
  rescue TreasureData::NotFoundError => e
@@ -15,8 +15,8 @@ module Command
15
15
  exit 1
16
16
  end
17
17
 
18
- puts "Name : #{r.name}"
19
- puts "URL : #{r.url}"
18
+ $stdout.puts "Name : #{r.name}"
19
+ $stdout.puts "URL : #{r.url}"
20
20
  end
21
21
 
22
22
  def result_list(op)
@@ -36,7 +36,7 @@ module Command
36
36
  map[:Name]
37
37
  }
38
38
 
39
- puts cmd_render_table(rows, :fields => [:Name, :URL], :render_format => op.render_format)
39
+ $stdout.puts cmd_render_table(rows, :fields => [:Name, :URL], :render_format => op.render_format)
40
40
 
41
41
  if rs.empty?
42
42
  $stderr.puts "There are no result URLs."
@@ -93,7 +93,7 @@ module Command
93
93
  if ask_password
94
94
  begin
95
95
  system "stty -echo" # TODO termios
96
- print "Password (typing will be hidden): "
96
+ $stdout.print "Password (typing will be hidden): "
97
97
  password = STDIN.gets || ""
98
98
  password = password[0..-2] # strip \n
99
99
  rescue Interrupt
@@ -101,7 +101,7 @@ module Command
101
101
  exit 1
102
102
  ensure
103
103
  system "stty echo" # TODO termios
104
- print "\n"
104
+ $stdout.print "\n"
105
105
  end
106
106
  end
107
107
 
@@ -32,9 +32,9 @@ EOF
32
32
  (class << self;self;end).module_eval do
33
33
  define_method(:usage) do |errmsg|
34
34
  require 'td/command/list'
35
- puts op.to_s
36
- puts ""
37
- puts <<EOF
35
+ $stdout.puts op.to_s
36
+ $stdout.puts ""
37
+ $stdout.puts <<EOF
38
38
  Basic commands:
39
39
 
40
40
  db # create/delete/list databases
@@ -59,7 +59,7 @@ Additional commands:
59
59
  Type 'td help COMMAND' for more information on a specific command.
60
60
  EOF
61
61
  if errmsg
62
- puts "Error: #{errmsg}"
62
+ $stdout.puts "Error: #{errmsg}"
63
63
  return 1
64
64
  else
65
65
  return 0
@@ -116,7 +116,7 @@ EOF
116
116
  }
117
117
 
118
118
  op.on('--version', "show version") {
119
- puts op.version
119
+ $stdout.puts op.version
120
120
  return 0
121
121
  }
122
122
 
@@ -191,13 +191,13 @@ EOF
191
191
  $!.backtrace.each {|bt|
192
192
  $stderr.puts " #{bt}"
193
193
  }
194
- puts ""
194
+ $stdout.puts ""
195
195
  end
196
- print "Error: "
196
+ $stdout.print "Error: "
197
197
  if [ForbiddenError, NotFoundError, AuthError].include?(e.class)
198
- print "#{e.class} - "
198
+ $stdout.print "#{e.class} - "
199
199
  end
200
- puts $!.to_s
200
+ $stdout.puts $!.to_s
201
201
 
202
202
  require 'socket'
203
203
  if e.is_a?(::SocketError)