realityforge-buildr 1.5.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/LICENSE +176 -0
  4. data/NOTICE +26 -0
  5. data/README.md +3 -0
  6. data/Rakefile +50 -0
  7. data/addon/buildr/checkstyle-report.xsl +104 -0
  8. data/addon/buildr/checkstyle.rb +254 -0
  9. data/addon/buildr/git_auto_version.rb +36 -0
  10. data/addon/buildr/gpg.rb +90 -0
  11. data/addon/buildr/gwt.rb +413 -0
  12. data/addon/buildr/jacoco.rb +161 -0
  13. data/addon/buildr/pmd.rb +185 -0
  14. data/addon/buildr/single_intermediate_layout.rb +71 -0
  15. data/addon/buildr/spotbugs.rb +265 -0
  16. data/addon/buildr/top_level_generate_dir.rb +37 -0
  17. data/addon/buildr/wsgen.rb +192 -0
  18. data/bin/buildr +20 -0
  19. data/buildr.gemspec +61 -0
  20. data/lib/buildr.rb +86 -0
  21. data/lib/buildr/core/application.rb +705 -0
  22. data/lib/buildr/core/assets.rb +96 -0
  23. data/lib/buildr/core/build.rb +587 -0
  24. data/lib/buildr/core/common.rb +167 -0
  25. data/lib/buildr/core/compile.rb +599 -0
  26. data/lib/buildr/core/console.rb +124 -0
  27. data/lib/buildr/core/doc.rb +275 -0
  28. data/lib/buildr/core/environment.rb +128 -0
  29. data/lib/buildr/core/filter.rb +405 -0
  30. data/lib/buildr/core/help.rb +114 -0
  31. data/lib/buildr/core/progressbar.rb +161 -0
  32. data/lib/buildr/core/project.rb +994 -0
  33. data/lib/buildr/core/test.rb +776 -0
  34. data/lib/buildr/core/transports.rb +456 -0
  35. data/lib/buildr/core/util.rb +77 -0
  36. data/lib/buildr/ide/idea.rb +1664 -0
  37. data/lib/buildr/java/commands.rb +230 -0
  38. data/lib/buildr/java/compiler.rb +85 -0
  39. data/lib/buildr/java/custom_pom.rb +300 -0
  40. data/lib/buildr/java/doc.rb +62 -0
  41. data/lib/buildr/java/packaging.rb +393 -0
  42. data/lib/buildr/java/pom.rb +191 -0
  43. data/lib/buildr/java/test_result.rb +54 -0
  44. data/lib/buildr/java/tests.rb +111 -0
  45. data/lib/buildr/packaging/archive.rb +586 -0
  46. data/lib/buildr/packaging/artifact.rb +1113 -0
  47. data/lib/buildr/packaging/artifact_namespace.rb +1010 -0
  48. data/lib/buildr/packaging/artifact_search.rb +138 -0
  49. data/lib/buildr/packaging/package.rb +237 -0
  50. data/lib/buildr/packaging/version_requirement.rb +189 -0
  51. data/lib/buildr/packaging/zip.rb +189 -0
  52. data/lib/buildr/packaging/ziptask.rb +387 -0
  53. data/lib/buildr/version.rb +18 -0
  54. data/rakelib/release.rake +99 -0
  55. data/spec/addon/checkstyle_spec.rb +58 -0
  56. data/spec/core/application_spec.rb +576 -0
  57. data/spec/core/build_spec.rb +922 -0
  58. data/spec/core/common_spec.rb +670 -0
  59. data/spec/core/compile_spec.rb +656 -0
  60. data/spec/core/console_spec.rb +65 -0
  61. data/spec/core/doc_spec.rb +194 -0
  62. data/spec/core/extension_spec.rb +200 -0
  63. data/spec/core/project_spec.rb +736 -0
  64. data/spec/core/test_spec.rb +1131 -0
  65. data/spec/core/transport_spec.rb +452 -0
  66. data/spec/core/util_spec.rb +154 -0
  67. data/spec/ide/idea_spec.rb +1952 -0
  68. data/spec/java/commands_spec.rb +79 -0
  69. data/spec/java/compiler_spec.rb +274 -0
  70. data/spec/java/custom_pom_spec.rb +165 -0
  71. data/spec/java/doc_spec.rb +55 -0
  72. data/spec/java/packaging_spec.rb +786 -0
  73. data/spec/java/pom_spec.rb +162 -0
  74. data/spec/java/test_coverage_helper.rb +257 -0
  75. data/spec/java/tests_spec.rb +224 -0
  76. data/spec/packaging/archive_spec.rb +686 -0
  77. data/spec/packaging/artifact_namespace_spec.rb +757 -0
  78. data/spec/packaging/artifact_spec.rb +1351 -0
  79. data/spec/packaging/packaging_helper.rb +63 -0
  80. data/spec/packaging/packaging_spec.rb +690 -0
  81. data/spec/sandbox.rb +166 -0
  82. data/spec/spec_helpers.rb +420 -0
  83. data/spec/version_requirement_spec.rb +145 -0
  84. data/spec/xpath_matchers.rb +123 -0
  85. metadata +295 -0
