td 0.19.1 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 31b1a67a8c7eb186dd15a4eca1908c17721d4357130e6dbaf5948e3caa8c1c93
4
- data.tar.gz: a953f89bbea10074a74b0db871826f0eb1be03f957cd2b1a7b99339969dc8ad7
3
+ metadata.gz: c5b298b2bc367af92e02a5c12b99851eb33241ccf1a695a273ddf3b9809a602f
4
+ data.tar.gz: aae07a24b93c4f728d982deb6be0b99741ccb8bf74c1d806cbf8f506746e188f
5
5
  SHA512:
6
- metadata.gz: f4b83dbd875db51fef4b233320c2a2b152c08445f78cba99697f8c0780340197d48f04fa058241ec09b1478d27062afeac09235f37b698704caf42fc9624a590
7
- data.tar.gz: 7bbba6e8fd833d248987f968b2952171b6cb54bf7fdc20593a6edab2f62283a2b2a220219242b65b326785feca21ec86e7c7a62c5fc1ebf49577d304bb977ff0
6
+ metadata.gz: 48f070f557923c3491dc2abe1125077b711ed5393c077a04345f80e2553a26e28dd1d04878712e5a47f4192f416ed049cc7aebcccab891c2e697ba0afaf1a208
7
+ data.tar.gz: c0c1ffa341bc4803c561c8852ba4b7cd51668fc0067faf2060644a9bd48d9c877a17165c7e79e32b28ffe8d03082cc43d524f58f4ec6395e3443f52a2468ae41
data/.circleci/config.yml CHANGED
@@ -19,13 +19,13 @@ commands:
19
19
  shell: powershell.exe
20
20
  command: choco install msys2 -y
21
21
  - run:
22
- name: "Install Ruby devkit"
22
+ name: "Install Ruby version"
23
23
  shell: powershell.exe
24
- command: ridk install 2 3
24
+ command: choco install ruby --version=<<parameters.ruby_version>> --allow-downgrade --yes
25
25
  - run:
26
- name: "Install Ruby version"
26
+ name: "Install Ruby devkit"
27
27
  shell: powershell.exe
28
- command: choco install ruby --version=<<parameters.ruby_version>>
28
+ command: ridk install 2 3
29
29
  - run:
30
30
  name: "Install bundler"
31
31
  command: gem install bundler
@@ -54,12 +54,6 @@ commands:
54
54
 
55
55
  jobs:
56
56
 
57
- ruby_27:
58
- docker:
59
- - image: cimg/ruby:2.7-browsers
60
- steps:
61
- - run-tests-flow
62
-
63
57
  ruby_30:
64
58
  docker:
65
59
  - image: cimg/ruby:3.0-browsers
@@ -103,7 +97,6 @@ jobs:
103
97
  workflows:
104
98
  tests:
105
99
  jobs:
106
- - ruby_27
107
100
  - ruby_30
108
101
  - ruby_31
109
102
  - ruby_32
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ == 2026-11-04 version 0.20.0
2
+
3
+ * Patch rubyzip v3.4
4
+
1
5
  == 2025-08-28 version 0.19.1
2
6
 
3
7
  * Update query command help text
data/README.rdoc CHANGED
@@ -51,7 +51,7 @@ Install following binary packages:
51
51
 
52
52
  * MinGW with MSYS Basic System and using mingw-get-inst
53
53
  * Git for Windows, with Windows Command Prompt support
54
- * Ruby ruby-1.9.3p327 using RubyInstaller for Windows, with PATH update
54
+ * Ruby 3.0 or later using RubyInstaller for Windows, with PATH update
55
55
  * Inno Setup 5
56
56
 
57
57
  Then run following commands on MinGW Shell:
data/Rakefile CHANGED
@@ -1,6 +1,6 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
- require 'zip/zip'
3
+ require 'zip'
4
4
  Bundler::GemHelper.install_tasks
5
5
 
6
6
  task :default => :build
@@ -133,7 +133,7 @@ def download_resource(url)
133
133
  end
134
134
 
135
135
  def zip_files(zip_name, target_dir)
136
- Zip::ZipFile.open(zip_name, Zip::ZipFile::CREATE) do |zip|
136
+ Zip::File.open(zip_name, create: true) do |zip|
137
137
  Dir["#{target_dir}/**/*"].each do |file|
