buildr 1.0.0 → 1.1.0

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 CHANGED
@@ -1,3 +1,20 @@
1
+ 1.1.0 (5/13/2007)
2
+ * Added: Proxy setting for downloading from remote repositories (use repositories.proxy = ...).
3
+ * Added: projects task to list all the projects you can build.
4
+ * Added: Project attribute target to specify the target directory.
5
+ * Changed: The project and projects methods now accepts relative names when called on a project. For example, project("foo").project("bar") finds the sub-project "bar" in "foo".
6
+ * Changed: The project method now returns self if called on a method with no name.
7
+ * Changed: The -warning flag (javac) is now set to true only when verbose.
8
+ * Changed: OpenJPA mapping now using Ant task instead of spawning another Java instance.
9
+ * Changed: The test:name pattern translates to *name* so you can run tests by package name, but only if you don't use * in the pattern.
10
+ * Changed: All projects are not evaluated when referenced (i.e. calling project/projects) or before running any task. Project tasks do not exist until a projet is evaluated.
11
+ * Removed: The projects method no longer accepts the :in argument, call projects on a project instead.
12
+ * Fixed: Local directory tasks now work from any directory in the project.
13
+ * Fixed: Artifacts no longer created with timestamp from server.
14
+ * Fixed: Buildr no longer fails when run without tools.jar or JAVA_HOME (OS/X). (Credit Lyle Johnson)
15
+ * Fixed: Manifest gets EOL to keep EOF company. (Credit Tommy Knowlton)
16
+ * Fixed: Compile tasks clean after themselves when target directory changed. (Credit Lyle Johnson)
17
+
1
18
  1.0.0 (5/4/2007)
2
19
  * Added: buildr:freeze and buildr:unfreeze task. These set the Rakefile to use a particular version of Buildr, freezing by setting to the current version of Buildr, unfreeze to use the latest Gem.
3
20
  * Added: Buildr.options, with three options to start with: test, debug and parallel.
data/LICENSE CHANGED
@@ -0,0 +1,202 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2006-2007, Intalio Inc.
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
202
+
data/README CHANGED
@@ -11,7 +11,7 @@ http://buildr.rubyforge.org
11
11
 
12
12
  === RTFM:
13
13
 
14
- * Buildr documentation: http://buildr.rubyforge.org/rdoc
14
+ * Buildr documentation: http://buildr.rubyforge.org
15
15
  * More about Rake: http://docs.rubyrake.org
16
16
  * Antwrap documentation: http://antwrap.rubyforge.org
17
17
 
@@ -52,7 +52,7 @@ To install:
52
52
  == Living On the Edge
53
53
 
54
54
  You can check the latest sources from SVN:
55
- svn co svn://www.intalio.org/usr/local/svn/repos/buildr/trunk buildr
55
+ svn co http://www.intalio.org/buildr/trunk/ buildr
56
56
  Or browse the SVN repository online: http://blog.intalio.org/viewrep/Buildr
57
57
 
58
58
  To install Buildr locally from source, do:
@@ -19,6 +19,8 @@ require "facet/array/head"
19
19
  require "facet/string/starts_with"
20
20
  require "facet/openobject"
21
21
  require "facets/core/kernel/tap"
22
+ # A different kind of buildr, one we use to create XML.
23
+ require "builder"
22
24
 
23
25
 
24
26
  module Kernel #:nodoc:
@@ -30,7 +32,7 @@ end
30
32
 
31
33
 
32
34
  module Buildr
33
- VERSION = "1.0.0"
35
+ VERSION = "1.1.0"
34
36
  end
35
37
 
36
38
  $LOAD_PATH.unshift __DIR__
@@ -49,10 +51,6 @@ class Object ; Buildr.constants.each { |c| const_set c, Buildr.const_get(c) unle
49
51
  class Project ; include Buildr ; end
50
52
 
51
53
 
52
- # The greate method_missing/Object extend bug requires us to load
53
- # XMLBuilder after we're done enhancing Object.
54
- require "builder"
55
-
56
54
  module Buildr
57
55
  @loaded_features_to_ignore = $LOADED_FEATURES
58
56
  end
@@ -73,3 +71,5 @@ Dir["#{Dir.pwd}/tasks/*.rake"].each do |file|
73
71
  $LOADED_FEATURES << file
74
72
  end
75
73
  end
74
+
75
+
@@ -5,9 +5,7 @@ module Buildr
5
5
 
6
6
  REQUIRES = [ "net.java.dev.javacc:javacc:jar:4.0", "net.java.dev.javacc:javacc:jar:4.0" ]
7
7
 
8
- Java.rjb.onload do
9
- Java.rjb.classpath << REQUIRES
10
- end
8
+ Java.rjb.classpath << REQUIRES
11
9
 
12
10
  class << self
13
11
 
@@ -45,7 +43,7 @@ module Buildr
45
43
  else
46
44
  in_package = []
47
45
  end
48
- file(path_to("target/generated/javacc")=>args.flatten) do |task|
46
+ file(path_to(:target, "generated/javacc")=>args.flatten) do |task|
49
47
  JavaCC.javacc task.prerequisites, :output=>File.join(task.name, in_package)
50
48
  end
51
49
  end
@@ -58,7 +56,7 @@ module Buildr
58
56
  else
59
57
  in_package = []
60
58
  end
61
- file(path_to("target/generated/jjtree")=>args.flatten) do |task|
59
+ file(path_to(:target, "generated/jjtree")=>args.flatten) do |task|
62
60
  JavaCC.jjtree task.prerequisites, :output=>File.join(task.name, in_package), :build_node_files=>build_node_files
63
61
  end
64
62
  end
@@ -43,10 +43,7 @@ module Buildr
43
43
  "org.mortbay.jetty:servlet-api-2.5:jar:6.1.1", "log4j:log4j:jar:1.2.13",
44
44
  "commons-logging:commons-logging:jar:1.1" ]
