mguymon-buildr 1.4.5-java

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 (220) hide show
  1. data/CHANGELOG +1291 -0
  2. data/LICENSE +176 -0
  3. data/NOTICE +26 -0
  4. data/README.rdoc +134 -0
  5. data/Rakefile +44 -0
  6. data/_buildr +35 -0
  7. data/_jbuildr +35 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/bnd.rb +147 -0
  10. data/addon/buildr/cobertura.rb +22 -0
  11. data/addon/buildr/drb.rb +281 -0
  12. data/addon/buildr/emma.rb +22 -0
  13. data/addon/buildr/hibernate.rb +149 -0
  14. data/addon/buildr/javacc.rb +85 -0
  15. data/addon/buildr/jaxb_xjc.rb +72 -0
  16. data/addon/buildr/jdepend.rb +60 -0
  17. data/addon/buildr/jetty.rb +248 -0
  18. data/addon/buildr/jibx.rb +86 -0
  19. data/addon/buildr/nailgun.rb +221 -0
  20. data/addon/buildr/openjpa.rb +88 -0
  21. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  22. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  23. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  25. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  26. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  27. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  28. data/addon/buildr/protobuf.rb +88 -0
  29. data/addon/buildr/xmlbeans.rb +93 -0
  30. data/bin/buildr +19 -0
  31. data/buildr.buildfile +58 -0
  32. data/buildr.gemspec +78 -0
  33. data/doc/_config.yml +1 -0
  34. data/doc/_layouts/default.html +90 -0
  35. data/doc/_layouts/preface.html +22 -0
  36. data/doc/artifacts.textile +217 -0
  37. data/doc/building.textile +276 -0
  38. data/doc/contributing.textile +268 -0
  39. data/doc/css/default.css +236 -0
  40. data/doc/css/print.css +101 -0
  41. data/doc/css/syntax.css +23 -0
  42. data/doc/download.textile +151 -0
  43. data/doc/extending.textile +212 -0
  44. data/doc/images/1442160941-frontcover.jpg +0 -0
  45. data/doc/images/asf-logo.gif +0 -0
  46. data/doc/images/asf-logo.png +0 -0
  47. data/doc/images/buildr-hires.png +0 -0
  48. data/doc/images/buildr.png +0 -0
  49. data/doc/images/favicon.png +0 -0
  50. data/doc/images/growl-icon.tiff +0 -0
  51. data/doc/images/note.png +0 -0
  52. data/doc/images/project-structure.png +0 -0
  53. data/doc/images/tip.png +0 -0
  54. data/doc/images/zbuildr.png +0 -0
  55. data/doc/images/zbuildr.tif +0 -0
  56. data/doc/index.textile +109 -0
  57. data/doc/installing.textile +284 -0
  58. data/doc/languages.textile +599 -0
  59. data/doc/mailing_lists.textile +29 -0
  60. data/doc/more_stuff.textile +845 -0
  61. data/doc/packaging.textile +618 -0
  62. data/doc/preface.textile +54 -0
  63. data/doc/projects.textile +276 -0
  64. data/doc/quick_start.textile +210 -0
  65. data/doc/releasing.textile +117 -0
  66. data/doc/scripts/buildr-git.rb +512 -0
  67. data/doc/scripts/gitflow.rb +296 -0
  68. data/doc/scripts/install-jruby.sh +44 -0
  69. data/doc/scripts/install-linux.sh +73 -0
  70. data/doc/scripts/install-osx.sh +52 -0
  71. data/doc/settings_profiles.textile +287 -0
  72. data/doc/testing.textile +247 -0
  73. data/etc/KEYS +189 -0
  74. data/lib/buildr.rb +44 -0
  75. data/lib/buildr/clojure.rb +34 -0
  76. data/lib/buildr/clojure/shell.rb +52 -0
  77. data/lib/buildr/core.rb +34 -0
  78. data/lib/buildr/core/application.rb +700 -0
  79. data/lib/buildr/core/build.rb +516 -0
  80. data/lib/buildr/core/cc.rb +166 -0
  81. data/lib/buildr/core/checks.rb +253 -0
  82. data/lib/buildr/core/common.rb +151 -0
  83. data/lib/buildr/core/compile.rb +622 -0
  84. data/lib/buildr/core/doc.rb +276 -0
  85. data/lib/buildr/core/environment.rb +129 -0
  86. data/lib/buildr/core/filter.rb +404 -0
  87. data/lib/buildr/core/generate.rb +197 -0
  88. data/lib/buildr/core/help.rb +119 -0
  89. data/lib/buildr/core/jrebel.rb +42 -0
  90. data/lib/buildr/core/linux.rb +30 -0
  91. data/lib/buildr/core/osx.rb +46 -0
  92. data/lib/buildr/core/progressbar.rb +161 -0
  93. data/lib/buildr/core/project.rb +975 -0
  94. data/lib/buildr/core/run.rb +43 -0
  95. data/lib/buildr/core/shell.rb +137 -0
  96. data/lib/buildr/core/test.rb +843 -0
  97. data/lib/buildr/core/transports.rb +575 -0
  98. data/lib/buildr/core/util.rb +537 -0
  99. data/lib/buildr/groovy.rb +20 -0
  100. data/lib/buildr/groovy/bdd.rb +106 -0
  101. data/lib/buildr/groovy/compiler.rb +153 -0
  102. data/lib/buildr/groovy/doc.rb +76 -0
  103. data/lib/buildr/groovy/shell.rb +57 -0
  104. data/lib/buildr/ide.rb +19 -0
  105. data/lib/buildr/ide/eclipse.rb +427 -0
  106. data/lib/buildr/ide/eclipse/java.rb +53 -0
  107. data/lib/buildr/ide/eclipse/plugin.rb +71 -0
  108. data/lib/buildr/ide/eclipse/scala.rb +68 -0
  109. data/lib/buildr/ide/idea.rb +576 -0
  110. data/lib/buildr/java.rb +25 -0
  111. data/lib/buildr/java/ant.rb +94 -0
  112. data/lib/buildr/java/bdd.rb +460 -0
  113. data/lib/buildr/java/cobertura.rb +297 -0
  114. data/lib/buildr/java/commands.rb +223 -0
  115. data/lib/buildr/java/compiler.rb +135 -0
  116. data/lib/buildr/java/deprecated.rb +141 -0
  117. data/lib/buildr/java/doc.rb +86 -0
  118. data/lib/buildr/java/ecj.rb +69 -0
  119. data/lib/buildr/java/emma.rb +244 -0
  120. data/lib/buildr/java/external.rb +73 -0
  121. data/lib/buildr/java/jruby.rb +122 -0
  122. data/lib/buildr/java/jtestr_result.rb +295 -0
  123. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  124. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  125. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +142 -0
  126. data/lib/buildr/java/packaging.rb +734 -0
  127. data/lib/buildr/java/pom.rb +178 -0
  128. data/lib/buildr/java/rjb.rb +154 -0
  129. data/lib/buildr/java/test_result.rb +101 -0
  130. data/lib/buildr/java/tests.rb +362 -0
  131. data/lib/buildr/java/version_requirement.rb +172 -0
  132. data/lib/buildr/packaging.rb +25 -0
  133. data/lib/buildr/packaging/archive.rb +535 -0
  134. data/lib/buildr/packaging/artifact.rb +904 -0
  135. data/lib/buildr/packaging/artifact_namespace.rb +984 -0
  136. data/lib/buildr/packaging/artifact_search.rb +140 -0
  137. data/lib/buildr/packaging/gems.rb +105 -0
  138. data/lib/buildr/packaging/package.rb +249 -0
  139. data/lib/buildr/packaging/repository_array.rb +108 -0
  140. data/lib/buildr/packaging/tar.rb +189 -0
  141. data/lib/buildr/packaging/version_requirement.rb +192 -0
  142. data/lib/buildr/packaging/zip.rb +178 -0
  143. data/lib/buildr/packaging/ziptask.rb +356 -0
  144. data/lib/buildr/resources/buildr.icns +0 -0
  145. data/lib/buildr/resources/completed.png +0 -0
  146. data/lib/buildr/resources/failed.png +0 -0
  147. data/lib/buildr/resources/icons-license.txt +17 -0
  148. data/lib/buildr/run.rb +195 -0
  149. data/lib/buildr/scala.rb +26 -0
  150. data/lib/buildr/scala/bdd.rb +118 -0
  151. data/lib/buildr/scala/compiler.rb +242 -0
  152. data/lib/buildr/scala/doc.rb +142 -0
  153. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.class +0 -0
  154. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.java +57 -0
  155. data/lib/buildr/scala/shell.rb +52 -0
  156. data/lib/buildr/scala/tests.rb +171 -0
  157. data/lib/buildr/shell.rb +185 -0
  158. data/lib/buildr/version.rb +18 -0
  159. data/rakelib/all-in-one.rake +113 -0
  160. data/rakelib/checks.rake +57 -0
  161. data/rakelib/doc.rake +137 -0
  162. data/rakelib/metrics.rake +39 -0
  163. data/rakelib/package.rake +73 -0
  164. data/rakelib/release.rake +160 -0
  165. data/rakelib/rspec.rake +91 -0
  166. data/rakelib/setup.rake +66 -0
  167. data/rakelib/stage.rake +220 -0
  168. data/spec/addon/bnd_spec.rb +330 -0
  169. data/spec/addon/drb_spec.rb +328 -0
  170. data/spec/addon/jaxb_xjc_spec.rb +125 -0
  171. data/spec/core/application_spec.rb +631 -0
  172. data/spec/core/build_spec.rb +837 -0
  173. data/spec/core/cc_spec.rb +224 -0
  174. data/spec/core/checks_spec.rb +519 -0
  175. data/spec/core/common_spec.rb +725 -0
  176. data/spec/core/compile_spec.rb +658 -0
  177. data/spec/core/doc_spec.rb +195 -0
  178. data/spec/core/extension_spec.rb +201 -0
  179. data/spec/core/generate_spec.rb +33 -0
  180. data/spec/core/project_spec.rb +772 -0
  181. data/spec/core/run_spec.rb +93 -0
  182. data/spec/core/shell_spec.rb +146 -0
  183. data/spec/core/test_spec.rb +1320 -0
  184. data/spec/core/transport_spec.rb +544 -0
  185. data/spec/core/util_spec.rb +141 -0
  186. data/spec/groovy/bdd_spec.rb +80 -0
  187. data/spec/groovy/compiler_spec.rb +251 -0
  188. data/spec/groovy/doc_spec.rb +65 -0
  189. data/spec/ide/eclipse_spec.rb +739 -0
  190. data/spec/ide/idea_spec.rb +1145 -0
  191. data/spec/java/ant_spec.rb +37 -0
  192. data/spec/java/bdd_spec.rb +374 -0
  193. data/spec/java/cobertura_spec.rb +112 -0
  194. data/spec/java/commands_spec.rb +93 -0
  195. data/spec/java/compiler_spec.rb +252 -0
  196. data/spec/java/doc_spec.rb +56 -0
  197. data/spec/java/ecj_spec.rb +115 -0
  198. data/spec/java/emma_spec.rb +121 -0
  199. data/spec/java/external_spec.rb +56 -0
  200. data/spec/java/java_spec.rb +132 -0
  201. data/spec/java/packaging_spec.rb +1266 -0
  202. data/spec/java/run_spec.rb +78 -0
  203. data/spec/java/test_coverage_helper.rb +257 -0
  204. data/spec/java/tests_spec.rb +497 -0
  205. data/spec/packaging/archive_spec.rb +775 -0
  206. data/spec/packaging/artifact_namespace_spec.rb +743 -0
  207. data/spec/packaging/artifact_spec.rb +1074 -0
  208. data/spec/packaging/packaging_helper.rb +63 -0
  209. data/spec/packaging/packaging_spec.rb +719 -0
  210. data/spec/packaging/repository_array_spec.rb +109 -0
  211. data/spec/sandbox.rb +165 -0
  212. data/spec/scala/bdd_spec.rb +124 -0
  213. data/spec/scala/compiler_spec.rb +289 -0
  214. data/spec/scala/doc_spec.rb +88 -0
  215. data/spec/scala/scala.rb +38 -0
  216. data/spec/scala/tests_spec.rb +283 -0
  217. data/spec/spec_helpers.rb +369 -0
  218. data/spec/version_requirement_spec.rb +143 -0
  219. data/spec/xpath_matchers.rb +121 -0
  220. metadata +600 -0
