assaf-buildr 1.3.3

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.
Files changed (163) hide show
  1. data/CHANGELOG +887 -0
  2. data/DISCLAIMER +7 -0
  3. data/LICENSE +176 -0
  4. data/NOTICE +26 -0
  5. data/README.rdoc +146 -0
  6. data/Rakefile +62 -0
  7. data/_buildr +38 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/cobertura.rb +236 -0
  10. data/addon/buildr/emma.rb +238 -0
  11. data/addon/buildr/hibernate.rb +142 -0
  12. data/addon/buildr/javacc.rb +85 -0
  13. data/addon/buildr/jdepend.rb +60 -0
  14. data/addon/buildr/jetty.rb +248 -0
  15. data/addon/buildr/jibx.rb +86 -0
  16. data/addon/buildr/nailgun.rb +817 -0
  17. data/addon/buildr/openjpa.rb +90 -0
  18. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  19. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  20. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  21. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  22. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  23. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  25. data/addon/buildr/xmlbeans.rb +93 -0
  26. data/bin/buildr +28 -0
  27. data/buildr.buildfile +53 -0
  28. data/buildr.gemspec +58 -0
  29. data/doc/css/default.css +228 -0
  30. data/doc/css/print.css +100 -0
  31. data/doc/css/syntax.css +52 -0
  32. data/doc/images/apache-incubator-logo.png +0 -0
  33. data/doc/images/buildr-hires.png +0 -0
  34. data/doc/images/buildr.png +0 -0
  35. data/doc/images/favicon.png +0 -0
  36. data/doc/images/growl-icon.tiff +0 -0
  37. data/doc/images/note.png +0 -0
  38. data/doc/images/project-structure.png +0 -0
  39. data/doc/images/tip.png +0 -0
  40. data/doc/images/zbuildr.tif +0 -0
  41. data/doc/pages/artifacts.textile +207 -0
  42. data/doc/pages/building.textile +240 -0
  43. data/doc/pages/contributing.textile +208 -0
  44. data/doc/pages/download.textile +62 -0
  45. data/doc/pages/extending.textile +175 -0
  46. data/doc/pages/getting_started.textile +273 -0
  47. data/doc/pages/index.textile +42 -0
  48. data/doc/pages/languages.textile +407 -0
  49. data/doc/pages/mailing_lists.textile +17 -0
  50. data/doc/pages/more_stuff.textile +286 -0
  51. data/doc/pages/packaging.textile +427 -0
  52. data/doc/pages/projects.textile +274 -0
  53. data/doc/pages/recipes.textile +103 -0
  54. data/doc/pages/settings_profiles.textile +274 -0
  55. data/doc/pages/testing.textile +212 -0
  56. data/doc/pages/troubleshooting.textile +103 -0
  57. data/doc/pages/whats_new.textile +323 -0
  58. data/doc/print.haml +51 -0
  59. data/doc/print.toc.yaml +29 -0
  60. data/doc/scripts/buildr-git.rb +412 -0
  61. data/doc/scripts/install-jruby.sh +44 -0
  62. data/doc/scripts/install-linux.sh +64 -0
  63. data/doc/scripts/install-osx.sh +52 -0
  64. data/doc/site.haml +56 -0
  65. data/doc/site.toc.yaml +47 -0
  66. data/etc/KEYS +151 -0
  67. data/etc/git-svn-authors +16 -0
  68. data/lib/buildr.rb +35 -0
  69. data/lib/buildr/core.rb +27 -0
  70. data/lib/buildr/core/application.rb +489 -0
  71. data/lib/buildr/core/application_cli.rb +139 -0
  72. data/lib/buildr/core/build.rb +311 -0
  73. data/lib/buildr/core/checks.rb +382 -0
  74. data/lib/buildr/core/common.rb +154 -0
  75. data/lib/buildr/core/compile.rb +596 -0
  76. data/lib/buildr/core/environment.rb +120 -0
  77. data/lib/buildr/core/filter.rb +362 -0
  78. data/lib/buildr/core/generate.rb +195 -0
  79. data/lib/buildr/core/help.rb +118 -0
  80. data/lib/buildr/core/progressbar.rb +156 -0
  81. data/lib/buildr/core/project.rb +892 -0
  82. data/lib/buildr/core/test.rb +715 -0
  83. data/lib/buildr/core/transports.rb +558 -0
  84. data/lib/buildr/core/util.rb +289 -0
  85. data/lib/buildr/groovy.rb +18 -0
  86. data/lib/buildr/groovy/bdd.rb +105 -0
  87. data/lib/buildr/groovy/compiler.rb +138 -0
  88. data/lib/buildr/ide.rb +19 -0
  89. data/lib/buildr/ide/eclipse.rb +212 -0
  90. data/lib/buildr/ide/idea.ipr.template +300 -0
  91. data/lib/buildr/ide/idea.rb +189 -0
  92. data/lib/buildr/ide/idea7x.ipr.template +290 -0
  93. data/lib/buildr/ide/idea7x.rb +210 -0
  94. data/lib/buildr/java.rb +23 -0
  95. data/lib/buildr/java/ant.rb +92 -0
  96. data/lib/buildr/java/bdd.rb +449 -0
  97. data/lib/buildr/java/commands.rb +211 -0
  98. data/lib/buildr/java/compiler.rb +348 -0
  99. data/lib/buildr/java/deprecated.rb +141 -0
  100. data/lib/buildr/java/jruby.rb +117 -0
  101. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  102. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  103. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +119 -0
  104. data/lib/buildr/java/packaging.rb +713 -0
  105. data/lib/buildr/java/pom.rb +178 -0
  106. data/lib/buildr/java/rjb.rb +155 -0
  107. data/lib/buildr/java/test_result.rb +308 -0
  108. data/lib/buildr/java/tests.rb +324 -0
  109. data/lib/buildr/java/version_requirement.rb +172 -0
  110. data/lib/buildr/packaging.rb +21 -0
  111. data/lib/buildr/packaging/artifact.rb +730 -0
  112. data/lib/buildr/packaging/artifact_namespace.rb +972 -0
  113. data/lib/buildr/packaging/artifact_search.rb +140 -0
  114. data/lib/buildr/packaging/gems.rb +102 -0
  115. data/lib/buildr/packaging/package.rb +233 -0
  116. data/lib/buildr/packaging/tar.rb +104 -0
  117. data/lib/buildr/packaging/zip.rb +722 -0
  118. data/lib/buildr/resources/buildr.icns +0 -0
  119. data/lib/buildr/scala.rb +19 -0
  120. data/lib/buildr/scala/compiler.rb +109 -0
  121. data/lib/buildr/scala/tests.rb +203 -0
  122. data/rakelib/apache.rake +191 -0
  123. data/rakelib/changelog.rake +57 -0
  124. data/rakelib/doc.rake +103 -0
  125. data/rakelib/package.rake +73 -0
  126. data/rakelib/release.rake +65 -0
  127. data/rakelib/rspec.rake +83 -0
  128. data/rakelib/rubyforge.rake +53 -0
  129. data/rakelib/scm.rake +49 -0
  130. data/rakelib/setup.rake +86 -0
  131. data/rakelib/stage.rake +48 -0
  132. data/spec/addon/cobertura_spec.rb +77 -0
  133. data/spec/addon/emma_spec.rb +120 -0
  134. data/spec/addon/test_coverage_spec.rb +255 -0
  135. data/spec/core/application_spec.rb +412 -0
  136. data/spec/core/artifact_namespace_spec.rb +646 -0
  137. data/spec/core/build_spec.rb +415 -0
  138. data/spec/core/checks_spec.rb +537 -0
  139. data/spec/core/common_spec.rb +664 -0
  140. data/spec/core/compile_spec.rb +566 -0
  141. data/spec/core/generate_spec.rb +33 -0
  142. data/spec/core/project_spec.rb +754 -0
  143. data/spec/core/test_spec.rb +1091 -0
  144. data/spec/core/transport_spec.rb +500 -0
  145. data/spec/groovy/bdd_spec.rb +80 -0
  146. data/spec/groovy/compiler_spec.rb +239 -0
  147. data/spec/ide/eclipse_spec.rb +243 -0
  148. data/spec/java/ant.rb +28 -0
  149. data/spec/java/bdd_spec.rb +358 -0
  150. data/spec/java/compiler_spec.rb +446 -0
  151. data/spec/java/java_spec.rb +88 -0
  152. data/spec/java/packaging_spec.rb +1103 -0
  153. data/spec/java/tests_spec.rb +466 -0
  154. data/spec/packaging/archive_spec.rb +503 -0
  155. data/spec/packaging/artifact_spec.rb +754 -0
  156. data/spec/packaging/packaging_helper.rb +63 -0
  157. data/spec/packaging/packaging_spec.rb +589 -0
  158. data/spec/sandbox.rb +137 -0
  159. data/spec/scala/compiler_spec.rb +228 -0
  160. data/spec/scala/tests_spec.rb +215 -0
  161. data/spec/spec_helpers.rb +304 -0
  162. data/spec/version_requirement_spec.rb +123 -0
  163. metadata +369 -0
