buildr 1.3.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +780 -0
- data/DISCLAIMER +7 -0
- data/KEYS +151 -0
- data/LICENSE +176 -0
- data/NOTICE +31 -0
- data/README +173 -0
- data/Rakefile +63 -0
- data/addon/buildr/antlr.rb +65 -0
- data/addon/buildr/cobertura.rb +232 -0
- data/addon/buildr/hibernate.rb +142 -0
- data/addon/buildr/javacc.rb +85 -0
- data/addon/buildr/jdepend.rb +60 -0
- data/addon/buildr/jetty.rb +248 -0
- data/addon/buildr/nailgun.rb +892 -0
- data/addon/buildr/openjpa.rb +90 -0
- 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/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
- data/addon/buildr/xmlbeans.rb +93 -0
- data/bin/buildr +21 -0
- 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 +47 -0
- 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/buildr/core/build.rb +262 -0
- data/lib/buildr/core/checks.rb +382 -0
- 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/buildr/core/generate.rb +195 -0
- data/lib/buildr/core/help.rb +118 -0
- data/lib/buildr/core/progressbar.rb +156 -0
- data/lib/buildr/core/project.rb +890 -0
- data/lib/buildr/core/test.rb +690 -0
- data/lib/buildr/core/transports.rb +486 -0
- data/lib/buildr/core/util.rb +235 -0
- data/lib/buildr/ide.rb +19 -0
- data/lib/buildr/ide/eclipse.rb +181 -0
- data/lib/buildr/ide/idea.ipr.template +300 -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/buildr/java/pom.rb +178 -0
- 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/buildr/packaging/artifact.rb +729 -0
- 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/buildr/packaging/tar.rb +104 -0
- data/lib/buildr/packaging/zip.rb +719 -0
- 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 +324 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
h1. Projects
|
|
2
|
+
|
|
3
|
+
h2. Starting Out
|
|
4
|
+
|
|
5
|
+
In Java, most projects are built the same way: compile source code, run test
|
|
6
|
+
cases, package the code, release it. Rinse, repeat.
|
|
7
|
+
|
|
8
|
+
Feed it a project definition, and Buildr will set up all these tasks for you.
|
|
9
|
+
The only thing you need to do is specify the parts that are specific to your
|
|
10
|
+
project, like the classpath dependencies, whether you're packaging a JAR or a
|
|
11
|
+
WAR, etc.
|
|
12
|
+
|
|
13
|
+
The remainder of this guide deals with what it takes to build a project. But
|
|
14
|
+
first, let's pick up a sample project to work with. We'll call it
|
|
15
|
+
_killer-app_:
|
|
16
|
+
|
|
17
|
+
{{{!ruby
|
|
18
|
+
require 'buildr'
|
|
19
|
+
|
|
20
|
+
VERSION_NUMBER = '1.0'
|
|
21
|
+
|
|
22
|
+
AXIS2 = 'org.apache.axis2:axis2:jar:1.2'
|
|
23
|
+
AXIOM = group('axiom-api', 'axiom-impl', 'axiom-dom',
|
|
24
|
+
:under=>'org.apache.ws.commons.axiom', :version=>'1.2.4')
|
|
25
|
+
AXIS_OF_WS = [AXIOM, AXIS2]
|
|
26
|
+
OPENJPA = ['org.apache.openjpa:openjpa-all:jar:0.9.7',
|
|
27
|
+
'net.sourceforge.serp:serp:jar:1.12.0']
|
|
28
|
+
|
|
29
|
+
repositories.remote << 'http://www.ibiblio.org/maven2/'
|
|
30
|
+
|
|
31
|
+
desc 'Code. Build. ??? Profit!'
|
|
32
|
+
define 'killer-app' do
|
|
33
|
+
|
|
34
|
+
project.version = VERSION_NUMBER
|
|
35
|
+
project.group = 'acme'
|
|
36
|
+
manifest['Copyright'] = 'Acme Inc (C) 2007'
|
|
37
|
+
compile.options.target = '1.5'
|
|
38
|
+
|
|
39
|
+
desc 'Abstract classes and interfaces'
|
|
40
|
+
define 'teh-api' do
|
|
41
|
+
package :jar
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
desc 'All those implementation details'
|
|
45
|
+
define 'teh-impl' do
|
|
46
|
+
compile.with AXIS_OF_WS, OPENJPA
|
|
47
|
+
compile { open_jpa_enhance }
|
|
48
|
+
package :jar
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
desc 'What our users see'
|
|
52
|
+
define 'la-web' do
|
|
53
|
+
test.using AXIS_OF_WS
|
|
54
|
+
package(:war).with :libs=>projects('teh-api', 'teh-impl')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
javadoc projects
|
|
58
|
+
package :javadoc
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
}}}
|
|
62
|
+
|
|
63
|
+
A project definition requires four pieces of information: the project name,
|
|
64
|
+
group identifier, version number and base directory. The project name ... do
|
|
65
|
+
we need to explain why its necessary? The group identifier and version number
|
|
66
|
+
are used for packaging and deployment, we'll talk more about that in the
|
|
67
|
+
"Packaging":packaging.html section. The base directory lets you find files
|
|
68
|
+
inside the project.
|
|
69
|
+
|
|
70
|
+
Everything else depends on what that particular project is building. And it
|
|
71
|
+
all goes inside the project definition block, the piece of code that comes
|
|
72
|
+
between @define <name> .. do@ and @end@.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
h2. The Directory Structure
|
|
76
|
+
|
|
77
|
+
Buildr follows a convention we picked from years of working with Apache
|
|
78
|
+
projects.
|
|
79
|
+
|
|
80
|
+
Java projects are laid out so the source files are in the @src/main/java@
|
|
81
|
+
directory and compile into the @target/classes@ directory. Resource files go
|
|
82
|
+
in the @src/main/resources@ directory, also copied over to @target/classes@.
|
|
83
|
+
Likewise, unit tests come from @src/test/java@ and @src/test/resources@, and
|
|
84
|
+
end life in @target/test/classes@.
|
|
85
|
+
|
|
86
|
+
WAR packages pick up additional files from the aptly named @src/main/webapp@.
|
|
87
|
+
And most stuff, including generated source files are parked under the @target@
|
|
88
|
+
directory. Test cases and such may generate reports in the, you guessed it,
|
|
89
|
+
@reports@ directory.
|
|
90
|
+
|
|
91
|
+
Other languages will use different directories, but following the same general
|
|
92
|
+
conventions. For example, Scala code compiles from the @src/main/scala@
|
|
93
|
+
directory, RSpec tests are found in the @src/test/rspec@ directory, and Flash
|
|
94
|
+
will compile to @target/flash@. Throughout this document we will show examples
|
|
95
|
+
using mostly Java, but you can imagine how this pattern applies to other
|
|
96
|
+
languages.
|
|
97
|
+
|
|
98
|
+
When projects grow big, you split them into smaller projects by nesting
|
|
99
|
+
projects inside each other. Each sub-project has a sub-directory under the
|
|
100
|
+
parent project and follows the same internal directory structure. You can, of
|
|
101
|
+
course, change all of that to suite your needs, but if you follow these
|
|
102
|
+
conventions, Buildr will figure all the paths for you.
|
|
103
|
+
|
|
104
|
+
Going back to the example above, the directory structure looks like this:
|
|
105
|
+
|
|
106
|
+
{{{
|
|
107
|
+
./buildfile <- Top of the world (killer-app)
|
|
108
|
+
|
|
|
109
|
+
|__ teh-api
|
|
110
|
+
| |__ src
|
|
111
|
+
| | |__ main
|
|
112
|
+
| | |__ java <- Java sources
|
|
113
|
+
| |
|
|
114
|
+
| |__ target <- JAR goes here
|
|
115
|
+
| | |__ classes <- Generated bytecode
|
|
116
|
+
| |__ reports <- From test cases,
|
|
117
|
+
| |__ junit <- like JUnit
|
|
118
|
+
|
|
|
119
|
+
|__ teh-impl
|
|
120
|
+
| |__ src
|
|
121
|
+
| | |__ main
|
|
122
|
+
| | | |__ java
|
|
123
|
+
| | | |__ resources
|
|
124
|
+
| | |__ test
|
|
125
|
+
| | |__ java
|
|
126
|
+
| |
|
|
127
|
+
| |__ target
|
|
128
|
+
| | |__ classes
|
|
129
|
+
| |__ reports
|
|
130
|
+
|
|
|
131
|
+
|__ la-web
|
|
132
|
+
| |__ src
|
|
133
|
+
| | |__ main
|
|
134
|
+
| | |__ webapp <- Webapp files
|
|
135
|
+
| |
|
|
136
|
+
| |__ target <- The WAR goes here
|
|
137
|
+
|
|
|
138
|
+
|__ reports
|
|
139
|
+
|__ junit <- For all test cases
|
|
140
|
+
}}}
|
|
141
|
+
|
|
142
|
+
Notice the @buildfile@ at the top. That's your project build script, the one
|
|
143
|
+
Buildr runs.
|
|
144
|
+
|
|
145
|
+
When you run the @buildr@ command, it picks up the @buildfile@ (which here
|
|
146
|
+
we'll just call _Buildfile_) from the current directory, or if not there, from
|
|
147
|
+
the closest parent directory. So you can run @buildr@ from any directory
|
|
148
|
+
inside your project, and it will always pick up the same Buildfile. That also
|
|
149
|
+
happens to be the base directory for the top project. If you have any
|
|
150
|
+
sub-projects, Buildr assumes they reflect sub-directories under their parent.
|
|
151
|
+
|
|
152
|
+
And yes, you can have two top projects in the same Buildfile. For example, you
|
|
153
|
+
can use that to have one project that groups all the application modules (JARs,
|
|
154
|
+
WARs, etc) and another project that groups all the distribution packages
|
|
155
|
+
(binary, sources, javadocs).
|
|
156
|
+
|
|
157
|
+
When you start with a new project you won't see the @target@ or @reports@
|
|
158
|
+
directories. Buildr creates these when it needs to. Just know that they're
|
|
159
|
+
there.
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
h2. Naming And Finding Projects
|
|
163
|
+
|
|
164
|
+
Each project has a given name, the first argument you pass when calling
|
|
165
|
+
@define@. The project name is just a string, but we advise to stay clear of
|
|
166
|
+
colon (@:@) and slashes (@/@ and @\@), which could conflict with other task and
|
|
167
|
+
file names. Also, avoid using common Buildr task names, don't pick @compile@
|
|
168
|
+
or @build@ for your project name.
|
|
169
|
+
|
|
170
|
+
Since each project knows its parent project, child projects and siblings, you
|
|
171
|
+
can reference them from within the project using just the given name. In other
|
|
172
|
+
cases, you'll need to use the full name. The full name is just @parent:child@.
|
|
173
|
+
So if you wanted to refer to _teh-impl_, you could do so with either
|
|
174
|
+
@project('killer-app:teh-impl')@ or
|
|
175
|
+
@project('killer-app').project('teh-impl')@.
|
|
176
|
+
|
|
177
|
+
The @project@ method is convenient when you have a dependency from one project
|
|
178
|
+
to another, e.g. using the other project in the classpath, or accessing one of
|
|
179
|
+
its source files. Call it with a project name and it will return that object
|
|
180
|
+
or raise an error. You can also call it with no arguments and it will return
|
|
181
|
+
the project itself. It's syntactic sugar that's useful when accessing project
|
|
182
|
+
properties.
|
|
183
|
+
|
|
184
|
+
The @projects@ method takes a list of names and returns a list of projects. If
|
|
185
|
+
you call it with no arguments on a project, it returns all its sub-projects.
|
|
186
|
+
If you call it with no argument in any other context, it returns all the
|
|
187
|
+
projects defined so far.
|
|
188
|
+
|
|
189
|
+
Let's illustrate this with a few examples:
|
|
190
|
+
|
|
191
|
+
{{{!ruby
|
|
192
|
+
puts projects.inspect
|
|
193
|
+
=> [project("killer-app"), project("killer-app:teh-api") ... ]
|
|
194
|
+
|
|
195
|
+
puts project('killer-app').projects.inspect
|
|
196
|
+
=> [project("killer-app:teh-api"), project("killer-app:teh-impl") ... ]
|
|
197
|
+
|
|
198
|
+
puts project('teh-api')
|
|
199
|
+
=> No such project teh-api
|
|
200
|
+
|
|
201
|
+
puts project('killer-app:teh-api').inspect
|
|
202
|
+
=> project("killer-app:teh-api")
|
|
203
|
+
|
|
204
|
+
puts project('killer-app').project('teh-api').inspect
|
|
205
|
+
=> project("killer-app:teh-api")
|
|
206
|
+
}}}
|
|
207
|
+
|
|
208
|
+
To see a list of all projects defined in your Buildfile:
|
|
209
|
+
|
|
210
|
+
{{{!sh
|
|
211
|
+
$ buildr help:projects
|
|
212
|
+
}}}
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
h2. Running Project Tasks
|
|
216
|
+
|
|
217
|
+
Most times, you run tasks like @build@ or @package@ that operate on the current
|
|
218
|
+
project and recursively on its sub-projects. The "current project" is the one
|
|
219
|
+
that uses the current working directory. So if you're in the @la-web/src@
|
|
220
|
+
directory looking at source files, _la-web_ is the current project. For
|
|
221
|
+
example:
|
|
222
|
+
|
|
223
|
+
{{{!sh
|
|
224
|
+
# build killer-app and all its sub-projects
|
|
225
|
+
$ buildr build
|
|
226
|
+
|
|
227
|
+
# switch to and test only teh-impl
|
|
228
|
+
$ cd teh-impl
|
|
229
|
+
$ buildr test
|
|
230
|
+
|
|
231
|
+
# switch to and package only la-web
|
|
232
|
+
$ cd ../la-web
|
|
233
|
+
$ buildr package
|
|
234
|
+
}}}
|
|
235
|
+
|
|
236
|
+
You can use the project's full name to invoke one of its tasks directly, and it
|
|
237
|
+
doesn't matter which directory you're in. For example:
|
|
238
|
+
|
|
239
|
+
{{{!sh
|
|
240
|
+
# build killer-app and all its sub-projects
|
|
241
|
+
$ buildr killer-app:build
|
|
242
|
+
|
|
243
|
+
# test only teh-impl
|
|
244
|
+
$ buildr killer-app:teh-impl:test
|
|
245
|
+
|
|
246
|
+
# package only la-web
|
|
247
|
+
$ buildr killer-app:la-web:package
|
|
248
|
+
}}}
|
|
249
|
+
|
|
250
|
+
Buildr provides the following tasks that you can run on the current project, or
|
|
251
|
+
on a specific project by prefixing them with the project's full name:
|
|
252
|
+
|
|
253
|
+
{{{
|
|
254
|
+
clean # Clean files generated during a build
|
|
255
|
+
compile # Compile all projects
|
|
256
|
+
build # Build the project
|
|
257
|
+
upload # Upload packages created by the project
|
|
258
|
+
install # Install packages created by the project
|
|
259
|
+
javadoc # Create the Javadocs for this project
|
|
260
|
+
package # Create packages
|
|
261
|
+
test # Run all test cases
|
|
262
|
+
uninstall # Remove previously installed packages
|
|
263
|
+
}}}
|
|
264
|
+
|
|
265
|
+
To see a list of all the tasks provided by Buildr:
|
|
266
|
+
|
|
267
|
+
{{{!sh
|
|
268
|
+
$ buildr help:tasks
|
|
269
|
+
}}}
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
h2. Setting Project Properties
|
|
273
|
+
|
|
274
|
+
We mentioned the group identifier, version number and base directory. These
|
|
275
|
+
are project properties. There are a few more properties we'll cover later on.
|
|
276
|
+
|
|
277
|
+
There are two ways to set project properties. You can pass them as a hash when
|
|
278
|
+
you call @define@, or use accessors to set them on the project directly. For
|
|
279
|
+
example:
|
|
280
|
+
|
|
281
|
+
{{{!ruby
|
|
282
|
+
define 'silly', :version=>'1.0' do
|
|
283
|
+
project.group = 'acme'
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
puts project('silly').version
|
|
287
|
+
=> 1.0
|
|
288
|
+
puts project('silly').group
|
|
289
|
+
=> acme
|
|
290
|
+
}}}
|
|
291
|
+
|
|
292
|
+
Project properties are inherited. You can specify them once in the parent
|
|
293
|
+
project, and they'll have the same value in all its sub-projects. In the
|
|
294
|
+
example, we only specify the version number once, for use in all sub-projects.
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
h2. Resolving Paths
|
|
298
|
+
|
|
299
|
+
You can run @buildr@ from any directory in your project. To keep tasks
|
|
300
|
+
consistent and happy, it switches over to the Buildfile directory and executes
|
|
301
|
+
all the tasks from there, before returning back to your working directory.
|
|
302
|
+
Your tasks can all rely on relative paths that start from the same directory as
|
|
303
|
+
the Buildfile.
|
|
304
|
+
|
|
305
|
+
But in practice, you'll want to use the @path_to@ method. This method
|
|
306
|
+
calculates a path relative to the project, a better way if you ever need to
|
|
307
|
+
refactor your code, say turn a ad hoc task into a function you reuse.
|
|
308
|
+
|
|
309
|
+
The @path_to@ method takes an array of strings and concatenates them into a
|
|
310
|
+
path. Absolute paths are returned as they are, relative paths are expanded
|
|
311
|
+
relative to the project's base directory. Slashes, if you don't already know,
|
|
312
|
+
work very well on both Windows, Linux and OS/X. And as a shortcut, you can use
|
|
313
|
+
@_@.
|
|
314
|
+
|
|
315
|
+
For example:
|
|
316
|
+
|
|
317
|
+
{{{!ruby
|
|
318
|
+
# Relative to the current project
|
|
319
|
+
path_to('src', 'main', 'java')
|
|
320
|
+
|
|
321
|
+
# Exactly the same thing
|
|
322
|
+
_('src/main/java')
|
|
323
|
+
|
|
324
|
+
# Relative to the teh-impl project
|
|
325
|
+
project('teh-impl')._('src/main/java')
|
|
326
|
+
}}}
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
h2. Defining The Project
|
|
330
|
+
|
|
331
|
+
The project definition itself gives you a lot of pre-canned tasks to start
|
|
332
|
+
with, but that's not enough to build a project. You need to specify what gets
|
|
333
|
+
built and how, which dependencies to use, the packages you want to create and
|
|
334
|
+
so forth. You can configure existing tasks, extend them to do additional work,
|
|
335
|
+
and create new tasks. All that magic happens inside the project definition
|
|
336
|
+
block.
|
|
337
|
+
|
|
338
|
+
Since the project definition executes each time you run Buildr, you don't want
|
|
339
|
+
to perform any work directly inside the project definition block. Rather, you
|
|
340
|
+
want to use it to specify how different build task work when you invoke them.
|
|
341
|
+
Here's an example to illustrate the point:
|
|
342
|
+
|
|
343
|
+
{{{!ruby
|
|
344
|
+
define 'silly' do
|
|
345
|
+
puts 'Running buildr'
|
|
346
|
+
|
|
347
|
+
build do
|
|
348
|
+
puts 'Building silly'
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
}}}
|
|
352
|
+
|
|
353
|
+
Each time you run Buildr, it will execute the project definition and print out
|
|
354
|
+
"Running buildr". We also extend the @build@ task, and whenever we run it, it
|
|
355
|
+
will print "Building silly". Incidentally, @build@ is the default task, so if
|
|
356
|
+
you run Buildr with no arguments, it will print both messages while executing
|
|
357
|
+
the build. If you run Buildr with a different task, say @clean@, it will only
|
|
358
|
+
print the first message.
|
|
359
|
+
|
|
360
|
+
The @define@ method gathers the project definition, but does not execute it
|
|
361
|
+
immediately. It executes the project definition the first time you reference
|
|
362
|
+
that project, directly or indirectly, for example, by calling @project@ with
|
|
363
|
+
that project's name, or calling @projects@ to return a list of all projects.
|
|
364
|
+
Executing a project definition will also execute all its sub-projects'
|
|
365
|
+
definitions. And, of course, all project definitions are executed once the
|
|
366
|
+
Buildfile loads, so Buildr can determine how to execute each of the build
|
|
367
|
+
tasks.
|
|
368
|
+
|
|
369
|
+
If this sounds a bit complex, don't worry. In reality, it does the right
|
|
370
|
+
thing. A simple rule to remember is that each project definition is executed
|
|
371
|
+
before you need it, lazy evaluation of sort. The reason we do that? So you
|
|
372
|
+
can write projects that depend on each other without worrying about their
|
|
373
|
+
order.
|
|
374
|
+
|
|
375
|
+
In our example, the _la-web_ project depends on packages created by the
|
|
376
|
+
_teh-api_ and _teh-impl_ projects, the later requiring _teh-api_ to compile.
|
|
377
|
+
That example is simple enough that we ended up specifying the projects in order
|
|
378
|
+
of dependency. But you don't always want to do that. For large projects, you
|
|
379
|
+
may want to group sub-projects by logical units, or sort them alphabetically
|
|
380
|
+
for easier editing.
|
|
381
|
+
|
|
382
|
+
One project can reference another ahead of its definition. If Buildr detects a
|
|
383
|
+
cyclic dependency, it will let you know.
|
|
384
|
+
|
|
385
|
+
In this example we define one project in terms of another, using the same
|
|
386
|
+
dependencies, so we only need to specify them once:
|
|
387
|
+
|
|
388
|
+
{{{!ruby
|
|
389
|
+
define 'bar' do
|
|
390
|
+
compile.with project('foo').compile.dependencies
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
define 'foo' do
|
|
394
|
+
compile.with ..lots of stuff..
|
|
395
|
+
end
|
|
396
|
+
}}}
|
|
397
|
+
|
|
398
|
+
One last thing to remember. Actually three, but they all go hand in hand.
|
|
399
|
+
|
|
400
|
+
*Self is project* Each of these project definition blocks executes in the
|
|
401
|
+
context of that project, just as if it was a method defined on the project. So
|
|
402
|
+
when you call the @compile@ method, you're essentially calling that method on
|
|
403
|
+
the current project: @compile@, @self.compile@ and @project.compile@ are all
|
|
404
|
+
the same.
|
|
405
|
+
|
|
406
|
+
*Blocks are closures* The project definition is also a closure, which can
|
|
407
|
+
reference variables from enclosing scopes. You can use that, for example, to
|
|
408
|
+
define constants, variables and even functions in your Buildfile, and reference
|
|
409
|
+
them from your project definition. As you'll see later on, in the
|
|
410
|
+
"Artifacts":#artifacts section, it will save you a lot of work.
|
|
411
|
+
|
|
412
|
+
*Projects are namespaces* While executing the project definition, Buildr
|
|
413
|
+
switches the namespace to the project name. If you define the task "do-this"
|
|
414
|
+
inside the _teh-impl_ project, the actual task name is
|
|
415
|
+
"killer-app:teh-impl:do-this". Likewise, the @compile@ task is actually
|
|
416
|
+
"killer-app:teh-impl:compile".
|
|
417
|
+
|
|
418
|
+
From outside the project you can reference a task by its full name, either
|
|
419
|
+
@task('foo:do')@ or @project('foo').task('do')@. If you need to reference a
|
|
420
|
+
task defined outside the project from within the project, prefix it with
|
|
421
|
+
"rake:", for example, @task('rake:globally-defined')@.
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
h2. Writing Your Own Tasks
|
|
425
|
+
|
|
426
|
+
Of all the features Buildr provide, it doesn't have a task for making coffee.
|
|
427
|
+
Yet. If you need to write your own tasks, you get all the power of Rake: you
|
|
428
|
+
can use regular tasks, file tasks, task rules and even write your own custom
|
|
429
|
+
task classes. Check out the "Rake documentation":http://docs.rubyrake.org/ for
|
|
430
|
+
more information.
|
|
431
|
+
|
|
432
|
+
We mentioned projects as namespaces before. When you call @task@ on a project,
|
|
433
|
+
it finds or defines the task using the project namespace. So given a project
|
|
434
|
+
object, @task('do-this')@ will return it's "do-this" task. If you lookup the
|
|
435
|
+
source code for the @compile@ method, you'll find that it's little more than a
|
|
436
|
+
shortcut for @task('compile')@.
|
|
437
|
+
|
|
438
|
+
Another shortcut is the @file@ method. When you call @file@ on a project,
|
|
439
|
+
Buildr uses the @path_to@ method to expand relative paths using the project's
|
|
440
|
+
base directory. If you call @file('src')@ on _teh-impl_, it will return you a
|
|
441
|
+
file task that points at the @teh-impl/src@ directory.
|
|
442
|
+
|
|
443
|
+
In the current implementation projects are also created as tasks, although you
|
|
444
|
+
don't invoke these tasks directly. That's the reason for not using a project
|
|
445
|
+
name that conflicts with an existing task name. If you do that, you'll find
|
|
446
|
+
quick enough, as the task will execute each time you run Buildr.
|
|
447
|
+
|
|
448
|
+
So now that you know everything about projects and tasks, let's go and "build
|
|
449
|
+
some code":building.html.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
h1. Recipes
|
|
2
|
+
|
|
3
|
+
Commond recipes for Buildr, collected from the mailing list.
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
h2. Creating a classpath
|
|
7
|
+
|
|
8
|
+
For Java, the classpath argument is simply a list of paths joined with an
|
|
9
|
+
OS-specific path separator:
|
|
10
|
+
|
|
11
|
+
{{{!ruby
|
|
12
|
+
cp = paths.join(File::PATH_SEPARATOR)
|
|
13
|
+
}}}
|
|
14
|
+
|
|
15
|
+
This assumes @paths@ points to files and/or directories, but what if you have a
|
|
16
|
+
list of artifact specifications? You can turn those into file names in two
|
|
17
|
+
steps. First, use @artifacts@ to return a list of file tasks that point to the
|
|
18
|
+
local repository:
|
|
19
|
+
|
|
20
|
+
{{{!ruby
|
|
21
|
+
tasks = Buildr.artifacts(specs)
|
|
22
|
+
}}}
|
|
23
|
+
|
|
24
|
+
Next, map that list of tasks into list of file names (essentially calling
|
|
25
|
+
@name@ on each task):
|
|
26
|
+
|
|
27
|
+
{{{!ruby
|
|
28
|
+
paths = tasks.map(&:name)
|
|
29
|
+
}}}
|
|
30
|
+
|
|
31
|
+
This works as long as the artifacts are already in your local repository,
|
|
32
|
+
otherwise they can't be found, but you can ask Buildr to download them by
|
|
33
|
+
calling @invoke@ on each of these tasks:
|
|
34
|
+
|
|
35
|
+
{{{!ruby
|
|
36
|
+
tasks = Buildr.artifacts(specs).each(&:invoke)
|
|
37
|
+
}}}
|
|
38
|
+
|
|
39
|
+
So let's roll this all into a single line:
|
|
40
|
+
|
|
41
|
+
{{{!ruby
|
|
42
|
+
cp = Buildr.artifacts(specs).each(&:invoke).map(&:name).join(File::PATH_SEPARATOR)
|
|
43
|
+
}}}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
h2. Keeping your Profiles.yaml file DRY
|
|
47
|
+
|
|
48
|
+
YAML allows you to use anchors (@&@), similar to ID attributes in XML, and
|
|
49
|
+
reference them later on (@*@). For example, if you have two profiles that are
|
|
50
|
+
identical, you can tell YAML that one is an alias for the other:
|
|
51
|
+
|
|
52
|
+
{{{!yaml
|
|
53
|
+
development: &common
|
|
54
|
+
db: oracle
|
|
55
|
+
port: 8080
|
|
56
|
+
test: *common
|
|
57
|
+
production: *common
|
|
58
|
+
}}}
|
|
59
|
+
|
|
60
|
+
If you have two elements that are almost identical, you can merge the values of
|
|
61
|
+
one element into another (@<<@), for example:
|
|
62
|
+
|
|
63
|
+
{{{!yaml
|
|
64
|
+
development: &common
|
|
65
|
+
db: hsql
|
|
66
|
+
jdbc: hsqldb:mem:devdb
|
|
67
|
+
test:
|
|
68
|
+
<<: *common
|
|
69
|
+
jdbc: hsqldb:file:testdb
|
|
70
|
+
}}}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
h2. Speeding JRuby
|
|
74
|
+
|
|
75
|
+
When using JRuby you will notice that Buildr takes a few seconds to start up.
|
|
76
|
+
To speed it up, we recommend switching to Java 1.6 and running the JVM in
|
|
77
|
+
client mode:
|
|
78
|
+
|
|
79
|
+
{{{!
|
|
80
|
+
$ export JAVA_OPTS=-client
|
|
81
|
+
}}}
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
h2. Continuous Integration with Atlassian Bamboo
|
|
85
|
+
|
|
86
|
+
This recipe outlines how to configure a new Bamboo project to use Buildr. The
|
|
87
|
+
following steps assume that you have logged-on to Bamboo as an Administrator.
|
|
88
|
+
|
|
89
|
+
*1. Configure a Builder*
|
|
90
|
+
|
|
91
|
+
* Select the Administration tab from the Bamboo toolbar.
|
|
92
|
+
* Select the Builders area (first option) from the Administration menu.
|
|
93
|
+
* Using the Add Builder dialog, configure a custom builder for Buildr with the
|
|
94
|
+
following options:
|
|
95
|
+
** Label: @buildr@
|
|
96
|
+
** Type: @Custom Command@
|
|
97
|
+
** Path: @/path/to/buildr@ (typically "/usr/bin/buildr")
|
|
98
|
+
|
|
99
|
+
*2. Create a Plan*
|
|
100
|
+
|
|
101
|
+
* Select the Create Plan tab from the Bamboo toolbar to enter the Create Plan
|
|
102
|
+
wizard.
|
|
103
|
+
* In "1. Plan Details", define your build plan including project name, project
|
|
104
|
+
key, build plan name and build plan key.
|
|
105
|
+
* In "2. Source Repository", specify your source code repository settings (CVS
|
|
106
|
+
or SVN).
|
|
107
|
+
* In "3. Builder Configuration", specify the "buildr" builder that you defined
|
|
108
|
+
above, along with the following:
|
|
109
|
+
** Argument: @"test=all"@ (ensures that all tests are run through even if
|
|
110
|
+
failures are encountered)
|
|
111
|
+
** Test Results Directory: @"**/reports/junit/*.xml"@ (or your path to test
|
|
112
|
+
results, if different).
|
|
113
|
+
* The remaining wizard sections may be either skipped or configured with your
|
|
114
|
+
preferred settings.
|
|
115
|
+
|
|
116
|
+
*3. Trigger a Build*
|
|
117
|
+
|
|
118
|
+
A build should occur automatically at the point of project creation. It can
|
|
119
|
+
also be manually triggered at any time
|
|
120
|
+
|
|
121
|
+
* Navigate to the project summary page (located at:
|
|
122
|
+
@http://YOUR_BAMBOO_URL/browse/PROJECTKEY-YOURPLAN@).
|
|
123
|
+
* Click on the small arrow to the left of the label "Build Actions"
|
|
124
|
+
* Select "Checkout and Build" from the pop-up menu to force a build.
|
|
125
|
+
|
|
126
|
+
The project page will contain full status information for previous builds and
|
|
127
|
+
the results tabs will integrate the results from your JUnit tests.
|