buildr 1.2.10 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. data/CHANGELOG +566 -268
  2. data/DISCLAIMER +7 -1
  3. data/KEYS +151 -0
  4. data/NOTICE +23 -8
  5. data/README +122 -22
  6. data/Rakefile +49 -229
  7. data/{lib → addon}/buildr/antlr.rb +23 -10
  8. data/addon/buildr/cobertura.rb +232 -0
  9. data/{lib → addon}/buildr/hibernate.rb +20 -4
  10. data/{lib → addon}/buildr/javacc.rb +27 -12
  11. data/addon/buildr/jdepend.rb +60 -0
  12. data/{lib → addon}/buildr/jetty.rb +34 -18
  13. data/addon/buildr/nailgun.rb +892 -0
  14. data/{lib → addon}/buildr/openjpa.rb +23 -6
  15. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  16. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  17. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  18. data/{lib/buildr/jetty → addon/buildr/org/apache/buildr}/JettyWrapper.java +19 -0
  19. data/{lib → addon}/buildr/xmlbeans.rb +39 -14
  20. data/bin/buildr +21 -7
  21. data/buildr.gemspec +50 -0
  22. data/doc/css/default.css +225 -0
  23. data/doc/css/print.css +95 -0
  24. data/doc/css/syntax.css +43 -0
  25. data/doc/images/apache-incubator-logo.png +0 -0
  26. data/doc/images/buildr-hires.png +0 -0
  27. data/doc/images/buildr.png +0 -0
  28. data/doc/images/note.png +0 -0
  29. data/doc/images/tip.png +0 -0
  30. data/doc/images/zbuildr.tif +0 -0
  31. data/doc/pages/artifacts.textile +317 -0
  32. data/doc/pages/building.textile +501 -0
  33. data/doc/pages/contributing.textile +178 -0
  34. data/doc/pages/download.textile +25 -0
  35. data/doc/pages/extending.textile +229 -0
  36. data/doc/pages/getting_started.textile +337 -0
  37. data/doc/pages/index.textile +63 -0
  38. data/doc/pages/mailing_lists.textile +17 -0
  39. data/doc/pages/more_stuff.textile +367 -0
  40. data/doc/pages/packaging.textile +592 -0
  41. data/doc/pages/projects.textile +449 -0
  42. data/doc/pages/recipes.textile +127 -0
  43. data/doc/pages/settings_profiles.textile +339 -0
  44. data/doc/pages/testing.textile +475 -0
  45. data/doc/pages/troubleshooting.textile +121 -0
  46. data/doc/pages/whats_new.textile +389 -0
  47. data/doc/print.haml +52 -0
  48. data/doc/print.toc.yaml +28 -0
  49. data/doc/scripts/buildr-git.rb +411 -0
  50. data/doc/scripts/install-jruby.sh +44 -0
  51. data/doc/scripts/install-linux.sh +64 -0
  52. data/doc/scripts/install-osx.sh +52 -0
  53. data/doc/site.haml +55 -0
  54. data/doc/site.toc.yaml +44 -0
  55. data/lib/buildr.rb +28 -45
  56. data/lib/buildr/core.rb +27 -0
  57. data/lib/buildr/core/application.rb +373 -0
  58. data/lib/buildr/core/application_cli.rb +134 -0
  59. data/lib/{core → buildr/core}/build.rb +91 -77
  60. data/lib/{core → buildr/core}/checks.rb +116 -95
  61. data/lib/buildr/core/common.rb +155 -0
  62. data/lib/buildr/core/compile.rb +594 -0
  63. data/lib/buildr/core/environment.rb +120 -0
  64. data/lib/buildr/core/filter.rb +258 -0
  65. data/lib/{core → buildr/core}/generate.rb +22 -5
  66. data/lib/buildr/core/help.rb +118 -0
  67. data/lib/buildr/core/progressbar.rb +156 -0
  68. data/lib/{core → buildr/core}/project.rb +468 -213
  69. data/lib/buildr/core/test.rb +690 -0
  70. data/lib/{core → buildr/core}/transports.rb +107 -127
  71. data/lib/buildr/core/util.rb +235 -0
  72. data/lib/buildr/ide.rb +19 -0
  73. data/lib/{java → buildr/ide}/eclipse.rb +86 -60
  74. data/lib/{java → buildr/ide}/idea.ipr.template +16 -0
  75. data/lib/buildr/ide/idea.rb +194 -0
  76. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  77. data/lib/buildr/ide/idea7x.rb +210 -0
  78. data/lib/buildr/java.rb +26 -0
  79. data/lib/buildr/java/ant.rb +71 -0
  80. data/lib/buildr/java/bdd_frameworks.rb +267 -0
  81. data/lib/buildr/java/commands.rb +210 -0
  82. data/lib/buildr/java/compilers.rb +432 -0
  83. data/lib/buildr/java/deprecated.rb +141 -0
  84. data/lib/buildr/java/groovyc.rb +137 -0
  85. data/lib/buildr/java/jruby.rb +99 -0
  86. data/lib/buildr/java/org/apache/buildr/BuildrNail$Main.class +0 -0
  87. data/lib/buildr/java/org/apache/buildr/BuildrNail.class +0 -0
  88. data/lib/buildr/java/org/apache/buildr/BuildrNail.java +41 -0
  89. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  90. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +116 -0
  91. data/lib/buildr/java/packaging.rb +706 -0
  92. data/lib/{java → buildr/java}/pom.rb +20 -4
  93. data/lib/buildr/java/rjb.rb +142 -0
  94. data/lib/buildr/java/test_frameworks.rb +290 -0
  95. data/lib/buildr/java/version_requirement.rb +172 -0
  96. data/lib/buildr/packaging.rb +21 -0
  97. data/lib/{java → buildr/packaging}/artifact.rb +170 -179
  98. data/lib/buildr/packaging/artifact_namespace.rb +957 -0
  99. data/lib/buildr/packaging/artifact_search.rb +140 -0
  100. data/lib/buildr/packaging/gems.rb +102 -0
  101. data/lib/buildr/packaging/package.rb +233 -0
  102. data/lib/{tasks → buildr/packaging}/tar.rb +18 -1
  103. data/lib/{tasks → buildr/packaging}/zip.rb +153 -105
  104. data/rakelib/apache.rake +126 -0
  105. data/rakelib/changelog.rake +56 -0
  106. data/rakelib/doc.rake +103 -0
  107. data/rakelib/package.rake +44 -0
  108. data/rakelib/release.rake +53 -0
  109. data/rakelib/rspec.rake +81 -0
  110. data/rakelib/rubyforge.rake +45 -0
  111. data/rakelib/scm.rake +49 -0
  112. data/rakelib/setup.rake +59 -0
  113. data/rakelib/stage.rake +45 -0
  114. data/spec/application_spec.rb +316 -0
  115. data/spec/archive_spec.rb +494 -0
  116. data/spec/artifact_namespace_spec.rb +635 -0
  117. data/spec/artifact_spec.rb +738 -0
  118. data/spec/build_spec.rb +193 -0
  119. data/spec/checks_spec.rb +537 -0
  120. data/spec/common_spec.rb +579 -0
  121. data/spec/compile_spec.rb +561 -0
  122. data/spec/groovy_compilers_spec.rb +239 -0
  123. data/spec/java_bdd_frameworks_spec.rb +238 -0
  124. data/spec/java_compilers_spec.rb +446 -0
  125. data/spec/java_packaging_spec.rb +1042 -0
  126. data/spec/java_test_frameworks_spec.rb +414 -0
  127. data/spec/packaging_helper.rb +63 -0
  128. data/spec/packaging_spec.rb +589 -0
  129. data/spec/project_spec.rb +739 -0
  130. data/spec/sandbox.rb +116 -0
  131. data/spec/scala_compilers_spec.rb +239 -0
  132. data/spec/spec.opts +6 -0
  133. data/spec/spec_helpers.rb +283 -0
  134. data/spec/test_spec.rb +871 -0
  135. data/spec/transport_spec.rb +300 -0
  136. data/spec/version_requirement_spec.rb +115 -0
  137. metadata +188 -77
  138. data/lib/buildr/cobertura.rb +0 -89
  139. data/lib/buildr/jdepend.rb +0 -40
  140. data/lib/buildr/jetty/JettyWrapper$1.class +0 -0
  141. data/lib/buildr/jetty/JettyWrapper$BuildrHandler.class +0 -0
  142. data/lib/buildr/jetty/JettyWrapper.class +0 -0
  143. data/lib/buildr/scala.rb +0 -368
  144. data/lib/core/application.rb +0 -188
  145. data/lib/core/common.rb +0 -562
  146. data/lib/core/help.rb +0 -72
  147. data/lib/core/rake_ext.rb +0 -81
  148. data/lib/java/ant.rb +0 -71
  149. data/lib/java/compile.rb +0 -589
  150. data/lib/java/idea.rb +0 -159
  151. data/lib/java/java.rb +0 -432
  152. data/lib/java/packaging.rb +0 -581
  153. data/lib/java/test.rb +0 -795
  154. data/lib/tasks/concat.rb +0 -35
@@ -0,0 +1,63 @@
1
+ h1. Welcome
2
+
3
+ Buildr is a build system for Java applications. We wanted something that's
4
+ simple and intuitive to use, so we only need to tell it what to do, and it
5
+ takes care of the rest. But also something we can easily extend for those
6
+ one-off tasks, with a language that's a joy to use. And of course, we wanted
7
+ it to be fast, reliable and have outstanding dependency management.
8
+
9
+ Here's what we got:
10
+
11
+ * A simple way to specify projects, and build large projects out of smaller
12
+ sub-projects.
13
+ * Pre-canned tasks that require the least amount of configuration, keeping the
14
+ build script DRY and simple.
15
+ * Compiling, copying and filtering resources, JUnit/TestNG test cases, APT
16
+ source code generation, Javadoc and more.
17
+ * A dependency mechanism that only builds what has changed since the last
18
+ release.
19
+ * A drop-in replacement for Maven 2.0, Buildr uses the same file layout,
20
+ artifact specifications, local and remote repositories.
21
+ * All your Ant tasks belong to us! Anything you can do with Ant, you can do
22
+ with Buildr.
23
+ * No overhead for building "plugins" or configuration. Just write new tasks or
24
+ functions.
25
+ * Buildr is Ruby all the way down. No one-off task is too demanding when you
26
+ write code using variables, functions and objects.
27
+ * Simple way to upgrade to new versions.
28
+ * Did we mention fast?
29
+
30
+
31
+ h2. News
32
+
33
+ Check out "all that's new in Buildr 1.3":whats_new.html.
34
+
35
+ * Buildr 1.3 now runs on JRuby 1.1
36
+ * Support for building Scala projects
37
+ * Support for building Groovy projects
38
+ * EAR packages
39
+ * Behaviour-Driven Development frameworks
40
+ * Profiles
41
+ * New API for accessing Java libraries
42
+ * Alternative source layouts
43
+ * More documentation
44
+ * Other features and bug fixes.
45
+
46
+
47
+ h2. Notices
48
+
49
+ The Apache Software Foundation is a non-profit organization, consider
50
+ "sponsoring":http://www.apache.org/foundation/sponsorship.html and check the
51
+ "thanks":http://www.apache.org/foundation/thanks.html page.
52
+
53
+ Apache Buildr is an effort undergoing incubation at The Apache Software
54
+ Foundation (ASF), sponsored by the Apache Incubator. Incubation is required of
55
+ all newly accepted projects until a further review indicates that the
56
+ infrastructure, communications, and decision making process have stabilized in
57
+ a manner consistent with other successful ASF projects. While incubation status
58
+ is not necessarily a reflection of the completeness or stability of the code,
59
+ it does indicate that the project has yet to be fully endorsed by the ASF.
60
+
61
+ "ColorCons":http://www.mouserunner.com/Spheres_ColoCons1_Free_Icons.html,
62
+ copyright of Ken Saunders. "DejaVu fonts":http://dejavu.sourceforge.net,
63
+ copyright of Bitstream, Inc.
@@ -0,0 +1,17 @@
1
+ h1. Mailing Lists
2
+
3
+
4
+ |_. buildr-user |_. For developers working with Buildr |
5
+ | Post | "buildr-user@incubator.apache.org":mailto:buildr-user@incubator.apache.org |
6
+ | Browse | "buildr-user archives":http://mail-archives.apache.org/mod_mbox/incubator-buildr-user/ |
7
+ | Subscribe | "buildr-user-subscribe@incubator.apache.org":mailto:buildr-user-subscribe@incubator.apache.org |
8
+ | Unsubscribe | "buildr-user-unsubscribe@incubator.apache.org":mailto:buildr-user-unsubscribe@incubator.apache.org |
9
+ |_. buildr-dev |_. For development of Buildr itself |
10
+ | Post | "buildr-dev@incubator.apache.org":mailto:buildr-dev@incubator.apache.org |
11
+ | Browse | "buildr-dev archives":http://mail-archives.apache.org/mod_mbox/incubator-buildr-dev/ |
12
+ | Subscribe | "buildr-dev-subscribe@incubator.apache.org":mailto:buildr-dev-subscribe@incubator.apache.org |
13
+ | Unsubscribe | "buildr-dev-unsubscribe@incubator.apache.org":mailto:buildr-dev-unsubscribe@incubator.apache.org |
14
+ |_. buildr-commits |_. Commit messages and JIRA status |
15
+ | Subscribe | "buildr-commits-subscribe@incubator.apache.org":mailto:buildr-commits-subscribe@incubator.apache.org |
16
+ | Unsubscribe | "buildr-commits-unsubscribe@incubator.apache.org":mailto:buildr-commits-unsubscribe@incubator.apache.org |
17
+ | Browse | "buildr-commits archives":http://mail-archives.apache.org/mod_mbox/incubator-buildr-commits/ |
@@ -0,0 +1,367 @@
1
+ h1. More Stuff
2
+
3
+
4
+ h2. Using Gems
5
+
6
+ The purpose of the buildfile is to define your projects, and the various tasks
7
+ and functions used for building them. Some of these are specific to your
8
+ projects, others are more general in nature, and you may want to share them
9
+ across projects.
10
+
11
+ There are several mechanisms for developing extensions and build features
12
+ across projects which we cover in more details in the section "Extending
13
+ Buildr":extending.html. Here we will talk about using extensions that are
14
+ distributed in the form of RubyGems.
15
+
16
+ "RubyGems":http://rubygems.rubyforge.org provides the @gem@ command line tool
17
+ that you can use to search, install, upgrade, package and distribute gems. It
18
+ installs all gems into a local repository that is shared across your builds and
19
+ all other Ruby applications you may have running. You can install a gem from a
20
+ local file, or download and install it from any number of remote repositories.
21
+
22
+ RubyGems is preconfigured to use the "RubyForge":http://rubyforge.org
23
+ repository. You'll find a large number of open source Ruby libraries there,
24
+ including Buildr itself and all its dependencies. RubyForge provides a free
25
+ account that you can use to host your projects and distribute your gems (you
26
+ can use RubyForge strictly for distribution, as we do with Buildr).
27
+
28
+ You can also set up your own private repository and use it instead or in
29
+ addition to RubyForge. Use the @gem sources@ command to add repositories, and
30
+ the @gem server@ command to run a remote repository. You can see all available
31
+ options by running @gem help@.
32
+
33
+ If your build depends on other gems, you will want to specify these
34
+ dependencies as part of your build and check that configuration into source
35
+ control. That way you can have a specific environment that will guarantee
36
+ repeatable builds, whether you're building a particular version, moving between
37
+ branches, or joining an existing project. Buildr will take care of installing
38
+ all the necessary dependencies, which you can then manage with the @gem@
39
+ command.
40
+
41
+ Use the @build.yaml@ file to specify these dependencies (see "Build
42
+ Settings":settings_profiles.html#build_settings for more information), for
43
+ example:
44
+
45
+ {{{!yaml
46
+ # This project requires the following gems
47
+ gems:
48
+ # Suppose we want to notify developers when testcases fail.
49
+ - buildr-twitter-notifier-addon >=1
50
+ # we test with ruby mock objects
51
+ - mocha
52
+ - ci_reporter
53
+ }}}
54
+
55
+ Gems contain executable code, and for that reason Buildr will not install gems
56
+ without your permission. When you run a build that includes any dependencies
57
+ that are not already installed on your machine, Buildr will ask for permission
58
+ before installing them. On Unix-based operating systems, you will also need
59
+ sudo privileges and will be asked for your password before proceeding.
60
+
61
+ Since this step requires your input, it will only happen when running Buildr
62
+ interactively from the command line. In all other cases, Buildr will fail and
63
+ report the missing dependencies. If you have an automated build environment,
64
+ make sure to run the build once manually to install all the necessary
65
+ dependencies.
66
+
67
+ When installing a gem for the first time, Buildr will automatically look for
68
+ the latest available version. You can specify a particular version number, or
69
+ a set of version numbers known to work with that build. You can use equality
70
+ operations to specify a range of versions, for example, @1.2.3@ to install only
71
+ version 1.2.3, and @=> 1.2.3@ to install version 1.2.3 or later.
72
+
73
+ You can also specify a range up to one version bump, for example, @~> 1.2.3@ is
74
+ the same as @>= 1.2.3 < 1.3.0@, and @~> 1.2@ is the same as @>= 1.2.0 < 2.0.0@.
75
+ If necessary, you can exclude a particular version number, for example, @~>
76
+ 1.2.3 != 1.2.7@.
77
+
78
+ Buildr will install the latest version that matches the version requirement.
79
+ To keep up with newer versions, execute the @gem update@ command periodically.
80
+ You can also use @gem outdated@ to determine which new versions are available.
81
+
82
+ Most gems include documentation that you can access in several forms. You can
83
+ use the @ri@ command line tool to find out more about a class, module or
84
+ specific method. For example:
85
+
86
+ {{{!sh
87
+ $ ri Buildr::Jetty
88
+ $ ri Buildr::Jetty.start
89
+ }}}
90
+
91
+ You can also access documentation from a Web browser by running @gem server@
92
+ and pointing your browser to "http://localhost:8808":http://localhost:8808.
93
+ Note that after installing a new gem, you will need to restart the gem server
94
+ to see its documentation.
95
+
96
+
97
+ h2. Using Java Libraries
98
+
99
+ Buildr runs along side a JVM, using either RJB or JRuby. The Java module
100
+ allows you to access Java classes and create Java objects.
101
+
102
+ Java classes are accessed as static methods on the @Java@ module, for example:
103
+
104
+ {{{!ruby
105
+ str = Java.java.lang.String.new('hai!')
106
+ str.toUpperCase
107
+ => 'HAI!'
108
+ Java.java.lang.String.isInstance(str)
109
+ => true
110
+ Java.com.sun.tools.javac.Main.compile(args)
111
+ }}}
112
+
113
+ The @classpath@ attribute allows Buildr to add JARs and directories to the
114
+ classpath, for example, we use it to load Ant and various Ant tasks, code
115
+ generators, test frameworks, and so forth.
116
+
117
+ When using an artifact specification, Buildr will automatically download and
118
+ install the artifact before adding it to the classpath.
119
+
120
+ For example, Ant is loaded as follows:
121
+
122
+ {{{!ruby
123
+ Java.classpath << 'org.apache.ant:ant:jar:1.7.0'
124
+ }}}
125
+
126
+ Artifacts can only be downloaded after the Buildfile has loaded, giving it a
127
+ chance to specify which remote repositories to use, so adding to classpath does
128
+ not by itself load any libraries. You must call @Java.load@ before accessing any
129
+ Java classes to give Buildr a chance to load the libraries specified in the
130
+ classpath.
131
+
132
+ When building an extension, make sure to follow these rules:
133
+
134
+ # Add to the @classpath@ when the extension is loaded (i.e. in module or class
135
+ definition), so the first call to @Java.load@ anywhere in the code will include
136
+ the libraries you specify.
137
+ # Call @Java.load@ once before accessing any Java classes, allowing Buildr to
138
+ set up the classpath.
139
+ # Only call @Java.load@ when invoked, otherwise you may end up loading the JVM
140
+ with a partial classpath, or before all remote repositories are listed.
141
+ # Check on a clean build with empty local repository.
142
+
143
+
144
+ h2. Nailgun
145
+
146
+ "Nailgun":http://www.martiansoftware.com/nailgun/index.html is a client,
147
+ protocol, and server for running Java programs from the command line without
148
+ incurring the JVM startup overhead.
149
+ Nailgun integration is available only when running Buildr within JRuby.
150
+
151
+ Buildr provides a custom nailgun server, allowing you to start a single JVM
152
+ and let buildr create a queue of runtimes.
153
+ These JRuby runtimes can be cached (indexed by buildfile path) and are
154
+ automatically reloaded when the buildfile has been modified.
155
+ Runtime caching allows you to execute tasks without spending time creating
156
+ the buildr environment.
157
+
158
+ Start the BuildrServer by executing
159
+
160
+ {{{!ruby
161
+ $ jruby -S buildr -rbuildr/nailgun nailgun:start
162
+ }}}
163
+
164
+ Server output will display a message when it becomes ready, you
165
+ will also see messages when the JRuby runtimes are being created,
166
+ or when a new buildr environment is being loaded on them.
167
+ After the runtime queues have been populated, you can start calling
168
+ buildr as you normally do, by invoking the $NAILGUN_HOME/ng binary:
169
+
170
+ {{{!sh
171
+ # on another terminal, change directory to a project.
172
+ # if this project is the same nailgun:start was invoked on, it's
173
+ # runtime has been cached, so no loading is performed unless
174
+ # the buildfile has been modified. otherwise the buildfile
175
+ # will be loaded on a previously loaded fresh-buildr runtime
176
+ # and it will be cached.
177
+ cd /some/buildr/project
178
+ ng nailgun:help # display nailgun help
179
+ ng nailgun:tasks # display overview of ng tasks
180
+ ng clean compile # just invoke those two tasks
181
+ }}}
182
+
183
+ Some nailgun tasks have been provided to manage the cached runtimes,
184
+ to get an overview of them execute the @nailgun:tasks@ task.
185
+
186
+ Be sure to read the nailgun help by executing the @nailgun:help@ task.
187
+
188
+
189
+ h2. Eclipse, IDEA
190
+
191
+ If you're using Eclipse, you can generate @.classpath@ and @.project@ from
192
+ your Buildfile and use them to create a project in your workspace:
193
+
194
+ {{{!sh
195
+ $ buildr eclipse
196
+ }}}
197
+
198
+ The @eclipse@ task will generate a @.classpath@ and @.project@ file for each
199
+ of projects (and sub-project) that compiles source code. It will not generate
200
+ files for other projects, for examples, projects you use strictly for
201
+ packaging a distribution, or creating command line scripts, etc.
202
+
203
+ If you add a new project, change the dependencies, or make any other change to
204
+ your Buildfile, just run the @eclipse@ task again to re-generate the Eclipse
205
+ project files.
206
+
207
+ If you prefer IntelliJ IDEA, you can always:
208
+
209
+ {{{!sh
210
+ $ buildr idea
211
+ }}}
212
+
213
+ It will generate a @.iml@ file for every project (or subproject) and a @.ipr@
214
+ that you can directly open for the root project. To allow IntelliJ Idea to
215
+ resolve external dependencies properly, you will need to add a @M2_REPO@
216
+ variable pointing to your Maven2 repository directory (@Settings / Path
217
+ Variables@).
218
+
219
+ If you're using IDEA 7 or later, use the @buildr idea7x@ task instead. This
220
+ task creates the proper @.ipr@ and @.iml@ files for IDEA version 7. It
221
+ includes the @-7x@ suffix in the generated files, so you can use the @idea@ and
222
+ @idea7x@ tasks side by side on the same project.
223
+
224
+ Also, check out the "Buildr plugin for
225
+ IDEA":http://www.digitalsanctum.com/buildr-plug-in/ (IDEA 7 and later). Once
226
+ installed, open your project with IDEA. If IDEA finds that you have Buildr
227
+ installed and finds a buildfile in the project's directory, it will show all
228
+ the tasks available for that project. To run a task, double-click it. When
229
+ the task completes, IDEA will show the results in the Buildr Output window.
230
+
231
+
232
+ h2. Cobertura, JDepend
233
+
234
+ You can use "Cobertura":http://cobertura.sourceforge.net/ to instrument your
235
+ code, run the tests and create a test coverage report in either HTML or XML
236
+ format.
237
+
238
+ There are two tasks, both of which generate a test coverage report in the
239
+ @reports/cobertura@ directory. For example:
240
+
241
+ {{{!sh
242
+ $ buildr test cobertura:html
243
+ }}}
244
+
245
+ As you can guess, the other task is @cobertura:xml@.
246
+
247
+ If you want to generate cobertura reports only for a specific project, you
248
+ can do so by using the project name as prefix to cobertura tasks.
249
+
250
+ {{{!sh
251
+ $ buildr subModule:cobertura:html
252
+ }}}
253
+
254
+ Each project can specify which classes to include or exclude from cobertura
255
+ instrumentation by giving a class-name regexp to the @cobertura.include@ or
256
+ @cobertura.exclude@ methods:
257
+
258
+ {{{!ruby
259
+ define 'someModule' do
260
+ cobertura.include 'some.package.*'
261
+ cobertura.include /some.(foo|bar).*/
262
+ cobertura.exclude 'some.foo.util.SimpleUtil'
263
+ cobertura.exclude /*.Const(ants)?/i
264
+ end
265
+ }}}
266
+
267
+ You can use "JDepend":http://clarkware.com/software/JDepend.html on to
268
+ generate design quality metrics. There are three tasks this time, the eye
269
+ candy one:
270
+
271
+ {{{!sh
272
+ $ buildr jdepend:swing
273
+ }}}
274
+
275
+ The other two tasks are @jdepend:text@ and @jdepend:xml@.
276
+
277
+ We want Buildr to load fast, and not everyone cares for these tasks, so we
278
+ don't include them by default. If you want to use either one, you need to
279
+ require it explicitly. The proper way to do it in Ruby:
280
+
281
+ {{{!ruby
282
+ require 'buildr/cobertura'
283
+ require 'buildr/jdepend'
284
+ }}}
285
+
286
+ You may want to add those to the Buildfile. Alternatively, you can use these
287
+ tasks for all your projects without modifying the Buildfile. One convenient
288
+ method is to add these two likes to the @buildr.rb@ file in your home
289
+ directory.
290
+
291
+ Another option is to require it from the command line (@--require@ or @-r@),
292
+ for example:
293
+
294
+ {{{!sh
295
+ $ buildr --require buildr/jdepend jdepend:swing
296
+ $ buildr -rbuildr/cobertura cobertura:html
297
+ }}}
298
+
299
+
300
+ h2. Anything Ruby Can Do
301
+
302
+ Buildr is Ruby code. That's an implementation detail for some, but a useful
303
+ features for others. You can use Ruby to keep your build scripts simple and
304
+ DRY, tackle ad hoc tasks and write reusable features without the complexity of
305
+ "plugins".
306
+
307
+ We already showed you one example where Ruby could help. You can use Ruby to
308
+ manage dependency by setting constants and reusing them, grouping related
309
+ dependencies into arrays and structures.
310
+
311
+ You can use Ruby to perform ad hoc tasks. For example, Buildr doesn't have
312
+ any pre-canned task for setting file permissions. But Ruby has a method for
313
+ that, so it's just a matter of writing a task:
314
+
315
+ {{{!ruby
316
+ bins = file('target/bin'=>FileList[_('src/main/dist/bin/*')]) do |task|
317
+ mkpath task.name
318
+ cp task.prerequisites, task.name
319
+ chmod 0755, FileList[task.name + '/*.sh'], :verbose=>false
320
+ end
321
+ }}}
322
+
323
+ You can use functions to keep your code simple. For example, in the ODE
324
+ project we create two binary distributions, both of which contain a common set
325
+ of files, and one additional file unique to each distribution. We use a
326
+ method to define the common distribution:
327
+
328
+ {{{!ruby
329
+ def distro(project, id)
330
+ project.package(:zip, :id=>id).path("#{id}-#{version}").tap do |zip|
331
+ zip.include meta_inf + ['RELEASE_NOTES', 'README'].map { |f| path_to(f) }
332
+ zip.path('examples').include project.path_to(:source, :examples), :as=>'.'
333
+ zip.merge project('ode:tools-bin').package(:zip)
334
+ zip.path('lib').include artifacts(COMMONS.logging, COMMONS.codec,
335
+ COMMONS.httpclient, COMMONS.pool, COMMONS.collections, JAXEN, SAXON,
336
+ LOG4J, WSDL4J, XALAN, XERCES)
337
+ project('ode').projects('utils', 'tools', 'bpel-compiler', 'bpel-api',
338
+ 'bpel-obj', 'bpel-schemas').map(&:packages).flatten.each do |pkg|
339
+ zip.include(pkg.to_s, :as=>"#{pkg.id}.#{pkg.type}", :path=>'lib')
340
+ end
341
+ yield zip
342
+ end
343
+ end
344
+ }}}
345
+
346
+ And then use it in the project definition:
347
+
348
+ {{{!ruby
349
+ define 'distro-axis2' do
350
+ parent.distro(self, "#{parent.id}-war") { |zip|
351
+ zip.include project('ode:axis2-war').package(:war), :as=>'ode.war' }
352
+ end
353
+ }}}
354
+
355
+ Ruby's functional style and blocks make some task extremely easy. For
356
+ example, let's say we wanted to count how many source files we have, and total
357
+ number of lines:
358
+
359
+ {{{!ruby
360
+ sources = projects.map { |prj| prj.compile.sources.
361
+ map { |src| FileList["#{src}/**/*.java"] } }.flatten
362
+ puts "There are #{source.size} source files"
363
+ lines = sources.inject(0) { |lines, src| lines += File.readlines(src).size }
364
+ puts "That contain #{lines} lines"
365
+ }}}
366
+
367
+
@@ -0,0 +1,592 @@
1
+ h1. Packaging
2
+
3
+ For our next trick, we're going to try and create an artifact ourselves. We're
4
+ going to start with:
5
+
6
+ {{{!ruby
7
+ package :jar
8
+ }}}
9
+
10
+ We just told the project to create a JAR file in the @target@ directory,
11
+ including all the classes (and resources) that we previously compiled into
12
+ @target/classes@. Or we can create a WAR file:
13
+
14
+ {{{!ruby
15
+ package :war
16
+ }}}
17
+
18
+ The easy case is always easy, but sometimes we have more complicated use cases
19
+ which we'll address through the rest of this section.
20
+
21
+ Now let's run the build, test cases and create these packages:
22
+
23
+ {{{!sh
24
+ $ buildr package
25
+ }}}
26
+
27
+ The @package@ task runs the @build@ task (remember: @compile@ and @test@) and
28
+ then runs each of the packaging tasks, creating packages in the projects'
29
+ target directories.
30
+
31
+ p(tip). The @package@ task and @package@ methods are related, but that relation is
32
+ different from other task/method pairs. The @package@ method creates a file
33
+ task that points to the package in the @target@ directory and knows how to
34
+ create it. It then adds itself as a prerequisite to the @package@ task.
35
+ Translation: you can create multiple packages from the same project.
36
+
37
+
38
+ h2. Specifying And Referencing Packages
39
+
40
+ Buildr supports several packaging types, and so when dealing with packages, you
41
+ have to indicate the desired package type. The packaging type can be the first
42
+ argument, or the value of the @:type@ argument. The following two are
43
+ equivalent:
44
+
45
+ {{{!ruby
46
+ package :jar
47
+ package :type=>:jar
48
+ }}}
49
+
50
+ If you do not specify a package type, Buildr will attempt to infer one.
51
+
52
+ In the documentation you will find a number of tasks dealing with specific
53
+ packaging types (@ZipTask@, @JarTask@, etc). The @package@ method is a
54
+ convenience mechanism that sets up the package for you associates it with
55
+ various project life cycle tasks.
56
+
57
+ To package a particular file, use the @:file@ argument, for example:
58
+
59
+ {{{!ruby
60
+ package :zip, :file=>_('target/interesting.zip')
61
+ }}}
62
+
63
+ This returns a file task that will run as part of the project's @package@ task
64
+ (generating all packages). It will invoke the @build@ task to generate any
65
+ necessary prerequisites, before creating the specified file.
66
+
67
+ The package type does not have to be the same as the file name extension, but
68
+ if you don't specify the package type, it will be inferred from the extension.
69
+
70
+ Most often you will want to use the second form to generate packages that are
71
+ also artifacts. These packages have an artifact specification, which you can
72
+ use to reference them from other projects (and buildfiles). They are also
73
+ easier to share across projects: artifacts install themselves in the local
74
+ repository when running the @install@ task, and upload to the remote repository
75
+ when running the @upload@ task (see "Installing and
76
+ Uploading":#installing_and_uploading).
77
+
78
+ The artifact specification is based on the project name (using dashes instead
79
+ of colons), group identifier and version number, all three obtained from the
80
+ project definition. You can specify different values using the @:id@,
81
+ @:group@, @:version@ and @:classifier@ arguments. For example:
82
+
83
+ {{{!ruby
84
+ define 'killer-app', :version=>'1.0' do
85
+ # Generates silly-1.0.jar
86
+ package :jar, :id=>'silly'
87
+
88
+ # Generates killer-app-la-web-1.x.war
89
+ project 'la-web' do
90
+ package :war, :version=>'1.x'
91
+ end
92
+
93
+ # Generates killer-app-the-api-1.0-sources.zip
94
+ project 'teh-api' do
95
+ package :zip, :classifier=>'sources'
96
+ end
97
+ end
98
+ }}}
99
+
100
+ The file name is determined from the identifier, version number, classifier and
101
+ extension associated with that packaging type.
102
+
103
+ If you do not specify the packaging type, Buildr attempt to infer it from the
104
+ project definition. In the general case it will use the default packaging
105
+ type, ZIP. A project that compiles Java classes will default to JAR packaging;
106
+ for other languages, consult the specific documentation.
107
+
108
+ A single project can create multiple packages. For example, a Java project may
109
+ generate a JAR package for the runtime library and another JAR containing just
110
+ the API; a ZIP file for the source code and another ZIP for the documentation.
111
+ Make sure to always call @package@ with enough information to identify the
112
+ specific package you are referencing. Even if the project only defines a
113
+ single package, calling the @package@ method with no arguments does not
114
+ necessarily refer to that one.
115
+
116
+ You can use the @packages@ method to obtain a list of all packages defined in
117
+ the project, for example:
118
+
119
+ {{{!ruby
120
+ project('killer-app:teh-impl').packages.first
121
+ project('killer-app:teh-impl').packages.select { |pkg| pkg.type == :zip }
122
+ }}}
123
+
124
+
125
+ h2. Packaging ZIPs
126
+
127
+ ZIP is the most common form of packaging, used by default when no other
128
+ packaging type applies. It also forms the basis for many other packaging types
129
+ (e.g. JAR and WAR). Most of what you'll find here applies to other packaging
130
+ types.
131
+
132
+ Let's start by including additional files in the ZIP package. We're going to
133
+ include the @target/docs@ directory and @README@ file:
134
+
135
+ {{{!ruby
136
+ package(:zip).include _('target/docs'), 'README'
137
+ }}}
138
+
139
+ The @include@ method accepts files, directories and file tasks. You can also
140
+ use file pattern to match multiple files and directories. File patterns
141
+ include asterisk (@*@) to match any file name or part of a file name, double
142
+ asterisk (@**@) to match directories recursively, question mark (@?@) to match
143
+ any character, square braces (@[]@) to match a set of characters, and curly
144
+ braces (@{}@) to match one of several names.
145
+
146
+ And the same way you @include@, you can also @exclude@ specific files you don't
147
+ want showing up in the ZIP. For example, to exclude @.draft@ and @.raw@ files:
148
+
149
+ {{{!ruby
150
+ package(:zip).include('target/docs').
151
+ exclude('target/docs/**/*.{draft,raw}')
152
+ }}}
153
+
154
+ So far we've included files under the root of the ZIP. Let's include some
155
+ files under a given path using the @:path@ option:
156
+
157
+ {{{!ruby
158
+ package(:zip).include 'target/docs', :path=>"#{id}-#{version}"
159
+ }}}
160
+
161
+ If you need to use the @:path@ option repeatedly, consider using the @tap@
162
+ method instead. For example:
163
+
164
+ {{{!ruby
165
+ package(:zip).path("#{id}-#{version}").tap do |path|
166
+ path.include 'target/docs'
167
+ path.include 'README'
168
+ end
169
+ }}}
170
+
171
+ p(tip). The @tap@ method is not part of the core library, but a very useful
172
+ extension. It takes an object, yields to the block with that object, and then
173
+ returns that object.
174
+
175
+ p(note). To allow you to spread files across different paths, the
176
+ include/exclude patterns are specific to a path. So in the above example, if
177
+ you want to exclude some files from the "target/docs" directory, make sure to
178
+ call @exclude@ on the path, not on the ZIP task itself.
179
+
180
+ If you need to include a file or directory under a different name, use the
181
+ @:as@ option. For example:
182
+
183
+ {{{!ruby
184
+ package(:zip).include('corporate-logo-350x240.png', :as=>'logo.png')
185
+ }}}
186
+
187
+ You can also use @:as=>'.'@ to include all files from the given directory. For
188
+ example:
189
+
190
+ {{{!ruby
191
+ package(:zip).include 'target/docs/*'
192
+ package(:zip).include 'target/docs', :as=>'.'
193
+ }}}
194
+
195
+ These two are almost identical. They both include all the files from the
196
+ @target/docs@ directory, but not the directory itself. But they operate
197
+ differently. The first line expands to include all the files in @target/docs@.
198
+ If you don't already have files in @target/docs@, well, then it won't do
199
+ anything interesting. Your ZIP will come up empty. The second file includes
200
+ the directory itself, but strips the path during inclusion. You can define it
201
+ now, create these files later, and then ZIP them all up.
202
+
203
+ For example, when @package :jar@ decides to include all the files from
204
+ @target/classes@, it's still working on the project definition, and has yet to
205
+ compile anything. Since @target/classes@ may be empty, may not even exist, it
206
+ uses @:as=>'.'@.
207
+
208
+ If you need to get rid of all the included files, call the @clean@ method.
209
+ Some packaging types default to adding various files and directories, for
210
+ example, JAR packaging will include all the compiled classes and resources.
211
+
212
+ You can also merge two ZIP files together, expanding the content of one ZIP
213
+ into the other. For example:
214
+
215
+ {{{!ruby
216
+ package(:zip).merge 'part1.zip', 'part2.zip'
217
+ }}}
218
+
219
+ If you need to be more selective, you can apply the include/exclude pattern to
220
+ the expanded ZIP. For example:
221
+
222
+ {{{!ruby
223
+ # Everything but the libs
224
+ package(:zip).merge('bigbad.war').exclude('libs/**/*')
225
+ }}}
226
+
227
+
228
+ h2. Packaging JARs
229
+
230
+ JAR packages extend ZIP packages with support for Manifest files and the
231
+ META-INF directory. They also default to include the class files found in the
232
+ @target/classes@ directory.
233
+
234
+ You can tell the JAR package to include a particular Manifest file:
235
+
236
+ {{{!ruby
237
+ package(:jar).with :manifest=>_('src/main/MANIFEST.MF')
238
+ }}}
239
+
240
+ Or generate a manifest from a hash:
241
+
242
+ {{{!ruby
243
+ package(:jar).with :manifest=>{ 'Copyright'=>'Acme Inc (C) 2007' }
244
+ }}}
245
+
246
+ You can also generate a JAR with no manifest with the value @false@, create a
247
+ manifest with several sections using an array of hashes, or create it from a
248
+ proc.
249
+
250
+ In large projects, where all the packages use the same manifest, it's easier to
251
+ set it once on the top project using the @manifest@ project property.
252
+ Sub-projects inherit the property from their parents, and the @package@ method
253
+ uses that property if you don't override it, as we do above.
254
+
255
+ For example, we can get the same result by specifying this at the top project:
256
+
257
+ {{{!ruby
258
+ manifest['Copyright'] = 'Acme Inc (C) 2007'
259
+ }}}
260
+
261
+ If you need to mix-in the project's manifest with values that only one package
262
+ uses, you can do so easily:
263
+
264
+ {{{!ruby
265
+ package(:jar).with :manifest=>manifest.merge('Main-Class'=>'com.acme.Main')
266
+ }}}
267
+
268
+ If you need to include more files in the @META-INF@ directory, you can use the
269
+ @:meta_inf@ option. You can give it a file, or array of files. And yes, there
270
+ is a @meta_inf@ project property you can set once to include the same set of
271
+ file in all the JARs. It works like this:
272
+
273
+ {{{!ruby
274
+ meta_inf << file('DISCLAIMER') << file('NOTICE')
275
+ }}}
276
+
277
+ If you have a @LICENSE@ file, it's already included in the @meta_inf@ list of
278
+ files.
279
+
280
+ Other than that, @package :jar@ includes the contents of the compiler's target
281
+ directory and resources, which most often is exactly what you intend it to do.
282
+ If you want to include other files in the JAR, instead or in addition, you can
283
+ do so using the @include@ and @exclude@ methods. If you do not want the target
284
+ directory included in your JAR, simply call the @clean@ method on it:
285
+
286
+ {{{!ruby
287
+ package(:jar).clean.include( only_these_files )
288
+ }}}
289
+
290
+
291
+ h2. Packaging WARs
292
+
293
+ Pretty much everything you know about JARs works the same way for WARs, so
294
+ let's just look at the differences.
295
+
296
+ Without much prompting, @package :war@ picks the contents of the
297
+ @src/main/webapp@ directory and places it at the root of the WAR, copies the
298
+ compiler target directory into the @WEB-INF/classes@ path, and copies any
299
+ compiled dependencies into the @WEB-INF/libs@ paths.
300
+
301
+ Again, you can use the @include@ and @exclude@ methods to change the contents
302
+ of the WAR. There are two convenience options you can use to make the more
303
+ common changes. If you need to include a classes directory other than the
304
+ default:
305
+
306
+ {{{!ruby
307
+ package(:war).with :classes=>_('target/additional')
308
+ }}}
309
+
310
+ If you want to include a different set of libraries other than the default:
311
+
312
+ {{{!ruby
313
+ package(:war).with :libs=>MYSQL_JDBC
314
+ }}}
315
+
316
+ Both options accept a single value or an array. The @:classes@ option accepts
317
+ the name of a directory containing class files, initially set to
318
+ @compile.target@ and @resources.target@. The @:libs@ option accepts artifact
319
+ specifications, file names and tasks, initially set to include everything in
320
+ @compile.dependencies@.
321
+
322
+ As you can guess, the package task has two attributes called @classes@ and
323
+ @libs@; the @with@ method merely sets their value. If you need more precise
324
+ control over these arrays, you can always work with them directly, for example:
325
+
326
+ {{{!ruby
327
+ # Add an artifact to the existing set:
328
+ package(:war).libs += artifacts(MYSQL_JDBC)
329
+ # Remove an artifact from the existing set:
330
+ package(:war).libs -= artifacts(LOG4J)
331
+ # List all the artifacts:
332
+ puts 'Artifacts included in WAR package:'
333
+ puts package(:war).libs.map(&:to_spec)
334
+ }}}
335
+
336
+
337
+ h2. Packaging AARs
338
+
339
+ Axis2 service archives are similar to JAR's (compiled classes go into the root
340
+ of the archive) but they can embed additional libraries under /lib and include
341
+ @services.xml@ and WSDL files.
342
+
343
+ {{{!ruby
344
+ package(:aar).with(:libs=>'log4j:log4j:jar:1.1')
345
+ package(:aar).with(:services_xml=>_('target/services.xml'), :wsdls=>_('target/*.wsdl'))
346
+ }}}
347
+
348
+ The @libs@ attribute is a list of .jar artifacts to be included in the archive
349
+ under /lib. The default is no artifacts; compile dependencies are not included
350
+ by default.
351
+
352
+ The @services_xml@ attribute points to an Axis2 services configuration file
353
+ called @services.xml@ that will be placed in the @META-INF@ directory inside
354
+ the archive. The default behavior is to point to the @services.xml@ file in
355
+ the project's @src/main/axis2@ directory. In the second example above we set
356
+ it explicitly.
357
+
358
+ The @wsdls@ attribute is a collection of file names or glob patterns for WSDL
359
+ files that get included in the @META-INF@ directory. In the second example we
360
+ include WSDL files from the @target@ directory, presumably created by an
361
+ earlier build task. In addition, AAR packaging will include all files ending
362
+ with @.wsdl@ from the @src/main/axis2@ directory.
363
+
364
+ If you already have WSDL files in the @src/main/axis2@ directory but would like
365
+ to perform some filtering, for example, to set the HTTP port number, consider
366
+ ignoring the originals and including only the filtered files, for example:
367
+
368
+ {{{!ruby
369
+ # Host name depends on environment.
370
+ host = ENV['ENV'] == 'test' ? 'test.host' : 'ws.example.com'
371
+ filter.from('src/main/axis2').into('target').
372
+ include('services.xml', '*.wsdl').using('http_port'=>'8080', 'http_host'=>host)
373
+ package(:aar).wsdls.clear
374
+ package(:aar).with(:services_xml=>_('target/services.xml'), :wsdls=>_('target/*.wsdl'))
375
+ }}}
376
+
377
+
378
+ h2. Packaging EARs
379
+
380
+ EAR packaging is slightly different from JAR/WAR packaging. It's main purpose
381
+ is to package components together, and so it includes special methods for
382
+ handling component inclusion that take care to update application.xml and the
383
+ component's classpath.
384
+
385
+ EAR packages support four component types:
386
+
387
+ |_. Argument |_. Component |
388
+ | @:war@ | J2EE Web Application (WAR). |
389
+ | @:ejb@ | Enterprise Java Bean (JAR). |
390
+ | @:jar@ | J2EE Application Client (JAR). |
391
+ | @:lib@ | Shared library (JAR). |
392
+
393
+ This example shows two ways for adding components built by other projects:
394
+
395
+ {{{!ruby
396
+ package(:ear) << project('coolWebService').package(:war)
397
+ package(:ear).add project('commonLib') # By default, the JAR package
398
+ }}}
399
+
400
+ Adding a WAR package assumes it's a WAR component and treats it as such, but
401
+ JAR packages can be any of three component types, so by default they are all
402
+ treated as shared libraries. If you want to add an EJB or Application Client
403
+ component, you need to say so explicitly, either passing @:type=>package@, or by
404
+ passing the component type in the @:type@ option.
405
+
406
+ Here are three examples:
407
+
408
+ {{{!ruby
409
+ # Assumed to be a shared library.
410
+ package(:ear).add 'org.springframework:spring:jar:2.6'
411
+ # Component type mapped to package.
412
+ package(:ear).add :ejb=>project('beanery')
413
+ # Adding component with specific package type.
414
+ package(:ear).add project('client'), :type=>:jar
415
+ }}}
416
+
417
+ By default, WAR components are all added under the @/war@ path, and likewise,
418
+ EJB components are added under the @/ejb@ path, shared libraries under @/lib@
419
+ and Application Client components under @/jar@.
420
+
421
+ If you want to place components in different locations you can do so using the
422
+ @:path@ option, or by specifying a different mapping between component types
423
+ and their destination directory. The following two examples are equivalent:
424
+
425
+ {{{!ruby
426
+ # Specify once per component.
427
+ package(:ear).add project('coolWebService').package(:war), :path=>'coolServices'
428
+ # Configure once and apply to all added components.
429
+ package(:ear).dirs[:war] = 'coolServices'
430
+ package(:ear) << project('coolWebService').package(:war)
431
+ }}}
432
+
433
+ EAR packages include an @application.xml@ file in the @META-INF@ directory that
434
+ describes the application and its components. This file is created for you
435
+ during packaging, by referencing all the components added to the EAR. There
436
+ are a couple of things you will typically want to change.
437
+
438
+ * *display-name* -- The application's display name defaults to the project's
439
+ identifier. You can change that by setting the @display_name@ attribute.
440
+
441
+ * *context-root* -- WAR components specify a context root, based on the package
442
+ identifier, for example, "cool-web-1.0.war" will have the context root
443
+ "cool-web". To specify a different context root, add the WAR package with the
444
+ @context_root@ option.
445
+
446
+ Again, by example:
447
+
448
+ {{{!ruby
449
+ package(:ear).display_name = 'MyCoolWebService'
450
+ package(:ear).add project('coolWebService').package(:war), :context-root=>'coolness'
451
+ }}}
452
+
453
+ If you need to disable the context root (e.g. for Portlets), set @context_root@
454
+ to @false@.
455
+
456
+
457
+ h2. Packaging Tars and GZipped Tars
458
+
459
+ Everything you know about working with ZIP files translates to Tar files, the
460
+ two tasks are identical in more respect, so here we'll just go over the
461
+ differences.
462
+
463
+ {{{!ruby
464
+ package(:tar).include _('target/docs'), 'README'
465
+ package(:tgz).include _('target/docs'), 'README'
466
+ }}}
467
+
468
+ The first line creates a Tar archive with the extension @.tar@, the second
469
+ creates a GZipped Tar archive with the extension @.tgz@.
470
+
471
+ In addition to packaging that includes the archive in the list of
472
+ installed/released files, you can use the method @tar@ to create a @TarTask@.
473
+ This task is similar to @ZipTask@, and introduces the @gzip@ attribute, which
474
+ you can use to tell it whether to create a regular file, or GZip it. By
475
+ default the attribute it set to true (GZip) if the file name ends with either
476
+ @.gz@ or @.tgz@.
477
+
478
+
479
+ h2. Installing and Uploading
480
+
481
+ You can bring in the artifacts you need from remote repositories and install
482
+ them in the local repositories. Other projects have the same expectation, that
483
+ your packages be their artifacts.
484
+
485
+ So let's create these packages and install them in the local repository where
486
+ other projects can access them:
487
+
488
+ {{{!sh
489
+ $ buildr install
490
+ }}}
491
+
492
+ If you changes your mind you can always:
493
+
494
+ {{{!sh
495
+ $ buildr uninstall
496
+ }}}
497
+
498
+ That works between projects you build on the same machine. Now let's share
499
+ these artifacts with other developers through a remote repository:
500
+
501
+ {{{!sh
502
+ $ buildr upload
503
+ }}}
504
+
505
+ Of course, you'll need to tell Buildr about the release server:
506
+
507
+ {{{!ruby
508
+ repositories.release_to = 'sftp://john:secret@release/usr/share/repo'
509
+ }}}
510
+
511
+ We're using the SFTP protocol, currently the only protocol Buildr uses for
512
+ uploads. The URL contains the release server ("release"), path to repository
513
+ ("user/share/repo") and username/password for access. The way SFTP works, you
514
+ specify the path on the release server, and give the user permissions to create
515
+ directories and files inside the repository. The file system path is different
516
+ from the path you use to download these artifacts through an HTTP server, and
517
+ starts at the root, not the user's home directory.
518
+
519
+ Of course, you'll want to specify the release server URL in the Buildfile, but
520
+ leave the username/password settings private in your local @buildr.rb@ file.
521
+ Let's break up the release server settings:
522
+
523
+ {{{!ruby
524
+ # build.rb, loaded first
525
+ repositories.release_to[:username] = 'john'
526
+ repositories.release_to[:password] = 'secret'
527
+
528
+ # Buildfile, loaded next
529
+ repositories.release_to[:url] = 'sftp://release/usr/share/repo'
530
+ }}}
531
+
532
+ The @upload@ task takes care of uploading all the packages created by your
533
+ project, along with their associated POM files and MD5/SHA1 signatures (Buildr
534
+ creates these for you).
535
+
536
+ If you need to upload other files, you can always extend the @upload@ task and
537
+ use @repositories.release_to@ in combination with @URI.upload@. You can also
538
+ extend it to upload to different servers, for example, to publish the
539
+ documentation and test coverage reports to your site:
540
+
541
+ {{{!ruby
542
+ # We'll let some other task decide how to create 'docs'
543
+ task 'deploy'=>'docs' do
544
+ uri = URI("sftp://#{username}:#{password}@var/www/docs")
545
+ uri.upload file('docs')
546
+ end
547
+ }}}
548
+
549
+
550
+ h2. Packaging Sources and JavaDocs
551
+
552
+ IDEs can take advantage of source packages to help you debug and trace through
553
+ compiled code. We'll start with a simple example:
554
+
555
+ {{{!ruby
556
+ package :sources
557
+ }}}
558
+
559
+ This one creates a ZIP package with the classifier "sources" that will contain
560
+ all the source directories in that project, typically @src/main/java@, but also
561
+ other sources generated from Apt, JavaCC, XMLBeans and friends.
562
+
563
+ You can also generate a ZIP package with the classifier "javadoc" that contains
564
+ the JavaDoc documentation for the project. It uses the same set of
565
+ documentation files generated by the project's @javadoc@ task, so you can use
566
+ it in combination with the @javadoc@ method. For example:
567
+
568
+ {{{!ruby
569
+ package :javadoc
570
+ javadoc :windowtitle=>'Buggy but Works'
571
+ }}}
572
+
573
+ By default Buildr picks the project's description for the window title.
574
+
575
+ You can also tell Buildr to automatically create sources and JavaDoc packages
576
+ in all the sub-projects that have any source files to package or document.
577
+ Just add either or both of these methods in the top-level project:
578
+
579
+ {{{!ruby
580
+ package_with_sources
581
+ package_with_javadoc
582
+ }}}
583
+
584
+ You can also tell it to be selective using the @:only@ and @:except@ options.
585
+ For example:
586
+
587
+ {{{!ruby
588
+ package_with_javadoc :except=>'la-web'
589
+ }}}
590
+
591
+ We packaged the code, but will it actually work? Let's see "what the tests
592
+ say":testing.html.