hadupils 0.3.0 → 0.4.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.
data/CHANGELOG.md CHANGED
@@ -38,3 +38,9 @@
38
38
  when a streaming query runs.
39
39
  * Some misc. utility functions in Hadupils::Util for reading tarballs.
40
40
 
41
+ ### 0.4.0
42
+
43
+ * Introduced Hadupils::Extensions::Hive.build_archive
44
+ Helper method for assembling gzipped archives the contents of which
45
+ are hive-ext compatible.
46
+
@@ -162,6 +162,71 @@ module Hadupils::Extensions
162
162
  def self.assemble_static_extension(path)
163
163
  Static.new(path)
164
164
  end
165
+
166
+ # Writes a gzipped tar archive to +io+, the contents of which
167
+ # are structured appropriately for use with this class.
168
+ #
169
+ # Provide the static hiverc and any other distributed cache-bound
170
+ # assets in +dist_assets+, and any auxiliary jars to include in
171
+ # +aux_jars+.
172
+ #
173
+ # This utilizes a system call to +tar+ under the hood, which requires
174
+ # that it be installed and on your +PATH+.
175
+ #
176
+ # You can use any file-like writable thing for +io+, so files,
177
+ # pipes, etc.
178
+ #
179
+ # See this example:
180
+ #
181
+ # File.open('foo.tar.gz', 'w') do |f|
182
+ # Hadupils::Extensions::Hive.build_archive f,
183
+ # ['/tmp/here/blah.jar',
184
+ # '/tmp/there/hiverc'],
185
+ # ['/tmp/elsewhere/foo.jar']
186
+ # end
187
+ #
188
+ # The following example would produce an archive named "foo.tar.gz",
189
+ # the contents of which would be:
190
+ #
191
+ # aux-jars/foo.jar
192
+ # blah.jar
193
+ # hiverc
194
+ #
195
+ # Note that it collapses things into two distinct directories, such
196
+ # that basename collisions are possible. That's on you to handle
197
+ # sanely.
198
+ def self.build_archive(io, dist_assets, aux_jars=nil)
199
+ dist, aux = [dist_assets, (aux_jars || [])].collect do |files|
200
+ files.collect do |asset|
201
+ path = ::File.expand_path(asset)
202
+ raise "Cannot include directory '#{path}'." if ::File.directory? path
203
+ path
204
+ end
205
+ end
206
+
207
+ require 'tempfile'
208
+ require 'fileutils'
209
+ ::Dir.mktmpdir do |workdir|
210
+ basenames = dist.collect do |src|
211
+ FileUtils.cp src, File.join(workdir, File.basename(src))
212
+ File.basename src
213
+ end
214
+
215
+ if aux.length > 0
216
+ basenames << AUX_PATH
217
+ aux_dir = File.join(workdir, AUX_PATH)
218
+ Dir.mkdir aux_dir
219
+ aux.each do |src|
220
+ FileUtils.cp src, File.join(aux_dir, File.basename(src))
221
+ end
222
+ end
223
+
224
+ ::Dir.chdir(workdir) do |p|
225
+ Kernel.system 'tar', 'cz', *basenames, :out => io
226
+ end
227
+ end
228
+ true
229
+ end
165
230
  end
166
231
 
167
232
  # Collection class for filesystem-based Hive extensions
@@ -106,6 +106,51 @@ class Hadupils::Extensions::HiveTest < Test::Unit::TestCase
106
106
  end
107
107
  end
108
108
 
109
+ shared_context :assembles_compressed_archive do
110
+ setup do
111
+ @unpack_dir = @tempdir.full_path('unpack')
112
+ Dir.mkdir @unpack_dir
113
+
114
+ @pipe_read, @pipe_write = IO.pipe
115
+ Dir.chdir @unpack_dir do |p|
116
+ @tar_pid = Kernel.spawn 'tar', 'xz', :in => @pipe_read
117
+ end
118
+ end
119
+
120
+ should 'assemble a hive-ext-compatible compressed archive' do
121
+ @pipe_write.close
122
+ Process.wait @tar_pid
123
+ dist, aux = [[@unpack_dir, ['aux-jars']],
124
+ [File.join(@unpack_dir, 'aux-jars'), []]].collect do |dir, excl|
125
+ excl += ['.', '..']
126
+ begin
127
+ Dir.entries(dir).inject({}) do |a, entry|
128
+ if not excl.include?(entry)
129
+ a[entry] = File.open(File.join(dir, entry), 'r') {|f| f.read}
130
+ end
131
+ a
132
+ end
133
+ rescue Exception => e
134
+ {}
135
+ end
136
+ end
137
+
138
+ dist_exp = {
139
+ File.basename(@dist_jar_a) => @dist_jar_a_content,
140
+ File.basename(@dist_jar_b) => @dist_jar_b_content,
141
+ File.basename(@hiverc) => @hiverc_content,
142
+ }
143
+
144
+ aux_exp = {
145
+ File.basename(@aux_jar_a) => @aux_jar_a_content,
146
+ File.basename(@aux_jar_b) => @aux_jar_b_content,
147
+ }
148
+
149
+ assert_equal dist_exp, dist
150
+ assert_equal aux_exp, aux
151
+ end
152
+ end
153
+
109
154
  tempdir_context Hadupils::Extensions::Hive do