45
45
 
46
- Java.rjb.onload do
47
- Java.rjb.classpath << REQUIRES
48
- Java.rjb.classpath << File.join(__DIR__, "jetty")
49
- end
46
+ Java.rjb.classpath << REQUIRES << File.join(__DIR__, "jetty")
50
47
 
51
48
  # Default URL for Jetty.
52
49
  URL = "http://localhost:8080"
@@ -15,6 +15,8 @@ module Buildr
15
15
  "org.apache.geronimo.specs:geronimo-jta_1.0.1B_spec:jar:1.0",
16
16
  "net.sourceforge.serp:serp:jar:1.11.0" ]
17
17
 
18
+ Java.rjb.classpath << REQUIRES
19
+
18
20
  class << self
19
21
 
20
22
  def enhance(options)
@@ -34,11 +36,7 @@ module Buildr
34
36
 
35
37
  def mapping_tool(options)
36
38
  rake_check_options options, :classpath, :properties, :sql, :action
37
- Java.java "org.apache.openjpa.jdbc.meta.MappingTool", "-p", options[:properties].to_s, "-sql", options[:sql],
38
- "-sa", options[:action], :classpath=>Buildr.artifacts(options[:classpath], requires), :name=>"Mapping Tool"
39
- # Hopefully this will work in a future release.
40
- =begin
41
- artifacts = Buildr.artifacts(options[:classpath]).each{ |a| a.invoke }.map(&:to_s) + requires
39
+ artifacts = Buildr.artifacts(options[:classpath]).each{ |a| a.invoke }.map(&:to_s)
42
40
  properties = file(options[:properties].to_s).tap { |task| task.invoke }.to_s
43
41
 
44
42
  Ant.executable("openjpa") do |ant|
@@ -49,13 +47,12 @@ module Buildr
49
47
  classpath :path=>artifacts.join(File::PATH_SEPARATOR)
50
48
  end
51
49
  end
52
- =end
53
50
  end
54
51
 
55
52
  private
56
53
 
57
54
  def requires()
58
- @required ||= Buildr.artifacts(REQUIRES).each { |artifact| artifact.invoke }.map(&:to_s)
55
+ @requires ||= Buildr.artifacts(REQUIRES).each { |artifact| artifact.invoke }.map(&:to_s)
59
56
  end
60
57
 
61
58
  end
@@ -35,7 +35,7 @@ module Buildr
35
35
 
36
36
  def compile_xml_beans(*args)
37
37
  # Generate sources and add them to the compile task.
38
- generated = file(path_to("target/generated/xmlbeans")=>FileList[args.flatten]) do |task|
38
+ generated = file(path_to(:target, "generated/xmlbeans")=>FileList[args.flatten]) do |task|
39
39
  XMLBeans.compile task.prerequisites, :output=>task.name,
40
40
  :javasource=>compile.options.source, :xsb=>compile.target
41
41
  end
@@ -52,6 +52,17 @@ module Buildr
52
52
 
53
53
  class Project
54
54
 
55
+ # The target directory. By default, it's the target directory inside the project. Various tasks
56
+ # use it to determine where to place files, e.g. when compiling or packaging. The clean task
57
+ # nukes it.
58
+ def target()
59
+ @target ||= _("target")
60
+ end
61
+
62
+ def target=(dir)
63
+ @target = _(dir)
64
+ end
65
+
55
66
  # :call-seq:
56
67
  # build(*prereqs) => task
57
68
  # build { |task| .. } => task
@@ -72,6 +83,10 @@ module Buildr
72
83
 
73
84
  end
74
85
 
86
+ Project.on_define do |project|
87
+ project.clean { verbose(false) { rm_rf project.path_to(:target) } }
88
+ end
89
+
75
90
  desc "The default task it build"
76
91
  task "default"=>"build"
77
92
 
@@ -273,5 +273,5 @@ module Buildr
273
273
  def filter(source)
274
274
  Filter.new.from(source)
275
275
  end
276
-
276
+
277
277
  end
@@ -90,12 +90,11 @@ module Buildr
90
90
  # | |__classes <-- Generated when compiling
91
91
  # | |__test-classes <-- Generated when compiling tests
92
92
  #
93
- # You can only define a project once using #define. Afterwards, you
94
- # can obtain the project definition using #project. However, when
95
- # working with sub-projects, one project may reference another ahead
96
- # of its definition: the sub-project definitions are then evaluated
97
- # based on their dependencies with each other. Circular dependencies
98
- # are not allowed.
93
+ # You can only define a project once using #define. Afterwards, you can obtain the project
94
+ # definition using #project. The order in which you define projects is not important,
95
+ # project definitions are evaluated when you ask for them. Circular dependencies will not
96
+ # work. Rake tasks are only created after the project is evaluated, so if you need to access
97
+ # a task (e.g. compile) use <code>project("foo").compile</code> instead of <code>task("foo:compile")</code>.
99
98
  #
