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,189 @@
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
+ require 'zip'
17
+
18
+ if RUBY_VERSION >= '1.9.0' # Required to properly load RubyZip under Ruby 1.9
19
+ $LOADED_FEATURES.unshift 'ftools'
20
+ require 'fileutils'
21
+
22
+ def File.move(source, dest)
23
+ FileUtils.move source, dest
24
+ end
25
+
26
+ def File.rm_rf(path)
27
+ FileUtils.rm_rf path
28
+ end
29
+ end
30
+
31
+ module Zip #:nodoc:
32
+
33
+ class CentralDirectory #:nodoc:
34
+ # Patch to add entries in alphabetical order.
35
+ def write_to_stream(io)
36
+ offset = io.tell
37
+ @entry_set.sort { |a,b| a.name <=> b.name }.each { |entry| entry.write_c_dir_entry(io) }
38
+ eocd_offset = io.tell
39
+ cdir_size = eocd_offset - offset
40
+ write_e_o_c_d(io, offset, cdir_size)
41
+ end
42
+ end
43
+
44
+ class File
45
+
46
+ # :call-seq:
47
+ # exist() => boolean
48
+ #
49
+ # Returns true if this entry exists.
50
+ def exist?(entry_name)
51
+ !!find_entry(entry_name)
52
+ end
53
+ end
54
+
55
+
56
+ class Entry
57
+
58
+ # :call-seq:
59
+ # exist() => boolean
60
+ #
61
+ # Returns true if this entry exists.
62
+ def exist?()
63
+ File.open(zipfile) { |zip| zip.exist?(@name) }
64
+ end
65
+
66
+ # :call-seq:
67
+ # empty?() => boolean
68
+ #
69
+ # Returns true if this entry is empty.
70
+ def empty?()
71
+ File.open(zipfile) { |zip| zip.read(@name) }.empty?
72
+ end
73
+
74
+ # :call-seq:
75
+ # contain(patterns*) => boolean
76
+ #
77
+ # Returns true if this ZIP file entry matches against all the arguments. An argument may be
78
+ # a string or regular expression.
79
+ def contain?(*patterns)
80
+ content = File.open(zipfile) { |zip| zip.read(@name) }
81
+ patterns.map { |pattern| Regexp === pattern ? pattern : Regexp.new(Regexp.escape(pattern.to_s)) }.
82
+ all? { |pattern| content =~ pattern }
83
+ end
84
+
85
+ # Override of write_c_dir_entry to fix comments being set to a fixnum instead of string
86
+ def write_c_dir_entry(io) #:nodoc:all
87
+ case @fstype
88
+ when FSTYPE_UNIX
89
+ ft = nil
90
+ case @ftype
91
+ when :file
92
+ ft = 010
93
+ @unix_perms ||= 0644
94
+ when :directory
95
+ ft = 004
96
+ @unix_perms ||= 0755
97
+ when :symlink
98
+ ft = 012
99
+ @unix_perms ||= 0755
100
+ else
101
+ raise ZipInternalError, "unknown file type #{self.inspect}"
102
+ end
103
+
104
+ @external_file_attributes = (ft << 12 | (@unix_perms & 07777)) << 16
105
+ end
106
+
107
+ io <<
108
+ [0x02014b50,
109
+ @version, # version of encoding software
110
+ @fstype, # filesystem type
111
+ 10, # @versionNeededToExtract
112
+ 0, # @gp_flags
113
+ @compression_method,
114
+ @time.to_binary_dos_time, # @lastModTime
115
+ @time.to_binary_dos_date, # @lastModDate
116
+ @crc,
117
+ @compressed_size,
118
+ @size,
119
+ @name ? @name.length : 0,
120
+ @extra ? @extra.c_dir_size : 0,
121
+ @comment ? comment.to_s.length : 0,
122
+ 0, # disk number start
123
+ @internal_file_attributes, # file type (binary=0, text=1)
124
+ @external_file_attributes, # native filesystem attributes
125
+ @local_header_offset,
126
+ @name,
127
+ @extra,
128
+ @comment
129
+ ].pack('VCCvvvvvVVVvvvvvVV')
130
+
131
+ io << @name
132
+ io << (@extra ? @extra.to_c_dir_bin : "")
133
+ io << @comment
134
+ end
135
+
136
+ # Override write_c_dir_entry to fix comments being set to a fixnum instead of string
137
+ def write_c_dir_entry(io) #:nodoc:all
138
+ @comment = "" if @comment.nil? || @comment == -1 # Hack fix @comment being nil or fixnum -1
139
+
140
+ case @fstype
141
+ when FSTYPE_UNIX
142
+ ft = nil
143
+ case @ftype
144
+ when :file
145
+ ft = 010
146
+ @unix_perms ||= 0644
147
+ when :directory
148
+ ft = 004
149
+ @unix_perms ||= 0755
150
+ when :symlink
151
+ ft = 012
152
+ @unix_perms ||= 0755
153
+ else
154
+ raise ZipInternalError, "unknown file type #{self.inspect}"
155
+ end
156
+
157
+ @external_file_attributes = (ft << 12 | (@unix_perms & 07777)) << 16
158
+ end
159
+
160
+ io <<
161
+ [0x02014b50,
162
+ @version, # version of encoding software
163
+ @fstype, # filesystem type
164
+ 10, # @versionNeededToExtract
165
+ 0, # @gp_flags
166
+ @compression_method,
167
+ @time.to_binary_dos_time, # @lastModTime
168
+ @time.to_binary_dos_date, # @lastModDate
169
+ @crc,
170
+ @compressed_size,
171
+ @size,
172
+ @name ? @name.length : 0,
173
+ @extra ? @extra.c_dir_size : 0,
174
+ @comment ? @comment.length : 0,
175
+ 0, # disk number start
176
+ @internal_file_attributes, # file type (binary=0, text=1)
177
+ @external_file_attributes, # native filesystem attributes
178
+ @local_header_offset,
179
+ @name,
180
+ @extra,
181
+ @comment].pack('VCCvvvvvVVVvvvvvVV')
182
+
183
+ io << @name
184
+ io << (@extra ? @extra.to_c_dir_bin : "")
185
+ io << @comment
186
+
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,387 @@
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
+ module Buildr #:nodoc:
17
+
18
+ # The ZipTask creates a new Zip file. You can include any number of files and and directories,
19
+ # use exclusion patterns, and include files into specific directories.
20
+ #
21
+ # For example:
22
+ # zip('test.zip').tap do |task|
23
+ # task.include 'srcs'
24
+ # task.include 'README', 'LICENSE'
25
+ # end
26
+ #
27
+ # See Buildr#zip and ArchiveTask.
28
+ class ZipTask < ArchiveTask
29
+
30
+ # Compression level for this Zip.
31
+ attr_accessor :compression_level
32
+
33
+ def initialize(*args) #:nodoc:
34
+ self.compression_level = Zlib::DEFAULT_COMPRESSION
35
+ super
36
+ end
37
+
38
+ # :call-seq:
39
+ # entry(name) => Entry
40
+ #
41
+ # Returns a ZIP file entry. You can use this to check if the entry exists and its contents,
42
+ # for example:
43
+ # package(:jar).entry("META-INF/LICENSE").should contain(/Apache Software License/)
44
+ def entry(entry_name)
45
+ ::Zip::Entry.new(name, entry_name)
46
+ end
47
+
48
+ def entries #:nodoc:
49
+ @entries ||= Zip::File.open(name) { |zip| zip.entries }
50
+ end
51
+
52
+ private
53
+
54
+ def create_from(file_map, transform_map)
55
+ Zip::OutputStream.open name do |zip|
56
+ seen = {}
57
+ mkpath = lambda do |dir|
58
+ dirname = (dir[-1..-1] =~ /\/$/) ? dir : dir + '/'
59
+ unless dir == '.' || seen[dirname]
60
+ mkpath.call File.dirname(dirname)
61
+ zip.put_next_entry(dirname, compression_level)
62
+ seen[dirname] = true
63
+ end
64
+ end
65
+
66
+ paths = file_map.keys.sort
67
+ paths.each do |path|
68
+ contents = file_map[path]
69
+ warn "Warning: Path in zipfile #{name} contains backslash: #{path}" if path =~ /\\/
70
+
71
+ # Must ensure that the directory entry is created for intermediate paths, otherwise
72
+ # zips can be created without entries for directories which can break some tools
73
+ mkpath.call File.dirname(path)
74
+
75
+ entry_created = false
76
+ to_transform = []
77
+ transform = transform_map.key?(path)
78
+ [contents].flatten.each do |content|
79
+ if content.respond_to?(:call)
80
+ unless entry_created
81
+ entry = zip.put_next_entry(path, compression_level)
82
+ entry.unix_perms = content.mode & 07777 if content.respond_to?(:mode)
83
+ entry_created = true
84
+ end
85
+ if transform
86
+ output = StringIO.new
87
+ content.call output
88
+ to_transform << output.string
89
+ else
90
+ content.call zip
91
+ end
92
+ elsif content.nil? || File.directory?(content.to_s)
93
+ mkpath.call path
94
+ else
95
+ File.open content.to_s, 'rb' do |is|
96
+ unless entry_created
97
+ entry = zip.put_next_entry(path, compression_level)
98
+ entry.unix_perms = is.stat.mode & 07777
99
+ entry_created = true
100
+ end
101
+ if transform
102
+ output = StringIO.new
103
+ while data = is.read(4096)
104
+ output << data
105
+ end
106
+ to_transform << output.string
107
+ else
108
+ while data = is.read(4096)
109
+ zip << data
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ if transform_map.key?(path)
116
+ zip << transform_map[path].call(to_transform)
117
+ end
118
+ end
119
+ end
120
+ end
121
+
122
+ end
123
+
124
+
125
+ # :call-seq:
126
+ # zip(file) => ZipTask
127
+ #
128
+ # The ZipTask creates a new Zip file. You can include any number of files and
129
+ # and directories, use exclusion patterns, and include files into specific
130
+ # directories.
131
+ #
132
+ # For example:
133
+ # zip('test.zip').tap do |task|
134
+ # task.include 'srcs'
135
+ # task.include 'README', 'LICENSE'
136
+ # end
137
+ def zip(file)
138
+ ZipTask.define_task(file)
139
+ end
140
+
141
+
142
+ # An object for unzipping/untarring a file into a target directory. You can tell it to include
143
+ # or exclude only specific files and directories, and also to map files from particular
144
+ # paths inside the zip file into the target directory. Once ready, call #extract.
145
+ #
146
+ # Usually it is more convenient to create a file task for extracting the zip file
147
+ # (see #unzip) and pass this object as a prerequisite to other tasks.
148
+ #
149
+ # See Buildr#unzip.
150
+ class Unzip
151
+
152
+ # The zip file to extract.
153
+ attr_accessor :zip_file
154
+ # The target directory to extract to.
155
+ attr_accessor :target
156
+
157
+ # Initialize with hash argument of the form target=>zip_file.
158
+ def initialize(args)
159
+ @target, arg_names, zip_file = Buildr.application.resolve_args([args])
160
+ @zip_file = zip_file.first
161
+ @paths = {}
162
+ end
163
+
164
+ # :call-seq:
165
+ # extract
166
+ #
167
+ # Extract the zip/tgz file into the target directory.
168
+ #
169
+ # You can call this method directly. However, if you are using the #unzip method,
170
+ # it creates a file task for the target directory: use that task instead as a
171
+ # prerequisite. For example:
172
+ # build unzip(dir=>zip_file)
173
+ # Or:
174
+ # unzip(dir=>zip_file).target.invoke
175
+ def extract
176
+ # If no paths specified, then no include/exclude patterns
177
+ # specified. Nothing will happen unless we include all files.
178
+ if @paths.empty?
179
+ @paths[nil] = FromPath.new(self, nil)
180
+ end
181
+
182
+ # Otherwise, empty unzip creates target as a file when touching.
183
+ mkpath target.to_s
184
+ if zip_file.to_s.match /\.t?gz$/
185
+ #un-tar.gz
186
+ Zlib::GzipReader.open(zip_file.to_s) { |tar|
187
+ Archive::Tar::Minitar::Input.open(tar) do |inp|
188
+ inp.each do |tar_entry|
189
+ @paths.each do |path, patterns|
190
+ patterns.map([tar_entry]).each do |dest, entry|
191
+ next if entry.directory?
192
+ dest = File.expand_path(dest, target.to_s)
193
+ trace "Extracting #{dest}"
194
+ mkpath File.dirname(dest) rescue nil
195
+ File.open(dest, 'wb', entry.mode) {|f| f.write entry.read}
196
+ File.chmod(entry.mode, dest)
197
+ end
198
+ end
199
+ end
200
+ end
201
+ }
202
+ else
203
+ Zip::File.open(zip_file.to_s) do |zip|
204
+ entries = zip.collect
205
+ @paths.each do |path, patterns|
206
+ patterns.map(entries).each do |dest, entry|
207
+ next if entry.directory?
208
+ dest = File.expand_path(dest, target.to_s)
209
+ trace "Extracting #{dest}"
210
+ mkpath File.dirname(dest) rescue nil
211
+ entry.restore_permissions = true
212
+ entry.extract(dest) { true }
213
+ end
214
+ end
215
+ end
216
+ end
217
+ # Let other tasks know we updated the target directory.
218
+ touch target.to_s
219
+ end
220
+
221
+ #reads the includes/excludes and apply them to the entry_name
222
+ def included?(entry_name)
223
+ @paths.each do |path, patterns|
224
+ return true if path.nil?
225
+ if entry_name =~ /^#{path}/
226
+ short = entry_name.sub(path, '')
227
+ if patterns.include.any? { |pattern| File.fnmatch(pattern, entry_name) } &&
228
+ !patterns.exclude.any? { |pattern| File.fnmatch(pattern, entry_name) }
229
+ # trace "tar_entry.full_name " + entry_name + " is included"
230
+ return true
231
+ end
232
+ end
233
+ end
234
+ # trace "tar_entry.full_name " + entry_name + " is excluded"
235
+ return false
236
+ end
237
+
238
+
239
+ # :call-seq:
240
+ # include(*files) => self
241
+ # include(*files, :path=>name) => self
242
+ #
243
+ # Include all files that match the patterns and returns self.
244
+ #
245
+ # Use include if you only want to unzip some of the files, by specifying
246
+ # them instead of using exclusion. You can use #include in combination
247
+ # with #exclude.
248
+ def include(*files)
249
+ if Hash === files.last
250
+ from_path(files.pop[:path]).include *files
251
+ else
252
+ from_path(nil).include *files
253
+ end
254
+ self
255
+ end
256
+ alias :add :include
257
+
258
+ # :call-seq:
259
+ # exclude(*files) => self
260
+ #
261
+ # Exclude all files that match the patterns and return self.
262
+ #
263
+ # Use exclude to unzip all files except those that match the pattern.
264
+ # You can use #exclude in combination with #include.
265
+ def exclude(*files)
266
+ if Hash === files.last
267
+ from_path(files.pop[:path]).exclude *files
268
+ else
269
+ from_path(nil).exclude *files
270
+ end
271
+ self
272
+ end
273
+
274
+ # :call-seq:
275
+ # from_path(name) => Path
276
+ #
277
+ # Allows you to unzip from a path. Returns an object you can use to
278
+ # specify which files to include/exclude relative to that path.
279
+ # Expands the file relative to that path.
280
+ #
281
+ # For example:
282
+ # unzip(Dir.pwd=>'test.jar').from_path('etc').include('LICENSE')
283
+ # will unzip etc/LICENSE into ./LICENSE.
284
+ #
285
+ # This is different from:
286
+ # unzip(Dir.pwd=>'test.jar').include('etc/LICENSE')
287
+ # which unzips etc/LICENSE into ./etc/LICENSE.
288
+ def from_path(name)
289
+ @paths[name] ||= FromPath.new(self, name)
290
+ end
291
+ alias :path :from_path
292
+
293
+ # :call-seq:
294
+ # root => Unzip
295
+ #
296
+ # Returns the root path, essentially the Unzip object itself. In case you are wondering
297
+ # down paths and want to go back.
298
+ def root
299
+ self
300
+ end
301
+
302
+ # Returns the path to the target directory.
303
+ def to_s
304
+ target.to_s
305
+ end
306
+
307
+ class FromPath #:nodoc:
308
+
309
+ def initialize(unzip, path)
310
+ @unzip = unzip
311
+ if path
312
+ @path = path[-1] == ?/ ? path : path + '/'
313
+ else
314
+ @path = ''
315
+ end
316
+ end
317
+
318
+ # See UnzipTask#include
319
+ def include(*files) #:doc:
320
+ @include ||= []
321
+ @include |= files
322
+ self
323
+ end
324
+
325
+ # See UnzipTask#exclude
326
+ def exclude(*files) #:doc:
327
+ @exclude ||= []
328
+ @exclude |= files
329
+ self
330
+ end
331
+
332
+ def map(entries)
333
+ includes = @include || ['*']
334
+ excludes = @exclude || []
335
+ entries.inject({}) do |map, entry|
336
+ if entry.name =~ /^#{@path}/
337
+ short = entry.name.sub(@path, '')
338
+ if includes.any? { |pat| File.fnmatch(pat, short) } &&
339
+ !excludes.any? { |pat| File.fnmatch(pat, short) }
340
+ map[short] = entry
341
+ end
342
+ end
343
+ map
344
+ end
345
+ end
346
+
347
+ # Documented in Unzip.
348
+ def root
349
+ @unzip
350
+ end
351
+
352
+ # The target directory to extract to.
353
+ def target
354
+ @unzip.target
355
+ end
356
+
357
+ end
358
+
359
+ end
360
+
361
+ # :call-seq:
362
+ # unzip(to_dir=>zip_file) => Zip
363
+ #
364
+ # Creates a task that will unzip a file into the target directory. The task name
365
+ # is the target directory, the prerequisite is the file to unzip.
366
+ #
367
+ # This method creates a file task to expand the zip file. It returns an Unzip object
368
+ # that specifies how the file will be extracted. You can include or exclude specific
369
+ # files from within the zip, and map to different paths.
370
+ #
371
+ # The Unzip object's to_s method return the path to the target directory, so you can
372
+ # use it as a prerequisite. By keeping the Unzip object separate from the file task,
373
+ # you overlay additional work on top of the file task.
374
+ #
375
+ # For example:
376
+ # unzip('all'=>'test.zip')
377
+ # unzip('src'=>'test.zip').include('README', 'LICENSE')
378
+ # unzip('libs'=>'test.zip').from_path('libs')
379
+ def unzip(args)
380
+ target, arg_names, zip_file = Buildr.application.resolve_args([args])
381
+ task = file(File.expand_path(target.to_s)=>zip_file)
382
+ Unzip.new(task=>zip_file).tap do |setup|
383
+ task.enhance { setup.extract }
384
+ end
385
+ end
386
+
387
+ end