| Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
|---|---|---|---|---|
| lib/buildr/java/packaging.rb | 734 | 429 | 15.80%
|
15.62%
|
Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.
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 'buildr/packaging' |
18 |
19 |
20 module Buildr |
21 module Packaging #:nodoc: |
22 |
23 # Adds packaging for Java projects: JAR, WAR, AAR, EAR, Javadoc. |
24 module Java |
25 |
26 class Manifest |
27 |
28 STANDARD_HEADER = { 'Manifest-Version'=>'1.0', 'Created-By'=>'Buildr' } |
29 LINE_SEPARATOR = /\r\n|\n|\r[^\n]/ #:nodoc: |
30 SECTION_SEPARATOR = /(#{LINE_SEPARATOR}){2}/ #:nodoc: |
31 |
32 class << self |
33 |
34 # :call-seq: |
35 # parse(str) => manifest |
36 # |
37 # Parse a string in MANIFEST.MF format and return a new Manifest. |
38 def parse(str) |
39 sections = str.split(SECTION_SEPARATOR).reject { |s| s.strip.empty? } |
40 new sections.map { |section| |
41 lines = section.split(LINE_SEPARATOR).inject([]) { |merged, line| |
42 if line[/^ /] == ' ' |
43 merged.last << line[1..-1] |
44 else |
45 merged << line |
46 end |
47 merged |
48 } |
49 lines.map { |line| line.scan(/(.*?):\s*(.*)/).first }. |
50 inject({}) { |map, (key, value)| map.merge(key=>value) } |
51 } |
52 end |
53 |
54 # :call-seq: |
55 # from_zip(file) => manifest |
56 # |
57 # Parse the MANIFEST.MF entry of a ZIP (or JAR) file and return a new Manifest. |
58 def from_zip(file) |
59 Zip::ZipInputStream::open(file.to_s) do |zip| |
60 while (entry = zip.get_next_entry) |
61 if entry.name == 'META-INF/MANIFEST.MF' |
62 return Manifest.parse zip.read |
63 end |
64 end |
65 end |
66 Manifest.new |
67 end |
68 |
69 # :call-seq: |
70 # update_manifest(file) { |manifest| ... } |
71 # |
72 # Updates the MANIFEST.MF entry of a ZIP (or JAR) file. Reads the MANIFEST.MF, |
73 # yields to the block with the Manifest object, and writes the modified object |
74 # back to the file. |
75 def update_manifest(file) |
76 manifest = from_zip(file) |
77 result = yield manifest |
78 Zip::ZipFile.open(file.to_s) do |zip| |
79 zip.get_output_stream('META-INF/MANIFEST.MF') do |out| |
80 out.write manifest.to_s |
81 out.write "\n" |
82 end |
83 end |
84 result |
85 end |
86 |
87 end |
88 |
89 # Returns a new Manifest object based on the argument: |
90 # * nil -- Empty Manifest. |
91 # * Hash -- Manifest with main section using the hash name/value pairs. |
92 # * Array -- Manifest with one section from each entry (must be hashes). |
93 # * String -- Parse (see Manifest#parse). |
94 # * Proc/Method -- New Manifest from result of calling proc/method. |
95 def initialize(arg = nil) |
96 case arg |
97 when nil, Hash then @sections = [arg || {}] |
98 when Array then @sections = arg |
99 when String then @sections = Manifest.parse(arg).sections |
100 when Proc, Method then @sections = Manifest.new(arg.call).sections |
101 else |
102 fail 'Invalid manifest, expecting Hash, Array, file name/task or proc/method.' |
103 end |
104 # Add Manifest-Version and Created-By, if not specified. |
105 STANDARD_HEADER.each do |name, value| |
106 sections.first[name] ||= value |
107 end |
108 end |
109 |
110 # The sections of this manifest. |
111 attr_reader :sections |
112 |
113 # The main (first) section of this manifest. |
114 def main |
115 sections.first |
116 end |
117 |
118 include Enumerable |
119 |
120 # Iterate over each section and yield to block. |
121 def each(&block) |
122 @sections.each(&block) |
123 end |
124 |
125 # Convert to MANIFEST.MF format. |
126 def to_s |
127 @sections.map { |section| |
128 keys = section.keys |
129 keys.unshift('Name') if keys.delete('Name') |
130 lines = keys.map { |key| manifest_wrap_at_72("#{key}: #{section[key]}") } |
131 lines + [''] |
132 }.flatten.join("\n") |
133 end |
134 |
135 private |
136 |
137 def manifest_wrap_at_72(line) |
138 return [line] if line.size < 72 |
139 [ line[0..70] ] + manifest_wrap_at_72(' ' + line[71..-1]) |
140 end |
141 |
142 end |
143 |
144 |
145 # Adds support for MANIFEST.MF and other META-INF files. |
146 module WithManifest #:nodoc: |
147 |
148 class << self |
149 def included(base) |
150 base.class_eval do |
151 alias :initialize_without_manifest :initialize |
152 alias :initialize :initialize_with_manifest |
153 end |
154 end |
155 |
156 end |
157 |
158 # Specifies how to create the manifest file. |
159 attr_accessor :manifest |
160 |
161 # Specifies files to include in the META-INF directory. |
162 attr_accessor :meta_inf |
163 |
164 def initialize_with_manifest(*args) #:nodoc: |
165 initialize_without_manifest *args |
166 @manifest = false |
167 @meta_inf = [] |
168 @dependencies = FileList[] |
169 |
170 prepare do |
171 @prerequisites << manifest if String === manifest || Rake::Task === manifest |
172 [meta_inf].flatten.map { |file| file.to_s }.uniq.each { |file| path('META-INF').include file } |
173 end |
174 |
175 enhance do |
176 if manifest |
177 # Tempfiles gets deleted on garbage collection, so we're going to hold on to it |
178 # through instance variable not closure variable. |
179 @manifest_tmp = Tempfile.new('MANIFEST.MF') |
180 File.chmod 0644, @manifest_tmp.path |
181 self.manifest = File.read(manifest.to_s) if String === manifest || Rake::Task === manifest |
182 self.manifest = Manifest.new(manifest) unless Manifest === manifest |
183 #@manifest_tmp.write Manifest::STANDARD_HEADER |
184 @manifest_tmp.write manifest.to_s |
185 @manifest_tmp.write "\n" |
186 @manifest_tmp.close |
187 path('META-INF').include @manifest_tmp.path, :as=>'MANIFEST.MF' |
188 end |
189 end |
190 end |
191 |
192 end |
193 |
194 class ::Buildr::ZipTask |
195 include WithManifest |
196 end |
197 |
198 |
199 # Extends the ZipTask to create a JAR file. |
200 # |
201 # This task supports two additional attributes: manifest and meta-inf. |
202 # |
203 # The manifest attribute specifies how to create the MANIFEST.MF file. |
204 # * A hash of manifest properties (name/value pairs). |
205 # * An array of hashes, one for each section of the manifest. |
206 # * A string providing the name of an existing manifest file. |
207 # * A file task can be used the same way. |
208 # * Proc or method called to return the contents of the manifest file. |
209 # * False to not generate a manifest file. |
210 # |
211 # The meta-inf attribute lists one or more files that should be copied into |
212 # the META-INF directory. |
213 # |
214 # For example: |
215 # package(:jar).with(:manifest=>'src/MANIFEST.MF') |
216 # package(:jar).meta_inf << file('README') |
217 class JarTask < ZipTask |
218 |
219 def initialize(*args) #:nodoc: |
220 super |
221 end |
222 |
223 # :call-seq: |
224 # with(options) => self |
225 # |
226 # Additional |
227 # Pass options to the task. Returns self. ZipTask itself does not support any options, |
228 # but other tasks (e.g. JarTask, WarTask) do. |
229 # |
230 # For example: |
231 # package(:jar).with(:manifest=>'MANIFEST_MF') |
232 def with(*args) |
233 super args.pop if Hash === args.last |
234 fail "package.with() should not contain nil values" if args.include? nil |
235 include :from=>args if args.size > 0 |
236 self |
237 end |
238 |
239 end |
240 |
241 |
242 # Extends the JarTask to create a WAR file. |
243 # |
244 # Supports all the same options as JarTask, in additon to these two options: |
245 # * :libs -- An array of files, tasks, artifact specifications, etc that will be added |
246 # to the WEB-INF/lib directory. |
247 # * :classes -- A directory containing class files for inclusion in the WEB-INF/classes |
248 # directory. |
249 # |
250 # For example: |
251 # package(:war).with(:libs=>'log4j:log4j:jar:1.1') |
252 class WarTask < JarTask |
253 |
254 # Directories with class files to include under WEB-INF/classes. |
255 attr_accessor :classes |
256 |
257 # Artifacts to include under WEB-INF/libs. |
258 attr_accessor :libs |
259 |
260 def initialize(*args) #:nodoc: |
261 super |
262 @classes = [] |
263 @libs = [] |
264 enhance do |war| |
265 @libs.each {|lib| lib.invoke if lib.respond_to?(:invoke) } |
266 @classes.to_a.flatten.each { |classes| include classes, :as => 'WEB-INF/classes' } |
267 path('WEB-INF/lib').include Buildr.artifacts(@libs) unless @libs.nil? || @libs.empty? |
268 end |
269 end |
270 |
271 def libs=(value) #:nodoc: |
272 @libs = Buildr.artifacts(value) |
273 end |
274 |
275 def classes=(value) #:nodoc: |
276 @classes = [value].flatten.map { |dir| file(dir.to_s) } |
277 end |
278 |
279 end |
280 |
281 |
282 # Extends the JarTask to create an AAR file (Axis2 service archive). |
283 # |
284 # Supports all the same options as JarTask, with the addition of :wsdls, :services_xml and :libs. |
285 # |
286 # * :wsdls -- WSDL files to include (under META-INF). By default packaging will include all WSDL |
287 # files found under src/main/axis2. |
288 # * :services_xml -- Location of services.xml file (included under META-INF). By default packaging |
289 # takes this from src/main/axis2/services.xml. Use a different path if you genereate the services.xml |
290 # file as part of the build. |
291 # * :libs -- Array of files, tasks, artifact specifications, etc that will be added to the /lib directory. |
292 # |
293 # For example: |
294 # package(:aar).with(:libs=>'log4j:log4j:jar:1.1') |
295 # |
296 # filter.from('src/main/axis2').into('target').include('services.xml', '*.wsdl').using('http_port'=>'8080') |
297 # package(:aar).wsdls.clear |
298 # package(:aar).with(:services_xml=>_('target/services.xml'), :wsdls=>_('target/*.wsdl')) |
299 class AarTask < JarTask |
300 # Artifacts to include under /lib. |
301 attr_accessor :libs |
302 # WSDLs to include under META-INF (defaults to all WSDLs under src/main/axis2). |
303 attr_accessor :wsdls |
304 # Location of services.xml file (defaults to src/main/axis2/services.xml). |
305 attr_accessor :services_xml |
306 |
307 def initialize(*args) #:nodoc: |
308 super |
309 @libs = [] |
310 @wsdls = [] |
311 prepare do |
312 path('META-INF').include @wsdls |
313 path('META-INF').include @services_xml, :as=>'services.xml' if @services_xml |
314 path('lib').include Buildr.artifacts(@libs) unless @libs.nil? || @libs.empty? |
315 end |
316 end |
317 |
318 def libs=(value) #:nodoc: |
319 @libs = Buildr.artifacts(value) |
320 end |
321 |
322 def wsdls=(value) #:nodoc: |
323 @wsdls |= Array(value) |
324 end |
325 end |
326 |
327 |
328 # Extend the JarTask to create an EAR file. |
329 # |
330 # The following component types are supported by the EARTask: |
331 # |
332 # * :war -- A J2EE Web Application |
333 # * :ejb -- An Enterprise Java Bean |
334 # * :jar -- A J2EE Application Client.[1] |
335 # * :lib -- An ear scoped shared library[2] (for things like logging, |
336 # spring, etc) common to the ear components |
337 # |
338 # The EarTask uses the "Mechanism 2: Bundled Optional Classes" as described on [2]. |
339 # All specified libraries are added to the EAR archive and the Class-Path manifiest entry is |
340 # modified for each EAR component. Special care is taken with WebApplications, as they can |
341 # contain libraries on their WEB-INF/lib directory, libraries already included in a war file |
342 # are not referenced by the Class-Path entry of the war in order to avoid class collisions |
343 # |
344 # EarTask supports all the same options as JarTask, in additon to these two options: |
345 # |
346 # * :display_name -- The displayname to for this ear on application.xml |
347 # |
348 # * :map -- A Hash used to map component type to paths within the EAR. |
349 # By default each component type is mapped to a directory with the same name, |
350 # for example, EJBs are stored in the /ejb path. To customize: |
351 # package(:ear).map[:war] = 'web-applications' |
352 # package(:ear).map[:lib] = nil # store shared libraries on root of archive |
353 # |
354 # EAR components are added by means of the EarTask#add, EarTask#<<, EarTask#push methods |
355 # Component type is determined from the artifact's type. |
356 # |
357 # package(:ear) << project('coolWebService').package(:war) |
358 # |
359 # The << method is just an alias for push, with the later you can add multiple components |
360 # at the same time. For example.. |
361 # |
362 # package(:ear).push 'org.springframework:spring:jar:2.6', |
363 # projects('reflectUtils', 'springUtils'), |
364 # project('coolerWebService').package(:war) |
365 # |
366 # The add method takes a single component with an optional hash. You can use it to override |
367 # some component attributes. |
368 # |
369 # You can override the component type for a particular artifact. The following example |
370 # shows how you can tell the EarTask to treat a JAR file as an EJB: |
371 # |
372 # # will add an ejb entry for the-cool-ejb-2.5.jar in application.xml |
373 # package(:ear).add 'org.coolguys:the-cool-ejb:jar:2.5', :type=>:ejb |
374 # # A better syntax for this is: |
375 # package(:ear).add :ejb=>'org.coolguys:the-cool-ejb:jar:2.5' |
376 # |
377 # By default, every JAR package is assumed to be a library component, so you need to specify |
378 # the type when including an EJB (:ejb) or Application Client JAR (:jar). |
379 # |
380 # For WebApplications (:war)s, you can customize the context-root that appears in application.xml. |
381 # The following example also specifies a different directory inside the EAR where to store the webapp. |
382 # |
383 # package(:ear).add project(:remoteService).package(:war), |
384 # :path=>'web-services', :context_root=>'/Some/URL/Path' |
385 # |
386 # [1] http://java.sun.com/j2ee/sdk_1.2.1/techdocs/guides/ejb/html/Overview5.html#10106 |
387 # [2] http://java.sun.com/j2ee/verified/packaging.html |
388 class EarTask < JarTask |
389 |
390 SUPPORTED_TYPES = [:war, :ejb, :jar, :rar, :lib] |
391 |
392 # The display-name entry for application.xml |
393 attr_accessor :display_name |
394 # The description entry for application.xml |
395 attr_accessor :description |
396 # Map from component type to path inside the EAR. |
397 attr_accessor :dirs |
398 # Security roles entry for application.xml |
399 attr_accessor :security_roles |
400 |
401 def initialize(*args) |
402 super |
403 @dirs = Hash.new { |h, k| k.to_s } |
404 @libs, @components, @security_roles = [], [], [] |
405 prepare do |
406 @components.each do |component| |
407 path(component[:path]).include(component[:clone] || component[:artifact]) |
408 end |
409 path('META-INF').include(descriptor) |
410 end |
411 end |
412 |
413 # Add an artifact to this EAR. |
414 def add(*args) |
415 options = Hash === args.last ? args.pop.clone : {} |
416 args.flatten! |
417 args.map! do |pkg| |
418 case pkg |
419 when Project |
420 pkg.packages.select { |pp| JarTask === pp && SUPPORTED_TYPES.include?(pp.type) } |
421 when Rake::FileTask |
422 pkg # add the explicitly provided file |
423 when Hash |
424 Buildr.artifact(pkg) |
425 when String |
426 begin |
427 Buildr.artifact(pkg) |
428 rescue # not an artifact spec, it must me a filename |
429 file(pkg) |
430 end |
431 else |
432 raise "Invalid EAR component #{pkg.class}: #{pkg}" |
433 end |
434 end |
435 args.flatten! |
436 args.compact! |
437 if args.empty? |
438 raise ":type must not be specified for type=>component argument style" if options.key?(:type) |
439 raise ":as must not be specified for type=>component argument style" if options.key?(:as) |
440 comps = {} |
441 options.delete_if { |k, v| comps[k] = v if SUPPORTED_TYPES.include?(k) } |
442 raise "You must specify at least one valid component to add" if comps.empty? |
443 comps.each { |k, v| add(v, {:as => k}.merge(options)) } |
444 else |
445 args.each do |artifact| |
446 type = options[:as] || options[:type] |
447 unless type |
448 type = artifact.respond_to?(:type) ? artifact.type : artifact.to_s.pathmap('%x').to_sym |
449 type = :lib if type == :jar |
450 end |
451 raise "Unknown EAR component type: #{type}. Perhaps you may explicity tell what component type to use." unless |
452 SUPPORTED_TYPES.include?(type) |
453 component = options.merge(:artifact => artifact, :type => type, |
454 :id=>artifact.respond_to?(:to_spec) ? artifact.id : artifact.to_s.pathmap('%n'), |
455 :path=>options[:path] || dirs[type].to_s) |
456 component[:clone] = component_clone(component) unless :lib == type |
457 # update_classpath(component) unless :lib == type || Artifact === artifact |
458 @components << component |
459 end |
460 end |
461 self |
462 end |
463 |
464 alias_method :push, :add |
465 alias_method :<<, :push |
466 |
467 protected |
468 |
469 def component_clone(component) |
470 file(path_to(component[:path], component[:artifact].to_s.pathmap('%f')) => component[:artifact]) do |task| |
471 mkpath task.to_s.pathmap('%d') |
472 cp component[:artifact].to_s, task.to_s |
473 Manifest.update_manifest(task) do |manifest| |
474 class_path = manifest.main['Class-Path'].to_s.split |
475 included_libs = class_path.map { |fn| fn.pathmap('%f') } |
476 Zip::ZipFile.foreach(task.to_s) do |entry| |
477 included_libs << entry.name.pathmap('%f') if entry.file? && entry.name =~ /^WEB-INF\/lib\/[^\/]+$/ |
478 end |
479 # Include all other libraries in the classpath. |
480 class_path += libs_classpath(component).reject { |path| included_libs.include?(File.basename(path)) } |
481 manifest.main['Class-Path'] = class_path.join(' ') |
482 end |
483 end |
484 end |
485 |
486 def associate(project) |
487 @project = project |
488 end |
489 |
490 def path_to(*args) #:nodoc: |
491 @project.path_to(:target, :ear, name.pathmap('%n'), *args) |
492 end |
493 alias_method :_, :path_to |
494 |
495 def update_classpath(component) |
496 package = file(component[:artifact].to_s) |
497 package.manifest = (package.manifest || {}).dup # avoid mofifying parent projects manifest |
498 package.prepare do |
499 header = case package.manifest |
500 when Hash then package.manifest |
501 when Array then package.manifest.first |
502 end |
503 if header |
504 # Determine which libraries are already included. |
505 class_path = header['Class-Path'].to_s.split |
506 included_libs = class_path.map { |fn| File.basename(fn) } |
507 included_libs += package.path('WEB-INF/lib').sources.map { |fn| File.basename(fn) } |
508 # Include all other libraries in the classpath. |
509 class_path += libs_classpath(component).reject { |path| included_libs.include?(File.basename(path)) } |
510 header['Class-Path'] = class_path.join(' ') |
511 end |
512 end |
513 end |
514 |
515 private |
516 |
517 # Classpath of all packages included as libraries (type :lib). |
518 def libs_classpath(component) |
519 from = component[:path] |
520 @classpath = @components.select { |comp| comp[:type] == :lib }. |
521 map do |lib| |
522 basename = lib[:artifact].to_s.pathmap('%f') |
523 full_path = lib[:path].empty? ? basename : File.join(lib[:path], basename) |
524 Util.relative_path(full_path, from) |
525 end |
526 end |
527 |
528 def descriptor_xml |
529 buffer = "" |
530 xml = Builder::XmlMarkup.new(:target=>buffer, :indent => 2) |
531 xml.declare! :DOCTYPE, :application, :PUBLIC, |
532 "-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN", |
533 "http://java.sun.com/j2ee/dtds/application_1_2.dtd" |
534 xml.application do |
535 xml.tag! 'display-name', display_name |
536 desc = self.description || @project.comment |
537 xml.tag! 'description', desc if desc |
538 @components.each do |comp| |
539 basename = comp[:artifact].to_s.pathmap('%f') |
540 uri = comp[:path].empty? ? basename : File.join(comp[:path], basename) |
541 case comp[:type] |
542 when :war |
543 xml.module :id=>comp[:id] do |
544 xml.web do |
545 xml.tag! 'web-uri', uri |
546 xml.tag! 'context-root', File.join('', (comp[:context_root] || comp[:id])) unless comp[:context_root] == false |
547 end |
548 end |
549 when :ejb |
550 xml.module :id=>comp[:id] do |
551 xml.ejb uri |
552 end |
553 when :jar |
554 xml.jar uri |
555 end |
556 end |
557 @security_roles.each do |role| |
558 xml.tag! 'security-role', :id=>role[:id] do |
559 xml.description role[:description] |
560 xml.tag! 'role-name', role[:name] |
561 end |
562 end |
563 end |
564 buffer |
565 end |
566 |
567 # return a FileTask to build the ear application.xml file |
568 def descriptor |
569 return @descriptor if @descriptor |
570 descriptor_path = path_to('META-INF/application.xml') |
571 @descriptor = file(descriptor_path) do |task| |
572 trace "Creating EAR Descriptor: #{task.to_s}" |
573 mkpath File.dirname(task.name) |
574 File.open(task.name, 'w') { |file| file.print task.xml } |
575 end |
576 class << @descriptor |
577 attr_accessor :ear |
578 |
579 def xml |
580 @xml ||= ear.send :descriptor_xml |
581 end |
582 |
583 def needed? |
584 super || xml != File.read(self.to_s) rescue true |
585 end |
586 end |
587 @descriptor.ear = self |
588 @descriptor |
589 end |
590 |
591 end |
592 |
593 |
594 include Extension |
595 |
596 before_define(:package => :build) do |project| |
597 if project.parent && project.parent.manifest |
598 project.manifest = project.parent.manifest.dup |
599 else |
600 project.manifest = { |
601 'Build-By'=>ENV['USER'], 'Build-Jdk'=>ENV_JAVA['java.version'], |
602 'Implementation-Title'=>project.comment || project.name, |
603 'Implementation-Version'=>project.version } |
604 end |
605 if project.parent && project.parent.meta_inf |
606 project.meta_inf = project.parent.meta_inf.dup |
607 else |
608 project.meta_inf = [project.file('LICENSE')].select { |file| File.exist?(file.to_s) } |
609 end |
610 end |
611 |
612 |
613 # Manifest used for packaging. Inherited from parent project. The default value is a hash that includes |
614 # the Build-By, Build-Jdk, Implementation-Title and Implementation-Version values. |
615 # The later are taken from the project's comment (or name) and version number. |
616 attr_accessor :manifest |
617 |
618 # Files to always include in the package META-INF directory. The default value include |
619 # the LICENSE file if one exists in the project's base directory. |
620 attr_accessor :meta_inf |
621 |
622 # :call-seq: |
623 # package_with_sources(options?) |
624 # |
625 # Call this when you want the project (and all its sub-projects) to create a source distribution. |
626 # You can use the source distribution in an IDE when debugging. |
627 # |
628 # A source distribution is a jar package with the classifier 'sources', which includes all the |
629 # sources used by the compile task. |
630 # |
631 # Packages use the project's manifest and meta_inf properties, which you can override by passing |
632 # different values (e.g. false to exclude the manifest) in the options. |
633 # |
634 # To create source distributions only for specific projects, use the :only and :except options, |
635 # for example: |
636 # package_with_sources :only=>['foo:bar', 'foo:baz'] |
637 # |
638 # (Same as calling package :sources on each project/sub-project that has source directories.) |
639 def package_with_sources(options = nil) |
640 options ||= {} |
641 enhance do |
642 selected = options[:only] ? projects(options[:only]) : |
643 options[:except] ? ([self] + projects - projects(options[:except])) : |
644 [self] + projects |
645 selected.reject { |project| project.compile.sources.empty? && project.resources.target.nil? }. |
646 each { |project| project.package(:sources) } |
647 end |
648 end |
649 |
650 # :call-seq: |
651 # package_with_javadoc(options?) |
652 # |
653 # Call this when you want the project (and all its sub-projects) to create a JavaDoc distribution. |
654 # You can use the JavaDoc distribution in an IDE when coding against the API. |
655 # |
656 # A JavaDoc distribution is a ZIP package with the classifier 'javadoc', which includes all the |
657 # sources used by the compile task. |
658 # |
659 # Packages use the project's manifest and meta_inf properties, which you can override by passing |
660 # different values (e.g. false to exclude the manifest) in the options. |
661 # |
662 # To create JavaDoc distributions only for specific projects, use the :only and :except options, |
663 # for example: |
664 # package_with_javadoc :only=>['foo:bar', 'foo:baz'] |
665 # |
666 # (Same as calling package :javadoc on each project/sub-project that has source directories.) |
667 def package_with_javadoc(options = nil) |
668 options ||= {} |
669 enhance do |
670 selected = options[:only] ? projects(options[:only]) : |
671 options[:except] ? ([self] + projects - projects(options[:except])) : |
672 [self] + projects |
673 selected.reject { |project| project.compile.sources.empty? }. |
674 each { |project| project.package(:javadoc) } |
675 end |
676 end |
677 |
678 protected |
679 |
680 def package_as_jar(file_name) #:nodoc: |
681 Java::JarTask.define_task(file_name).tap do |jar| |
682 jar.with :manifest=>manifest, :meta_inf=>meta_inf |
683 jar.with [compile.target, resources.target].compact |
684 end |
685 end |
686 |
687 def package_as_war(file_name) #:nodoc: |
688 Java::WarTask.define_task(file_name).tap do |war| |
689 war.with :manifest=>manifest, :meta_inf=>meta_inf |
690 # Add libraries in WEB-INF lib, and classes in WEB-INF classes |
691 war.with :classes=>[compile.target, resources.target].compact |
692 war.with :libs=>compile.dependencies |
693 # Add included files, or the webapp directory. |
694 webapp = path_to(:source, :main, :webapp) |
695 war.with webapp if File.exist?(webapp) |
696 end |
697 end |
698 |
699 def package_as_aar(file_name) #:nodoc: |
700 Java::AarTask.define_task(file_name).tap do |aar| |
701 aar.with :manifest=>manifest, :meta_inf=>meta_inf |
702 aar.with :wsdls=>path_to(:source, :main, :axis2, '*.wsdl') |
703 aar.with :services_xml=>path_to(:source, :main, :axis2, 'services.xml') |
704 aar.with [compile.target, resources.target].compact |
705 aar.with :libs=>compile.dependencies |
706 end |
707 end |
708 |
709 def package_as_ear(file_name) #:nodoc: |
710 Java::EarTask.define_task(file_name).tap do |ear| |
711 ear.send :associate, self |
712 ear.with :display_name=>id, :manifest=>manifest, :meta_inf=>meta_inf |
713 end |
714 end |
715 |
716 def package_as_javadoc_spec(spec) #:nodoc: |
717 spec.merge(:type=>:jar, :classifier=>'javadoc') |
718 end |
719 |
720 def package_as_javadoc(file_name) #:nodoc: |
721 ZipTask.define_task(file_name).tap do |zip| |
722 zip.include :from=>doc.target |
723 end |
724 end |
725 |
726 end |
727 |
728 end |
729 end |
730 |
731 |
732 class Buildr::Project |
733 include Buildr::Packaging::Java |
734 end |
Generated on 2011-07-06 23:35:37 -0700 with rcov 0.9.8