buildr 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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