assaf-buildr 1.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. data/CHANGELOG +887 -0
  2. data/DISCLAIMER +7 -0
  3. data/LICENSE +176 -0
  4. data/NOTICE +26 -0
  5. data/README.rdoc +146 -0
  6. data/Rakefile +62 -0
  7. data/_buildr +38 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/cobertura.rb +236 -0
  10. data/addon/buildr/emma.rb +238 -0
  11. data/addon/buildr/hibernate.rb +142 -0
  12. data/addon/buildr/javacc.rb +85 -0
  13. data/addon/buildr/jdepend.rb +60 -0
  14. data/addon/buildr/jetty.rb +248 -0
  15. data/addon/buildr/jibx.rb +86 -0
  16. data/addon/buildr/nailgun.rb +817 -0
  17. data/addon/buildr/openjpa.rb +90 -0
  18. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  19. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  20. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  21. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  22. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  23. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  25. data/addon/buildr/xmlbeans.rb +93 -0
  26. data/bin/buildr +28 -0
  27. data/buildr.buildfile +53 -0
  28. data/buildr.gemspec +58 -0
  29. data/doc/css/default.css +228 -0
  30. data/doc/css/print.css +100 -0
  31. data/doc/css/syntax.css +52 -0
  32. data/doc/images/apache-incubator-logo.png +0 -0
  33. data/doc/images/buildr-hires.png +0 -0
  34. data/doc/images/buildr.png +0 -0
  35. data/doc/images/favicon.png +0 -0
  36. data/doc/images/growl-icon.tiff +0 -0
  37. data/doc/images/note.png +0 -0
  38. data/doc/images/project-structure.png +0 -0
  39. data/doc/images/tip.png +0 -0
  40. data/doc/images/zbuildr.tif +0 -0
  41. data/doc/pages/artifacts.textile +207 -0
  42. data/doc/pages/building.textile +240 -0
  43. data/doc/pages/contributing.textile +208 -0
  44. data/doc/pages/download.textile +62 -0
  45. data/doc/pages/extending.textile +175 -0
  46. data/doc/pages/getting_started.textile +273 -0
  47. data/doc/pages/index.textile +42 -0
  48. data/doc/pages/languages.textile +407 -0
  49. data/doc/pages/mailing_lists.textile +17 -0
  50. data/doc/pages/more_stuff.textile +286 -0
  51. data/doc/pages/packaging.textile +427 -0
  52. data/doc/pages/projects.textile +274 -0
  53. data/doc/pages/recipes.textile +103 -0
  54. data/doc/pages/settings_profiles.textile +274 -0
  55. data/doc/pages/testing.textile +212 -0
  56. data/doc/pages/troubleshooting.textile +103 -0
  57. data/doc/pages/whats_new.textile +323 -0
  58. data/doc/print.haml +51 -0
  59. data/doc/print.toc.yaml +29 -0
  60. data/doc/scripts/buildr-git.rb +412 -0
  61. data/doc/scripts/install-jruby.sh +44 -0
  62. data/doc/scripts/install-linux.sh +64 -0
  63. data/doc/scripts/install-osx.sh +52 -0
  64. data/doc/site.haml +56 -0
  65. data/doc/site.toc.yaml +47 -0
  66. data/etc/KEYS +151 -0
  67. data/etc/git-svn-authors +16 -0
  68. data/lib/buildr.rb +35 -0
  69. data/lib/buildr/core.rb +27 -0
  70. data/lib/buildr/core/application.rb +489 -0
  71. data/lib/buildr/core/application_cli.rb +139 -0
  72. data/lib/buildr/core/build.rb +311 -0
  73. data/lib/buildr/core/checks.rb +382 -0
  74. data/lib/buildr/core/common.rb +154 -0
  75. data/lib/buildr/core/compile.rb +596 -0
  76. data/lib/buildr/core/environment.rb +120 -0
  77. data/lib/buildr/core/filter.rb +362 -0
  78. data/lib/buildr/core/generate.rb +195 -0
  79. data/lib/buildr/core/help.rb +118 -0
  80. data/lib/buildr/core/progressbar.rb +156 -0
  81. data/lib/buildr/core/project.rb +892 -0
  82. data/lib/buildr/core/test.rb +715 -0
  83. data/lib/buildr/core/transports.rb +558 -0
  84. data/lib/buildr/core/util.rb +289 -0
  85. data/lib/buildr/groovy.rb +18 -0
  86. data/lib/buildr/groovy/bdd.rb +105 -0
  87. data/lib/buildr/groovy/compiler.rb +138 -0
  88. data/lib/buildr/ide.rb +19 -0
  89. data/lib/buildr/ide/eclipse.rb +212 -0
  90. data/lib/buildr/ide/idea.ipr.template +300 -0
  91. data/lib/buildr/ide/idea.rb +189 -0
  92. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  93. data/lib/buildr/ide/idea7x.rb +210 -0
  94. data/lib/buildr/java.rb +23 -0
  95. data/lib/buildr/java/ant.rb +92 -0
  96. data/lib/buildr/java/bdd.rb +449 -0
  97. data/lib/buildr/java/commands.rb +211 -0
  98. data/lib/buildr/java/compiler.rb +348 -0
  99. data/lib/buildr/java/deprecated.rb +141 -0
  100. data/lib/buildr/java/jruby.rb +117 -0
  101. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  102. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  103. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +119 -0
  104. data/lib/buildr/java/packaging.rb +713 -0
  105. data/lib/buildr/java/pom.rb +178 -0
  106. data/lib/buildr/java/rjb.rb +155 -0
  107. data/lib/buildr/java/test_result.rb +308 -0
  108. data/lib/buildr/java/tests.rb +324 -0
  109. data/lib/buildr/java/version_requirement.rb +172 -0
  110. data/lib/buildr/packaging.rb +21 -0
  111. data/lib/buildr/packaging/artifact.rb +730 -0
  112. data/lib/buildr/packaging/artifact_namespace.rb +972 -0
  113. data/lib/buildr/packaging/artifact_search.rb +140 -0
  114. data/lib/buildr/packaging/gems.rb +102 -0
  115. data/lib/buildr/packaging/package.rb +233 -0
  116. data/lib/buildr/packaging/tar.rb +104 -0
  117. data/lib/buildr/packaging/zip.rb +722 -0
  118. data/lib/buildr/resources/buildr.icns +0 -0
  119. data/lib/buildr/scala.rb +19 -0
  120. data/lib/buildr/scala/compiler.rb +109 -0
  121. data/lib/buildr/scala/tests.rb +203 -0
  122. data/rakelib/apache.rake +191 -0
  123. data/rakelib/changelog.rake +57 -0
  124. data/rakelib/doc.rake +103 -0
  125. data/rakelib/package.rake +73 -0
  126. data/rakelib/release.rake +65 -0
  127. data/rakelib/rspec.rake +83 -0
  128. data/rakelib/rubyforge.rake +53 -0
  129. data/rakelib/scm.rake +49 -0
  130. data/rakelib/setup.rake +86 -0
  131. data/rakelib/stage.rake +48 -0
  132. data/spec/addon/cobertura_spec.rb +77 -0
  133. data/spec/addon/emma_spec.rb +120 -0
  134. data/spec/addon/test_coverage_spec.rb +255 -0
  135. data/spec/core/application_spec.rb +412 -0
  136. data/spec/core/artifact_namespace_spec.rb +646 -0
  137. data/spec/core/build_spec.rb +415 -0
  138. data/spec/core/checks_spec.rb +537 -0
  139. data/spec/core/common_spec.rb +664 -0
  140. data/spec/core/compile_spec.rb +566 -0
  141. data/spec/core/generate_spec.rb +33 -0
  142. data/spec/core/project_spec.rb +754 -0
  143. data/spec/core/test_spec.rb +1091 -0
  144. data/spec/core/transport_spec.rb +500 -0
  145. data/spec/groovy/bdd_spec.rb +80 -0
  146. data/spec/groovy/compiler_spec.rb +239 -0
  147. data/spec/ide/eclipse_spec.rb +243 -0
  148. data/spec/java/ant.rb +28 -0
  149. data/spec/java/bdd_spec.rb +358 -0
  150. data/spec/java/compiler_spec.rb +446 -0
  151. data/spec/java/java_spec.rb +88 -0
  152. data/spec/java/packaging_spec.rb +1103 -0
  153. data/spec/java/tests_spec.rb +466 -0
  154. data/spec/packaging/archive_spec.rb +503 -0
  155. data/spec/packaging/artifact_spec.rb +754 -0
  156. data/spec/packaging/packaging_helper.rb +63 -0
  157. data/spec/packaging/packaging_spec.rb +589 -0
  158. data/spec/sandbox.rb +137 -0
  159. data/spec/scala/compiler_spec.rb +228 -0
  160. data/spec/scala/tests_spec.rb +215 -0
  161. data/spec/spec_helpers.rb +304 -0
  162. data/spec/version_requirement_spec.rb +123 -0
  163. metadata +369 -0