@@ -0,0 +1,116 @@
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
+ # | \ / _ \ | \| |/ _ \_ _| | __| \_ _|_ _| |_ _| || |_ _/ __|
18
+ # | |) | (_) | | .` | (_) || | | _|| |) | | | | | | | __ || |\__ \
19
+ # |___/ \___/ |_|\_|\___/ |_| |___|___/___| |_| |_| |_||_|___|___/
20
+ #
21
+ # ___ ___ _ ___
22
+ # | __|_ _| | | __| CHANGES TO THIS FILE WILL BE LOST
23
+ # | _| | || |__| _| AUTO-GENERATED BY BUILDR on <%= Time.now %>
24
+ # |_| |___|____|___| PREFER TO EDIT JtestR CONFIGURATION FILE:
25
+ #
26
+ # <%= user_config %>
27
+
28
+ begin
29
+ <%= jruby_gem %>
30
+ <%= dependencies.map(&:to_s).inspect %>.each { |dep| $CLASSPATH << dep }
31
+ <%= runner.gems.inspect %>.each { |ary| JRuby.gem(*ary.flatten) }
32
+ <%= runner.requires.inspect %>.each { |rb| Kernel.require rb }
33
+
34
+ jtestr = JtestR::TestRunner.new
35
+
36
+ class << jtestr
37
+ def config(&block)
38
+ @config_blocks ||= []
39
+ @config_blocks << block if block
40
+ @config_blocks
41
+ end
42
+
43
+ def load_configuration
44
+ super
45
+ config.each { |block| @configuration.instance_eval(&block) }
46
+ end
47
+ end
48
+
49
+ jtestr.config do
50
+ classpath [] # already loaded
51
+ add_common_classpath false
52
+
53
+ <% ts = ( @jtestr_tests[:junit] & tests ).map { |c| 'Java.' + c } %>
54
+ junit [<%= ts.join(', ') %>]
55
+
56
+ <% ts = ( @jtestr_tests[:testng] & tests ).map { |c| 'Java.' + c } %>
57
+ testng [<%= ts.join(', ') %>]
58
+
59
+ <% ts = @jtestr_tests[:testunit] & tests %>
60
+ test_unit <%= ts.inspect %>
61
+
62
+ <% ts = @jtestr_tests[:story] & tests %>
63
+ story <%= ts.inspect %>
64
+
65
+ <% ts = @jtestr_tests[:rspec] & tests %>
66
+ rspec <%= ts.inspect %>
67
+
68
+ <% ts = @jtestr_tests[:expect] & tests %>
69
+ expectations <%= ts.inspect %>
70
+
71
+ ignore __FILE__
72
+
73
+ if File.file?(<%= user_config.inspect %>)
74
+ ignore <%= user_config.inspect %>
75
+ load <%= user_config.inspect %>
76
+ end
77
+ end # config
78
+
79
+ fake_out = StringIO.new
80
+
81
+ <% if runner.output == false %>
82
+ output = fake_out
83
+ <% elsif runner.output.kind_of?(String) %>
84
+ output = File.open(<%= result.output.inspect %>, 'w')
85
+ <% else %>
86
+ output = STDOUT
87
+ <% end %>
88
+
89
+ args = [ '<%= spec_dir %>', # the directory to search for jtestr files
90
+ JtestR::SimpleLogger::ERR, # log level (DEBUG/WARN/ERR)
91
+ JtestR::GenericResultHandler::QUIET, #output level (QUIET/VERBOSE)
92
+ fake_out, # output STDOUT
93
+ [], # groups to run
94
+ # Use JtestR::GenericResultHandler for debugging
95
+ Buildr::JtestR::ResultHandler, # result handler
96
+ [] # classpath
97
+ ]
98
+
99
+ argv = <%= runner.rspec.inspect %> || []
100
+ argv.push *<%= tests.inspect %>
101
+ Buildr::JtestR::ResultHandler.init(argv, output, output)
102
+ Buildr::JtestR::ResultHandler.test_files = <%= tests.inspect %>
103
+
104
+ jtestr.run *args
105
+
106
+ rescue => e
107
+ Buildr::TestFramework::TestResult::Error.dump_yaml('<%= runner.result %>', e) rescue \
108
+ puts "-[--- ERROR ---]-", e.class, e.message, *e.backtrace
109
+ end
110
+
111
+ exit 0 # let buildr find the errors from the result yaml
112
+
113
+ # Local Variables:
114
+ # mode: ruby
115
+ # End:
116
+
@@ -0,0 +1,142 @@
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 Throwable {
120
+ Vector testCases = new Vector();
121
+ for (int i = names.length ; i-- > 0 ;) {
122
+ try {
123
+ Class cls = _loader.loadClass(names[i]);
124
+ if (isTest(cls)) { testCases.add(names[i]); }
125
+ } catch (Throwable e) {
126
+ System.err.println("JavaTestFilter: Unable to load class "+names[i]+" to determine testing ability");
127
+ throw e;
128
+ }
129
+ }
130
+ String[] result = new String[testCases.size()];
131
+ testCases.toArray(result);
132
+ return result;
133
+ }
134
+
135
+ }
136
+
137
+ /*
138
+ * Local Variables:
139
+ * indent-tabs-mode: nil
140
+ * c-basic-offset: 2
141
+ * End:
142
+ */
@@ -0,0 +1,734 @@
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