realityforge-buildr 1.5.9

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.
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