@@ -0,0 +1,274 @@
1
+ h1. Projects
2
+
3
+ h2. Starting Out
4
+
5
+ In Java, most projects are built the same way: compile source code, run test cases, package the code, release it. Rinse, repeat.
6
+
7
+ Feed it a project definition, and Buildr will set up all these tasks for you. The only thing you need to do is specify the parts that are specific to your project, like the classpath dependencies, whether you're packaging a JAR or a WAR, etc.
8
+
9
+ The remainder of this guide deals with what it takes to build a project. But first, let's pick up a sample project to work with. We'll call it _killer-app_:
10
+
11
+ {{{!ruby
12
+ require 'buildr'
13
+
14
+ VERSION_NUMBER = '1.0'
15
+
16
+ AXIS2 = 'org.apache.axis2:axis2:jar:1.2'
17
+ AXIOM = group('axiom-api', 'axiom-impl', 'axiom-dom',
18
+ :under=>'org.apache.ws.commons.axiom', :version=>'1.2.4')
19
+ AXIS_OF_WS = [AXIOM, AXIS2]
20
+ OPENJPA = ['org.apache.openjpa:openjpa-all:jar:0.9.7',
21
+ 'net.sourceforge.serp:serp:jar:1.12.0']
22
+
23
+ repositories.remote << 'http://www.ibiblio.org/maven2/'
24
+
25
+ desc 'Code. Build. ??? Profit!'
26
+ define 'killer-app' do
27
+
28
+ project.version = VERSION_NUMBER
29
+ project.group = 'acme'
30
+ manifest['Copyright'] = 'Acme Inc (C) 2007'
31
+ compile.options.target = '1.5'
32
+
33
+ desc 'Abstract classes and interfaces'
34
+ define 'teh-api' do
35
+ package :jar
36
+ end
37
+
38
+ desc 'All those implementation details'
39
+ define 'teh-impl' do
40
+ compile.with AXIS_OF_WS, OPENJPA
41
+ compile { open_jpa_enhance }
42
+ package :jar
43
+ end
44
+
45
+ desc 'What our users see'
46
+ define 'la-web' do
47
+ test.using AXIS_OF_WS
48
+ package(:war).with :libs=>projects('teh-api', 'teh-impl')
49
+ end
50
+
51
+ javadoc projects
52
+ package :javadoc
53
+
54
+ end
55
+ }}}
56
+
57
+ A project definition requires four pieces of information: the project name, group identifier, version number and base directory. The project name ... do we need to explain why its necessary? The group identifier and version number are used for packaging and deployment, we'll talk more about that in the "Packaging":packaging.html section. The base directory lets you find files inside the project.
58
+
59
+ Everything else depends on what that particular project is building. And it all goes inside the project definition block, the piece of code that comes between @define <name> .. do@ and @end@.
60
+
61
+
62
+ h2. The Directory Structure
63
+
64
+ Buildr follows a convention we picked from years of working with Apache projects.
65
+
66
+ Java projects are laid out so the source files are in the @src/main/java@ directory and compile into the @target/classes@ directory. Resource files go in the @src/main/resources@ directory, and copied over to @target/resources@. Likewise, tests come from @src/test/java@ and @src/test/resources@, and end life in @target/test/classes@ and @target/test/resources@, respectively.
67
+
68
+ WAR packages pick up additional files from the aptly named @src/main/webapp@. And most stuff, including generated source files are parked under the @target@ directory. Test cases and such may generate reports in the, you guessed it, @reports@ directory.
69
+
70
+ Other languages will use different directories, but following the same general conventions. For example, Scala code compiles from the @src/main/scala@ directory, RSpec tests are found in the @src/test/rspec@ directory, and Flash will compile to @target/flash@. Throughout this document we will show examples using mostly Java, but you can imagine how this pattern applies to other languages.
71
+
72
+ When projects grow big, you split them into smaller projects by nesting projects inside each other. Each sub-project has a sub-directory under the parent project and follows the same internal directory structure. You can, of course, change all of that to suite your needs, but if you follow these conventions, Buildr will figure all the paths for you.
73
+
74
+ Going back to the example above, the directory structure will look something like this:
75
+
76
+ p=. !images/project-structure.png!
77
+
78
+ Notice the @buildfile@ at the top. That's your project build script, the one Buildr runs.
79
+
80
+ When you run the @buildr@ command, it picks up the @buildfile@ (which here we'll just call _Buildfile_) from the current directory, or if not there, from the closest parent directory. So you can run @buildr@ from any directory inside your project, and it will always pick up the same Buildfile. That also happens to be the base directory for the top project. If you have any sub-projects, Buildr assumes they reflect sub-directories under their parent.
81
+
82
+ And yes, you can have two top projects in the same Buildfile. For example, you can use that to have one project that groups all the application modules (JARs, WARs, etc) and another project that groups all the distribution packages (binary, sources, javadocs).
83
+
84
+ When you start with a new project you won't see the @target@ or @reports@ directories. Buildr creates these when it needs to. Just know that they're there.
85
+
86
+
87
+ h2. Naming And Finding Projects
88
+
89
+ Each project has a given name, the first argument you pass when calling @define@. The project name is just a string, but we advise to stay clear of colon (@:@) and slashes (@/@ and @\@), which could conflict with other task and file names. Also, avoid using common Buildr task names, don't pick @compile@ or @build@ for your project name.
90
+
91
+ Since each project knows its parent project, child projects and siblings, you can reference them from within the project using just the given name. In other cases, you'll need to use the full name. The full name is just @parent:child@. So if you wanted to refer to _teh-impl_, you could do so with either @project('killer-app:teh-impl')@ or @project('killer-app').project('teh-impl')@.
92
+
93
+ The @project@ method is convenient when you have a dependency from one project to another, e.g. using the other project in the classpath, or accessing one of its source files. Call it with a project name and it will return that object or raise an error. You can also call it with no arguments and it will return the project itself. It's syntactic sugar that's useful when accessing project properties.
94
+
95
+ The @projects@ method takes a list of names and returns a list of projects. If you call it with no arguments on a project, it returns all its sub-projects. If you call it with no argument in any other context, it returns all the projects defined so far.
96
+
97
+ Let's illustrate this with a few examples:
98
+
99
+ {{{!ruby
100
+ puts projects.inspect
101
+ => [project("killer-app"), project("killer-app:teh-api") ... ]
102
+
103
+ puts project('killer-app').projects.inspect
104
+ => [project("killer-app:teh-api"), project("killer-app:teh-impl") ... ]
105
+
106
+ puts project('teh-api')
107
+ => No such project teh-api
108
+
109
+ puts project('killer-app:teh-api').inspect
110
+ => project("killer-app:teh-api")
111
+
112
+ puts project('killer-app').project('teh-api').inspect
113
+ => project("killer-app:teh-api")
114
+ }}}
115
+
116
+ To see a list of all projects defined in your Buildfile:
117
+
118
+ {{{!sh
119
+ $ buildr help:projects
120
+ }}}
121
+
122
+
123
+ h2. Running Project Tasks
124
+
125
+ Most times, you run tasks like @build@ or @package@ that operate on the current project and recursively on its sub-projects. The "current project" is the one that uses the current working directory. So if you're in the @la-web/src@ directory looking at source files, _la-web_ is the current project. For example:
126
+
127
+ {{{!sh
128
+ # build killer-app and all its sub-projects
129
+ $ buildr build
130
+
131
+ # switch to and test only teh-impl
132
+ $ cd teh-impl
133
+ $ buildr test
134
+
135
+ # switch to and package only la-web
136
+ $ cd ../la-web
137
+ $ buildr package
138
+ }}}
139
+
140
+ You can use the project's full name to invoke one of its tasks directly, and it doesn't matter which directory you're in. For example:
141
+
142
+ {{{!sh
143
+ # build killer-app and all its sub-projects
144
+ $ buildr killer-app:build
145
+
146
+ # test only teh-impl
147
+ $ buildr killer-app:teh-impl:test
148
+
149
+ # package only la-web
150
+ $ buildr killer-app:la-web:package
151
+ }}}
152
+
153
+ Buildr provides the following tasks that you can run on the current project, or on a specific project by prefixing them with the project's full name:
154
+
155
+ {{{
156
+ clean # Clean files generated during a build
157
+ compile # Compile all projects
158
+ build # Build the project
159
+ upload # Upload packages created by the project
160
+ install # Install packages created by the project
161
+ javadoc # Create the Javadocs for this project
162
+ package # Create packages
163
+ test # Run all test cases
164
+ uninstall # Remove previously installed packages
165
+ }}}
166
+
167
+ To see a list of all the tasks provided by Buildr:
168
+
169
+ {{{!sh
170
+ $ buildr help:tasks
171
+ }}}
172
+
173
+ h2. Setting Project Properties
174
+
175
+ We mentioned the group identifier, version number and base directory. These are project properties. There are a few more properties we'll cover later on.
176
+
177
+ There are two ways to set project properties. You can pass them as a hash when you call @define@, or use accessors to set them on the project directly. For example:
178
+
179
+ {{{!ruby
180
+ define 'silly', :version=>'1.0' do
181
+ project.group = 'acme'
182
+ end
183
+
184
+ puts project('silly').version
185
+ => 1.0
186
+ puts project('silly').group
187
+ => acme
188
+ }}}
189
+
190
+ Project properties are inherited. You can specify them once in the parent project, and they'll have the same value in all its sub-projects. In the example, we only specify the version number once, for use in all sub-projects.
191
+
192
+
193
+ h2. Resolving Paths
194
+
195
+ You can run @buildr@ from any directory in your project. To keep tasks consistent and happy, it switches over to the Buildfile directory and executes all the tasks from there, before returning back to your working directory. Your tasks can all rely on relative paths that start from the same directory as the Buildfile.
196
+
197
+ But in practice, you'll want to use the @path_to@ method. This method calculates a path relative to the project, a better way if you ever need to refactor your code, say turn a ad hoc task into a function you reuse.
198
+
199
+ The @path_to@ method takes an array of strings and concatenates them into a path. Absolute paths are returned as they are, relative paths are expanded relative to the project's base directory. Slashes, if you don't already know, work very well on both Windows, Linux and OS X. And as a shortcut, you can use @_@.
200
+
201
+ For example:
202
+
203
+ {{{!ruby
204
+ # Relative to the current project
205
+ path_to('src', 'main', 'java')
206
+
207
+ # Exactly the same thing
208
+ _('src/main/java')
209
+
210
+ # Relative to the teh-impl project
211
+ project('teh-impl')._('src/main/java')
212
+ }}}
213
+
214
+
215
+ h2. Defining The Project
216
+
217
+ The project definition itself gives you a lot of pre-canned tasks to start with, but that's not enough to build a project. You need to specify what gets built and how, which dependencies to use, the packages you want to create and so forth. You can configure existing tasks, extend them to do additional work, and create new tasks. All that magic happens inside the project definition block.
218
+
219
+ Since the project definition executes each time you run Buildr, you don't want to perform any work directly inside the project definition block. Rather, you want to use it to specify how different build task work when you invoke them. Here's an example to illustrate the point:
220
+
221
+ {{{!ruby
222
+ define 'silly' do
223
+ puts 'Running buildr'
224
+
225
+ build do
226
+ puts 'Building silly'
227
+ end
228
+ end
229
+ }}}
230
+
231
+ Each time you run Buildr, it will execute the project definition and print out "Running buildr". We also extend the @build@ task, and whenever we run it, it will print "Building silly". Incidentally, @build@ is the default task, so if you run Buildr with no arguments, it will print both messages while executing the build. If you run Buildr with a different task, say @clean@, it will only print the first message.
232
+
233
+ The @define@ method gathers the project definition, but does not execute it immediately. It executes the project definition the first time you reference that project, directly or indirectly, for example, by calling @project@ with that project's name, or calling @projects@ to return a list of all projects. Executing a project definition will also execute all its sub-projects' definitions. And, of course, all project definitions are executed once the Buildfile loads, so Buildr can determine how to execute each of the build tasks.
234
+
235
+ If this sounds a bit complex, don't worry. In reality, it does the right thing. A simple rule to remember is that each project definition is executed before you need it, lazy evaluation of sort. The reason we do that? So you can write projects that depend on each other without worrying about their order.
236
+
237
+ In our example, the _la-web_ project depends on packages created by the _teh-api_ and _teh-impl_ projects, the later requiring _teh-api_ to compile. That example is simple enough that we ended up specifying the projects in order of dependency. But you don't always want to do that. For large projects, you may want to group sub-projects by logical units, or sort them alphabetically for easier editing.
238
+
239
+ One project can reference another ahead of its definition. If Buildr detects a cyclic dependency, it will let you know.
240
+
241
+ In this example we define one project in terms of another, using the same dependencies, so we only need to specify them once:
242
+
243
+ {{{!ruby
244
+ define 'bar' do
245
+ compile.with project('foo').compile.dependencies
246
+ end
247
+
248
+ define 'foo' do
249
+ compile.with ..lots of stuff..
250
+ end
251
+ }}}
252
+
253
+ One last thing to remember. Actually three, but they all go hand in hand.
254
+
255
+ *Self is project* Each of these project definition blocks executes in the context of that project, just as if it was a method defined on the project. So when you call the @compile@ method, you're essentially calling that method on the current project: @compile@, @self.compile@ and @project.compile@ are all the same.
256
+
257
+ *Blocks are closures* The project definition is also a closure, which can reference variables from enclosing scopes. You can use that, for example, to define constants, variables and even functions in your Buildfile, and reference them from your project definition. As you'll see later on, in the "Artifacts":#artifacts section, it will save you a lot of work.
258
+
259
+ *Projects are namespaces* While executing the project definition, Buildr switches the namespace to the project name. If you define the task "do-this" inside the _teh-impl_ project, the actual task name is "killer-app:teh-impl:do-this". Likewise, the @compile@ task is actually "killer-app:teh-impl:compile".
260
+
261
+ From outside the project you can reference a task by its full name, either @task('foo:do')@ or @project('foo').task('do')@. If you need to reference a task defined outside the project from within the project, prefix it with "rake:", for example, @task('rake:globally-defined')@.
262
+
263
+
264
+ h2. Writing Your Own Tasks
265
+
266
+ Of all the features Buildr provide, it doesn't have a task for making coffee. Yet. If you need to write your own tasks, you get all the power of Rake: you can use regular tasks, file tasks, task rules and even write your own custom task classes. Check out the "Rake documentation":http://docs.rubyrake.org/ for more information.
267
+
268
+ We mentioned projects as namespaces before. When you call @task@ on a project, it finds or defines the task using the project namespace. So given a project object, @task('do-this')@ will return it's "do-this" task. If you lookup the source code for the @compile@ method, you'll find that it's little more than a shortcut for @task('compile')@.
269
+
270
+ Another shortcut is the @file@ method. When you call @file@ on a project, Buildr uses the @path_to@ method to expand relative paths using the project's base directory. If you call @file('src')@ on _teh-impl_, it will return you a file task that points at the @teh-impl/src@ directory.
271
+
272
+ In the current implementation projects are also created as tasks, although you don't invoke these tasks directly. That's the reason for not using a project name that conflicts with an existing task name. If you do that, you'll find quick enough, as the task will execute each time you run Buildr.
273
+
274
+ So now that you know everything about projects and tasks, let's go and "build some code":building.html.
@@ -0,0 +1,103 @@
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 OS-specific path separator:
9
+
10
+ {{{!ruby
11
+ cp = paths.join(File::PATH_SEPARATOR)
12
+ }}}
13
+
14
+ This assumes @paths@ points to files and/or directories, but what if you have a list of artifact specifications? You can turn those into file names in two steps. First, use @artifacts@ to return a list of file tasks that point to the local repository:
15
+
16
+ {{{!ruby
17
+ tasks = Buildr.artifacts(specs)
18
+ }}}
19
+
20
+ Next, map that list of tasks into list of file names (essentially calling @name@ on each task):
21
+
22
+ {{{!ruby
23
+ paths = tasks.map(&:name)
24
+ }}}
25
+
26
+ This works as long as the artifacts are already in your local repository, otherwise they can't be found, but you can ask Buildr to download them by calling @invoke@ on each of these tasks:
27
+
28
+ {{{!ruby
29
+ tasks = Buildr.artifacts(specs).each(&:invoke)
30
+ }}}
31
+
32
+ So let's roll this all into a single line:
33
+
34
+ {{{!ruby
35
+ cp = Buildr.artifacts(specs).each(&:invoke).map(&:name).join(File::PATH_SEPARATOR)
36
+ }}}
37
+
38
+
39
+ h2. Keeping your Profiles.yaml file DRY
40
+
41
+ YAML allows you to use anchors (@&@), similar to ID attributes in XML, and reference them later on (@*@). For example, if you have two profiles that are identical, you can tell YAML that one is an alias for the other:
42
+
43
+ {{{!yaml
44
+ development: &common
45
+ db: oracle
46
+ port: 8080
47
+ test: *common
48
+ production: *common
49
+ }}}
50
+
51
+ If you have two elements that are almost identical, you can merge the values of one element into another (@<<@), for example:
52
+
53
+ {{{!yaml
54
+ development: &common
55
+ db: hsql
56
+ jdbc: hsqldb:mem:devdb
57
+ test:
58
+ <<: *common
59
+ jdbc: hsqldb:file:testdb
60
+ }}}
61
+
62
+
63
+ h2. Speeding JRuby
64
+
65
+ When using JRuby you will notice that Buildr takes a few seconds to start up. To speed it up, we recommend switching to Java 1.6 and running the JVM in client mode:
66
+
67
+ {{{!
68
+ $ export JAVA_OPTS=-client
69
+ }}}
70
+
71
+
72
+ h2. Continuous Integration with Atlassian Bamboo
73
+
74
+ This recipe outlines how to configure a new Bamboo project to use Buildr. The following steps assume that you have logged-on to Bamboo as an Administrator.
75
+
76
+ *1. Configure a Builder*
77
+
78
+ * Select the Administration tab from the Bamboo toolbar.
79
+ * Select the Builders area (first option) from the Administration menu.
80
+ * Using the Add Builder dialog, configure a custom builder for Buildr with the following options:
81
+ ** Label: @buildr@
82
+ ** Type: @Custom Command@
83
+ ** Path: @/path/to/buildr@ (typically "/usr/bin/buildr")
84
+
85
+ *2. Create a Plan*
86
+
87
+ * Select the Create Plan tab from the Bamboo toolbar to enter the Create Plan wizard.
88
+ * In "1. Plan Details", define your build plan including project name, project key, build plan name and build plan key.
89
+ * In "2. Source Repository", specify your source code repository settings (CVS or SVN).
90
+ * In "3. Builder Configuration", specify the "buildr" builder that you defined above, along with the following:
91
+ ** Argument: @"test=all"@ (ensures that all tests are run through even if failures are encountered)
92
+ ** Test Results Directory: @"**/reports/junit/*.xml"@ (or your path to test results, if different).
93
+ * The remaining wizard sections may be either skipped or configured with your preferred settings.
94
+
95
+ *3. Trigger a Build*
96
+
97
+ A build should occur automatically at the point of project creation. It can also be manually triggered at any time
98
+
99
+ * Navigate to the project summary page (located at: @http://YOUR_BAMBOO_URL/browse/PROJECTKEY-YOURPLAN@).
100
+ * Click on the small arrow to the left of the label "Build Actions"
101
+ * Select "Checkout and Build" from the pop-up menu to force a build.
102
+
103
+ The project page will contain full status information for previous builds and the results tabs will integrate the results from your JUnit tests.
@@ -0,0 +1,274 @@
1
+ h1. Settings/Profiles
2
+
3
+
4
+ h2. Environment Variables
5
+
6
+ Buildr uses several environment variables that help you control how it works. Some environment variables you will only set once or change infrequently. You can set these in your profile, OS settings or any tool you use to launch Buildr (e.g. continuous integration).
7
+
8
+ For example:
9
+
10
+ {{{!sh
11
+ $ export HTTP_PROXY=http://myproxy:8080
12
+ }}}
13
+
14
+ There are other environment variables you will want to set when running Buildr, for example, to do a full build without running the tests:
15
+
16
+ {{{!sh
17
+ $ buildr test=no
18
+ }}}
19
+
20
+ For convenience, when you set environment variables on the command line, the variable name is case insensitive, you can use either @test=no@ or @TEST=no@. Any other way (@export@, @ENV@, etc) the variable names are case sensitive.
21
+
22
+ You can also set environment variables from within your Buildfile. For example, if you discover that building your project requires gobs of JVM heap space, and you want all other team members to run with the same settings:
23
+
24
+ {{{!ruby
25
+ # This project builds a lot of code.
26
+ ENV['JAVA_OPTS'] ||= '-Xms1g -Xmx1g'
27
+ }}}
28
+
29
+ Make sure to set any environment variables at the very top of the Buildfile, above any Ruby statement (even @require@).
30
+
31
+ p(tip). Using @||=@ sets the environment variable, if not already set, so it's still possible for other developers to override this environment variable without modifying the Buildfile.
32
+
33
+ Buildr supports the following environment variables:
34
+
35
+ |_. Variable |_. Description |
36
+ | @BUILDR_ENV@ | Environment name (development, production, test, etc). Another way to set this is using the @-e@ command line option. |
37
+ | @DEBUG@ | Set to @no/off@ if you want Buildr to compile without debugging information (default when running the @release@ task, see "Compiling":building.html#compiling). |
38
+ | @HOME@ | Your home directory. |
39
+ | @HTTP_PROXY@ | URL for HTTP proxy server (see "Specifying Repositories":artifacts.html#specifying_repositories). |
40
+ | @JAVA_HOME@ | Points to your JDK, required when using Java and Ant. |
41
+ | @JAVA_OPTS@ | Command line options to pass to the JDK (e.g. @'-Xms1g'@). |
42
+ | @M2_REPO@ | Location of the Maven2 local repository. Defaults to the @.m2@ directory in your home directory (@ENV['HOME']@). |
43
+ | @NO_PROXY@ | Comma separated list of hosts and domain that should not be proxied (see "Specifying Repositories":artifacts.html#specifying_repositories). |
44
+ | @TEST@ | Set to @no/off@ to tell Buildr to skip tests, or @all@ to tell Buildr to run all tests and ignore failures (see "Running Tests":testing.html#running_tests). |
45
+ | @USER@ | Tasks that need your user name, for example to log to remote servers, will use this environment variable. |
46
+
47
+ p(note). Buildr does not check any of the arguments in @JAVA_OPTS@. A common mistake is to pass an option like @mx512mb@, where it should be @Xmx512mb@. Make sure to double check @JAVA_OPTS@.
48
+
49
+ Some extensions may use additional environment variables, and of course, you can always add your own. This example uses two environment variables for specifying the username and password:
50
+
51
+ {{{!ruby
52
+ repositories.upload_to[:username] = ENV['USERNAME']
53
+ repositories.upload_to[:password] = ENV['PASSWORD']
54
+ }}}
55
+
56
+
57
+ h2. Personal Settings
58
+
59
+ Some things clearly do not belong in the Buildfile. For example, the username and password you use to upload releases. If you're working in a team or on an open source project, you'd want to keep these in a separate place.
60
+
61
+ You may want to use personal settings for picking up a different location for the local repository, or use a different set of preferred remote repositories, and so forth.
62
+
63
+ The prefered way to store personal settings is to create a @.buildr/settings.yaml@ file under your home directory. Settings stored there will be applied the same across all builds.
64
+
65
+ Here's an example @settings.yaml@:
66
+
67
+ {{{!yaml
68
+ # The repositories hash is read automatically by buildr.
69
+ repositories:
70
+
71
+ # customize user local maven2 repository location
72
+ local: some/path/to/my_repo
73
+
74
+ # prefer the local or nearest mirrors
75
+ remote:
76
+ - https://intra.net/maven2
77
+ - http://example.com
78
+
79
+ relase_to:
80
+ url: http://intra.net/maven2
81
+ username: john
82
+ password: secret
83
+
84
+ # You can place settings of your own, and reference them
85
+ # on buildfiles.
86
+ im:
87
+ server: jabber.company.com
88
+ usr: notifier@company-jabber.com
89
+ pwd: secret
90
+ }}}
91
+
92
+ Later your buildfile or addons can reference user preferences using the hash returned by the @Buildr.settings.user@ accessor.
93
+
94
+ {{{!ruby
95
+ task 'relase-notification' do
96
+ usr, pwd, server = settings.user['im'].values_at('usr', 'pwd', 'server')
97
+ jabber = JabberAPI.new(server, usr, pwd)
98
+ jabber.msg("We are pleased to announce the last stable version #{VERSION}")
99
+ end
100
+ }}}
101
+
102
+
103
+ h2. Build Settings
104
+
105
+ Build settings are local to the project being built, and are placed in the @build.yaml@ file located in the same directory that the @buildfile@. Normally this file would be managed by the project revision control system, so settings here are shared between developers.
106
+
107
+ They help keep the buildfile and build.yaml file simple and readable, working to the advantages of each one. Example for build settings are gems, repositories and artifacts used by that build.
108
+
109
+ {{{!yaml
110
+ # This project requires the following ruby gems, buildr addons
111
+ gems:
112
+ # Suppose we want to notify developers when testcases fail.
113
+ - buildr-twitter-notifier-addon >=1
114
+ # we test with ruby mock objects
115
+ - mocha
116
+ - ci_reporter
117
+
118
+ # The artifact declarations will be automatically loaded by buildr, so that
119
+ # you can reference artifacts by name (a ruby-symbol) on your buildfile.
120
+ artifacts:
121
+ spring: org.springframework:spring:jar:2.0
122
+ log4j: log4j:log4j:jar:1.0
123
+ j2ee: geronimo-spec:geronimo-spec-j2ee:jar:1.4-rc4
124
+
125
+ # Of course project settings can be defined here
126
+ twitter:
127
+ notify:
128
+ test_failure: unless-modified
129
+ compile_failure: never
130
+ developers:
131
+ - joe
132
+ - jane
133
+
134
+ jira:
135
+ uri: https://jira.corp.org
136
+ }}}
137
+
138
+ When buildr is loaded, required ruby gems will be installed if needed, thus adding features like the imaginary twitter notifier addon.
139
+
140
+ Artifacts defined on @build.yaml@ can be referenced on your buildfile by supplying the ruby symbol to the @Buildr.artifact@ and @Buildr.artifacts@ methods. The @compile.with@, @test.with@ methods can also be given these names.
141
+
142
+ {{{!ruby
143
+ define 'my_project' do
144
+ compile.with artifacts(:log4j, :j2ee)
145
+ test.with :spring, :j2ee
146
+ end
147
+ }}}
148
+
149
+ Build settings can be retreived using the @Buildr.settings.build@ accessor.
150
+
151
+ {{{!ruby
152
+ task 'create_patch' do
153
+ patch = Git.create_patch :interactive => true
154
+ if patch && agree("Would you like to request inclusion of #{patch}")
155
+ jira = Jira.new( Buildr.settings.build['jira']['uri'] ) # submit a patch
156
+ jira.create(:improvement, patch.summary, :attachment => patch.blob)
157
+ end
158
+ end
159
+ }}}
160
+
161
+ h2. Non constant settings
162
+
163
+ Before loading the Buildfile, Buildr will attempt to load two other files: the @buildr.rb@ file it finds in your home directory, followed by the @buildr.rb@ file it finds in the build directory.
164
+
165
+ The loading order allows you to place global settings that affect all your builds in your home directory's @buildr.rb@, but also over-ride those with settings for a given project.
166
+
167
+ Here's an example @buildr.rb@:
168
+
169
+ {{{!ruby
170
+ # Only I should know that
171
+ repositories.upload_to[:username] = 'assaf'
172
+ repositories.upload_to[:password] = 'supersecret'
173
+ # Search here first, it's faster
174
+ repositories.remote << 'http://inside-the-firewall'
175
+ }}}
176
+
177
+
178
+ h2. Environments
179
+
180
+ One common use case is adapting the build to different environments. For example, to compile code with debugging information during development and testing, but strip it for production. Another example is using different databases for development, testing and production, or running services at different URLs.
181
+
182
+ So let's start by talking about the build environment. Buildr has a global attributes that indicates which environment it's running in, accessible from the @environment@ method. You can set the current build environment in one of two ways. Using the @-e/--environment@ command line option:
183
+
184
+ {{{!sh
185
+ $ buildr -e test
186
+ (in /home/john/project, test)
187
+ }}}
188
+
189
+ Or by setting the environment variable @BUILDR_ENV@:
190
+
191
+ {{{!
192
+ $ export BUILDR_ENV=production
193
+ $ buildr
194
+ (in /home/john/project, production)
195
+ }}}
196
+
197
+ Unless you tell it otherwise, Buildr assumes you're developing and sets the environment to @development@.
198
+
199
+ Here's a simple example for handling different environments within the Buildfile:
200
+
201
+ {{{!ruby
202
+ project 'db-module' do
203
+ db = (environment == 'production' ? 'oracle' : 'hsql')
204
+ resources.from(_(:source, :main, db))
205
+ end
206
+ }}}
207
+
208
+ We recommend picking a convention for your different environments and following it across all your projects. For example:
209
+
210
+ |_. Environment |_. Use when ... |
211
+ | development | Developing on your machine. |
212
+ | test | Running in test environment, continuous integration. |
213
+ | production | Building for release/production. |
214
+
215
+
216
+ h2. Profiles
217
+
218
+ Different environments may require different configurations, some you will want to control with code, others you will want to specify in the profiles file.
219
+
220
+ The profiles file is a YAML file called @profiles.yaml@ that you place in the same directory as the Buildfile. We selected YAML because it's easier to read and edit than XML.
221
+
222
+ For example, to support three different database configurations, we could write:
223
+
224
+ {{{!yaml
225
+ # HSQL, don't bother storing to disk.
226
+ development:
227
+ db: hsql
228
+ jdbc: hsqldb:mem:devdb
229
+
230
+ # Make sure we're not messing with bigstrong.
231
+ test:
232
+ db: oracle
233
+ jdbc: oracle:thin:@localhost:1521:test
234
+
235
+ # The real deal.
236
+ production:
237
+ db: oracle
238
+ jdbc: oracle:thin:@bigstrong:1521:mighty
239
+ }}}
240
+
241
+ Here's a simple example for a buildfile that uses the profile information:
242
+
243
+ {{{!ruby
244
+ project 'db-module' do
245
+ # Copy SQL files specific for the database we're using,
246
+ # for example, everything under src/main/hsql.
247
+ resources.from(_(:source, :main, profile['db']))
248
+ # Set the JDBC URL in copied resource files (config.xml needs this).
249
+ resources.filter :jdbc=>profile['jdbc']
250
+ end
251
+ }}}
252
+
253
+ The @profile@ method returns the current profile, selected based on the current "environment":#environments. You can get a list of all profiles by calling @profiles@.
254
+
255
+ When you run the above example in @development@, the current profile will return the hash @{ 'db'=>'hsql', 'jdbc'=>'hsqldb:mem:devdb' }@.
256
+
257
+ We recommend following conventions and using the same environments in all your projects, but sometimes the profiles end up being the same, so here's a trick you can use to keep your profiles DRY.
258
+
259
+ YAML allows you to use anchors (@&@), similar to ID attributes in XML, reference the anchored element (@*@) elsewhere, and merge one element into another (@<<@). For example:
260
+
261
+ {{{!yaml
262
+ # We'll reference this one as common.
263
+ development: &common
264
+ db: hsql
265
+ jdbc: hsqldb:mem:devdb
266
+ resources:
267
+ copyright: Me (C) 2008
268
+ # Merge the values from common, override JDBC URL.
269
+ test:
270
+ <<: *common
271
+ jdbc: hsqldb:file:testdb
272
+ }}}
273
+
274
+ You can "learn more about YAML here":http://www.yaml.org, and use this handy "YAML quick reference":http://www.yaml.org/refcard.html.