100
99
  # For example:
101
100
  # define "myapp", :version=>"1.1" do
@@ -121,6 +120,9 @@ module Buildr
121
120
 
122
121
  class << self
123
122
 
123
+ # :call-seq:
124
+ # define(name, properties?) { |project| ... } => project
125
+ #
124
126
  # See Buildr#define.
125
127
  def define(name, properties, &block) #:nodoc:
126
128
  # Make sure a sub-project is only defined within the parent project,
@@ -145,34 +147,62 @@ module Buildr
145
147
  # Top-level project? Invoke the project definition. Sub-project? We don't invoke
146
148
  # the project definiton yet (allow project() calls to establish order of evaluation),
147
149
  # but must do so before the parent project's definition is done.
148
- if project.parent
149
- project.parent.enhance { project.invoke }
150
- else
151
- project.invoke
152
- end
150
+ project.parent.enhance { project.invoke } if project.parent
153
151
  end
154
152
  end
155
153
 
154
+ # :call-seq:
155
+ # project(name) => project
156
+ #
156
157
  # See Buildr#project.
157
- def project(name) #:nodoc:
158
- @projects && @projects[name] or raise "No such project #{name}"
159
- @projects[name].tap { |project| project.invoke }
158
+ def project(*args) #:nodoc:
159
+ options = args.pop if Hash === args.last
160
+ rake_check_options options, :scope if options
161
+ raise ArgumentError, "Only one project name at a time" unless args.size == 1
162
+ @projects ||= {}
163
+ name = args.first
164
+ if options && options[:scope]
165
+ # We assume parent project is evaluated.
166
+ project = options[:scope].split(":").inject([[]]) { |scopes, scope| scopes << (scopes.last + [scope]) }.
167
+ map { |scope| @projects[(scope + [name]).join(":")] }.
168
+ select { |project| project }.last
169
+ end
170
+ unless project
171
+ # Parent project not evaluated.
172
+ name.split(":").tap { |parts| @projects[parts.first].invoke if parts.size > 1 }
173
+ project = @projects[name]
174
+ end
175
+ raise "No such project #{name}" unless project
176
+ project.invoke
177
+ project
160
178
  end
161
179
 
180
+ # :call-seq:
181
+ # projects(*names) => projects
182
+ #
162
183
  # See Buildr#projects.
163
184
  def projects(*names) #:nodoc:
164
185
  options = names.pop if Hash === names.last
165
- rake_check_options options, :in if options
186
+ rake_check_options options, :scope if options
166
187
  @projects ||= {}
167
- names = @projects.keys if names.empty?
168
- if options && options[:in]
169
- parent = @projects[options[:in].to_s] or raise "No such project #{options[:in].to_s}"
170
- names.uniq.map { |name| @projects[name] or raise "No such project #{name}" }.
171
- select { |project| project.parent == parent }.
172
- each { |project| project.invoke }.sort_by(&:name)
188
+ if options && options[:scope]
189
+ # We assume parent project is evaluated.
190
+ if names.empty?
191
+ parent = @projects[options[:scope]] or raise "No such project #{options[:scope]}"
192
+ @projects.values.select { |project| project.parent == parent }.
193
+ each { |project| project.invoke }.sort_by(&:name)
194
+ else
195
+ names.uniq.map { |name| project(name, :scope=>options[:scope]) }
196
+ end
197
+ elsif names.empty?
198
+ # Parent project(s) not evaluated so we don't know all the projects yet.
199
+ @projects.values.each(&:invoke)
200
+ @projects.keys.map { |name| project(name) or raise "No such project #{name}" }.sort_by(&:name)
173
201
  else
202
+ # Parent project(s) not evaluated, for the sub-projects we may need to find.
203
+ names.map { |name| name.split(":") }.select { |name| name.size > 1 }.map(&:first).uniq.each { |name| project(name) }
174
204
  names.uniq.map { |name| project(name) or raise "No such project #{name}" }.sort_by(&:name)
175
- end
205
+ end
176
206
  end
177
207
 
178
208
  # :call-seq:
@@ -207,7 +237,7 @@ module Buildr
207
237
  # and returns a message that, for example "Building project #{name}".
208
238
  def local_task(args, &block)
209
239
  task args do |task|
210
- projects = Project.projects.select { |project| project.base_dir == Rake.application.original_dir }
240
+ projects = local_projects
211
241
  if projects.empty?
212
242
  warn "No projects defined for directory #{Rake.application.original_dir}" if verbose
213
243
  else
@@ -237,22 +267,20 @@ module Buildr
237
267
  (@on_define ||= []) << block if block
238
268
  end
239
269
 
