td 0.11.10 → 0.11.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e564b64771f7174a938bb3bbc1018c29dde82e23
4
+ data.tar.gz: 4ef2d5ce846fa9eb2b2e6a250f4a21947d9c86a0
5
+ SHA512:
6
+ metadata.gz: ccd286b00461da0f4880faaee3f82663ea37559fe79e13ff5d606a77012f3fc7df1f0e7b99b1468eb4a0118a51ba00dcbdfa61df5aa4c42b24984592dd172e4d
7
+ data.tar.gz: d5a9c05c266d1efd0a2c853e2497bcc5f6389a38de0a6d45f76d2535fa20431a077db2eb860cff9369dd96c59a0843117fd15ebeb0a10f8ddf469893b41d3f8e
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore CHANGED
@@ -5,4 +5,5 @@ Gemfile.lock
5
5
  vendor/*
6
6
  pkg/
7
7
  build/*
8
+ coverage/
8
9
  *~
data/.travis.yml ADDED
@@ -0,0 +1,18 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - 2.1.0
7
+ - 2.1.1
8
+ - 2.2.0
9
+ - ruby-head
10
+
11
+ gemfile:
12
+ - Gemfile
13
+
14
+ script: bundle exec rake spec
15
+
16
+ matrix:
17
+ allow_failures:
18
+ - rvm: ruby-head
data/ChangeLog CHANGED
@@ -1,3 +1,13 @@
1
+ == 2015-07-10 version 0.11.11
2
+
3
+ * Updated 'td-client' gem dependency to 0.8.71. The new gem removed to/from
4
+ parameter from table/tail API.
5
+ * Version up bundled Ruby for Mac and Windows.
6
+ * Remove -t (to) and -f (from) from table:tail command.
7
+ * connector:guess shows help message if no arguments are set.
8
+ * table:* unsupported 'item' table.
9
+ * upgrade rubyzip
10
+
1
11
  == 2015-05-19 version 0.11.10
2
12
 
3
13
  * Updated 'td-client' gem dependency to 0.8.70. The new gem removed client
data/README.rdoc CHANGED
@@ -1,4 +1,6 @@
1
1
  = Treasure Data command line tool
2
+ {<img src="https://travis-ci.org/treasure-data/td.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/treasure-data/td]
3
+ {<img src="https://coveralls.io/repos/treasure-data/td/badge.svg?branch=master&service=github" alt="Coverage Status" />}[https://coveralls.io/github/treasure-data/td?branch=master]
2
4
 
3
5
  This CUI utility wraps the {Ruby Client Library td-client-ruby}[https://github.com/treasure-data/td-client-ruby]
4
6
  to interact with the REST API in managing databases and jobs on the Treasure Data Cloud.
@@ -146,5 +148,5 @@ These are the available hooks:
146
148
 
147
149
  = Copyright
148
150
 
149
- Copyright:: Copyright (c) 2014 Treasure Data Inc.
151
+ Copyright:: Copyright (c) 2015 Treasure Data Inc.
150
152
  License:: Apache License, Version 2.0
data/Rakefile CHANGED
@@ -145,3 +145,14 @@ Dir[File.expand_path("../dist/**/*.rake", __FILE__)].each do |rake|
145
145
  import rake
146
146
  end
147
147
 
148
+ require 'rspec/core'
149
+ require 'rspec/core/rake_task'
150
+
151
+ RSpec::Core::RakeTask.new(:spec) do |spec|
152
+ spec.pattern = FileList['spec/**/*_spec.rb']
153
+ end
154
+
155
+ task :coverage do |t|
156
+ ENV['SIMPLE_COV'] = '1'
157
+ Rake::Task["spec"].invoke
158
+ end
data/appveyor.yml ADDED
@@ -0,0 +1,17 @@
1
+ ---
2
+ version: "{build}"
3
+ clone_depth: 10
4
+ install:
5
+ - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
6
+ - ruby --version
7
+ - gem --version
8
+ - gem install bundler --quiet --no-ri --no-rdoc
9
+ - bundler --version
10
+ - bundle install
11
+ build_script:
12
+ - bundle exec rake build
13
+ test_script:
14
+ - bundle exec rake spec
15
+ environment:
16
+ matrix:
17
+ - ruby_version: "22"
@@ -18,21 +18,31 @@ module Command
18
18
  id = secret = source = nil
19
19
  out = 'td-bulkload.yml'
20
20
 
21
- op.on('--type[=TYPE]', "connector type; only 's3' is supported") { |s| type = s }
22
- op.on('--access-id ID', "access ID (S3 access key id for type: s3)") { |s| id = s }
23
- op.on('--access-secret SECRET', "access secret (S3 secret access key for type: s3)") { |s| secret = s }
24
- op.on('--source SOURCE', "resource(s) URI to be imported (e.g. https://s3-us-west-1.amazonaws.com/bucketname/path/prefix/to/import/)") { |s| source = s }
25
- op.on('--out FILE_NAME', "configuration file") { |s| out = s }
26
-
27
- config = op.cmd_parse
28
- if config
29
- job = prepare_bulkload_job_config(config)
30
- out ||= config
21
+ op.on('--type[=TYPE]', "(obsoleted)") { |s| type = s }
22
+ op.on('--access-id ID', "(obsoleted)") { |s| id = s }
23
+ op.on('--access-secret SECRET', "(obsoleted)") { |s| secret = s }
24
+ op.on('--source SOURCE', "(obsoleted)") { |s| source = s }
25
+ op.on('-o', '--out FILE_NAME', "output file name for connector:preview") { |s| out = s }
26
+
27
+ config_file = op.cmd_parse
28
+ if config_file
29
+ config = prepare_bulkload_job_config(config_file)
30
+ out ||= config_file
31
31
  else
32
- required('--access-id', id)
33
- required('--access-secret', secret)
34
- required('--source', source)
35
- required('--out', out)
32
+ begin
33
+ required('--access-id', id)
34
+ required('--access-secret', secret)
35
+ required('--source', source)
36
+ required('--out', out)
37
+ rescue ParameterConfigurationError
38
+ if id == nil && secret == nil && source == nil
39
+ $stdout.puts op.to_s
40
+ $stdout.puts ""
41
+ raise ParameterConfigurationError, "path to configuration file is required"
42
+ else
43
+ raise
44
+ end
45
+ end
36
46
 
37
47
  uri = URI.parse(source)
38
48
  endpoint = uri.host
@@ -40,26 +50,24 @@ module Command
40
50
  bucket = path_components.shift.sub(/\//, '')
41
51
  path_prefix = path_components.join.sub(/\//, '')
42
52
 
43
- job = {
44
- :config => {
45
- :type => type,
46
- :access_key_id => id,
47
- :secret_access_key => secret,
48
- :endpoint => endpoint,
49
- :bucket => bucket,
50
- :path_prefix => path_prefix,
51
- }
53
+ config = {
54
+ :type => type,
55
+ :access_key_id => id,
56
+ :secret_access_key => secret,
57
+ :endpoint => endpoint,
58
+ :bucket => bucket,
59
+ :path_prefix => path_prefix,
52
60
  }
53
61
  end
54
62
 
55
63
  client = get_client
56
- job = client.bulk_load_guess(job)
64
+ job = client.bulk_load_guess(config: config)
57
65
 
58
66
  create_bulkload_job_file_backup(out)
59
67
  if /\.json\z/ =~ out
60
- config_str = JSON.pretty_generate(job)
68
+ config_str = JSON.pretty_generate(job['config'])
61
69
  else
62
- config_str = YAML.dump(job)
70
+ config_str = YAML.dump(job['config'])
63
71
  end
64
72
  File.open(out, 'w') do |f|
65
73
  f << config_str
@@ -76,9 +84,9 @@ module Command
76
84
  def connector_preview(op)
77
85
  set_render_format_option(op)
78
86
  config_file = op.cmd_parse
79
- job = prepare_bulkload_job_config(config_file)
87
+ config = prepare_bulkload_job_config(config_file)
80
88
  client = get_client()
81
- preview = client.bulk_load_preview(job)
89
+ preview = client.bulk_load_preview(config: config)
82
90
 
83
91
  cols = preview['schema'].sort_by { |col|
84
92
  col['index']
@@ -105,7 +113,7 @@ module Command
105
113
  wait = exclude = false
106
114
  op.on('--database DB_NAME', "destination database") { |s| database = s }
107
115
  op.on('--table TABLE_NAME', "destination table") { |s| table = s }
108
- op.on('--time-column COLUMN_NAME', "data partitioning key") { |s| time_column = s }
116
+ op.on('--time-column COLUMN_NAME', "data partitioning key") { |s| time_column = s } # unnecessary but for backward compatibility
109
117
  op.on('-w', '--wait', 'wait for finishing the job', TrueClass) { |b| wait = b }
110
118
  op.on('-x', '--exclude', 'do not automatically retrieve the job result', TrueClass) { |b| exclude = b }
111
119
 
@@ -114,11 +122,11 @@ module Command
114
122
  required('--database', database)
115
123
  required('--table', table)
116
124
 
117
- job = prepare_bulkload_job_config(config_file)
118
- job['time_column'] = time_column if time_column
125
+ config = prepare_bulkload_job_config(config_file)
126
+ (config['out'] ||= {})['time_column'] = time_column if time_column # TODO will not work once embulk implements multi-job
119
127
 
120
128
  client = get_client()
121
- job_id = client.bulk_load_issue(database, table, job)
129
+ job_id = client.bulk_load_issue(database, table, config: job)
122
130
 
123
131
  $stdout.puts "Job #{job_id} is queued."
124
132
  $stdout.puts "Use '#{$prog} " + Config.cl_options_string + "job:show #{job_id}' to show the status."
@@ -166,13 +174,13 @@ module Command
166
174
 
167
175
  name, cron, database, table, config_file = op.cmd_parse
168
176
 
169
- job = prepare_bulkload_job_config(config_file)
177
+ config = prepare_bulkload_job_config(config_file)
170
178
  opts[:cron] = cron
171
179
 
172
180
  client = get_client()
173
181
  get_table(client, database, table)
174
182
 
175
- session = client.bulk_load_create(name, database, table, job, opts)
183
+ session = client.bulk_load_create(name, database, table, opts.merge(config: config))
176
184
  dump_connector_session(session)
177
185
  end
178
186
 
@@ -187,10 +195,10 @@ module Command
187
195
  def connector_update(op)
188
196
  name, config_file = op.cmd_parse
189
197
 
190
- job = prepare_bulkload_job_config(config_file)
198
+ config = prepare_bulkload_job_config(config_file)
191
199
 
192
200
  client = get_client()
193
- session = client.bulk_load_update(name, job)
201
+ session = client.bulk_load_update(name, config: config)
194
202
  dump_connector_session(session)
195
203
  end
196
204
 
@@ -264,10 +272,24 @@ private
264
272
  raise ParameterConfigurationError, "configuration file: #{config_file} not found"
265
273
  end
266
274
  config_str = File.read(config_file)
267
- if file_type(config_str) == :yaml
268
- config_str = JSON.pretty_generate(YAML.load(config_str))
275
+
276
+ config = nil
277
+ begin
278
+ if file_type(config_str) == :yaml
279
+ config_str = JSON.pretty_generate(YAML.load(config_str))
280
+ end
281
+ config = JSON.load(config_str)
282
+ rescue => e
283
+ raise ParameterConfigurationError, "configuration file: #{config_file} #{e.message}"
284
+ end
285
+
286
+ if config['config']
287
+ if config.size != 1
288
+ raise "Setting #{(config.keys - ['config']).inspect} keys in a configuration file is not supported. Please set options to the command line argument."
289
+ end
290
+ config = config['config']
269
291
  end
270
- JSON.load(config_str)
292
+ config
271
293
  end
272
294
 
273
295
  def create_bulkload_job_file_backup(out)
@@ -283,14 +305,14 @@ private
283
305
  end
284
306
 
285
307
  def dump_connector_session(session)
286
- $stdout.puts "Name : #{session.name}"
287
- $stdout.puts "Cron : #{session.cron}"
288
- $stdout.puts "Timezone : #{session.timezone}"
289
- $stdout.puts "Delay : #{session.delay}"
290
- $stdout.puts "Database : #{session.database}"
291
- $stdout.puts "Table : #{session.table}"
308
+ $stdout.puts "Name : #{session["name"]}"
309
+ $stdout.puts "Cron : #{session["cron"]}"
310
+ $stdout.puts "Timezone : #{session["timezone"]}"
311
+ $stdout.puts "Delay : #{session["delay"]}"
312
+ $stdout.puts "Database : #{session["database"]}"
313
+ $stdout.puts "Table : #{session["table"]}"
292
314
  $stdout.puts "Config"
293
- $stdout.puts YAML.dump(session.config)
315
+ $stdout.puts YAML.dump(session["config"])
294
316
  end
295
317
 
296
318
  def wait_connector_job(client, job_id, exclude)
@@ -150,11 +150,15 @@ module Command
150
150
  begin
151
151
  Timeout.timeout(@timeout) do
152
152
  pid = Process.spawn(*@cmd)
153
- Process.waitpid(pid)
154
- return $?
153
+ waitpid(pid)
155
154
  end
156
155
  rescue Timeout::Error
157
156
  if pid
157
+ # NOTE last check has not been completed the process during sleep
158
+ if Process.waitpid(pid, Process::WNOHANG)
159
+ return $?
160
+ end
161
+
158
162
  require 'rbconfig'
159
163
  # win32 ruby does not support QUIT and TERM
160
164
  if RbConfig::CONFIG['host_os'] !~ /mswin|mingw|cygwin/
@@ -172,6 +176,17 @@ module Command
172
176
  return $?
173
177
  end
174
178
  end
179
+
180
+ def waitpid(pid)
181
+ # NOTE Use nonblocking mode, because Process.waitpid is block other thread at Windows.
182
+ loop do
183
+ if Process.waitpid(pid, Process::WNOHANG)
184
+ return $?
185
+ end
186
+
187
+ sleep 1
188
+ end
189
+ end
175
190
  end
176
191
 
177
192
  def check_java
@@ -236,7 +236,7 @@ module List
236
236
  add_list 'table:import', %w[db table files_], 'Parse and import files to a table', ['table:import example_db table1 --apache access.log', 'table:import example_db table1 --json -t time - < test.json']
237
237
  add_list 'table:export', %w[db table], 'Dump logs in a table to the specified storage', ['table:export example_db table1 --s3-bucket mybucket -k KEY_ID -s SECRET_KEY']
238
238
  add_list 'table:swap', %w[db table1 table2], 'Swap names of two tables', ['table:swap example_db table1 table2']
239
- add_list 'table:tail', %w[db table], 'Get recently imported logs', ['table:tail example_db table1', 'table:tail example_db table1 -t "2011-01-02 03:04:05" -n 30']
239
+ add_list 'table:tail', %w[db table], 'Get recently imported logs', ['table:tail example_db table1', 'table:tail example_db table1 -n 30']
240
240
  add_list 'table:partial_delete', %w[db table], 'Delete logs from the table within the specified time range', ['table:partial_delete example_db table1 --from 1341000000 --to 1341003600']
241
241
  add_list 'table:expire', %w[db table expire_days], 'Expire data in table after specified number of days. Set to 0 to disable the expiration.', ['table:expire example_db table1 30']
242
242
 
@@ -332,7 +332,17 @@ module List
332
332
 
333
333
  add_list 'update', %w[], 'Update td and related libraries for TreasureData toolbelt'
334
334
 
335
- add_list 'connector:guess', %w[config?], 'Run guess to generate connector config file', ['connector:guess td-bulkload.yml', 'connector:guess --access-id s3accessId --access-secret s3AccessKey --source https://s3.amazonaws.com/bucketname/path/prefix --database connector_database --table connector_table']
335
+ connector_guess_example_config = "
336
+ in:
337
+ type: s3
338
+ bucket: my-s3-bucket
339
+ endpoint: s3-us-west-1.amazonaws.com
340
+ path_prefix: path/prefix/to/import/
341
+ access_key_id: ABCXYZ123ABCXYZ123
342
+ secret_access_key: AbCxYz123aBcXyZ123
343
+ out:
344
+ mode: append"
345
+ add_list 'connector:guess', %w[config?], 'Run guess to generate connector config file', ["connector:guess config.yml -o td-bulkload.yml\n\nexample config.yml:#{connector_guess_example_config}"]
336
346
  add_list 'connector:preview', %w[config], 'Show preview of connector execution', ['connector:preview td-bulkload.yml']
337
347
 
338
348
  add_list 'connector:issue', %w[config], 'Run one time connector execution', ['connector:issue td-bulkload.yml']
@@ -18,9 +18,9 @@ module Command
18
18
  primary_key = nil
19
19
  primary_key_type = nil
20
20
 
21
- op.on('-T', '--type TYPE', 'set table type (log or item)') {|s|
22
- unless ['item', 'log'].include?(s)
23
- raise "Unknown table type #{s.dump}. Supported types: log and item"
21
+ op.on('-T', '--type TYPE', 'set table type (log)') {|s|
22
+ unless s == 'log'
23
+ raise "Unknown table type #{s.dump}. Supported types: log"
24
24
  end
25
25
  type = s.to_sym
26
26
  }
@@ -49,19 +49,10 @@ module Command
49
49
  $stderr.puts " For a list of all reserved keywords, see our FAQ: http://docs.treasure-data.com/articles/faq"
50
50
  end
51
51
 
52
- if type == :item && (primary_key.nil? || primary_key_type.nil?)
53
- $stderr.puts "for TYPE 'item', the primary-key is required"
54
- exit 1
55
- end
56
-
57
52
  client = get_client
58
53
 
59
54
  begin
60
- if type == :item
61
- client.create_item_table(db_name, table_name, primary_key, primary_key_type)
62
- else
63
- client.create_log_table(db_name, table_name)
64
- end
55
+ client.create_log_table(db_name, table_name)
65
56
  rescue NotFoundError
66
57
  cmd_debug_error $!
67
58
  $stderr.puts "Database '#{db_name}' does not exist."
@@ -144,10 +135,6 @@ module Command
144
135
  databases = client.databases
145
136
  end
146
137
 
147
- has_item = databases.select {|db|
148
- db.permission != :import_only ? (db.tables.select {|table| table.type == :item}.length > 0) : false
149
- }.length > 0
150
-
151
138
  # ref. https://github.com/treasure-data/td/issues/26
152
139
  should_number_format = [nil, "table"].include?(op.render_format)
153
140
  rows = []
@@ -168,9 +155,7 @@ module Command
168
155
  'Last log timestamp' => table.last_log_timestamp ? table.last_log_timestamp.localtime : nil,
169
156
  :Schema => pschema
170
157
  }
171
- if has_item and table.type == :item
172
- new_row['Primary key'] = "#{table.primary_key}:#{table.primary_key_type}"
173
- end
158
+
174
159
  rows << new_row
175
160
  }
176
161
  rescue APIError => e
@@ -185,12 +170,7 @@ module Command
185
170
  [map[:Database], map[:Type].size, map[:Table]]
186
171
  }
187
172
 
188
- fields = []
189
- if has_item
190
- fields = [:Database, :Table, :Type, :Count, :Size, 'Last import', 'Last log timestamp', 'Primary key', :Schema]
191
- else
192
- fields = [:Database, :Table, :Type, :Count, :Size, 'Last import', 'Last log timestamp', :Schema]
193
- end
173
+ fields = [:Database, :Table, :Type, :Count, :Size, 'Last import', 'Last log timestamp', :Schema]
194
174
  $stdout.puts cmd_render_table(rows, :fields => fields, :max_width => 500, :render_format => op.render_format)
195
175
 
196
176
  if rows.empty?
@@ -235,7 +215,6 @@ module Command
235
215
  $stdout.puts "Type : #{table.type}"
236
216
  $stdout.puts "Count : #{table.count}"
237
217
  # p table.methods.each {|m| $stdout.puts m}
238
- $stdout.puts "Primary key : #{table.primary_key}:#{table.primary_key_type}" if table.type == :item
239
218
  $stdout.puts "Schema : ("
240
219
  table.schema.fields.each {|f|
241
220
  $stdout.puts " #{f.name}:#{f.type}"
@@ -244,27 +223,9 @@ module Command
244
223
  end
245
224
 
246
225
  def table_tail(op)
247
- from = nil
248
- to = nil
249
226
  count = 10
250
227
  pretty = nil
251
228
 
252
- op.on('-t', '--to TIME', 'end time of logs to get') {|s|
253
- if s.to_i.to_s == s
254
- to = s.to_i
255
- else
256
- require 'time'
257
- to = Time.parse(s).to_i
258
- end
259
- }
260
- op.on('-f', '--from TIME', 'start time of logs to get') {|s|
261
- if s.to_i.to_s == s
262
- from = s.to_i
263
- else
264
- require 'time'
265
- from = Time.parse(s).to_i
266
- end
267
- }
268
229
  op.on('-n', '--count N', 'number of logs to get', Integer) {|i|
269
230
  count = i
270
231
  }
@@ -278,7 +239,7 @@ module Command
278
239
 
279
240
  table = get_table(client, db_name, table_name)
280
241
 
281
- rows = table.tail(count, to, from)
242
+ rows = table.tail(count)
282
243
 
283
244
  require 'json'
284
245
  if pretty
data/lib/td/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module TreasureData
2
- TOOLBELT_VERSION = '0.11.10'
2
+ TOOLBELT_VERSION = '0.11.11'
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -8,13 +8,19 @@ if ENV['SIMPLE_COV']
8
8
  # SimpleCov
9
9
  # https://github.com/colszowka/simplecov
10
10
  require 'simplecov'
11
- SimpleCov.start do
11
+ SimpleCov.start do
12
12
  add_filter 'spec/'
13
13
  add_filter 'pkg/'
14
14
  add_filter 'vendor/'
15
15
  end
16
16
  end
17
17
 
18
+ # XXX skip coverage setting if run appveyor. Because, fail to push coveralls in appveyor.
19
+ unless ENV['APPVEYOR']
20
+ require 'coveralls'
21
+ Coveralls.wear!('rails')
22
+ end
23
+
18
24
  require 'td/command/runner'
19
25
 
20
26
  def execute_td(command_line)
@@ -6,6 +6,10 @@ require 'td/command/connector'
6
6
  module TreasureData::Command
7
7
  describe 'connector commands' do
8
8
  describe '#connector_preview' do
9
+ let :command do
10
+ Class.new { include TreasureData::Command }.new
11
+ end
12
+
9
13
  subject do
10
14
  backup = $stdout.dup
11
15
  buf = StringIO.new
@@ -13,7 +17,8 @@ module TreasureData::Command
13
17
  begin
14
18
  $stdout = buf
15
19
 
16
- TreasureData::Command::Runner.new.run ["connector:preview", tempfile]
20
+ op = List::CommandParser.new("connector:preview", ["config"], [], nil, [File.join("spec", "td", "fixture", "bulk_load.yml")], true)
21
+ command.connector_preview(op)
17
22
 
18
23
  buf.string
19
24
  ensure
@@ -21,10 +26,6 @@ module TreasureData::Command
21
26
  end
22
27
  end
23
28
 
24
- let(:tempfile) do
25
- File.join("spec", "td", "fixture", "bulk_load.yml")
26
- end
27
-
28
29
  let(:preview_result) do
29
30
  {
30
31
  "schema" => [
@@ -42,7 +43,8 @@ module TreasureData::Command
42
43
  end
43
44
 
44
45
  before do
45
- TreasureData::Client.any_instance.stub(:bulk_load_preview).and_return(preview_result)
46
+ client = double(:client, bulk_load_preview: preview_result)
47
+ command.stub(:get_client).and_return(client)
46
48
  end
47
49
 
48
50
  it 'should include too_long_column_name without truncated' do
@@ -13,7 +13,7 @@ module TreasureData::Command
13
13
  end
14
14
 
15
15
  describe 'write_result' do
16
- let(:file) { Tempfile.new("job_spec") }
16
+ let(:file) { Tempfile.new("job_spec").tap {|s| s.close } }
17
17
 
18
18
  let :job do
19
19
  job = TreasureData::Job.new(nil, 12345, 'hive', 'select * from employee')
@@ -395,6 +395,14 @@ ACTUAL
395
395
  [multibyte_string, 2.0, {multibyte_string => multibyte_string}]
396
396
  end
397
397
 
398
+ let(:line_separator) {
399
+ if RUBY_PLATFORM =~ /mswin32|mingw32/
400
+ "\r\n"
401
+ else
402
+ "\n"
403
+ end
404
+ }
405
+
398
406
  let :job do
399
407
  row = multibyte_row
400
408
  job = TreasureData::Job.new(nil, 12345, 'hive', 'select * from employee')
@@ -414,24 +422,24 @@ ACTUAL
414
422
 
415
423
  it 'supports json output' do
416
424
  row = multibyte_row
417
- file = Tempfile.new("job_spec")
425
+ file = Tempfile.new("job_spec").tap {|s| s.close }
418
426
  command.send(:show_result, job, file, nil, 'json')
419
- File.read(file.path).should == '[' + [row, row].map { |e| Yajl.dump(e) }.join(",\n") + ']'
427
+ File.read(file.path, encoding: 'UTF-8').should == '[' + [row, row].map { |e| Yajl.dump(e) }.join(",\n") + ']'
420
428
  end
421
429
 
422
430
  it 'supports csv output' do
423
431
  row = multibyte_row.map { |e| dump_column(e) }
424
- file = Tempfile.new("job_spec")
432
+ file = Tempfile.new("job_spec").tap {|s| s.close }
425
433
  command.send(:show_result, job, file, nil, 'csv')
426
- File.binread(file.path).should == [row, row].map { |e| CSV.generate_line(e) }.join
434
+ File.binread(file.path).should == [row, row].map { |e| CSV.generate_line(e, :row_sep => line_separator) }.join
427
435
  File.open(file.path, 'r:Windows-31J').read.encode('UTF-8').split.first.should == 'メール,2.0,"{""メール"":""メール""}"'
428
436
  end
429
437
 
430
438
  it 'supports tsv output' do
431
439
  row = multibyte_row.map { |e| dump_column(e) }
432
- file = Tempfile.new("job_spec")
440
+ file = Tempfile.new("job_spec").tap {|s| s.close }
433
441
  command.send(:show_result, job, file, nil, 'tsv')
434
- File.binread(file.path).should == [row, row].map { |e| e.join("\t") + "\n" }.join
442
+ File.binread(file.path).should == [row, row].map { |e| e.join("\t") + line_separator }.join
435
443
  File.open(file.path, 'r:Windows-31J').read.encode('UTF-8').split("\n").first.should == "メール\t2.0\t{\"メール\":\"メール\"}"
436
444
  end
437
445
  end
@@ -8,34 +8,42 @@ require 'logger'
8
8
 
9
9
  module TreasureData::Updater
10
10
 
11
- describe 'without the TD_TOOLBELT_UPDATE_ROOT environment variable defined' do
12
- let :default_toolbelt_url do
13
- "http://toolbelt.treasuredata.com"
14
- end
11
+ %w(x86_64-darwin14 i386-mingw32).each do |platform|
12
+ describe "RUBY_PLATFORM is '#{platform}'" do
13
+ before do
14
+ stub_const('RUBY_PLATFORM', platform)
15
+ end
16
+
17
+ describe 'without the TD_TOOLBELT_UPDATE_ROOT environment variable defined' do
18
+ let :default_toolbelt_url do
19
+ "http://toolbelt.treasuredata.com"
20
+ end
15
21
 
16
- describe 'endpoints methods' do
17
- it 'use the default root path' do
18
- TreasureData::Updater.endpoint_root.should == default_toolbelt_url
19
- TreasureData::Updater.version_endpoint.should =~ Regexp.new(default_toolbelt_url)
20
- TreasureData::Updater.update_package_endpoint.should =~ Regexp.new(default_toolbelt_url)
22
+ describe 'endpoints methods' do
23
+ it 'use the default root path' do
24
+ TreasureData::Updater.endpoint_root.should == default_toolbelt_url
25
+ TreasureData::Updater.version_endpoint.should =~ Regexp.new(default_toolbelt_url)
26
+ TreasureData::Updater.update_package_endpoint.should =~ Regexp.new(default_toolbelt_url)
27
+ end
28
+ end
21
29
  end
22
- end
23
- end
24
30
 
25
- describe 'with the TD_TOOLBELT_UPDATE_ROOT environment variable defined' do
26
- before do
27
- ENV['TD_TOOLBELT_UPDATE_ROOT'] = 'https://0.0.0.0:5000/'
28
- end
29
- describe 'endpoints methods' do
30
- it 'use the custom root path' do
31
- TreasureData::Updater.endpoint_root.should == ENV['TD_TOOLBELT_UPDATE_ROOT']
32
- TreasureData::Updater.version_endpoint.should =~ Regexp.new(ENV['TD_TOOLBELT_UPDATE_ROOT'])
33
- TreasureData::Updater.update_package_endpoint.should =~ Regexp.new(ENV['TD_TOOLBELT_UPDATE_ROOT'])
31
+ describe 'with the TD_TOOLBELT_UPDATE_ROOT environment variable defined' do
32
+ before do
33
+ ENV['TD_TOOLBELT_UPDATE_ROOT'] = 'https://0.0.0.0:5000/'
34
+ end
35
+ describe 'endpoints methods' do
36
+ it 'use the custom root path' do
37
+ TreasureData::Updater.endpoint_root.should == ENV['TD_TOOLBELT_UPDATE_ROOT']
38
+ TreasureData::Updater.version_endpoint.should =~ Regexp.new(ENV['TD_TOOLBELT_UPDATE_ROOT'])
39
+ TreasureData::Updater.update_package_endpoint.should =~ Regexp.new(ENV['TD_TOOLBELT_UPDATE_ROOT'])
40
+ end
41
+ end
42
+ after do
43
+ ENV.delete 'TD_TOOLBELT_UPDATE_ROOT'
44
+ end
34
45
  end
35
46
  end
36
- after do
37
- ENV.delete 'TD_TOOLBELT_UPDATE_ROOT'
38
- end
39
47
  end
40
48
 
41
49
  describe 'with a proxy' do
data/td.gemspec CHANGED
@@ -21,10 +21,12 @@ Gem::Specification.new do |gem|
21
21
  gem.add_dependency "yajl-ruby", "~> 1.1"
22
22
  gem.add_dependency "hirb", ">= 0.4.5"
23
23
  gem.add_dependency "parallel", "~> 0.6.1"
24
- gem.add_dependency "td-client", "~> 0.8.70"
24
+ gem.add_dependency "td-client", "~> 0.8.71"
25
25
  gem.add_dependency "td-logger", "~> 0.3.21"
26
- gem.add_dependency "rubyzip", "~> 0.9.9"
26
+ gem.add_dependency "rubyzip", "~> 1.1.7"
27
+ gem.add_dependency "zip-zip", "~> 0.3"
27
28
  gem.add_development_dependency "rake", "~> 0.9"
28
29
  gem.add_development_dependency "rspec", "~> 2.11.0"
29
- gem.add_development_dependency "simplecov", "~> 0.5.4"
30
+ gem.add_development_dependency "simplecov", "~> 0.10.0"
31
+ gem.add_development_dependency 'coveralls'
30
32
  end
metadata CHANGED
@@ -1,34 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: td
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.10
5
- prerelease:
4
+ version: 0.11.11
6
5
  platform: ruby
7
6
  authors:
8
7
  - Treasure Data, Inc.
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-05-19 00:00:00.000000000 Z
11
+ date: 2015-07-15 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: msgpack
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 0.4.4
22
- - - ! '!='
20
+ - - '!='
23
21
  - !ruby/object:Gem::Version
24
22
  version: 0.5.0
25
- - - ! '!='
23
+ - - '!='
26
24
  - !ruby/object:Gem::Version
27
25
  version: 0.5.1
28
- - - ! '!='
26
+ - - '!='
29
27
  - !ruby/object:Gem::Version
30
28
  version: 0.5.2
31
- - - ! '!='
29
+ - - '!='
32
30
  - !ruby/object:Gem::Version
33
31
  version: 0.5.3
34
32
  - - <
@@ -37,21 +35,20 @@ dependencies:
37
35
  type: :runtime
38
36
  prerelease: false
39
37
  version_requirements: !ruby/object:Gem::Requirement
40
- none: false
41
38
  requirements:
42
- - - ! '>='
39
+ - - '>='
43
40
  - !ruby/object:Gem::Version
44
41
  version: 0.4.4
45
- - - ! '!='
42
+ - - '!='
46
43
  - !ruby/object:Gem::Version
47
44
  version: 0.5.0
48
- - - ! '!='
45
+ - - '!='
49
46
  - !ruby/object:Gem::Version
50
47
  version: 0.5.1
51
- - - ! '!='
48
+ - - '!='
52
49
  - !ruby/object:Gem::Version
53
50
  version: 0.5.2
54
- - - ! '!='
51
+ - - '!='
55
52
  - !ruby/object:Gem::Version
56
53
  version: 0.5.3
57
54
  - - <
@@ -60,7 +57,6 @@ dependencies:
60
57
  - !ruby/object:Gem::Dependency
61
58
  name: yajl-ruby
62
59
  requirement: !ruby/object:Gem::Requirement
63
- none: false
64
60
  requirements:
65
61
  - - ~>
66
62
  - !ruby/object:Gem::Version
@@ -68,7 +64,6 @@ dependencies:
68
64
  type: :runtime
69
65
  prerelease: false
70
66
  version_requirements: !ruby/object:Gem::Requirement
71
- none: false
72
67
  requirements:
73
68
  - - ~>
74
69
  - !ruby/object:Gem::Version
@@ -76,23 +71,20 @@ dependencies:
76
71
  - !ruby/object:Gem::Dependency
77
72
  name: hirb
78
73
  requirement: !ruby/object:Gem::Requirement
79
- none: false
80
74
  requirements:
81
- - - ! '>='
75
+ - - '>='
82
76
  - !ruby/object:Gem::Version
83
77
  version: 0.4.5
84
78
  type: :runtime
85
79
  prerelease: false
86
80
  version_requirements: !ruby/object:Gem::Requirement
87
- none: false
88
81
  requirements:
89
- - - ! '>='
82
+ - - '>='
90
83
  - !ruby/object:Gem::Version
91
84
  version: 0.4.5
92
85
  - !ruby/object:Gem::Dependency
93
86
  name: parallel
94
87
  requirement: !ruby/object:Gem::Requirement
95
- none: false
96
88
  requirements:
97
89
  - - ~>
98
90
  - !ruby/object:Gem::Version
@@ -100,7 +92,6 @@ dependencies:
100
92
  type: :runtime
101
93
  prerelease: false
102
94
  version_requirements: !ruby/object:Gem::Requirement
103
- none: false
104
95
  requirements:
105
96
  - - ~>
106
97
  - !ruby/object:Gem::Version
@@ -108,23 +99,20 @@ dependencies:
108
99
  - !ruby/object:Gem::Dependency
109
100
  name: td-client
110
101
  requirement: !ruby/object:Gem::Requirement
111
- none: false
112
102
  requirements:
113
103
  - - ~>
114
104
  - !ruby/object:Gem::Version
115
- version: 0.8.70
105
+ version: 0.8.71
116
106
  type: :runtime
117
107
  prerelease: false
118
108
  version_requirements: !ruby/object:Gem::Requirement
119
- none: false
120
109
  requirements:
121
110
  - - ~>
122
111
  - !ruby/object:Gem::Version
123
- version: 0.8.70
112
+ version: 0.8.71
124
113
  - !ruby/object:Gem::Dependency
125
114
  name: td-logger
126
115
  requirement: !ruby/object:Gem::Requirement
127
- none: false
128
116
  requirements:
129
117
  - - ~>
130
118
  - !ruby/object:Gem::Version
@@ -132,7 +120,6 @@ dependencies:
132
120
  type: :runtime
133
121
  prerelease: false
134
122
  version_requirements: !ruby/object:Gem::Requirement
135
- none: false
136
123
  requirements:
137
124
  - - ~>
138
125
  - !ruby/object:Gem::Version
@@ -140,23 +127,34 @@ dependencies:
140
127
  - !ruby/object:Gem::Dependency
141
128
  name: rubyzip
142
129
  requirement: !ruby/object:Gem::Requirement
143
- none: false
144
130
  requirements:
145
131
  - - ~>
146
132
  - !ruby/object:Gem::Version
147
- version: 0.9.9
133
+ version: 1.1.7
148
134
  type: :runtime
149
135
  prerelease: false
150
136
  version_requirements: !ruby/object:Gem::Requirement
151
- none: false
152
137
  requirements:
153
138
  - - ~>
154
139
  - !ruby/object:Gem::Version
155
- version: 0.9.9
140
+ version: 1.1.7
141
+ - !ruby/object:Gem::Dependency
142
+ name: zip-zip
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ~>
146
+ - !ruby/object:Gem::Version
147
+ version: '0.3'
148
+ type: :runtime
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ~>
153
+ - !ruby/object:Gem::Version
154
+ version: '0.3'
156
155
  - !ruby/object:Gem::Dependency
157
156
  name: rake
158
157
  requirement: !ruby/object:Gem::Requirement
159
- none: false
160
158
  requirements:
161
159
  - - ~>
162
160
  - !ruby/object:Gem::Version
@@ -164,7 +162,6 @@ dependencies:
164
162
  type: :development
165
163
  prerelease: false
166
164
  version_requirements: !ruby/object:Gem::Requirement
167
- none: false
168
165
  requirements:
169
166
  - - ~>
170
167
  - !ruby/object:Gem::Version
@@ -172,7 +169,6 @@ dependencies:
172
169
  - !ruby/object:Gem::Dependency
173
170
  name: rspec
174
171
  requirement: !ruby/object:Gem::Requirement
175
- none: false
176
172
  requirements:
177
173
  - - ~>
178
174
  - !ruby/object:Gem::Version
@@ -180,7 +176,6 @@ dependencies:
180
176
  type: :development
181
177
  prerelease: false
182
178
  version_requirements: !ruby/object:Gem::Requirement
183
- none: false
184
179
  requirements:
185
180
  - - ~>
186
181
  - !ruby/object:Gem::Version
@@ -188,19 +183,31 @@ dependencies:
188
183
  - !ruby/object:Gem::Dependency
189
184
  name: simplecov
190
185
  requirement: !ruby/object:Gem::Requirement
191
- none: false
192
186
  requirements:
193
187
  - - ~>
194
188
  - !ruby/object:Gem::Version
195
- version: 0.5.4
189
+ version: 0.10.0
196
190
  type: :development
197
191
  prerelease: false
198
192
  version_requirements: !ruby/object:Gem::Requirement
199
- none: false
200
193
  requirements:
201
194
  - - ~>
202
195
  - !ruby/object:Gem::Version
203
- version: 0.5.4
196
+ version: 0.10.0
197
+ - !ruby/object:Gem::Dependency
198
+ name: coveralls
199
+ requirement: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - '>='
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ type: :development
205
+ prerelease: false
206
+ version_requirements: !ruby/object:Gem::Requirement
207
+ requirements:
208
+ - - '>='
209
+ - !ruby/object:Gem::Version
210
+ version: '0'
204
211
  description: CLI to manage data on Treasure Data, the Hadoop-based cloud data warehousing
205
212
  email: support@treasure-data.com
206
213
  executables:
@@ -208,11 +215,14 @@ executables:
208
215
  extensions: []
209
216
  extra_rdoc_files: []
210
217
  files:
218
+ - .coveralls.yml
211
219
  - .gitignore
220
+ - .travis.yml
212
221
  - ChangeLog
213
222
  - Gemfile
214
223
  - README.rdoc
215
224
  - Rakefile
225
+ - appveyor.yml
216
226
  - bin/td
217
227
  - contrib/completion/_td
218
228
  - contrib/completion/td-completion.bash
@@ -277,30 +287,26 @@ files:
277
287
  - td.gemspec
278
288
  homepage: http://treasure-data.com/
279
289
  licenses: []
290
+ metadata: {}
280
291
  post_install_message:
281
292
  rdoc_options: []
282
293
  require_paths:
283
294
  - lib
284
295
  required_ruby_version: !ruby/object:Gem::Requirement
285
- none: false
286
296
  requirements:
287
- - - ! '>='
297
+ - - '>='
288
298
  - !ruby/object:Gem::Version
289
299
  version: '1.9'
290
300
  required_rubygems_version: !ruby/object:Gem::Requirement
291
- none: false
292
301
  requirements:
293
- - - ! '>='
302
+ - - '>='
294
303
  - !ruby/object:Gem::Version
295
304
  version: '0'
296
- segments:
297
- - 0
298
- hash: -1990136432195876879
299
305
  requirements: []
300
306
  rubyforge_project:
301
- rubygems_version: 1.8.23.2
307
+ rubygems_version: 2.0.14
302
308
  signing_key:
303
- specification_version: 3
309
+ specification_version: 4
304
310
  summary: CLI to manage data on Treasure Data, the Hadoop-based cloud data warehousing
305
311
  test_files:
306
312
  - spec/file_reader/filter_spec.rb