138
138
  zipped_path = file[target_dir.length + 1..-1]
139
139
  zip.add(zipped_path, file) { true }
data/appveyor.yml CHANGED
@@ -1,17 +1,26 @@
1
1
  ---
2
2
  version: "{build}"
3
+ image: Visual Studio 2022
3
4
  clone_depth: 10
4
5
  install:
6
+ - IF NOT EXIST C:\Ruby%ruby_version%\bin\ruby.exe EXIT /B 1
5
7
  - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
6
8
  - ruby --version
9
+ - call ridk install 3
10
+ - call ridk enable
11
+ - gcc -dumpmachine
7
12
  - gem --version
8
13
  - bundle --version
14
+ # Ruby 3.1 callback declarations require pre-C23 semantics with modern GCC.
15
+ - bundle config set --local build.yajl-ruby "--with-cflags=-std=gnu17"
9
16
  - bundle install
10
17
  build_script:
11
18
  - bundle exec rake build
12
19
  test_script:
13
20
  - bundle exec rake spec
21
+ on_failure:
22
+ - ps: Get-Content "C:\Ruby$env:ruby_version\lib\ruby\gems\*\extensions\*\*\msgpack-*\mkmf.log" -ErrorAction SilentlyContinue
14
23
  environment:
15
24
  matrix:
16
- - ruby_version: "26"
17
- - ruby_version: "26-x64"
25
+ - ruby_version: "31"
26
+ - ruby_version: "31-x64"
@@ -28,6 +28,8 @@ module Command
28
28
  /\A[\+]?2\z/ => 2,
29
29
  }
30
30
 
31
+ QUERY_JOB_TYPES = [:hive, :pig, :impala, :presto, :trino].freeze
32
+
31
33
  def job_list(op)
32
34
  page = 0
33
35
  skip = 0
@@ -176,7 +178,7 @@ private
176
178
  $stdout.puts "Start At : #{job.start_at}"
177
179
  $stdout.puts "End At : #{job.end_at}"
178
180
  # exclude some fields from bulk_import_perform type jobs
179
- if [:hive, :pig, :impala, :presto].include?(job.type)
181
+ if QUERY_JOB_TYPES.include?(job.type)
180
182
  $stdout.puts "Priority : #{job_priority_name_of(job.priority)}"
181
183
  $stdout.puts "Retry limit : #{job.retry_limit}"
182
184
  $stdout.puts "Output : #{job.result_url}"
@@ -192,7 +194,7 @@ private
192
194
  if [:hive].include?(job.type)
193
195
  $stdout.puts "CPU time : #{Command.humanize_time(job.cpu_time, true)}"
194
196
  end
195
- if [:hive, :pig, :impala, :presto].include?(job.type)
197
+ if QUERY_JOB_TYPES.include?(job.type)
196
198
  $stdout.puts "Result size : #{Command.humanize_bytesize(job.result_size, 2)}"
197
199
  end
198
200
  end
@@ -200,11 +202,11 @@ private
200
202
  if wait && !job.finished?
201
203
  $stderr.puts "the job #{job.job_id} is still running..."
202
204
  wait_job(job)
203
- if [:hive, :pig, :impala, :presto].include?(job.type) && !exclude
205
+ if QUERY_JOB_TYPES.include?(job.type) && !exclude
204
206
  show_result_with_retry(job, output, limit, format, render_opts)
205
207
  end
206
208
  else
207
- if [:hive, :pig, :impala, :presto].include?(job.type) && !exclude && job.finished?
209
+ if QUERY_JOB_TYPES.include?(job.type) && !exclude && job.finished?
208
210
  show_result_with_retry(job, output, limit, format, render_opts)
209
211
  end
210
212
 
@@ -65,7 +65,7 @@ module Command
65
65
  op.on('-q', '--query PATH', 'use file instead of inline query') {|s|
66
66
  query = File.open(s) { |f| f.read.strip }
67
67
  }