240
- def warnings() #:nodoc:
241
- [].tap do |msgs|
242
- msgs << "There are no project definitions in your Rakefile" if @projects.nil? || @projects.empty?
243
- # Find all projects that:
244
- # * Are referenced but never defined. This is probably a typo.
245
- # * Do not have a base directory.
246
- (@projects || {}).each do |name, project|
247
- msgs << "Project #{name} refers to the directory #{project.base_dir}, which does not exist" unless File.exist?(project.base_dir)
248
- end
249
- end
250
- end
251
-
252
270
  def scope_name(scope, task_name) #:nodoc:
253
271
  task_name
254
272
  end
255
273
 
274
+ def local_projects(dir = Rake.application.original_dir) #:nodoc:
275
+ dir = File.expand_path(dir)
276
+ projects = Project.projects.select { |project| project.base_dir == dir }
277
+ if projects.empty? && dir != Dir.pwd && File.dirname(dir) != dir
278
+ local_projects(File.dirname(dir))
279
+ else
280
+ projects
281
+ end
282
+ end
283
+
256
284
  end
257
285
 
258
286
  include InheritedAttributes
@@ -297,9 +325,7 @@ module Buildr
297
325
  if @parent
298
326
  # For sub-project, a good default is a directory in the parent's base_dir,
299
327
  # using the same name as the project.
300
- sub_dir = File.join(@parent.base_dir, name.split(":").last)
301
- @base_dir = File.exist?(sub_dir) ? sub_dir : @parent.base_dir
302
- @base_dir = sub_dir
328
+ @base_dir = File.join(@parent.base_dir, name.split(":").last)
303
329
  else
304
330
  # For top-level project, a good default is the directory where we found the Rakefile.
305
331
  @base_dir = Dir.pwd
@@ -356,18 +382,41 @@ module Buildr
356
382
 
357
383
  # :call-seq:
358
384
  # project(name) => project
385
+ # project => self
386
+ #
387
+ # Same as Buildr#project. This method is called on a project, so a relative name is
388
+ # sufficient to find a sub-project.
359
389
  #
360
- # Same as Buildr#project.
361
- def project(name)
362
- Project.project(name)
390
+ # When called on a project without a name, returns the project itself. You can use that when
391
+ # setting project properties, for example:
392
+ # define "foo" do
393
+ # project.version = "1.0"
394
+ # end
395
+ def project(*args)
396
+ if Hash === args.last
397
+ options = args.pop
398
+ else
399
+ options = {}
400
+ end
401
+ if args.empty?
402
+ self
403
+ else
404
+ Project.project *(args + [{ :scope=>self.name }.merge(options)])
405
+ end
363
406
  end
364
407
 
365
408
  # :call-seq:
366
409
  # projects(*names) => projects
367
410
  #
368
- # Same as Buildr#projects.
369
- def projects(*names)
370
- Project.projects(*names)
411
+ # Same as Buildr#projects. This method is called on a project, so relative names are
412
+ # sufficient to find sub-projects.
413
+ def projects(*args)
414
+ if Hash === args.last
415
+ options = args.pop
416
+ else
417
+ options = {}
418
+ end
419
+ Project.projects *(args + [{ :scope=>self.name }.merge(options)])
371
420
  end
372
421
 
373
422
  # :call-seq:
@@ -459,6 +508,10 @@ module Buildr
459
508
  Rake.application.in_namespace(":#{name}") { super }
460
509
  end
461
510
 