@@ -0,0 +1,686 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+
17
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helpers'))
18
+
19
+
20
+ module ArchiveTaskHelpers
21
+ # Not too smart, we just create some content based on file name to make sure you read what you write.
22
+ def content_for(file)
23
+ "Content for #{File.basename(file)}"
24
+ end
25
+
26
+ # Qualify a filename
27
+ #
28
+ # e.g. qualify("file.zip", "src") => "file-src.zip"
29
+ def qualify(filename, qualifier)
30
+ ext = (filename =~ /\.$/) ? "." : File.extname(filename)
31
+ base = filename[0..0-ext.size-1]
32
+ base + "-" + qualifier + ext
33
+ end
34
+
35
+ # Create an archive not using the archive task, this way we do have a file in existence, but we don't
36
+ # have an already invoked task. Yield an archive task to the block which can use it to include files,
37
+ # set options, etc.
38
+ def create_without_task
39
+ archive(qualify(@archive, "tmp")).tap do |task|
40
+ yield task if block_given?
41
+ task.invoke
42
+ mv task.name, @archive
43
+ end
44
+ end
45
+
46
+ def create_for_merge
47
+ zip(qualify(@archive, "src")).include(@files).tap do |task|
48
+ yield task
49
+ end
50
+ end
51
+
52
+ def init_dir
53
+ unless @dir
54
+ @dir = File.expand_path('test')
55
+ @files = %w{Test1.txt Text2.html}.map { |file| File.expand_path(file, @dir) }.
56
+ each { |file| write file, content_for(file) }
57
+ @empty_dirs = %w{EmptyDir1 EmptyDir2}.map { |file| File.expand_path(file, @dir) }.
58
+ each { |file| mkdir file }
59
+ end
60
+ end
61
+ end
62
+
63
+ RSpec.shared_examples 'ArchiveTask' do
64
+ include ArchiveTaskHelpers
65
+
66
+ before(:each) do
67
+ init_dir
68
+ end
69
+
70
+ it 'should point to archive file' do
71
+ archive(@archive).name.should eql(@archive)
72
+ end
73
+
74
+ it 'should create file' do
75
+ lambda { archive(@archive).invoke }.should change { File.exist?(@archive) }.to(true)
76
+ end
77
+
78
+ it 'should create empty archive if no files included' do
79
+ archive(@archive).invoke
80
+ inspect_archive { |archive| archive.should be_empty }
81
+ end
82
+
83
+ it 'should raise error when include() is called with nil values' do
84
+ lambda { archive(@archive).include(nil) }.should raise_error
85
+ lambda { archive(@archive).include([nil]) }.should raise_error
86
+ end
87
+
88
+ it 'should create empty archive if called #clean method' do
89
+ archive(@archive).include(@files).clean.invoke
90
+ inspect_archive { |archive| archive.should be_empty }
91
+ end
92
+
93
+ it 'should archive all included files' do
94
+ archive(@archive).include(@files).invoke
95
+ inspect_archive { |archive| @files.each { |f| archive[File.basename(f)].should eql(content_for(f)) } }
96
+ inspect_archive.size.should eql(@files.size)
97
+ end
98
+
99
+ it 'should archive file tasks' do
100
+ tasks = @files.map { |fn| file(fn) }
101
+ archive(@archive).include(tasks).invoke
102
+ inspect_archive { |archive| @files.each { |f| archive[File.basename(f)].should eql(content_for(f)) } }
103
+ inspect_archive.size.should eql(@files.size)
104
+ end
105
+
106
+ it 'should invoke and archive file tasks' do
107
+ file = file('included') { write 'included' }
108
+ lambda { archive(@archive).include(file).invoke }.should change { File.exist?(file.to_s) }.to(true)
109
+ inspect_archive.keys.should include('included')
110
+ end
111
+
112
+ it 'should archive artifacts' do
113
+ write 'library-1.0.txt', 'library-1.0'
114
+ artifact("org.example:library:txt:1.0").from 'library-1.0.txt'
115
+ archive(@archive).include("org.example:library:txt:1.0").invoke
116
+ inspect_archive.keys.should include('library-1.0.txt')
117
+ end
118
+
119
+ it 'should archive project artifacts' do
120
+ define 'p1' do
121
+ project.version = '1.0'
122
+ package(:zip)
123
+ end
124
+ archive(@archive).include(project('p1')).invoke
125
+ inspect_archive.keys.should include('p1-1.0.zip')
126
+ end
127
+
128
+ it 'should include entry for directory' do
129
+ archive(@archive).include(@dir).invoke
130
+ inspect_archive { |archive| @files.each { |f| archive['test/' + File.basename(f)].should eql(content_for(f)) } }
131
+ end
132
+
133
+ it 'should not archive any excluded files' do
134
+ archive(@archive).include(@files).exclude(@files.last).invoke
135
+ inspect_archive do |archive|
136
+ archive.keys.should include(File.basename(@files.first))
137
+ archive.keys.should_not include(File.basename(@files.last))
138
+ end
139
+ end
140
+
141
+ it 'should not archive any excluded files in included directories' do
142
+ archive(@archive).include(@dir).exclude(@files.last).invoke
143
+ inspect_archive do |archive|
144
+ archive.keys.should include('test/' + File.basename(@files.first))
145
+ archive.keys.should_not include('test/' + File.basename(@files.last))
146
+ end
147
+ end
148
+
149
+ it 'should not archive any excluded files when using :from/:as' do
150
+ archive(@archive).include(:from=>@dir).exclude(@files.last).invoke
151
+ inspect_archive do |archive|
152
+ archive.keys.should include(File.basename(@files.first))
153
+ archive.keys.should_not include(File.basename(@files.last))
154
+ end
155
+ end
156
+
157
+ it 'should raise error when using :from with nil value' do
158
+ lambda {
159
+ archive(@archive).include(:from=>nil)
160
+ }.should raise_error
161
+ end
162
+
163
+ it 'should exclude entire directory and all its children' do
164
+ mkpath "#{@dir}/sub"
165
+ write "#{@dir}/sub/test"
166
+ archive(@archive).include(@dir).exclude("#{@dir}/sub").invoke
167
+ inspect_archive do |archive|
168
+ archive.keys.select { |file| file =~ /sub/ }.should be_empty
169
+ end
170
+ end
171
+
172
+ it 'should not archive any excluded files when pattern is *.ext' do
173
+ write "test/file.txt"
174
+ write "test/file.swf"
175
+ archive(@archive).include(@dir).exclude('**/*.swf').invoke
176
+ inspect_archive do |archive|
177
+ archive.keys.should include('test/file.txt')
178
+ archive.keys.should_not include('test/file.swf')
179
+ end
180
+ end
181
+
182
+ it 'should archive files into specified path' do
183
+ archive(@archive).include(@files, :path=>'code').invoke
184
+ inspect_archive { |archive| @files.each { |f| archive['code/' + File.basename(f)].should eql(content_for(f)) } }
185
+ end
186
+
187
+ it 'should include entry for directory' do
188
+ archive(@archive).include(@dir).invoke
189
+ inspect_archive { |archive| @files.each { |f| archive['test/' + File.basename(f)].should eql(content_for(f)) } }
190
+ end
191
+
192
+ it 'should archive files into specified path' do
193
+ archive(@archive).include(@files, :path=>'code').invoke
194
+ inspect_archive { |archive| @files.each { |f| archive['code/' + File.basename(f)].should eql(content_for(f)) } }
195
+ end
196
+
197
+ it 'should archive directories into specified path' do
198
+ archive(@archive).include(@dir, :path=>'code').invoke
199
+ inspect_archive { |archive| @files.each { |f| archive['code/test/' + File.basename(f)].should eql(content_for(f)) } }
200
+ end
201
+
202
+ it 'should understand . in path' do
203
+ archive(@archive).path('.').should == archive(@archive).path('')
204
+ archive(@archive).path('foo').path('.').should == archive(@archive).path('foo')
205
+ end
206
+
207
+ it 'should understand .. in path' do
208
+ archive(@archive).path('..').should == archive(@archive).path('')
209
+ archive(@archive).path('foo').path('..').should == archive(@archive).path('')
210
+ archive(@archive).path('foo/bar').path('..').should == archive(@archive).path('foo')
211
+ end
212
+
213
+ it 'should understand leading / in path' do
214
+ archive(@archive).path('/').should == archive(@archive).path('')
215
+ archive(@archive).path('foo/bar').path('/').should == archive(@archive).path('')
216
+ end
217
+
218
+ it 'should archive file into specified name' do
219
+ archive(@archive).include(@files.first, :as=>'test/sample').invoke
220
+ inspect_archive { |archive| @files.each { |f| archive['test/sample'].should eql(content_for(@files.first)) } }
221
+ end
222
+
223
+ it 'should archive directory into specified alias, without using "."' do
224
+ archive(@archive).include(@dir, :as=>'.').invoke
225
+ inspect_archive { |archive| archive.keys.should_not include(".") }
226
+ end
227
+
228
+ it 'should archive directories into specified alias, even if it has the same name' do
229
+ archive(@archive).include(@dir, :as=>File.basename(@dir)).invoke
230
+ inspect_archive { |archive|
231
+ archive.keys.should_not include "#{File.basename(@dir)}"
232
+ }
233
+ end
234
+
235
+ it 'should archive file into specified name/path' do
236
+ archive(@archive).include(@files.first, :as=>'test/sample', :path=>'path').invoke
237
+ inspect_archive { |archive| @files.each { |f| archive['path/test/sample'].should eql(content_for(@files.first)) } }
238
+ end
239
+
240
+ it 'should archive files starting with dot' do
241
+ write 'test/.config', '# configuration'
242
+ archive(@archive).include('test').invoke
243
+ inspect_archive { |archive| @files.each { |f| archive['test/.config'].should eql('# configuration') } }
244
+ end
245
+
246
+ it 'should archive directory into specified name' do
247
+ archive(@archive).include(@dir, :as=>'code').invoke
248
+ inspect_archive { |archive| @files.each { |f| archive['code/' + File.basename(f)].should eql(content_for(f)) } }
249
+ end
250
+
251
+ it 'should archive directory into specified name/path' do
252
+ archive(@archive).include(@dir, :as=>'code', :path=>'path').invoke
253
+ inspect_archive { |archive| @files.each { |f| archive['path/code/' + File.basename(f)].should eql(content_for(f)) } }
254
+ end
255
+
256
+ it 'should archive directory contents' do
257
+ archive(@archive).include(@dir, :as=>'.').invoke
258
+ inspect_archive { |archive| @files.each { |f| archive[File.basename(f)].should eql(content_for(f)) } }
259
+ end
260
+
261
+ it 'should archive directory contents into specified path' do
262
+ archive(@archive).include(@dir, :as=>'.', :path=>'path').invoke
263
+ inspect_archive { |archive| @files.each { |f| archive['path/' + File.basename(f)].should eql(content_for(f)) } }
264
+ end
265
+
266
+ it 'should not allow two files with the :as argument' do
267
+ lambda { archive(@archive).include(@files.first, @files.last, :as=>'test/sample') }.should raise_error(RuntimeError, /one file/)
268
+ end
269
+
270
+ it 'should expand another archive file' do
271
+ create_for_merge do |src|
272
+ archive(@archive).merge(src)
273
+ archive(@archive).invoke
274
+ inspect_archive { |archive| @files.each { |f| archive[File.basename(f)].should eql(content_for(f)) } }
275
+ end
276
+ end
277
+
278
+ it 'should expand another archive file with include pattern' do
279
+ create_for_merge do |src|
280
+ archive(@archive).merge(src).include(File.basename(@files.first))
281
+ archive(@archive).invoke
282
+ inspect_archive do |archive|
283
+ archive[File.basename(@files.first)].should eql(content_for(@files.first))
284
+ archive[File.basename(@files.last)].should be_nil
285
+ end
286
+ end
287
+ end
288
+
289
+ it 'should expand another archive file with exclude pattern' do
290
+ create_for_merge do |src|
291
+ archive(@archive).merge(src).exclude(File.basename(@files.first))
292
+ archive(@archive).invoke
293
+ inspect_archive do |archive|
294
+ @files[1..-1].each { |f| archive[File.basename(f)].should eql(content_for(f)) }
295
+ archive[File.basename(@files.first)].should be_nil
296
+ end
297
+ end
298
+ end
299
+
300
+ it 'should expand another archive file with nested exclude pattern' do
301
+ @files = %w{Test1.txt Text2.html}.map { |file| File.join(@dir, "foo", file) }.
302
+ each { |file| write file, content_for(file) }
303
+ zip(qualify(@archive, "src")).include(@dir).tap do |task|
304
+ archive(@archive).merge(task).exclude('test/*')
305
+ archive(@archive).invoke
306
+ inspect_archive.should be_empty
307
+ end
308
+ end
309
+
310
+ it 'should merge archives, concatenate file contents' do
311
+ @files = %w{foo1 foo2}.map { |folder| File.join(@dir, folder) }.
312
+ map do |dir|
313
+ txt_file = File.join(dir, 'test1.txt')
314
+ write txt_file, content_for('test1.txt')
315
+ zip(File.join(dir, 'test1.zip')).include(txt_file)
316
+ end
317
+ archive(@archive).merge(@files).concatenate("test1.txt")
318
+ archive(@archive).invoke
319
+ inspect_archive do |archive|
320
+ archive['test1.txt'].should eql(content_for('test1.txt') * @files.size)
321
+ end
322
+ end
323
+
324
+ it 'should merge archives, transforming file contents' do
325
+ @files = %w{foo1 foo2}.map { |folder| File.join(@dir, folder) }.
326
+ map do |dir|
327
+ txt_file = File.join(dir, 'test1.txt')
328
+ write txt_file, content_for('test1.txt')
329
+ zip(File.join(dir, 'test1.zip')).include(txt_file)
330
+ end
331
+ archive(@archive).merge(@files).transform("test1.txt") do |matches|
332
+ matches.join("\n=====\n")
333
+ end
334
+ archive(@archive).invoke
335
+ inspect_archive do |archive|
336
+ archive['test1.txt'].should eql("#{content_for('test1.txt')}\n=====\n#{content_for('test1.txt')}")
337
+ end
338
+ end
339
+
340
+ it 'should expand another archive file into path' do
341
+ create_for_merge do |src|
342
+ archive(@archive).path('test').merge(src)
343
+ archive(@archive).invoke
344
+ inspect_archive { |archive| @files.each { |f| archive['test/' + File.basename(f)].should eql(content_for(f)) } }
345
+ end
346
+ end
347
+
348
+ it 'should expand another archive file into path with :path option' do
349
+ create_for_merge do |src|
350
+ archive(@archive).merge(src, :path=>'test')
351
+ archive(@archive).invoke
352
+ inspect_archive { |archive| @files.each { |f| archive['test/' + File.basename(f)].should eql(content_for(f)) } }
353
+ end
354
+ end
355
+
356
+ it "should expand another archive file into path with :path=>'/'" do
357
+ create_for_merge do |src|
358
+ archive(@archive).merge(src, :path=>'/')
359
+ archive(@archive).invoke
360
+ inspect_archive { |archive| @files.each { |f| archive[File.basename(f)].should eql(content_for(f)) } }
361
+ end
362
+ end
363
+
364
+ it 'should expand another archive file into path with merge option' do
365
+ create_for_merge do |src|
366
+ archive(@archive).include(src, :merge=>true)
367
+ archive(@archive).invoke
368
+ inspect_archive { |archive| @files.each { |f| archive[File.basename(f)].should eql(content_for(f)) } }
369
+ end
370
+ end
371
+
372
+ it 'should update if one of the files is recent' do
373
+ create_without_task { |archive| archive.include(@files) }
374
+ # Touch archive file to some point in the past. This effectively makes
375
+ # all included files newer.
376
+ File.utime Time.now - 100, Time.now - 100, @archive
377
+ archive(@archive).include(@files).invoke
378
+ File.stat(@archive).mtime.should be_within(10).of(Time.now)
379
+ end
380
+
381
+ it 'should update if a file in a subdir is more recent' do
382
+ subdir = File.expand_path("subdir", @dir)
383
+ test3 = File.expand_path("test3.css", subdir)
384
+
385
+ mkdir_p subdir
386
+ write test3, '/* Original */'
387
+
388
+ create_without_task { |archive| archive.include(:from => @dir) }
389
+ inspect_archive { |archive| archive["subdir/test3.css"].should eql('/* Original */') }
390
+
391
+ write test3, '/* Refreshed */'
392
+ File.utime(Time.now + 100, Time.now + 100, test3)
393
+ archive(@archive).include(:from => @dir).invoke
394
+ inspect_archive { |archive| archive["subdir/test3.css"].should eql('/* Refreshed */') }
395
+ end
396
+
397
+ it 'should do nothing if all files are uptodate' do
398
+ create_without_task { |archive| archive.include(@files) }
399
+ # By touching all files in the past, there's nothing new to update.
400
+ (@files + [@archive]).each { |f| File.utime Time.now - 100, Time.now - 100, f }
401
+ archive(@archive).include(@files).invoke
402
+ File.stat(@archive).mtime.should be_within(10).of(Time.now - 100)
403
+ end
404
+
405
+ it 'should update if one of the files is recent' do
406
+ create_without_task { |archive| archive.include(@files) }
407
+ # Change files, we expect to see new content.
408
+ write @files.first, '/* Refreshed */'
409
+ File.utime(Time.now - 100, Time.now - 100, @archive) # Touch archive file to some point in the past.
410
+ archive(@archive).include(@files).invoke
411
+ inspect_archive { |archive| archive[File.basename(@files.first)].should eql('/* Refreshed */') }
412
+ end
413
+
414
+ it 'should create new archive when updating' do
415
+ create_without_task { |archive| archive.include(@files) }
416
+ File.utime(Time.now - 100, Time.now - 100, @archive) # Touch archive file to some point in the past.
417
+ archive(@archive).include(@files[1..-1]).invoke
418
+ inspect_archive.size.should be(@files.size - 1)
419
+ end
420
+
421
+ it 'should not accept invalid options' do
422
+ archive(@archive).include(@files)
423
+ lambda { archive(@archive).with :option=>true }.should raise_error
424
+ end
425
+
426
+ it 'should invoke paths supplied in from parameters' do
427
+ included_file = File.expand_path("somefile.myext")
428
+ write included_file, content_for(included_file)
429
+ archive2_filename = File.expand_path("somebug.zip")
430
+ a2 = zip(archive2_filename).
431
+ include(included_file, :as => 'folder1/somefile1.ext').
432
+ include(included_file, :as => 'folder2/somefile2.ext').
433
+ invoke
434
+ a = archive(@archive)
435
+ f1 = unzip('target/folder1' => archive2_filename).from_path("folder1/*").root
436
+ f2 = unzip('target/folder2' => archive2_filename).from_path("folder2/*").root
437
+ a.include(:from => f1)
438
+ a.include(:from => f2)
439
+ a.invoke
440
+ contents = inspect_archive
441
+ contents["folder1/somefile1.ext"].should_not be_nil
442
+ contents["folder2/somefile2.ext"].should_not be_nil
443
+ end
444
+ end
445
+
446
+ describe "ZipTask" do
447
+ include ArchiveTaskHelpers
448
+
449
+ it_should_behave_like 'ArchiveTask'
450
+
451
+ before(:each) do
452
+ init_dir
453
+ @archive = File.expand_path('test.zip')
454
+ end
455
+
456
+ define_method(:archive) { |file| zip(file) }
457
+
458
+ after(:each) do
459
+ check_zip(@archive)
460
+ end
461
+
462
+ # Check for possible corruption using Java's "jar" command since they are stricter than rubyzip
463
+ def check_zip(file)
464
+ return unless File.exist?(file)
465
+
466
+ sh "#{File.join(ENV['JAVA_HOME'], 'bin', 'jar')} tvf #{file}"
467
+ end
468
+
469
+ def inspect_archive
470
+ entries = {}
471
+ Zip::File.open @archive do |zip|
472
+ zip.entries.each do |entry|
473
+ if entry.directory?
474
+ # Ignore the / directory created for empty ZIPs when using java.util.zip.
475
+ if entry.name.to_s != '/'
476
+ entries[entry.name.to_s] = nil
477
+ end
478
+ else
479
+ entries[entry.name.to_s] = zip.read(entry.name)
480
+ end
481
+ end
482
+ end
483
+ yield entries if block_given?
484
+ entries
485
+ end
486
+
487
+ it 'should include empty dirs' do
488
+ archive(@archive).include(@dir)
489
+ archive(@archive).invoke
490
+ inspect_archive do |archive|
491
+ archive.keys.should include('test/EmptyDir1/')
492
+ end
493
+ end
494
+
495
+ it 'should include empty dirs from Dir' do
496
+ archive(@archive).include(Dir["#{@dir}/*"])
497
+ archive(@archive).invoke
498
+ inspect_archive do |archive|
499
+ archive.keys.should include('EmptyDir1/')
500
+ end
501
+ end
502
+
503
+ it 'should work with path object' do
504
+ archive(@archive).path('code').include(@files)
505
+ archive(@archive).invoke
506
+ inspect_archive { |archive| archive.keys.should include('code/') }
507
+ end
508
+
509
+ it 'should have path object that includes empty dirs' do
510
+ archive(@archive).path('code').include(Dir["#{@dir}/*"])
511
+ archive(@archive).invoke
512
+ inspect_archive do |archive|
513
+ archive.keys.should include('code/EmptyDir1/')
514
+ end
515
+ end
516
+
517
+ # chmod is not reliable on Windows
518
+ it 'should preserve file permissions' do
519
+ # with JRuby it's important to use absolute paths with File.chmod()
520
+ # http://jira.codehaus.org/browse/JRUBY-3300
521
+ hello = File.expand_path('src/main/bin/hello')
522
+ write hello, 'echo hi'
523
+ File.chmod(0777, hello)
524
+ fail("Failed to set permission on #{hello}") unless (File.stat(hello).mode & 0777) == 0777
525
+
526
+ zip('foo.zip').include('src/main/bin/*').invoke
527
+ unzip('target' => 'foo.zip').extract
528
+ (File.stat('target/hello').mode & 0777).should == 0777
529
+ end
530
+
531
+ it 'should preserve file permissions when merging zip files' do
532
+ # with JRuby it's important to use absolute paths with File.chmod()
533
+ # http://jira.codehaus.org/browse/JRUBY-3300
534
+ hello = File.expand_path('src/main/bin/hello')
535
+ write hello, 'echo hi'
536
+ File.chmod(0777, hello)
537
+ fail("Failed to set permission on #{hello}") unless (File.stat(hello).mode & 0777) == 0777
538
+
539
+ foo = zip('foo.zip')
540
+ foo.include('src/main/bin/*').invoke
541
+ bar = zip('bar.zip')
542
+ bar.merge(foo)
543
+ bar.invoke
544
+ unzip('target' => 'bar.zip').extract
545
+ (File.stat('target/hello').mode & 0777).should == 0777
546
+ end
547
+ end
548
+
549
+ describe Unzip do
550
+ before(:each) do
551
+ @zip = File.expand_path('test.zip')
552
+ @dir = File.expand_path('test')
553
+ @files = %w{Test1.txt Text2.html}.map { |file| File.join(@dir, file) }.
554
+ each { |file| write file, content_for(file) }
555
+ @target = File.expand_path('target')
556
+ end
557
+
558
+ # Not too smart, we just create some content based on file name to
559
+ # make sure you read what you write.
560
+ def content_for(file)
561
+ "Content for #{File.basename(file)}"
562
+ end
563
+
564
+ def with_zip(*args)
565
+ zip(@zip).include(*args.empty? ? @files : args).invoke
566
+ yield
567
+ end
568
+
569
+ it 'should touch target directory' do
570
+ with_zip do
571
+ mkdir @target
572
+ File.utime(Time.now - 10, Time.now - 10, @target)
573
+ unzip(@target=>@zip).target.invoke
574
+ end
575
+ File.stat(@target).mtime.should be_within(2).of(Time.now)
576
+ end
577
+
578
+ it 'should expand files' do
579
+ with_zip do
580
+ unzip(@target=>@zip).target.invoke
581
+ @files.each { |f| File.read(File.join(@target, File.basename(f))).should eql(content_for(f)) }
582
+ end
583
+ end
584
+
585
+ it 'should expand all files' do
586
+ with_zip do
587
+ unzip(@target=>@zip).target.invoke
588
+ FileList[File.join(@target, '*')].size.should be(@files.size)
589
+ end
590
+ end
591
+
592
+ it 'should expand only included files' do
593
+ with_zip do
594
+ only = File.basename(@files.first)
595
+ unzip(@target=>@zip).include(only).target.invoke
596
+ FileList[File.join(@target, '*')].should include(File.expand_path(only, @target))
597
+ FileList[File.join(@target, '*')].size.should be(1)
598
+ end
599
+ end
600
+
601
+ it 'should expand all but excluded files' do
602
+ with_zip do
603
+ except = File.basename(@files.first)
604
+ unzip(@target=>@zip).exclude(except).target.invoke
605
+ FileList[File.join(@target, '*')].should_not include(File.expand_path(except, @target))
606
+ FileList[File.join(@target, '*')].size.should be(@files.size - 1)
607
+ end
608
+ end
609
+
610
+ it 'should include with nested path patterns' do
611
+ with_zip @files, :path=>'test/path' do
612
+ only = File.basename(@files.first)
613
+ unzip(@target=>@zip).include(only).target.invoke
614
+ FileList[File.join(@target, '*')].should be_empty
615
+
616
+ Rake::Task.clear ; rm_rf @target
617
+ unzip(@target=>@zip).include('test/path/' + only).target.invoke
618
+ FileList[File.join(@target, 'test/path/*')].size.should be(1)
619
+
620
+ Rake::Task.clear ; rm_rf @target
621
+ unzip(@target=>@zip).include('test/**/*').target.invoke
622
+ FileList[File.join(@target, 'test/path/*')].size.should be(2)
623
+
624
+ Rake::Task.clear ; rm_rf @target
625
+ unzip(@target=>@zip).include('test/*').target.invoke
626
+ FileList[File.join(@target, 'test/path/*')].size.should be(2)
627
+ end
628
+ end
629
+
630
+ it 'should include with relative path' do
631
+ with_zip @files, :path=>'test/path' do
632
+ only = File.basename(@files.first)
633
+ unzip(@target=>@zip).tap { |unzip| unzip.from_path('test').include(only) }.target.invoke
634
+ FileList[File.join(@target, '*')].should be_empty
635
+
636
+ Rake::Task.clear ; rm_rf @target
637
+ unzip(@target=>@zip).tap { |unzip| unzip.from_path('test').include('test/*') }.target.invoke
638
+ FileList[File.join(@target, 'path/*')].should be_empty
639
+
640
+ Rake::Task.clear ; rm_rf @target
641
+ unzip(@target=>@zip).tap { |unzip| unzip.from_path('test').include('path/*' + only) }.target.invoke
642
+ FileList[File.join(@target, 'path/*')].size.should be(1)
643
+
644
+ Rake::Task.clear ; rm_rf @target
645
+ unzip(@target=>@zip).tap { |unzip| unzip.from_path('test').include('path/*') }.target.invoke
646
+ FileList[File.join(@target, 'path/*')].size.should be(2)
647
+ end
648
+ end
649
+
650
+ it 'should exclude with relative path' do
651
+ with_zip @files, :path=>'test' do
652
+ except = File.basename(@files.first)
653
+ unzip(@target=>@zip).tap { |unzip| unzip.from_path('test').exclude(except) }.target.invoke
654
+ FileList[File.join(@target, '*')].should include(File.join(@target, File.basename(@files[1])))
655
+ FileList[File.join(@target, '*')].size.should be(@files.size - 1)
656
+ end
657
+ end
658
+
659
+ it "should handle relative paths without any includes or excludes" do
660
+ lib_files = %w{Test3.so Test4.rb}.
661
+ map { |file| File.join(@dir, file) }.
662
+ each { |file| write file, content_for(file) }
663
+ zip(@zip).include(@files, :path => 'src').include(lib_files, :path => 'lib').invoke
664
+
665
+ unzip(@target=>@zip).tap { |unzip| unzip.from_path('lib') }.target.invoke
666
+ FileList[File.join(@target, '**/*')].should have(2).files
667
+ end
668
+
669
+ it 'should return itself from root method' do
670
+ task = unzip(@target=>@zip)
671
+ task.root.should be(task)
672
+ task.from_path('foo').root.should be(task)
673
+ end
674
+
675
+ it 'should return target task from target method' do
676
+ task = unzip(@target=>@zip)
677
+ task.target.should be(file(@target))
678
+ task.from_path('foo').target.should be(file(@target))
679
+ end
680
+
681
+ it 'should alias from_path as path' do
682
+ task = unzip(@target=>@zip)
683
+ task.from_path('foo').should be(task.path('foo'))
684
+ end
685
+
686
+ end