@@ -0,0 +1,412 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+
17
+ require File.join(File.dirname(__FILE__), '../spec_helpers')
18
+
19
+
20
+ describe Buildr::Application do
21
+
22
+ describe 'home_dir' do
23
+ it 'should point to ~/.buildr' do
24
+ Buildr.application.home_dir.should eql(File.expand_path('.buildr', ENV['HOME']))
25
+ end
26
+
27
+ it 'should point to existing directory' do
28
+ File.directory?(Buildr.application.home_dir).should be_true
29
+ end
30
+ end
31
+
32
+ describe '#run' do
33
+ it 'should execute *_load methods in order' do
34
+ last = nil
35
+ order = [:find_buildfile, :load_gems, :load_artifacts, :load_tasks,
36
+ :load_requires, :load_buildfile, :load_imports, :top_level]
37
+ order.each { |method| Buildr.application.should_receive(method).ordered }
38
+ Buildr.application.stub!(:exit) # With this, shows the correct error instead of SystemExit.
39
+ Buildr.application.run
40
+ end
41
+ end
42
+
43
+ describe 'environment' do
44
+ it 'should return value of BUILDR_ENV' do
45
+ ENV['BUILDR_ENV'] = 'qa'
46
+ Buildr::Application.new.environment.should eql('qa')
47
+ end
48
+
49
+ it 'should default to development' do
50
+ Buildr::Application.new.environment.should eql('development')
51
+ end
52
+
53
+ it 'should set environment name from -e argument' do
54
+ ARGV.push('-e', 'test')
55
+ Buildr::Application.new.environment.should eql('test')
56
+ ENV['BUILDR_ENV'].should eql('test')
57
+ end
58
+
59
+ it 'should be echoed to user' do
60
+ write 'buildfile'
61
+ lambda { Buildr.application.send :load_buildfile }.should show_info(%r{(in .*, development)})
62
+ end
63
+
64
+ after do
65
+ ENV['BUILDR_ENV'] = nil
66
+ end
67
+ end
68
+
69
+ describe 'gems' do
70
+ before do
71
+ Buildr.application.private_methods(true).should include('load_gems')
72
+ class << Buildr.application
73
+ public :load_gems
74
+ end
75
+ end
76
+
77
+ def load_with_yaml
78
+ write 'build.yaml', <<-YAML
79
+ gems:
80
+ - rspec
81
+ - rake >= 0.8
82
+ YAML
83
+ Buildr.application.load_gems
84
+ end
85
+
86
+ it 'should return empty array if no gems specified' do
87
+ Buildr.application.load_gems
88
+ Buildr.application.gems.should be_empty
89
+ end
90
+
91
+ it 'should return one entry for each gem specified in buildr.yaml' do
92
+ load_with_yaml
93
+ Buildr.application.gems.size.should be(2)
94
+ end
95
+
96
+ it 'should return a Gem::Specification for each installed gem' do
97
+ load_with_yaml
98
+ Buildr.application.gems.each { |gem| gem.should be_kind_of(Gem::Specification) }
99
+ end
100
+
101
+ it 'should parse Gem name correctly' do
102
+ load_with_yaml
103
+ Buildr.application.gems.map(&:name).should include('rake', 'rspec')
104
+ end
105
+
106
+ it 'should find installed version of Gem' do
107
+ load_with_yaml
108
+ Buildr.application.gems.each { |gem| gem.version.should eql(Gem.loaded_specs[gem.name].version) }
109
+ end
110
+ end
111
+
112
+
113
+ describe 'load_gems' do
114
+ before do
115
+ Buildr.application.private_methods(true).should include('load_gems')
116
+ class << Buildr.application
117
+ public :load_gems
118
+ end
119
+ @spec = Gem::Specification.new do |spec|
120
+ spec.name = 'foo'
121
+ spec.version = '1.2'
122
+ end
123
+ $stdout.stub!(:isatty).and_return(true)
124
+ end
125
+
126
+ it 'should do nothing if no gems specified' do
127
+ lambda { Buildr.application.load_gems }.should_not raise_error
128
+ end
129
+
130
+ it 'should install nothing if specified gems already installed' do
131
+ Buildr.application.should_receive(:listed_gems).and_return([Gem.loaded_specs['rspec']])
132
+ Util.should_not_receive(:ruby)
133
+ lambda { Buildr.application.load_gems }.should_not raise_error
134
+ end
135
+
136
+ it 'should fail if required gem not found in remote repository' do
137
+ Buildr.application.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
138
+ Gem::SourceInfoCache.should_receive(:search).and_return([])
139
+ lambda { Buildr.application.load_gems }.should raise_error(LoadError, /cannot be found/i)
140
+ end
141
+
142
+ it 'should fail if need to install gem and not running in interactive mode' do
143
+ Buildr.application.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
144
+ Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
145
+ $stdout.should_receive(:isatty).and_return(false)
146
+ lambda { Buildr.application.load_gems }.should raise_error(LoadError, /this build requires the gems/i)
147
+ end
148
+
149
+ it 'should ask permission before installing required gems' do
150
+ Buildr.application.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
151
+ Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
152
+ $terminal.should_receive(:agree).with(/install/, true)
153
+ lambda { Buildr.application.load_gems }.should raise_error
154
+ end
155
+
156
+ it 'should fail if permission not granted to install gem' do
157
+ Buildr.application.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
158
+ Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
159
+ $terminal.should_receive(:agree).and_return(false)
160
+ lambda { Buildr.application.load_gems }.should raise_error(LoadError, /cannot build without/i)
161
+ end
162
+
163
+ it 'should install gem if permission granted' do
164
+ Buildr.application.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
165
+ Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
166
+ $terminal.should_receive(:agree).and_return(true)
167
+ Util.should_receive(:ruby) do |*args|
168
+ args.should include('install', 'foo', '-v', '1.2')
169
+ end
170
+ Buildr.application.should_receive(:gem).and_return(false)
171
+ Buildr.application.load_gems
172
+ end
173
+
174
+ it 'should reload gem cache after installing required gems' do
175
+ Buildr.application.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
176
+ Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
177
+ $terminal.should_receive(:agree).and_return(true)
178
+ Util.should_receive(:ruby)
179
+ Gem.source_index.should_receive(:load_gems_in).with(Gem::SourceIndex.installed_spec_directories)
180
+ Buildr.application.should_receive(:gem).and_return(false)
181
+ Buildr.application.load_gems
182
+ end
183
+
184
+ it 'should load previously installed gems' do
185
+ Buildr.application.should_receive(:listed_gems).and_return([Gem.loaded_specs['rspec']])
186
+ Buildr.application.should_receive(:gem).with('rspec', Gem.loaded_specs['rspec'].version.to_s)
187
+ Buildr.application.load_gems
188
+ end
189
+
190
+ it 'should load newly installed gems' do
191
+ Buildr.application.should_receive(:listed_gems).and_return([Gem::Dependency.new('foo', '>=1.1')])
192
+ Gem::SourceInfoCache.should_receive(:search).and_return([@spec])
193
+ $terminal.should_receive(:agree).and_return(true)
194
+ Util.should_receive(:ruby)
195
+ Buildr.application.should_receive(:gem).with('foo', @spec.version.to_s)
196
+ Buildr.application.load_gems
197
+ end
198
+
199
+ it 'should default to >=0 version requirement if not specified' do
200
+ write 'build.yaml', 'gems: foo'
201
+ Gem::SourceInfoCache.should_receive(:search).with(Gem::Dependency.new('foo', '>=0')).and_return([])
202
+ lambda { Buildr.application.load_gems }.should raise_error
203
+ end
204
+
205
+ it 'should parse exact version requirement' do
206
+ write 'build.yaml', 'gems: foo 2.5'
207
+ Gem::SourceInfoCache.should_receive(:search).with(Gem::Dependency.new('foo', '=2.5')).and_return([])
208
+ lambda { Buildr.application.load_gems }.should raise_error
209
+ end
210
+
211
+ it 'should parse range version requirement' do
212
+ write 'build.yaml', 'gems: foo ~>2.3'
213
+ Gem::SourceInfoCache.should_receive(:search).with(Gem::Dependency.new('foo', '~>2.3')).and_return([])
214
+ lambda { Buildr.application.load_gems }.should raise_error
215
+ end
216
+
217
+ it 'should parse multiple version requirements' do
218
+ write 'build.yaml', 'gems: foo >=2.0 !=2.1'
219
+ Gem::SourceInfoCache.should_receive(:search).with(Gem::Dependency.new('foo', ['>=2.0', '!=2.1'])).and_return([])
220
+ lambda { Buildr.application.load_gems }.should raise_error
221
+ end
222
+ end
223
+
224
+ end
225
+
226
+
227
+ describe Buildr, 'settings' do
228
+
229
+ describe 'user' do
230
+
231
+ it 'should be empty hash if no settings.yaml file' do
232
+ Buildr.settings.user.should == {}
233
+ end
234
+
235
+ it 'should return loaded settings.yaml file' do
236
+ write 'home/.buildr/settings.yaml', 'foo: bar'
237
+ Buildr.settings.user.should == { 'foo'=>'bar' }
238
+ end
239
+
240
+ it 'should return loaded settings.yml file' do
241
+ write 'home/.buildr/settings.yml', 'foo: bar'
242
+ Buildr.settings.user.should == { 'foo'=>'bar' }
243
+ end
244
+
245
+ it 'should fail if settings.yaml file is not a hash' do
246
+ write 'home/.buildr/settings.yaml', 'foo bar'
247
+ lambda { Buildr.settings.user }.should raise_error(RuntimeError, /expecting.*settings.yaml/i)
248
+ end
249
+
250
+ it 'should be empty hash if settings.yaml file is empty' do
251
+ write 'home/.buildr/settings.yaml'
252
+ Buildr.settings.user.should == {}
253
+ end
254
+ end
255
+
256
+ describe 'configuration' do
257
+ it 'should be empty hash if no build.yaml file' do
258
+ Buildr.settings.build.should == {}
259
+ end
260
+
261
+ it 'should return loaded build.yaml file' do
262
+ write 'build.yaml', 'foo: bar'
263
+ Buildr.settings.build.should == { 'foo'=>'bar' }
264
+ end
265
+
266
+ it 'should return loaded build.yml file' do
267
+ write 'build.yml', 'foo: bar'
268
+ Buildr.settings.build.should == { 'foo'=>'bar' }
269
+ end
270
+
271
+ it 'should fail if build.yaml file is not a hash' do
272
+ write 'build.yaml', 'foo bar'
273
+ lambda { Buildr.settings.build }.should raise_error(RuntimeError, /expecting.*build.yaml/i)
274
+ end
275
+
276
+ it 'should be empty hash if build.yaml file is empty' do
277
+ write 'build.yaml'
278
+ Buildr.settings.build.should == {}
279
+ end
280
+ end
281
+
282
+ describe 'profiles' do
283
+ it 'should be empty hash if no profiles.yaml file' do
284
+ Buildr.settings.profiles.should == {}
285
+ end
286
+
287
+ it 'should return loaded profiles.yaml file' do
288
+ write 'profiles.yaml', <<-YAML
289
+ development:
290
+ foo: bar
291
+ YAML
292
+ Buildr.settings.profiles.should == { 'development'=> { 'foo'=>'bar' } }
293
+ end
294
+
295
+ it 'should return loaded profiles.yml file' do
296
+ write 'profiles.yml', <<-YAML
297
+ development:
298
+ foo: bar
299
+ YAML
300
+ Buildr.settings.profiles.should == { 'development'=> { 'foo'=>'bar' } }
301
+ end
302
+
303
+ it 'should fail if profiles.yaml file is not a hash' do
304
+ write 'profiles.yaml', 'foo bar'
305
+ lambda { Buildr.settings.profiles }.should raise_error(RuntimeError, /expecting.*profiles.yaml/i)
306
+ end
307
+
308
+ it 'should be empty hash if profiles.yaml file is empty' do
309
+ write 'profiles.yaml'
310
+ Buildr.settings.profiles.should == {}
311
+ end
312
+ end
313
+
314
+ describe 'profile' do
315
+ it 'should be empty hash if no profiles.yaml' do
316
+ Buildr.settings.profile.should == {}
317
+ end
318
+
319
+ it 'should be empty hash if no matching profile' do
320
+ write 'profiles.yaml', <<-YAML
321
+ test:
322
+ foo: bar
323
+ YAML
324
+ Buildr.settings.profile.should == {}
325
+ end
326
+
327
+ it 'should return profile matching environment name' do
328
+ write 'profiles.yaml', <<-YAML
329
+ development:
330
+ foo: bar
331
+ test:
332
+ foo: baz
333
+ YAML
334
+ Buildr.settings.profile.should == { 'foo'=>'bar' }
335
+ end
336
+ end
337
+
338
+ describe 'buildfile task' do
339
+ before do
340
+ @buildfile_time = Time.now - 10
341
+ write 'buildfile'; File.utime(@buildfile_time, @buildfile_time, 'buildfile')
342
+ end
343
+
344
+ it 'should point to the buildfile' do
345
+ Buildr.application.buildfile.should point_to_path('buildfile')
346
+ end
347
+
348
+ it 'should be a defined task' do
349
+ Buildr.application.buildfile.should == file(File.expand_path('buildfile'))
350
+ end
351
+
352
+ it 'should ignore any rake namespace' do
353
+ namespace 'dummy_ns' do
354
+ Buildr.application.buildfile.should point_to_path('buildfile')
355
+ end
356
+ end
357
+
358
+ it 'should have the same timestamp as the buildfile' do
359
+ Buildr.application.buildfile.timestamp.should be_close(@buildfile_time, 1)
360
+ end
361
+
362
+ it 'should have the same timestamp as build.yaml if the latter is newer' do
363
+ write 'build.yaml'; File.utime(@buildfile_time + 5, @buildfile_time + 5, 'build.yaml')
364
+ Buildr.application.run
365
+ Buildr.application.buildfile.timestamp.should be_close(@buildfile_time + 5, 1)
366
+ end
367
+
368
+ it 'should have the same timestamp as the buildfile if build.yaml is older' do
369
+ write 'build.yaml'; File.utime(@buildfile_time - 5, @buildfile_time - 5, 'build.yaml')
370
+ Buildr.application.run
371
+ Buildr.application.buildfile.timestamp.should be_close(@buildfile_time, 1)
372
+ end
373
+
374
+ it 'should have the same timestamp as build.rb in home dir if the latter is newer' do
375
+ write 'home/buildr.rb'; File.utime(@buildfile_time + 5, @buildfile_time + 5, 'home/buildr.rb')
376
+ Buildr.application.send :load_tasks
377
+ Buildr.application.buildfile.timestamp.should be_close(@buildfile_time + 5, 1)
378
+ end
379
+
380
+ it 'should include explicitly required files as dependencies' do
381
+ write 'some/file.rb'; File.utime(@buildfile_time + 5, @buildfile_time + 5, 'some/file.rb')
382
+ Buildr.application.instance_variable_set(:@requires, ['rbconfig', 'some/file.rb'])
383
+ Buildr.application.send :load_buildfile
384
+ Buildr.application.buildfile.timestamp.should be_close(@buildfile_time + 5, 1)
385
+ Buildr.application.buildfile.prerequisites.should include(File.expand_path('some/file.rb'))
386
+ Buildr.application.buildfile.prerequisites.should_not include('rbconfig')
387
+ end
388
+ end
389
+ end
390
+
391
+
392
+ describe Buildr do
393
+
394
+ describe 'environment' do
395
+ it 'should be same as Buildr.application.environment' do
396
+ Buildr.environment.should eql(Buildr.application.environment)
397
+ end
398
+ end
399
+
400
+ describe 'application' do
401
+ it 'should be same as Rake.application' do
402
+ Buildr.application.should == Rake.application
403
+ end
404
+ end
405
+
406
+ describe 'settings' do
407
+ it 'should be same as Buildr.application.settings' do
408
+ Buildr.settings.should == Buildr.application.settings
409
+ end
410
+ end
411
+ end
412
+
@@ -0,0 +1,646 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ require File.join(File.dirname(__FILE__), '../spec_helpers')
17
+
18
+ describe Buildr::ArtifactNamespace do
19
+
20
+ before(:each) { Buildr::ArtifactNamespace.clear }
21
+
22
+ def abc_module
23
+ Object.module_eval 'module A; module B; module C; end; end; end'
24
+ yield
25
+ ensure
26
+ Object.send :remove_const, :A
27
+ end
28
+
29
+ describe '.root' do
30
+ it 'should return the top level namespace' do
31
+ Buildr::ArtifactNamespace.root.should be_root
32
+ end
33
+
34
+ it 'should yield the namespace if a block is given' do
35
+ Buildr::ArtifactNamespace.root { |ns| ns.should be_root }
36
+ end
37
+ end
38
+
39
+ describe '.instance' do
40
+ it 'should return the top level namespace when invoked outside a project definition' do
41
+ artifact_ns.should be_root
42
+ end
43
+
44
+ it 'should return the namespace for the receiving project' do
45
+ define('foo') { }
46
+ project('foo').artifact_ns.name.should == 'foo'
47
+ end
48
+
49
+ it 'should return the current project namespace when invoked inside a project' do
50
+ define 'foo' do
51
+ artifact_ns.should_not be_root
52
+ artifact_ns.name.should == 'foo'
53
+ task :doit do
54
+ artifact_ns.should_not be_root
55
+ artifact_ns.name.should == 'foo'
56
+ end.invoke
57
+ end
58
+ end
59
+
60
+ it 'should return the root namespace if given :root' do
61
+ artifact_ns(:root).should be_root
62
+ end
63
+
64
+ it 'should return the namespace for the given name' do
65
+ artifact_ns(:foo).name.should == 'foo'
66
+ artifact_ns('foo:bar').name.should == 'foo:bar'
67
+ artifact_ns(['foo', 'bar', 'baz']).name.should == 'foo:bar:baz'
68
+ abc_module do
69
+ artifact_ns(A::B::C).name.should == 'A::B::C'
70
+ end
71
+ artifact_ns(:root).should be_root
72
+ artifact_ns(:current).should be_root
73
+ define 'foo' do
74
+ artifact_ns(:current).name.should == 'foo'
75
+ define 'baz' do
76
+ artifact_ns(:current).name.should == 'foo:baz'
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ describe '#parent' do
83
+ it 'should be nil for root namespace' do
84
+ artifact_ns(:root).parent.should be_nil
85
+ end
86
+
87
+ it 'should be the parent namespace for nested modules' do
88
+ abc_module do
89
+ artifact_ns(A::B::C).parent.should == artifact_ns(A::B)
90
+ artifact_ns(A::B).parent.should == artifact_ns(A)
91
+ artifact_ns(A).parent.should == artifact_ns(:root)
92
+ end
93
+ end
94
+
95
+ it 'should be the parent namespace for nested projects' do
96
+ define 'a' do
97
+ define 'b' do
98
+ define 'c' do
99
+ artifact_ns.parent.should == artifact_ns(parent)
100
+ end
101
+ artifact_ns.parent.should == artifact_ns(parent)
102
+ end
103
+ artifact_ns.parent.should == artifact_ns(:root)
104
+ end
105
+ end
106
+ end
107
+
108
+ describe '#parent=' do
109
+ it 'should reject to set parent for root namespace' do
110
+ lambda { artifact_ns(:root).parent = :foo }.should raise_error(Exception, /cannot set parent/i)
111
+ end
112
+
113
+ it 'should allow to set parent' do
114
+ artifact_ns(:bar).parent = :foo
115
+ artifact_ns(:bar).parent.should == artifact_ns(:foo)
116
+ artifact_ns(:bar).parent = artifact_ns(:baz)
117
+ artifact_ns(:bar).parent.should == artifact_ns(:baz)
118
+ end
119
+
120
+ it 'should allow to set parent to :current' do
121
+ abc_module do
122
+ mod = A::B
123
+ artifact_ns(mod).parent = :current
124
+ def mod.stuff
125
+ Buildr::artifact_ns(self)
126
+ end
127
+ define 'a' do
128
+ define 'b' do
129
+ mod.stuff.parent.should == artifact_ns
130
+ end
131
+ mod.stuff.parent.should == artifact_ns
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ describe '#need' do
138
+ it 'should accept an artifact spec' do
139
+ define 'one' do
140
+ artifact_ns.need 'a:b:c:1'
141
+ # referenced by spec
142
+ artifact_ns['a:b:c'].should_not be_selected
143
+
144
+ # referenced by name
145
+ artifact_ns[:b].should_not be_selected
146
+ artifact_ns[:b].should be_satisfied_by('a:b:c:1')
147
+ artifact_ns[:b].should_not be_satisfied_by('a:b:c:2')
148
+ artifact_ns[:b].should_not be_satisfied_by('d:b:c:1')
149
+ artifact_ns[:b].version.should == '1'
150
+ end
151
+ end
152
+
153
+ it 'should accept a requirement_spec' do
154
+ define 'one' do
155
+ artifact_ns.need 'thing -> a:b:c:2.1 -> ~>2.0'
156
+ # referenced by spec
157
+ artifact_ns['a:b:c'].should_not be_selected
158
+
159
+ # referenced by name
160
+ artifact_ns.key?(:b).should be_false
161
+ artifact_ns[:thing].should_not be_selected
162
+ artifact_ns[:thing].should be_satisfied_by('a:b:c:2.5')
163
+ artifact_ns[:thing].should_not be_satisfied_by('a:b:c:3')
164
+ artifact_ns[:thing].version.should == '2.1'
165
+ end
166
+ end
167
+
168
+ it 'should accept a hash :name -> requirement_spec' do
169
+ define 'one' do
170
+ artifact_ns.need :thing => 'a:b:c:2.1 -> ~>2.0'
171
+ artifact_ns[:thing].should be_satisfied_by('a:b:c:2.5')
172
+ artifact_ns[:thing].should_not be_satisfied_by('a:b:c:3')
173
+ artifact_ns[:thing].version.should == '2.1'
174
+ end
175
+
176
+ define 'two' do
177
+ artifact_ns.need :thing => 'a:b:c:(~>2.0 | 2.1)'
178
+ artifact_ns[:thing].should be_satisfied_by('a:b:c:2.5')
179
+ artifact_ns[:thing].should_not be_satisfied_by('a:b:c:3')
180
+ artifact_ns[:thing].version.should == '2.1'
181
+ end
182
+ end
183
+
184
+ it 'should take a hash :name -> specs_array' do
185
+ define 'one' do
186
+ artifact_ns.need :things => ['foo:bar:jar:1.0',
187
+ 'foo:baz:jar:2.0',]
188
+ artifact_ns['foo:bar:jar'].should_not be_selected
189
+ artifact_ns['foo:baz:jar'].should_not be_selected
190
+ artifact_ns[:bar, :baz].should == [nil, nil]
191
+ artifact_ns[:things].map(&:unversioned_spec).should include('foo:bar:jar', 'foo:baz:jar')
192
+ artifact_ns.alias :baz, 'foo:baz:jar'
193
+ artifact_ns[:baz].should == artifact_ns['foo:baz:jar']
194
+ end
195
+ end
196
+
197
+ it 'should select best matching version if defined' do
198
+ define 'one' do
199
+ artifact_ns.use :a => 'foo:bar:jar:1.5'
200
+ artifact_ns.use :b => 'foo:baz:jar:2.0'
201
+ define 'two' do
202
+ artifact_ns[:a].requirement.should be_nil
203
+ artifact_ns[:a].should be_selected
204
+
205
+ artifact_ns.need :c => 'foo:bat:jar:3.0'
206
+ artifact_ns['foo:bat:jar'].should_not be_selected
207
+ artifact_ns[:c].should_not be_selected
208
+
209
+ artifact_ns.need :one => 'foo:bar:jar:>=1.0'
210
+ artifact_ns[:one].version.should == '1.5'
211
+ artifact_ns[:one].should be_selected
212
+ artifact_ns[:a].requirement.should be_nil
213
+
214
+ artifact_ns.need :two => 'foo:baz:jar:>2'
215
+ artifact_ns[:two].version.should be_nil
216
+ artifact_ns[:two].should_not be_selected
217
+ artifact_ns[:b].requirement.should be_nil
218
+ end
219
+ end
220
+ end
221
+ end
222
+
223
+ describe '#use' do
224
+ it 'should register the artifact on namespace' do
225
+ define 'one' do
226
+ artifact_ns.use :thing => 'a:b:c:1'
227
+ artifact_ns[:thing].requirement.should be_nil
228
+ artifact_ns[:thing].version.should == '1'
229
+ artifact_ns[:thing].id.should == 'b'
230
+ define 'one' do
231
+ artifact_ns.use :thing => 'a:d:c:2'
232
+ artifact_ns[:thing].requirement.should be_nil
233
+ artifact_ns[:thing].version.should == '2'
234
+ artifact_ns[:thing].id.should == 'd'
235
+
236
+ artifact_ns.use :copied => artifact_ns.parent[:thing]
237
+ artifact_ns[:copied].should_not == artifact_ns.parent[:thing]
238
+ artifact_ns[:copied].requirement.should be_nil
239
+ artifact_ns[:copied].version.should == '1'
240
+ artifact_ns[:copied].id.should == 'b'
241
+
242
+ artifact_ns.use :aliased => :copied
243
+ artifact_ns[:aliased].should == artifact_ns[:copied]
244
+
245
+ lambda { artifact_ns.use :invalid => :unknown }.should raise_error(NameError, /undefined/i)
246
+ end
247
+ artifact_ns[:copied].should be_nil
248
+ end
249
+ end
250
+
251
+ it 'should register two artifacts with different version on namespace' do
252
+ define 'one' do
253
+ artifact_ns.use :foo => 'a:b:c:1'
254
+ artifact_ns.use :bar => 'a:b:c:2'
255
+ artifact_ns[:foo].version.should == '1'
256
+ artifact_ns[:bar].version.should == '2'
257
+ # unversioned references the last version set.
258
+ artifact_ns['a:b:c'].version.should == '2'
259
+ end
260
+ end
261
+
262
+ it 'should complain if namespace requirement is not satisfied' do
263
+ define 'one' do
264
+ artifact_ns.need :bar => 'foo:bar:baz:~>1.5'
265
+ lambda { artifact_ns.use :bar => '1.4' }.should raise_error(Exception, /unsatisfied/i)
266
+ end
267
+ end
268
+
269
+ it 'should be able to register a group' do
270
+ specs = ['its:me:here:1', 'its:you:there:2']
271
+ artifact_ns.use :them => specs
272
+ artifact_ns[:them].map(&:to_spec).should == specs
273
+ artifact_ns['its:me:here'].should_not be_nil
274
+ artifact_ns[:you].should be_nil
275
+ end
276
+
277
+ it 'should be able to assign sub namespaces' do
278
+ artifact_ns(:foo).bar = "foo:bar:baz:0"
279
+ artifact_ns(:moo).foo = artifact_ns(:foo)
280
+ artifact_ns(:moo).foo.should == artifact_ns(:foo)
281
+ artifact_ns(:moo).foo_bar.should == artifact_ns(:foo).bar
282
+ end
283
+
284
+ end
285
+
286
+ describe '#values' do
287
+ it 'returns the artifacts defined on namespace' do
288
+ define 'foo' do
289
+ artifact_ns.use 'foo:one:baz:1.0'
290
+ define 'bar' do
291
+ artifact_ns.use 'foo:two:baz:1.0'
292
+
293
+ specs = artifact_ns.values.map(&:to_spec)
294
+ specs.should include('foo:two:baz:1.0')
295
+ specs.should_not include('foo:one:baz:1.0')
296
+
297
+ specs = artifact_ns.values(true).map(&:to_spec)
298
+ specs.should include('foo:two:baz:1.0', 'foo:one:baz:1.0')
299
+ end
300
+ end
301
+ end
302
+ end
303
+
304
+ describe '#values_at' do
305
+ it 'returns the named artifacts' do
306
+ define 'foo' do
307
+ artifact_ns.use 'foo:one:baz:1.0'
308
+ define 'bar' do
309
+ artifact_ns.use :foo_baz => 'foo:two:baz:1.0'
310
+
311
+ specs = artifact_ns.values_at('one').map(&:to_spec)
312
+ specs.should include('foo:one:baz:1.0')
313
+ specs.should_not include('foo:two:baz:1.0')
314
+
315
+ specs = artifact_ns.values_at('foo_baz').map(&:to_spec)
316
+ specs.should include('foo:two:baz:1.0')
317
+ specs.should_not include('foo:one:baz:1.0')
318
+ end
319
+ end
320
+ end
321
+
322
+ it 'returns first artifacts by their unversioned spec' do
323
+ define 'foo' do
324
+ artifact_ns.use 'foo:one:baz:2.0'
325
+ define 'bar' do
326
+ artifact_ns.use :older => 'foo:one:baz:1.0'
327
+
328
+ specs = artifact_ns.values_at('foo:one:baz').map(&:to_spec)
329
+ specs.should include('foo:one:baz:1.0')
330
+ specs.should_not include('foo:one:baz:2.0')
331
+ end
332
+ specs = artifact_ns.values_at('foo:one:baz').map(&:to_spec)
333
+ specs.should include('foo:one:baz:2.0')
334
+ specs.should_not include('foo:one:baz:1.0')
335
+ end
336
+ end
337
+
338
+ it 'return first artifact satisfying a dependency' do
339
+ define 'foo' do
340
+ artifact_ns.use 'foo:one:baz:2.0'
341
+ define 'bar' do
342
+ artifact_ns.use :older => 'foo:one:baz:1.0'
343
+
344
+ specs = artifact_ns.values_at('foo:one:baz:>1.0').map(&:to_spec)
345
+ specs.should include('foo:one:baz:2.0')
346
+ specs.should_not include('foo:one:baz:1.0')
347
+ end
348
+ end
349
+ end
350
+ end
351
+
352
+ describe '#method_missing' do
353
+ it 'should use cool_aid! to create a requirement' do
354
+ define 'foo' do
355
+ artifact_ns.cool_aid!('cool:aid:jar:2').should be_kind_of(ArtifactNamespace::ArtifactRequirement)
356
+ artifact_ns[:cool_aid].version.should == '2'
357
+ artifact_ns[:cool_aid].should_not be_selected
358
+ define 'bar' do
359
+ artifact_ns.cool_aid! 'cool:aid:man:3', '>2'
360
+ artifact_ns[:cool_aid].version.should == '3'
361
+ artifact_ns[:cool_aid].requirement.should be_satisfied_by('2.5')
362
+ artifact_ns[:cool_aid].should_not be_selected
363
+ end
364
+ end
365
+ end
366
+
367
+ it 'should use cool_aid= as shorhand for [:cool_aid]=' do
368
+ artifact_ns.cool_aid = 'cool:aid:jar:1'
369
+ artifact_ns[:cool_aid].should be_selected
370
+ end
371
+
372
+ it 'should use cool_aid as shorthand for [:cool_aid]' do
373
+ artifact_ns.need :cool_aid => 'cool:aid:jar:1'
374
+ artifact_ns.cool_aid.should_not be_selected
375
+ end
376
+
377
+ it 'should use cool_aid? to test if artifact has been defined and selected' do
378
+ artifact_ns.need :cool_aid => 'cool:aid:jar:>1'
379
+ artifact_ns.should_not have_cool_aid
380
+ artifact_ns.should_not have_unknown
381
+ artifact_ns.cool_aid = '2'
382
+ artifact_ns.should have_cool_aid
383
+ end
384
+ end
385
+
386
+ describe '#ns' do
387
+ it 'should create a sub namespace' do
388
+ artifact_ns.ns :foo
389
+ artifact_ns[:foo].should be_kind_of(ArtifactNamespace)
390
+ artifact_ns(:foo).should_not === artifact_ns.foo
391
+ artifact_ns.foo.parent.should == artifact_ns
392
+ end
393
+
394
+ it 'should take any use arguments' do
395
+ artifact_ns.ns :foo, :bar => 'foo:bar:jar:0', :baz => 'foo:baz:jar:0'
396
+ artifact_ns.foo.bar.should be_selected
397
+ artifact_ns.foo[:baz].should be_selected
398
+ end
399
+
400
+ it 'should access sub artifacts using with foo_bar like syntax' do
401
+ artifact_ns.ns :foo, :bar => 'foo:bar:jar:0', :baz => 'foo:baz:jar:0'
402
+ artifact_ns[:foo_baz].should be_selected
403
+ artifact_ns.foo_bar.should be_selected
404
+
405
+ artifact_ns.foo.ns :bat, 'bat:man:jar:>1'
406
+ batman = artifact_ns.foo.bat.man
407
+ batman.should be_selected
408
+ artifact_ns[:foo_bat_man] = '3'
409
+ artifact_ns[:foo_bat_man].should == batman
410
+ artifact_ns[:foo_bat_man].version.should == '3'
411
+ end
412
+
413
+ it 'should include sub artifacts when calling #values' do
414
+ artifact_ns.ns :bat, 'bat:man:jar:>1'
415
+ artifact_ns.values.should_not be_empty
416
+ artifact_ns.values.first.unversioned_spec.should == 'bat:man:jar'
417
+ end
418
+
419
+ it 'should reopen a sub-namespace' do
420
+ artifact_ns.ns :bat, 'bat:man:jar:>1'
421
+ bat = artifact_ns[:bat]
422
+ bat.should == artifact_ns.ns(:bat)
423
+ end
424
+
425
+ it 'should fail reopening if not a sub-namespace' do
426
+ artifact_ns.foo = 'foo:bar:baz:0'
427
+ lambda { artifact_ns.ns(:foo) }.should raise_error(TypeError, /not a sub/i)
428
+ end
429
+
430
+ it 'should clone artifacts when assigned' do
431
+ artifact_ns(:foo).bar = "foo:bar:jar:0"
432
+ artifact_ns(:moo).ns :muu, :miu => artifact_ns(:foo).bar
433
+ artifact_ns(:moo).muu.miu.should_not == artifact_ns(:foo).bar
434
+ artifact_ns(:moo).muu.miu.to_spec.should == artifact_ns(:foo).bar.to_spec
435
+ end
436
+
437
+ it 'should clone parent artifacts by name' do
438
+ define 'foo' do
439
+ artifact_ns.bar = "foo:bar:jar:0"
440
+ define 'moo' do
441
+ artifact_ns.ns(:muu).use :bar
442
+ artifact_ns.muu_bar.should be_selected
443
+ artifact_ns.muu.bar.should_not == artifact_ns.bar
444
+ end
445
+ end
446
+ end
447
+ end
448
+
449
+ it 'should be an Enumerable' do
450
+ artifact_ns.should be_kind_of(Enumerable)
451
+ artifact_ns.use 'foo:bar:baz:1.0'
452
+ artifact_ns.map(&:artifact).should include(artifact('foo:bar:baz:1.0'))
453
+ end
454
+
455
+ end # ArtifactNamespace
456
+
457
+ describe Buildr do
458
+ before(:each) { Buildr::ArtifactNamespace.clear }
459
+
460
+ describe '.artifacts' do
461
+ it 'should take ruby symbols and ask the current namespace for them' do
462
+ define 'foo' do
463
+ artifact_ns.cool = 'cool:aid:jar:1.0'
464
+ artifact_ns.use 'some:other:jar:1.0'
465
+ artifact_ns.use 'bat:man:jar:1.0'
466
+ compile.with :cool, :other, :'bat:man:jar'
467
+ compile.classpath.map(&:to_spec).should include('cool:aid:jar:1.0', 'some:other:jar:1.0', 'bat:man:jar:1.0')
468
+ end
469
+ end
470
+
471
+ it 'should take a namespace' do
472
+ artifact_ns(:moo).muu = 'moo:muu:jar:1.0'
473
+ define 'foo' do
474
+ compile.with artifact_ns(:moo)
475
+ compile.classpath.map(&:to_spec).should include('moo:muu:jar:1.0')
476
+ end
477
+ end
478
+ end
479
+
480
+ describe '.artifact' do
481
+ it 'should search current namespace if given a symbol' do
482
+ define 'foo' do
483
+ artifact_ns.use :cool => 'cool:aid:jar:1.0'
484
+ define 'bar' do
485
+ artifact(:cool).should == artifact_ns[:cool].artifact
486
+ end
487
+ end
488
+ end
489
+
490
+ it 'should search current namespace if given a symbol spec' do
491
+ define 'foo' do
492
+ artifact_ns.use 'cool:aid:jar:1.0'
493
+ define 'bar' do
494
+ artifact(:'cool:aid:jar').should == artifact_ns[:aid].artifact
495
+ end
496
+ end
497
+ end
498
+
499
+ it 'should fail when no artifact by that name is found' do
500
+ define 'foo' do
501
+ artifact_ns.use 'cool:aid:jar:1.0'
502
+ define 'bar' do
503
+ lambda { artifact(:cool) }.should raise_error(IndexError, /artifact/)
504
+ end
505
+ end
506
+ end
507
+ end
508
+ end
509
+
510
+ describe "Extension using ArtifactNamespace" do
511
+ before(:each) { Buildr::ArtifactNamespace.clear }
512
+
513
+ def abc_module
514
+ Object.module_eval 'module A; module B; module C; end; end; end'
515
+ yield
516
+ ensure
517
+ Object.send :remove_const, :A
518
+ end
519
+
520
+ it 'can register namespace listeners' do
521
+ abc_module do
522
+ # An example extension to illustrate namespace listeners and method forwarding
523
+ class A::Example
524
+
525
+ module Ext
526
+ include Buildr::Extension
527
+ def example; @example ||= A::Example.new; end
528
+ before_define do |p|
529
+ Rake::Task.define_task('example') { p.example.doit }
530
+ end
531
+ end
532
+
533
+ REQUIRES = ArtifactNamespace.for(self) do |ns|
534
+ ns.xmlbeans! 'org.apache.xmlbeans:xmlbeans:jar:2.3.0', '>2'
535
+ ns.stax_api! 'stax:stax-api:jar:>=1.0.1'
536
+ end
537
+
538
+ attr_reader :options, :requires
539
+
540
+ def initialize
541
+ # We could actually use the REQUIRES namespace, but to make things
542
+ # a bit more interesting, suppose each Example instance can have its
543
+ # own artifact requirements in adition to those specified on REQUIRES.
544
+ # To achieve this we create an anonymous namespace.
545
+ @requires = ArtifactNamespace.new # a namespace per instance
546
+ REQUIRES.each { |requirement| @requires.need requirement }
547
+
548
+ # For user convenience, we make the options object respond to
549
+ # :xmlbeans, :xmlbeans=, :xmlbeans?
550
+ # forwarding them to the namespace.
551
+ @options = OpenObject.new.extend(@requires.accessor(:xmlbeans, :stax_api))
552
+ # Register callbacks so we can perform some logic when an artifact
553
+ # is selected by the user.
554
+ options.xmlbeans.add_listener &method(:selected_xmlbeans)
555
+ options.stax_api.add_listener do |stax|
556
+ # Now using a proc
557
+ stax.should be_selected
558
+ stax.version.should == '1.6180'
559
+ options[:math] = :golden # customize our options for this version
560
+ # In this example we set the stax version when running outside
561
+ # a project definition. This means we have no access to the project
562
+ # namespace unless we had a reference to the project or knew it's name
563
+ Buildr.artifact_ns(:current).name.should == 'root'
564
+ end
565
+ end
566
+
567
+ include Spec::Matchers # for assertions
568
+
569
+ # Called with the ArtifactRequirement that has just been selected
570
+ # by a user. This allows extension author to selectively perform
571
+ # some action by inspecting the requirement state.
572
+ def selected_xmlbeans(xmlbeans)
573
+ xmlbeans.should be_selected
574
+ xmlbeans.version.should == '3.1415'
575
+ options[:math] = :pi
576
+ # This example just sets xmlbeans for foo:bar project
577
+ # So the currently running namespace should have the foo:bar name
578
+ Buildr.artifact_ns(:current).name.should == 'foo:bar'
579
+ end
580
+
581
+ # Suppose we invoke an ant task here or something else.
582
+ def doit
583
+ # Now call ant task with our selected artifact and options
584
+ classpath = requires.map(&:artifact).map(&:to_s).join(File::PATH_SEPARATOR)
585
+ lambda { ant('thing') { |ant| ant.classpath classpath, :math => options[:math] } }
586
+
587
+ # We are not a Project instance, hence we have no artifact_ns
588
+ lambda { artifact_ns }.should raise_error(NameError)
589
+
590
+ # Extension authors may NOT rely project's namespaces.
591
+ # However the ruby-way gives you power and at the same time
592
+ # makes you dangerous, (think open-modules, monkey-patching)
593
+ # Given that buildr is pure ruby, consider it a sharp-edged sword.
594
+ # Having said that, you may actually inspect a project's
595
+ # namespace, but don't write on it without letting your users
596
+ # know you will.
597
+ # This example obtains the current project namespace to make
598
+ # some assertions.
599
+
600
+ # To obtain a project's namespace we need either
601
+ # 1) a reference to the project, and call artifact_ns on it
602
+ # project.artifact_ns # the namespace for project
603
+ # 2) know the project name
604
+ # Buildr.artifact_ns('the:project')
605
+ # 3) Use :current to reference the currently running project
606
+ # Buildr.artifact_ns(:current)
607
+ name = Buildr.artifact_ns(:current).name
608
+ case name
609
+ when 'foo:bar'
610
+ options[:math].should == :pi
611
+ requires.xmlbeans.version.should == '3.1415'
612
+ requires.stax_api.version.should == '1.0.1'
613
+ when 'foo:baz'
614
+ options[:math].should == :golden
615
+ requires.xmlbeans.version.should == '2.3.0'
616
+ requires.stax_api.version.should == '1.6180'
617
+ else
618
+ fail "This example expects foo:bar or foo:baz projects not #{name.inspect}"
619
+ end
620
+ end
621
+ end
622
+
623
+ define 'foo' do
624
+ define 'bar' do
625
+ extend A::Example::Ext
626
+ task('setup') do
627
+ example.options.xmlbeans = '3.1415'
628
+ end
629
+ task('run' => [:setup, :example])
630
+ end
631
+ define 'baz' do
632
+ extend A::Example::Ext
633
+ end
634
+ end
635
+
636
+ project('foo:bar').example.requires.should_not == project('foo:baz').example.requires
637
+ project('foo:bar').example.requires.xmlbeans.should_not == project('foo:baz').example.requires.xmlbeans
638
+
639
+ # current namespace outside a project is :root, see the stax callback
640
+ project('foo:baz').example.options.stax_api = '1.6180'
641
+ # we call the task outside the project, see #doit
642
+ lambda { task('foo:bar:run').invoke }.should run_task('foo:bar:example')
643
+ lambda { task('foo:baz:example').invoke }.should run_task('foo:baz:example')
644
+ end
645
+ end
646
+ end