110
155
  context 'with auxiliary jars' do
111
156
  provide_hive_ext
@@ -188,6 +233,92 @@ class Hadupils::Extensions::HiveTest < Test::Unit::TestCase
188
233
  end
189
234
  end
190
235
  end
236
+
237
+ context 'build_archive singleton method' do
238
+ require 'stringio'
239
+
240
+ setup do
241
+ ::Dir.mkdir(@some_dir = @tempdir.full_path('some_stuff'))
242
+ ::Dir.mkdir(@other_dir = @tempdir.full_path('other_stuff'))
243
+ @dist_jar_a = ::File.open(::File.join(@some_dir, 'a.jar'), 'w') do |f|
244
+ f.write(@dist_jar_a_content = 'dist jar a')
245
+ f.path
246
+ end
247
+
248
+ @aux_jar_a = ::File.open(::File.join(@some_dir, 'auxa.jar'), 'w') do |f|
249
+ f.write(@aux_jar_a_content = 'aux jar a')
250
+ f.path
251
+ end
252
+
253
+ @hiverc = @tempdir.file('hiverc') {|f| f.write(@hiverc_content = 'hiverc stuff'); f.path}
254
+
255
+ @dist_jar_b = ::File.open(::File.join(@other_dir, 'b.jar'), 'w') do |f|
256
+ f.write(@dist_jar_b_content = 'dist jar b')
257
+ f.path
258
+ end
259
+
260
+ @aux_jar_b = ::File.open(::File.join(@other_dir, 'auxb.jar'), 'w') do |f|
261
+ f.write(@aux_jar_b_content = 'aux jar b')
262
+ f.path
263
+ end
264
+
265
+ @mod = Hadupils::Extensions::Hive
266
+ end
267
+
268
+ should 'barf on a dist directory' do
269
+ # assert_raise ain't doing this for me...
270
+ e = nil
271
+ begin
272
+ @mod.build_archive StringIO.new(''), [@tempdir.path]
273
+ rescue Exception => e
274
+ end
275
+
276
+ assert_instance_of RuntimeError, e
277
+ assert_equal "Cannot include directory '#{@tempdir.path}'.", e.message
278
+ end
279
+
280
+ should 'barf on an aux directory' do
281
+ # assert_raise ain't doing this for me...
282
+ e = nil
283
+ begin
284
+ @mod.build_archive StringIO.new(''), [], [@tempdir.path]
285
+ rescue Exception => e
286
+ end
287
+
288
+ assert_instance_of RuntimeError, e
289
+ assert_equal "Cannot include directory '#{@tempdir.path}'.", e.message
290
+ end
291
+
292
+ context 'given absolute paths' do
293
+ assembles_compressed_archive
294
+
295
+ setup do
296
+ @mod.build_archive @pipe_write,
297
+ [@dist_jar_a, @dist_jar_b, @hiverc],
298
+ [@aux_jar_a, @aux_jar_b]
299
+ end
300
+ end
301
+
302
+ context 'given relative paths' do
303
+ assembles_compressed_archive
304
+
305
+ setup do
306
+ chars = @tempdir.path.length + 1 # +1 for trailing slash
307
+
308
+ dist = [@dist_jar_a, @dist_jar_b, @hiverc].collect do |path|
309
+ path[chars..-1]
310
+ end
311
+
312
+ aux = [@aux_jar_a, @aux_jar_b].collect do |path|
313
+ path[chars..-1]
314
+ end
315
+
316
+ Dir.chdir(@tempdir.path) do |p|
317
+ @mod.build_archive @pipe_write, dist, aux
318
+ end
319
+ end
320
+ end
321
+ end
191
322
  end
192
323
 
193
324
  tempdir_context Hadupils::Extensions::HiveSet do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hadupils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: