buildr 1.2.10 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +566 -268
- data/DISCLAIMER +7 -1
- data/KEYS +151 -0
- data/NOTICE +23 -8
- data/README +122 -22
- data/Rakefile +49 -229
- data/{lib → addon}/buildr/antlr.rb +23 -10
- data/addon/buildr/cobertura.rb +232 -0
- data/{lib → addon}/buildr/hibernate.rb +20 -4
- data/{lib → addon}/buildr/javacc.rb +27 -12
- data/addon/buildr/jdepend.rb +60 -0
- data/{lib → addon}/buildr/jetty.rb +34 -18
- data/addon/buildr/nailgun.rb +892 -0
- data/{lib → addon}/buildr/openjpa.rb +23 -6
- data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
- data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
- data/{lib/buildr/jetty → addon/buildr/org/apache/buildr}/JettyWrapper.java +19 -0
- data/{lib → addon}/buildr/xmlbeans.rb +39 -14
- data/bin/buildr +21 -7
- data/buildr.gemspec +50 -0
- data/doc/css/default.css +225 -0
- data/doc/css/print.css +95 -0
- data/doc/css/syntax.css +43 -0
- data/doc/images/apache-incubator-logo.png +0 -0
- data/doc/images/buildr-hires.png +0 -0
- data/doc/images/buildr.png +0 -0
- data/doc/images/note.png +0 -0
- data/doc/images/tip.png +0 -0
- data/doc/images/zbuildr.tif +0 -0
- data/doc/pages/artifacts.textile +317 -0
- data/doc/pages/building.textile +501 -0
- data/doc/pages/contributing.textile +178 -0
- data/doc/pages/download.textile +25 -0
- data/doc/pages/extending.textile +229 -0
- data/doc/pages/getting_started.textile +337 -0
- data/doc/pages/index.textile +63 -0
- data/doc/pages/mailing_lists.textile +17 -0
- data/doc/pages/more_stuff.textile +367 -0
- data/doc/pages/packaging.textile +592 -0
- data/doc/pages/projects.textile +449 -0
- data/doc/pages/recipes.textile +127 -0
- data/doc/pages/settings_profiles.textile +339 -0
- data/doc/pages/testing.textile +475 -0
- data/doc/pages/troubleshooting.textile +121 -0
- data/doc/pages/whats_new.textile +389 -0
- data/doc/print.haml +52 -0
- data/doc/print.toc.yaml +28 -0
- data/doc/scripts/buildr-git.rb +411 -0
- data/doc/scripts/install-jruby.sh +44 -0
- data/doc/scripts/install-linux.sh +64 -0
- data/doc/scripts/install-osx.sh +52 -0
- data/doc/site.haml +55 -0
- data/doc/site.toc.yaml +44 -0
- data/lib/buildr.rb +28 -45
- data/lib/buildr/core.rb +27 -0
- data/lib/buildr/core/application.rb +373 -0
- data/lib/buildr/core/application_cli.rb +134 -0
- data/lib/{core → buildr/core}/build.rb +91 -77
- data/lib/{core → buildr/core}/checks.rb +116 -95
- data/lib/buildr/core/common.rb +155 -0
- data/lib/buildr/core/compile.rb +594 -0
- data/lib/buildr/core/environment.rb +120 -0
- data/lib/buildr/core/filter.rb +258 -0
- data/lib/{core → buildr/core}/generate.rb +22 -5
- data/lib/buildr/core/help.rb +118 -0
- data/lib/buildr/core/progressbar.rb +156 -0
- data/lib/{core → buildr/core}/project.rb +468 -213
- data/lib/buildr/core/test.rb +690 -0
- data/lib/{core → buildr/core}/transports.rb +107 -127
- data/lib/buildr/core/util.rb +235 -0
- data/lib/buildr/ide.rb +19 -0
- data/lib/{java → buildr/ide}/eclipse.rb +86 -60
- data/lib/{java → buildr/ide}/idea.ipr.template +16 -0
- data/lib/buildr/ide/idea.rb +194 -0
- data/lib/buildr/ide/idea7x.ipr.template +290 -0
- data/lib/buildr/ide/idea7x.rb +210 -0
- data/lib/buildr/java.rb +26 -0
- data/lib/buildr/java/ant.rb +71 -0
- data/lib/buildr/java/bdd_frameworks.rb +267 -0
- data/lib/buildr/java/commands.rb +210 -0
- data/lib/buildr/java/compilers.rb +432 -0
- data/lib/buildr/java/deprecated.rb +141 -0
- data/lib/buildr/java/groovyc.rb +137 -0
- data/lib/buildr/java/jruby.rb +99 -0
- data/lib/buildr/java/org/apache/buildr/BuildrNail$Main.class +0 -0
- data/lib/buildr/java/org/apache/buildr/BuildrNail.class +0 -0
- data/lib/buildr/java/org/apache/buildr/BuildrNail.java +41 -0
- data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
- data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +116 -0
- data/lib/buildr/java/packaging.rb +706 -0
- data/lib/{java → buildr/java}/pom.rb +20 -4
- data/lib/buildr/java/rjb.rb +142 -0
- data/lib/buildr/java/test_frameworks.rb +290 -0
- data/lib/buildr/java/version_requirement.rb +172 -0
- data/lib/buildr/packaging.rb +21 -0
- data/lib/{java → buildr/packaging}/artifact.rb +170 -179
- data/lib/buildr/packaging/artifact_namespace.rb +957 -0
- data/lib/buildr/packaging/artifact_search.rb +140 -0
- data/lib/buildr/packaging/gems.rb +102 -0
- data/lib/buildr/packaging/package.rb +233 -0
- data/lib/{tasks → buildr/packaging}/tar.rb +18 -1
- data/lib/{tasks → buildr/packaging}/zip.rb +153 -105
- data/rakelib/apache.rake +126 -0
- data/rakelib/changelog.rake +56 -0
- data/rakelib/doc.rake +103 -0
- data/rakelib/package.rake +44 -0
- data/rakelib/release.rake +53 -0
- data/rakelib/rspec.rake +81 -0
- data/rakelib/rubyforge.rake +45 -0
- data/rakelib/scm.rake +49 -0
- data/rakelib/setup.rake +59 -0
- data/rakelib/stage.rake +45 -0
- data/spec/application_spec.rb +316 -0
- data/spec/archive_spec.rb +494 -0
- data/spec/artifact_namespace_spec.rb +635 -0
- data/spec/artifact_spec.rb +738 -0
- data/spec/build_spec.rb +193 -0
- data/spec/checks_spec.rb +537 -0
- data/spec/common_spec.rb +579 -0
- data/spec/compile_spec.rb +561 -0
- data/spec/groovy_compilers_spec.rb +239 -0
- data/spec/java_bdd_frameworks_spec.rb +238 -0
- data/spec/java_compilers_spec.rb +446 -0
- data/spec/java_packaging_spec.rb +1042 -0
- data/spec/java_test_frameworks_spec.rb +414 -0
- data/spec/packaging_helper.rb +63 -0
- data/spec/packaging_spec.rb +589 -0
- data/spec/project_spec.rb +739 -0
- data/spec/sandbox.rb +116 -0
- data/spec/scala_compilers_spec.rb +239 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helpers.rb +283 -0
- data/spec/test_spec.rb +871 -0
- data/spec/transport_spec.rb +300 -0
- data/spec/version_requirement_spec.rb +115 -0
- metadata +188 -77
- data/lib/buildr/cobertura.rb +0 -89
- data/lib/buildr/jdepend.rb +0 -40
- data/lib/buildr/jetty/JettyWrapper$1.class +0 -0
- data/lib/buildr/jetty/JettyWrapper$BuildrHandler.class +0 -0
- data/lib/buildr/jetty/JettyWrapper.class +0 -0
- data/lib/buildr/scala.rb +0 -368
- data/lib/core/application.rb +0 -188
- data/lib/core/common.rb +0 -562
- data/lib/core/help.rb +0 -72
- data/lib/core/rake_ext.rb +0 -81
- data/lib/java/ant.rb +0 -71
- data/lib/java/compile.rb +0 -589
- data/lib/java/idea.rb +0 -159
- data/lib/java/java.rb +0 -432
- data/lib/java/packaging.rb +0 -581
- data/lib/java/test.rb +0 -795
- 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.
|