68
- op.on('-T', '--type TYPE', 'set query type (hive, trino)') {|s|
68
+ op.on('-T', '--type TYPE', 'set query type (hive, presto, trino)') {|s|
69
69
  type = s.to_sym
70
70
  }
71
71
  op.on('--sampling DENOMINATOR', 'OBSOLETE - enable random sampling to reduce records 1/DENOMINATOR', Integer) {|i|
@@ -77,7 +77,7 @@ module Command
77
77
  op.on('-R', '--retry COUNT', 'automatic retrying count', Integer) {|i|
78
78
  retry_limit = i
79
79
  }
80
- op.on('-T', '--type TYPE', 'set query type (hive)') {|s|
80
+ op.on('-T', '--type TYPE', 'set query type (hive, presto, trino)') {|s|
81
81
  type = s
82
82
  }
83
83
  op.on('--engine-version ENGINE_VERSION', 'EXPERIMENTAL: specify query engine version by name') {|s|
@@ -195,7 +195,7 @@ module Command
195
195
  op.on('-R', '--retry COUNT', 'automatic retrying count', Integer) {|i|
196
196
  retry_limit = i
197
197
  }
198
- op.on('-T', '--type TYPE', 'set query type (hive)') {|s|
198
+ op.on('-T', '--type TYPE', 'set query type (hive, presto, trino)') {|s|
199
199
  type = s
200
200
  }
201
201
  op.on('--engine-version ENGINE_VERSION', 'EXPERIMENTAL: specify query engine version by name') {|s|
@@ -246,8 +246,8 @@ EOF
246
246
  return false
247
247
  end
248
248
  if output =~ /openjdk version/ or output =~ /java version/
249
- m = output.match(/version "(\d+)\.(\d+)\.(\d+)(\.\d+)?(?:_(\d+))?"/)
250
- if not m or m.size < 4
249
+ m = output.match(/version "(\d+)(?:\.(\d+))?(?:[._+-][^"]*)?"/)
250
+ if not m
251
251
  return false
252
252
  end
253
253
  major = m[1].to_i
@@ -357,17 +357,20 @@ EOF
357
357
  private
358
358
  def extract_zip(zip_archive, destination, strip)
359
359
  require 'fileutils'
360
- require 'zip/zip'
361
- Zip::ZipFile.open(zip_archive) { |zip_file|
360
+ require 'zip'
361
+ Zip::File.open(zip_archive) { |zip_file|
362
362
  zip_file.each { |f|
363
363
  stripped = strip_components(f.name, strip)
364
364
  if stripped.empty?
365
365
  next
366
366
  end
367
- dest = File.join destination, stripped
367
+ dest = File.expand_path(stripped, destination)
368
+ unless dest.start_with?(File.expand_path(destination) + File::SEPARATOR)
369
+ raise Zip::EntryNameError, f.name
370
+ end
368
371
  FileUtils.rm_rf dest if File.exist? dest
369
372
  FileUtils.mkdir_p(File.dirname(dest))
370
- zip_file.extract(f, dest)
373
+ f.extract(stripped, destination_directory: destination)
371
374
  }
372
375
  }
373
376
  end
data/lib/td/updater.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require "fileutils"
3
3
  require "shellwords"
4
- require "zip/zip"
4
+ require "zip"
5
5
 
6
6
  module TreasureData
7
7
  module Updater
@@ -155,7 +155,7 @@ module ModuleDefinition
155
155
  require "td"
156
156
  require 'open-uri'
157
157
  require "tmpdir"
158
- require "zip/zip"
158
+ require "zip"
159
159
 
160
160
  latest_version = fetch(version_endpoint)
161
161
 
@@ -175,11 +175,14 @@ module ModuleDefinition
175
175
  indicator.finish
176
176
 
177
177
  $stdout.print "Unpacking updated toolbelt package..."
178
- Zip::ZipFile.open("#{download_dir}/td-update.zip") do |zip|
178
+ Zip::File.open("#{download_dir}/td-update.zip") do |zip|
179
179
  zip.each do |entry|
180
- target = File.join(download_dir, entry.to_s)
180
+ target = File.expand_path(entry.name, download_dir)
181
+ unless target.start_with?(File.expand_path(download_dir) + File::SEPARATOR)
182
+ raise Zip::EntryNameError, entry.name
183
+ end
181
184
  FileUtils.mkdir_p(File.dirname(target))
182
- zip.extract(entry, target) { true }
185
+ entry.extract(destination_directory: download_dir) { true }
183
186
  end
184
187
  end
185
188
  $stdout.print " done\n"
data/lib/td/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module TreasureData
2
- TOOLBELT_VERSION = '0.19.1'
2
+ TOOLBELT_VERSION = '0.20.0'
3
3
  end
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,7 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
 
4
4
  require 'rspec'
5
5
  require 'json'
6
+ require 'td/helpers'
6
7
 
7
8
  if ENV['SIMPLE_COV']
8
9
  # SimpleCov
@@ -15,8 +16,8 @@ if ENV['SIMPLE_COV']
15
16
  end
16
17
  end
17
18
 
18
- # XXX skip coverage setting if run appveyor. Because, fail to push coveralls in appveyor.
19
- unless ENV['APPVEYOR']
19
+ # Skip Coveralls on Windows because the legacy client's TLS 1.0 uploads fail.
20
+ unless ENV['APPVEYOR'] || TreasureData::Helpers.on_windows?
20
21
  require 'coveralls'
21
22
  Coveralls.wear!('rails')
22
23
  end
@@ -93,6 +93,28 @@ module TreasureData::Command
93
93
  FileUtils.rm_rf tmpdir
94
94
  }
95
95
 
96
+ describe '#detect_system_java' do
97
+ {
98
+ '1.8.0_472' => true,
99
+ '11.0.2' => true,
100
+ '17.0.17+10-LTS' => true,
101
+ '21' => true,
102
+ '25-ea' => true,
103
+ '1.7.0_80' => false,
104
+ '8' => false,
105
+ 'invalid' => false,
106
+ }.each do |version, supported|
107
+ it "#{supported ? 'accepts' : 'rejects'} Java #{version} for system workflow execution" do
108
+ status = double(:success? => true)
109
+ allow(Open3).to receive(:capture2e).with('java', '-version').and_return(
110
+ ["openjdk version \"#{version}\"", status])
111
+ with_env('TD_WF_JAVA', '') do
112
+ expect(command.send(:detect_system_java)).to eq(supported)
113
+ end
114
+ end
115
+ end
116
+ end
117
+
96
118
  describe '#workflow' do
97
119
  let(:empty_option) {
98
120
  List::CommandParser.new("workflow", [], [], nil, [], true)
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+ require 'td/command/common'
3
+ require 'td/command/workflow'
4
+ require 'td/updater'
5
+ require 'tmpdir'
6
+
7
+ describe 'ZIP extraction' do
8
+ include_context 'quiet_out'
9
+
10
+ around do |example|
11
+ Dir.mktmpdir do |directory|
12
+ @directory = directory
13
+ example.run
14
+ end
15
+ end
16
+
17
+ let(:destination) { File.join(@directory, 'upload') }
18
+ let(:archive) { File.join(@directory, 'archive.zip') }
19
+
20
+ def write_archive(name)
21
+ Zip::OutputStream.open(archive) do |zip|
22
+ zip.put_next_entry(name)
23
+ zip.write('new content')
24
+ end
25
+ end
26
+
27
+ shared_examples 'confined extraction' do
28
+ it 'extracts nested files into the destination' do
29
+ write_archive("#{prefix}bin/java")
30
+ extract
31
+ expect(File.read(File.join(destination, 'bin/java'))).to eq('new content')
32
+ end
33
+
34
+ it 'rejects sibling paths sharing the destination prefix before modifying files' do
35
+ sibling = File.join(@directory, 'upload_backup')
36
+ FileUtils.mkdir_p(sibling)
37
+ victim = File.join(sibling, 'owned.sh')
38
+ File.write(victim, 'keep')
39
+ write_archive("#{prefix}../upload_backup/owned.sh")
40
+
41
+ expect { extract }.to raise_error(Zip::EntryNameError)
42
+ expect(File.read(victim)).to eq('keep')
43
+ end
44
+ end
45
+
46
+ context 'workflow Java installation' do
47
+ let(:prefix) { 'jdk/' }
48
+ let(:command) { Class.new { include TreasureData::Command }.new }
49
+
50
+ def extract
51
+ command.send(:extract_zip, archive, destination, 1)
52
+ end
53
+
54
+ include_examples 'confined extraction'
55
+ end
56
+
57
+ context 'toolbelt update' do
58
+ let(:prefix) { '' }
59
+ let(:updater) { Object.new.extend(TreasureData::Updater::ModuleDefinition) }
60
+
61
+ before do
62
+ FileUtils.mkdir_p(destination)
63
+ allow(Dir).to receive(:mktmpdir).and_yield(destination)
64
+ allow(updater).to receive(:updating_lock_path).and_return(File.join(@directory, 'lock'))
65
+ allow(updater).to receive(:updated_client_path).and_return(File.join(@directory, 'updated'))
66
+ allow(updater).to receive(:latest_local_version).and_return('0.0.0')
67
+ allow(updater).to receive(:fetch).and_return('1.0.0')
68
+ allow(updater).to receive(:client_version_from_path).and_return('1.0.0')
69
+ allow(updater).to receive(:package_category).and_return('exe')
70
+ allow(updater).to receive(:stream_fetch) do |url, file|
71
+ IO.copy_stream(archive, file)
72
+ end
73
+ end
74
+
75
+ def extract
76
+ updater.update
77
+ end
78
+
79
+ include_examples 'confined extraction'
80
+ end
81
+ end
data/td.gemspec CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |gem|
14
14
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
15
  gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
16
16
  gem.require_paths = ['lib']
17
- gem.required_ruby_version = '>= 2.1'
17
+ gem.required_ruby_version = '>= 3.0'
18
18
  gem.licenses = ["Apache-2.0"]
19
19
 
20
20
  gem.add_dependency "msgpack"
@@ -24,13 +24,12 @@ Gem::Specification.new do |gem|
24
24
  gem.add_dependency "parallel", "~> 1.20.0"
25
25
  gem.add_dependency "td-client", ">= 1.0.8", "< 4"
26
26
  gem.add_dependency "td-logger", ">= 0.3.21", "< 2"
27
- gem.add_dependency "rubyzip", "~> 1.3.0"
28
- gem.add_dependency "zip-zip", "~> 0.3"
27
+ gem.add_dependency "rubyzip", "~> 3.4"
29
28
  gem.add_dependency "ruby-progressbar", "~> 1.7"
30
29
  gem.add_dependency "csv"
31
30
  gem.add_development_dependency "rake"
32
31
  gem.add_development_dependency "rspec"
33
32
  gem.add_development_dependency 'webrick'
34
33
  gem.add_development_dependency "simplecov"
35
- gem.add_development_dependency 'coveralls'
34
+ gem.add_development_dependency 'coveralls' unless Gem.win_platform?
36
35
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: td
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.1
4
+ version: 0.20.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Treasure Data, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-08-28 00:00:00.000000000 Z
11
+ date: 2026-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -132,28 +132,14 @@ dependencies:
132
132
  requirements:
133
133
  - - "~>"
134
134
  - !ruby/object:Gem::Version
135
- version: 1.3.0
135
+ version: '3.4'
136
136
  type: :runtime
137
137
  prerelease: false
138
138
  version_requirements: !ruby/object:Gem::Requirement
139
139
  requirements:
140
140
  - - "~>"
141
141
  - !ruby/object:Gem::Version
142
- version: 1.3.0
143
- - !ruby/object:Gem::Dependency
144
- name: zip-zip
145
- requirement: !ruby/object:Gem::Requirement
146
- requirements:
147
- - - "~>"
148
- - !ruby/object:Gem::Version
149
- version: '0.3'
150
- type: :runtime
151
- prerelease: false
152
- version_requirements: !ruby/object:Gem::Requirement
153
- requirements:
154
- - - "~>"
155
- - !ruby/object:Gem::Version
156
- version: '0.3'
142
+ version: '3.4'
157
143
  - !ruby/object:Gem::Dependency
158
144
  name: ruby-progressbar
159
145
  requirement: !ruby/object:Gem::Requirement
@@ -344,6 +330,7 @@ files:
344
330
  - spec/td/helpers_spec.rb
345
331
  - spec/td/updater_spec.rb
346
332
  - spec/td/version_spec.rb
333
+ - spec/td/zip_extraction_spec.rb
347
334
  - td.gemspec
348
335
  homepage: http://treasure-data.com/
349
336
  licenses:
@@ -357,7 +344,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
357
344
  requirements:
358
345
  - - ">="
359
346
  - !ruby/object:Gem::Version
360
- version: '2.1'
347
+ version: '3.0'
361
348
  required_rubygems_version: !ruby/object:Gem::Requirement
362
349
  requirements:
363
350
  - - ">="
@@ -401,3 +388,4 @@ test_files:
401
388
  - spec/td/helpers_spec.rb
402
389
  - spec/td/updater_spec.rb
403
390
  - spec/td/version_spec.rb
391
+ - spec/td/zip_extraction_spec.rb