511
+ def inspect() #:nodoc:
512
+ %Q{project(#{name.inspect})}
513
+ end
514
+
462
515
  end
463
516
 
464
517
  # :call-seq:
@@ -504,6 +557,11 @@ module Buildr
504
557
  #
505
558
  # Returns a project definition.
506
559
  #
560
+ # When called from outside a project definition, must reference the project by its
561
+ # full name, e.g. "foo:bar" to access the sub-project "bar" in "foo". When called
562
+ # from inside a project, relative names are sufficient, e.g. <code>project("foo").project("bar")</code>
563
+ # will find the sub-project "bar" in "foo".
564
+ #
507
565
  # You cannot reference a project before the project is defined. When working with
508
566
  # sub-projects, the project definition is stored by calling #define, and evaluated
509
567
  # before a call to the parent project's #define method returns.
@@ -519,7 +577,7 @@ module Buildr
519
577
  #
520
578
  # define "webapp" do
521
579
  # # webapp is defined first, but beans is evaluated first
522
- # compile.with project("myapp:beans")
580
+ # compile.with project("beans")
523
581
  # package :war
524
582
  # end
525
583
  #
@@ -527,34 +585,46 @@ module Buildr
527
585
  # package :jar
528
586
  # end
529
587
  # end
530
- def project(name)
531
- Project.project(name)
588
+ #
589
+ # puts project("myapp:beans").version
590
+ def project(*args)
591
+ Project.project *args
532
592
  end
533
593
 
534
594
  # :call-seq:
535
595
  # projects(*names) => projects
536
- # projects(:in=>parent) => projects
537
596
  #
538
- # With no arguments, returns a list of all projects defined so far. With arguments,
539
- # returns a list of these projects, fails on undefined projects.
597
+ # With no arguments, returns a list of all projects defined so far. When called on a project,
598
+ # returns all its sub-projects (direct descendants).
599
+ #
600
+ # With arguments, returns a list of named projects, fails on any name that does not exist.
601
+ # As with #project, you can use relative names when calling this method on a project.
540
602
  #
541
603
  # Like #project, this method evaluates the definition of each project before returning it.
542
604
  # Be advised of circular dependencies.
543
605
  #
544
- # Use the :in option if you only want the sub-projects of a given parent project.
545
- #
546
606
  # For example:
547
607
  # files = projects.map { |prj| FileList[prj.path_to("src/**/*.java") }.flatten
548
608
  # puts "There are #{files.size} source files in #{projects.size} projects"
549
609
  #
550
610
  # puts projects("myapp:beans", "myapp:webapp").map(&:name)
551
611
  # Same as:
552
- # puts projects(:in=>"mayapp").map(&:name)
553
- def projects(*names)
554
- Project.projects *names
612
+ # puts project("myapp").projects.map(&:name)
613
+ def projects(*args)
614
+ Project.projects *args
615
+ end
616
+
617
+ desc "List all projects defined by this Rakefile"
618
+ task "projects" do
619
+ wide = projects.map(&:name).map(&:size).max
620
+ projects.each do |project|
621
+ puts project.comment.blank? ? project.name : ("%-#{wide}s #%s" % [project.name, project.comment])
622
+ end
555
623
  end
556
624
 
557
- # Add project definition tests.
558
- task("check") { |task| task.note *Project.warnings }
625
+ # Forces all the projects to be evaluated before executing any other task.
626
+ # If we don't do that, we don't get to have tasks available when running Rake.
627
+ task("buildr:projects") { projects }
628
+ Rake.application.top_level_tasks.unshift "buildr:projects"
559
629
 
560
630
  end
@@ -36,6 +36,10 @@ module Buildr
36
36
  # The HTTP transport is used for all URLs with the scheme http or https. You can only
37
37
  # use the HTTP transport to download artifacts.
38
38
  #
39
+ # The HTTP transport supports the following options:
40
+ # * :proxy -- Proxy server to use. A hash with the values host, port, user and password.
41
+ # You can also pass a URL (string or URI object).
42
+ #
39
43
  # The SFTP transport is used for all URLs with the schema sftp. You can only use the
40
44
  # SFTP transport to upload artifacts.
41
45
  #
@@ -269,15 +273,28 @@ module Buildr
269
273
 
270
274
  def initialize(url, options)
271
275
  super
272
- rake_check_options options, :digests if options
273
- @http = Net::HTTP.start(@uri.host, @uri.port)
276
+ if options
277
+ rake_check_options options, :proxy, :digests
278
+ proxy = options[:proxy]
279
+ end
280
+
281
+ case proxy
282
+ when Hash
283
+ @http = Net::HTTP.start(@uri.host, @uri.port, proxy[:host], proxy[:port], proxy[:user], proxy[:password])
284
+ when URI, String
285
+ proxy = URI.parse(proxy.to_s)
286
+ @http = Net::HTTP.start(@uri.host, @uri.port, proxy.host, proxy.port, proxy.user, proxy.password)
287
+ else
288
+ @http = Net::HTTP.start(@uri.host, @uri.port)
289
+ end
274
290
  end
275
291
 
276
292
  def download(path, target = nil, &block)
277
293
  puts "Requesting #{@uri}/#{path} " if Rake.application.options.trace
278
- last_modified = File.stat(target).mtime.utc if target && File.exist?(target)
279
- headers = {}
280
- headers["If-Modified-Since"] = CGI.rfc1123_date(last_modified) if last_modified
294
+ if target && File.exist?(target)
295
+ last_modified = File.stat(target).mtime.utc
296
+ headers = { "If-Modified-Since" => CGI.rfc1123_date(last_modified) }
297
+ end
281
298
  @http.request_get(@base_path + path, headers) do |response|
282
299
  case response
283
300
  when Net::HTTPNotModified
@@ -323,7 +340,6 @@ module Buildr
323
340
  download[ proc { |chunk| temp.write chunk } ]
324
341
  temp.close
325
342
  File.move temp.path, target
326
- File.utime last_modified, last_modified, target
327
343
  else
328
344
  download[ block ]
329
345
  end
@@ -331,7 +347,7 @@ module Buildr
331
347
  end
332
348
  end
333
349
  when Net::HTTPNotFound
334
- raise NotFound
350
+ raise NotFound, "Looking for #{@uri}/#{path} and all I got was a 404!"
335
351
  else
336
352
  fail "Failed to download #{@uri}/#{path}: #{response.message}"
337
353
  end
@@ -8,10 +8,8 @@ module Buildr
8
8
  REQUIRES = [ "ant:ant:jar:1.6.5", "ant:ant-launcher:jar:1.6.5", "xerces:xercesImpl:jar:2.6.2" ]
9
9
 
10
10
  # Make sure Ant and friends show on the classpath. Antwrap must only be loaded after RJB.
11
- Java.rjb.onload do
12
- Java.rjb.classpath += REQUIRES
13
- Java.rjb.onload { require "antwrap" }
14
- end
11
+ Java.rjb.classpath << REQUIRES
12
+ Java.rjb.onload { require "antwrap" }
15
13
 
16
14
  class << self
17
15
 
@@ -319,6 +319,44 @@ module Buildr
319
319
  end
320
320
  end
321
321
 
322
+ # :call-seq:
323
+ # proxy() => Hash
324
+ #
325
+ # Returns the proxy settings used when downloading from remote repositories.
326
+ def proxy()
327
+ @proxy ||= {}
328
+ end
329
+
330
+ # :call-seq:
331
+ # proxy = Hash
332
+ # proxy = String
333
+ # proxy = URI
334
+ # proxy = nil
335
+ #
336
+ # Sets the proxy settings used when downloading from remote repositories.
337
+ # You can specify proxy settings using a Hash with values for :host, :port,
338
+ # :user and :password.
339
+ #
340
+ # You can also pass a URL as a string or URI object. The settings are converted
341
+ # to a hash.
342
+ #
343
+ # For example:
344
+ # repositories.proxy = { :host=>"proxy.acme.com", :port=>8080 }
345
+ # repositories.proxy = "proxy.acme.com:8080"
346
+ def proxy=(proxy)
347
+ case proxy
348
+ when Hash, nil
349
+ @proxy = proxy || {}
350
+ when String
351
+ proxy = "http://#{proxy}" unless proxy =~ /^http(s?)/i
352
+ proxy = URI.parse(proxy)
353
+ @proxy = { :host=>proxy.host, :port=>proxy.port, :user=>proxy.user, :password=>proxy.password }
354
+ when URI
355
+ @proxy = { :host=>proxy.host, :port=>proxy.port, :user=>proxy.user, :password=>proxy.password }
356
+ else
357
+ fail "Expecting a Hash, String or URI."
358
+ end
359
+ end
322
360
 
323
361
  # :call-seq:
324
362
  # download(spec) => boolean
@@ -340,7 +378,7 @@ module Buildr
340
378
  begin
341
379
  rel_path = spec[:group].gsub(".", "/") +
342
380
  "/#{spec[:id]}/#{spec[:version]}/#{Artifact.hash_to_file_name(spec)}"
343
- Transports.perform URI.parse(repo_url.to_s) do |http|
381
+ Transports.perform URI.parse(repo_url.to_s), :proxy=>proxy do |http|
344
382
  mkpath File.dirname(path), :verbose=>false
345
383
  http.download(rel_path, path)
346
384
  begin
@@ -467,10 +505,8 @@ module Buildr
467
505
  # artifact project("my-app") # All packages
468
506
  # artifact project("mu-app").package(:war) # Only the WAR
469
507
  def artifacts(*specs)
470
- specs.inject([]) do |set, spec|
508
+ specs.flatten.inject([]) do |set, spec|
471
509
  case spec
472
- when Array
473
- set |= artifacts(*spec)
474
510
  when Hash
475
511
  set |= [artifact(spec)]
476
512
  when /([^:]+:){2,4}/ # A spec as opposed to a file name.
@@ -512,23 +548,22 @@ module Buildr
512
548
  # specify the deployment repository. Otherwise, obtains the deployment repository by calling
513
549
  # Repositories#deploy_to.
514
550
  #
551
+ # When deploying files, you can specify a path relative to the deployment URL. Artifacts are
552
+ # always deployed to a path that combined the group identifier, artifact identifier and
553
+ # version number.
554
+ #
515
555
  # For example:
516
556
  # deploy(foo.packages, :url=>"sftp://example.com/var/www/repo")
557
+ # deploy(file("LICENSE"), :path=>group.tr(".", "/"))
517
558
  def deploy(*args)
518
559
  # Where do we release to?
519
- if Hash === args.last
520
- options = args.pop
521
- else
522
- options = repositories.deploy_to.clone
523
- options = { :url=>options.to_s } unless Hash === options
524
- end
525
- # Strip all options since the transport requires them separately from the URL.
526
- url = options[:url]
527
- options = options.reject { |k,v| k === :url }
528
- fail "Don't know where to deploy, perhaps you forgot to set repositories.deploy_to" if url.blank?
560
+ options = Hash === args.last ? args.pop : {}
561
+ deploy_to = options[:url] ? options : repositories.deploy_to
562
+ fail "Don't know where to deploy, perhaps you forgot to set repositories.deploy_to" if deploy_to[:url].blank?
529
563
 
530
564
  args.flatten.each { |arg| arg.invoke if arg.respond_to?(:invoke) }
531
- Transports.perform url, options do |session|
565
+ # Strip :url and :path, in case the transport checks for valid options.
566
+ Transports.perform deploy_to[:url], deploy_to.reject{ |k,v| k == :url || k == :path } do |session|
532
567
  args.flatten.each do |artifact|
533
568
  if artifact.respond_to?(:to_spec)
534
569
  # Upload artifact relative to base URL, need to create path before uploading.
@@ -540,7 +575,7 @@ module Buildr
540
575
  else
541
576
  # Upload artifact to URL.
542
577
  puts "Deploying #{artifact}" if verbose
543
- session.upload artifact.to_s, File.basename(artifact.to_s)
578
+ session.upload artifact.to_s, File.join(*(options[:path].to_a + [File.basename(artifact.to_s)]).compact)
544
579
  end
545
580
  end
546
581
  end
@@ -49,7 +49,7 @@ module Buildr
49
49
 
50
50
  # Generate warnings (opposite of -nowarn).
51
51
  attr_accessor :warnings
52
- inherited_attr :warnings, false
52
+ inherited_attr(:warnings) { verbose }
53
53
  # Output source locations where deprecated APIs are used.
54
54
  attr_accessor :deprecation
55
55
  inherited_attr :deprecation, false
@@ -88,7 +88,7 @@ module Buildr
88
88
  # Returns Javac command line arguments from the set of options.
89
89
  def javac_args()
90
90
  args = []
91
- args << "-nowarn" unless warnings && verbose
91
+ args << "-nowarn" unless warnings
92
92
  args << "-verbose" if Rake.application.options.trace
93
93
  args << "-g" if debug
94
94
  args << "-deprecation" if deprecation
@@ -540,20 +540,20 @@ module Buildr
540
540
  # Compile task requires prepare and performs resources, if anything compiled.
541
541
  compile = Java::CompileTask.define_task("compile"=>[prepare, resources])
542
542
  project.path_to("src/main/java").tap { |dir| compile.from dir if File.exist?(dir) }
543
- compile.into project.path_to("target/classes")
543
+ compile.into project.path_to(:target, "classes")
544
544
  resources.filter.into project.compile.target
545
545
  Java::JavadocTask.define_task("javadoc"=>prepare).tap do |javadoc|
546
- javadoc.into project.path_to("target/javadoc")
546
+ javadoc.into project.path_to(:target, "javadoc")
547
547
  javadoc.using :windowtitle=>project.comment || project.name
548
548
  end
549
549
  project.recursive_task("compile")
550
- project.clean { verbose(false) { rm_rf project.path_to("target") } }
551
550
 
552
551
  project.enhance do |project|
553
552
  # This comes last because the target path may change.
554
553
  project.build project.compile.target
555
554
  # This comes last so we can determine all the source paths and classpath dependencies.
556
555
  project.javadoc.from project
556
+ project.clean { verbose(false) { rm_rf project.compile.target.to_s } }
557
557
  end
558
558
  end
559
559
 
@@ -569,8 +569,11 @@ module Buildr
569
569
  # The release tasks runs a build with <tt>DEBUG=no</tt>.
570
570
  attr_accessor :debug
571
571
 
572
- end
572
+ def debug()
573
+ @debug = (ENV["DEBUG"] || ENV["debug"]) !~ /(no|off|false)/ if @debug.nil?
574
+ @debug
575
+ end
573
576
 
574
- options.debug = (ENV["DEBUG"] || ENV["debug"]) !~ /(no|off|false)/
577
+ end
575
578
 
576
579
  end
@@ -113,7 +113,7 @@ module Buildr
113
113
  File.open(task.name, "w") do |file|
114
114
  xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
115
115
  xml.projectDescription do
116
- xml.name project.name
116
+ xml.name project.name.tr(":", "-")
117
117
  xml.projects
118
118
  xml.buildSpec do
119
119
  xml.buildCommand do
@@ -26,7 +26,7 @@ module Buildr
26
26
  include Singleton
27
27
 
28
28
  def initialize() #:nodoc:
29
- @classpath = [Java.tools_jar]
29
+ @classpath = [Java.tools_jar].compact
30
30
  @onload = []
31
31
  onload do
32
32
  onload do
@@ -40,7 +40,7 @@ module Buildr
40
40
  attr_accessor :classpath
41
41
 
42
42
  # :call-seq:
43
- # onload { ... }
43
+ # onload { |rjb| ... }
44
44
  #
45
45
  # Adds a block to call when loading RJB and returns self.
46
46
  #
@@ -56,7 +56,7 @@ module Buildr
56
56
  #
57
57
  # Loads RJB. You can also call Java#ejb with a block to get the same effect.
58
58
  def load()
59
- @onload.each(&:call)
59
+ @onload.each { |block| block.call self }
60
60
  @onload.clear
61
61
  end
62
62
 
@@ -82,21 +82,20 @@ module Buildr
82
82
  # :call-seq:
83
83
  # tools_jar() => path
84
84
  #
85
- # Returns a path to tools.jar.
85
+ # Returns a path to tools.jar. Returns nil if tools.jar not found, which may be a problem,
86
+ # unless you're running OS/X.
86
87
  def tools_jar()
87
- unless @tools
88
- tools = File.join(home, "lib/tools.jar")
89
- @tools = tools if File.exist?(tools)
90
- end
91
- @tools
88
+ return nil if darwin?
89
+ @tools ||= File.join(home, "lib/tools.jar") or raise "I need tools.jar to compile, can't find it in #{home}/lib"
92
90
  end
93
91
 
94
92
  # :call-seq:
95
93
  # home() => path
96
94
  #
97
- # Returns JAVA_HOME.
95
+ # Returns JAVA_HOME, fails if JAVA_HOME not set. Returns nil for OS/X, we just assume Java is in the path.
98
96
  def home()
99
- @home ||= ENV["JAVA_HOME"] or fail "Are we forgetting something? JAVA_HOME not set?"
97
+ return nil if darwin?
98
+ @home ||= ENV["JAVA_HOME"] or fail "Are we forgetting something? JAVA_HOME not set."
100
99
  end
101
100
 
102
101
  # :call-seq:
@@ -302,9 +301,8 @@ module Buildr
302
301
  # With a block, loads RJB and yields to the block, returning its result.
303
302
  #
304
303
  # For example:
305
- # Java.rjb.classpath += REQUIRES
304
+ # Java.rjb.classpath << REQUIRES
306
305
  # Java.rjb.onload { require "antwrap" }
307
- # . . .
308
306
  #
309
307
  # def execute(name, options)
310
308
  # options = options.merge(:name=>name, :base_dir=>Dir.pwd, :declarative=>true)
@@ -325,7 +323,7 @@ module Buildr
325
323
  # Returns the path to the specified Java command (with no argument to java itself).
326
324
  # Uses JAVA_HOME if set, otherwise assumes the command is accessible from the path.
327
325
  def path_to_bin(name = "java")
328
- File.join(home, "bin", name)
326
+ home ? File.join(home, "bin", name) : File.join("bin", name)
329
327
  end
330
328
 
331
329
  protected
@@ -348,6 +346,10 @@ module Buildr
348
346
  @junit_artifacts ||= Buildr.artifacts(JUNIT_REQUIRES).each { |task| task.invoke }.map(&:to_s)
349
347
  end
350
348
 
349
+ def darwin?() #:nodoc:
350
+ RUBY_PLATFORM =~ /darwin/i
351
+ end
352
+
351
353
  end
352
354
 
353
355
  # See Java#java.
@@ -366,7 +368,7 @@ module Buildr
366
368
  #
367
369
  def apt(*sources)
368
370
  sources = compile.sources if sources.empty?
369
- file(path_to("target/generated/apt")=>sources) do |task|
371
+ file(path_to(:target, "generated/apt")=>sources) do |task|
370
372
  Java.apt(sources.map(&:to_s) - [task.name], :output=>task.name,
371
373
  :classpath=>compile.classpath, :source=>compile.options.source)
372
374
  end
@@ -73,11 +73,11 @@ module Buildr
73
73
  if manifest
74
74
  case manifest
75
75
  when Hash
76
- output << manifest.map { |pair| pair.map(&:to_s).join(": ") }.sort.join("\n")
76
+ output << manifest.map { |pair| pair.map(&:to_s).join(": ") }.sort.join("\n") << "\n"
77
77
  when Array
78
78
  output << manifest.reject { |section| section.empty? }.map { |section|
79
79
  section.map { |pair| pair.join(": ") }.sort.join("\n").concat("\n")
80
- }.join("\n")
80
+ }.join("\n") << "\n"
81
81
  when Proc, Method
82
82
  output << manifest.call
83
83
  when String, Task
@@ -233,7 +233,7 @@ module Buildr
233
233
  options[:group] ||= self.group
234
234
  options[:version] ||= self.version
235
235
  options[:type] = type
236
- file_name = path_to("target", Artifact.hash_to_file_name(options))
236
+ file_name = path_to(:target, Artifact.hash_to_file_name(options))
237
237
 
238
238
  packager = method("package_as_#{type}") rescue
239
239
  fail("Don't know how to create a package of type #{type}")
@@ -378,5 +378,4 @@ module Buildr
378
378
 
379
379
  end
380
380
 
381
-
382
381
  end
@@ -289,7 +289,7 @@ module Buildr
289
289
  # Similar to the regular compile task but using different paths.
290
290
  compile = Java::CompileTask.define_task("test:compile"=>[project.compile, project.test.prepare, project.test.resources])
291
291
  project.path_to("src/test/java").tap { |dir| compile.from dir if File.exist?(dir) }
292
- compile.into project.path_to("target/test-classes")
292
+ compile.into project.path_to(:target, "test-classes")
293
293
  resources.filter.into compile.target
294
294
  # Define the JUnit task here, otherwise we get a normal task.
295
295
  Java::JUnitTask.define_task("test:junit")
@@ -309,6 +309,7 @@ module Buildr
309
309
  options[:properties] ||= {}
310
310
  options[:properties]["baseDir"] ||= project.test.compile.target.to_s
311
311
  end
312
+ project.clean { verbose(false) { rm_rf project.test.compile.target.to_s } }
312
313
  end
313
314
  end
314
315
 
@@ -317,9 +318,9 @@ module Buildr
317
318
  # will run the test case class com.example.MyTest, if found in the current project.
318
319
  rule /^test:.*$/ do |task|
319
320
  test = task.name.scan(/test:(.*)/)[0][0]
320
- Project.projects.select { |project| project.base_dir == Rake.application.original_dir }.
321
- map { |project| project.test }.each { |task| task.junit.instance_eval { @include = ["*#{test}"] ; @exclude.clear } }.
322
- each(&:invoke)
321
+ test = "*#{test}*" unless test =~ /\*/
322
+ Project.local_projects.map { |project| project.test }.
323
+ each { |task| task.junit.instance_eval { @include = [test] ; @exclude.clear } }.each(&:invoke)
323
324
  end
324
325
 
325
326
 
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.2
2
+ rubygems_version: 0.9.3
3
3
  specification_version: 1
4
4
  name: buildr
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.0
7
- date: 2007-05-04 00:00:00 -07:00
6
+ version: 1.1.0
7
+ date: 2007-05-13 00:00:00 -07:00
8
8
  summary: A build system that doesn't suck
9
9
  require_paths:
10
10
  - lib