buildr 1.3.5-x86-mswin32

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