td 0.11.9 → 0.11.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)