realityforge-buildr 1.5.9

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 (85) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/LICENSE +176 -0
  4. data/NOTICE +26 -0
  5. data/README.md +3 -0
  6. data/Rakefile +50 -0
  7. data/addon/buildr/checkstyle-report.xsl +104 -0
  8. data/addon/buildr/checkstyle.rb +254 -0
  9. data/addon/buildr/git_auto_version.rb +36 -0
  10. data/addon/buildr/gpg.rb +90 -0
  11. data/addon/buildr/gwt.rb +413 -0
  12. data/addon/buildr/jacoco.rb +161 -0
  13. data/addon/buildr/pmd.rb +185 -0
  14. data/addon/buildr/single_intermediate_layout.rb +71 -0
  15. data/addon/buildr/spotbugs.rb +265 -0
  16. data/addon/buildr/top_level_generate_dir.rb +37 -0
  17. data/addon/buildr/wsgen.rb +192 -0
  18. data/bin/buildr +20 -0
  19. data/buildr.gemspec +61 -0
  20. data/lib/buildr.rb +86 -0
  21. data/lib/buildr/core/application.rb +705 -0
  22. data/lib/buildr/core/assets.rb +96 -0
  23. data/lib/buildr/core/build.rb +587 -0
  24. data/lib/buildr/core/common.rb +167 -0
  25. data/lib/buildr/core/compile.rb +599 -0
  26. data/lib/buildr/core/console.rb +124 -0
  27. data/lib/buildr/core/doc.rb +275 -0
  28. data/lib/buildr/core/environment.rb +128 -0
  29. data/lib/buildr/core/filter.rb +405 -0
  30. data/lib/buildr/core/help.rb +114 -0
  31. data/lib/buildr/core/progressbar.rb +161 -0
  32. data/lib/buildr/core/project.rb +994 -0
  33. data/lib/buildr/core/test.rb +776 -0
  34. data/lib/buildr/core/transports.rb +456 -0
  35. data/lib/buildr/core/util.rb +77 -0
  36. data/lib/buildr/ide/idea.rb +1664 -0
  37. data/lib/buildr/java/commands.rb +230 -0
  38. data/lib/buildr/java/compiler.rb +85 -0
  39. data/lib/buildr/java/custom_pom.rb +300 -0
  40. data/lib/buildr/java/doc.rb +62 -0
  41. data/lib/buildr/java/packaging.rb +393 -0
  42. data/lib/buildr/java/pom.rb +191 -0
  43. data/lib/buildr/java/test_result.rb +54 -0
  44. data/lib/buildr/java/tests.rb +111 -0
  45. data/lib/buildr/packaging/archive.rb +586 -0
  46. data/lib/buildr/packaging/artifact.rb +1113 -0
  47. data/lib/buildr/packaging/artifact_namespace.rb +1010 -0
  48. data/lib/buildr/packaging/artifact_search.rb +138 -0
  49. data/lib/buildr/packaging/package.rb +237 -0
  50. data/lib/buildr/packaging/version_requirement.rb +189 -0
  51. data/lib/buildr/packaging/zip.rb +189 -0
  52. data/lib/buildr/packaging/ziptask.rb +387 -0
  53. data/lib/buildr/version.rb +18 -0
  54. data/rakelib/release.rake +99 -0
  55. data/spec/addon/checkstyle_spec.rb +58 -0
  56. data/spec/core/application_spec.rb +576 -0
  57. data/spec/core/build_spec.rb +922 -0
  58. data/spec/core/common_spec.rb +670 -0
  59. data/spec/core/compile_spec.rb +656 -0
  60. data/spec/core/console_spec.rb +65 -0
  61. data/spec/core/doc_spec.rb +194 -0
  62. data/spec/core/extension_spec.rb +200 -0
  63. data/spec/core/project_spec.rb +736 -0
  64. data/spec/core/test_spec.rb +1131 -0
  65. data/spec/core/transport_spec.rb +452 -0
  66. data/spec/core/util_spec.rb +154 -0
  67. data/spec/ide/idea_spec.rb +1952 -0
  68. data/spec/java/commands_spec.rb +79 -0
  69. data/spec/java/compiler_spec.rb +274 -0
  70. data/spec/java/custom_pom_spec.rb +165 -0
  71. data/spec/java/doc_spec.rb +55 -0
  72. data/spec/java/packaging_spec.rb +786 -0
  73. data/spec/java/pom_spec.rb +162 -0
  74. data/spec/java/test_coverage_helper.rb +257 -0
  75. data/spec/java/tests_spec.rb +224 -0
  76. data/spec/packaging/archive_spec.rb +686 -0
  77. data/spec/packaging/artifact_namespace_spec.rb +757 -0
  78. data/spec/packaging/artifact_spec.rb +1351 -0
  79. data/spec/packaging/packaging_helper.rb +63 -0
  80. data/spec/packaging/packaging_spec.rb +690 -0
  81. data/spec/sandbox.rb +166 -0
  82. data/spec/spec_helpers.rb +420 -0
  83. data/spec/version_requirement_spec.rb +145 -0
  84. data/spec/xpath_matchers.rb +123 -0
  85. metadata +295 -0
@@ -0,0 +1,757 @@
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.expand_path(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
+ flag = false
36
+ Buildr::ArtifactNamespace.root { |ns| flag = true; ns.should be_root }
37
+ flag.should == true
38
+ end
39
+
40
+ it 'should return the root when used outside of a project definition' do
41
+ artifact_ns.should be_root
42
+ end
43
+
44
+ it 'should yield to a block when used outside of a project definition' do
45
+ flag = false
46
+ artifact_ns {|ns| flag = true; ns.should be_root}
47
+ flag.should == true
48
+ end
49
+ end
50
+
51
+ describe '.instance' do
52
+ it 'should return the top level namespace when invoked outside a project definition' do
53
+ artifact_ns.should be_root
54
+ end
55
+
56
+ it 'should return the namespace for the receiving project' do
57
+ define('foo') { }
58
+ project('foo').artifact_ns.name.should == 'foo'
59
+ end
60
+
61
+ it 'should return the current project namespace when invoked inside a project' do
62
+ define 'foo' do
63
+ artifact_ns.should_not be_root
64
+ artifact_ns.name.should == 'foo'
65
+ task :doit do
66
+ artifact_ns.should_not be_root
67
+ artifact_ns.name.should == 'foo'
68
+ end.invoke
69
+ end
70
+ end
71
+
72
+ it 'should return the root namespace if given :root' do
73
+ artifact_ns(:root).should be_root
74
+ end
75
+
76
+ it 'should return the namespace for the given name' do
77
+ artifact_ns(:foo).name.should == 'foo'
78
+ artifact_ns('foo:bar').name.should == 'foo:bar'
79
+ artifact_ns(%w[foo bar baz]).name.should == 'foo:bar:baz'
80
+ abc_module do
81
+ artifact_ns(A::B::C).name.should == 'A::B::C'
82
+ end
83
+ artifact_ns(:root).should be_root
84
+ artifact_ns(:current).should be_root
85
+ define 'foo' do
86
+ artifact_ns(:current).name.should == 'foo'
87
+ define 'baz' do
88
+ artifact_ns(:current).name.should == 'foo:baz'
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ describe '#parent' do
95
+ it 'should be nil for root namespace' do
96
+ artifact_ns(:root).parent.should be_nil
97
+ end
98
+
99
+ it 'should be the parent namespace for nested modules' do
100
+ abc_module do
101
+ artifact_ns(A::B::C).parent.should == artifact_ns(A::B)
102
+ artifact_ns(A::B).parent.should == artifact_ns(A)
103
+ artifact_ns(A).parent.should == artifact_ns(:root)
104
+ end
105
+ end
106
+
107
+ it 'should be the parent namespace for nested projects' do
108
+ define 'a' do
109
+ define 'b' do
110
+ define 'c' do
111
+ artifact_ns.parent.should == artifact_ns(parent)
112
+ end
113
+ artifact_ns.parent.should == artifact_ns(parent)
114
+ end
115
+ artifact_ns.parent.should == artifact_ns(:root)
116
+ end
117
+ end
118
+ end
119
+
120
+ describe '#parent=' do
121
+ it 'should reject to set parent for root namespace' do
122
+ lambda { artifact_ns(:root).parent = :foo }.should raise_error(Exception, /cannot set parent/i)
123
+ end
124
+
125
+ it 'should allow to set parent' do
126
+ artifact_ns(:bar).parent = :foo
127
+ artifact_ns(:bar).parent.should == artifact_ns(:foo)
128
+ artifact_ns(:bar).parent = artifact_ns(:baz)
129
+ artifact_ns(:bar).parent.should == artifact_ns(:baz)
130
+ end
131
+
132
+ it 'should allow to set parent to :current' do
133
+ abc_module do
134
+ mod = A::B
135
+ artifact_ns(mod).parent = :current
136
+ def mod.stuff
137
+ Buildr::artifact_ns(self)
138
+ end
139
+ define 'a' do
140
+ define 'b' do
141
+ mod.stuff.parent.should == artifact_ns
142
+ end
143
+ mod.stuff.parent.should == artifact_ns
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ describe '#need' do
150
+ it 'should accept an artifact spec' do
151
+ define 'one' do
152
+ artifact_ns.need 'a:b:c:1'
153
+ # referenced by spec
154
+ artifact_ns['a:b:c'].should_not be_selected
155
+
156
+ # referenced by name
157
+ artifact_ns[:b].should_not be_selected
158
+ artifact_ns[:b].should be_satisfied_by('a:b:c:1')
159
+ artifact_ns[:b].should_not be_satisfied_by('a:b:c:2')
160
+ artifact_ns[:b].should_not be_satisfied_by('d:b:c:1')
161
+ artifact_ns[:b].version.should == '1'
162
+ end
163
+ end
164
+
165
+ it 'should accept an artifact spec with classifier' do
166
+ define 'one' do
167
+ artifact_ns.need 'a:b:c:d:1'
168
+ # referenced by spec
169
+ artifact_ns['a:b:c:d:'].should_not be_selected
170
+
171
+ # referenced by name
172
+ artifact_ns[:b].should_not be_selected
173
+ artifact_ns[:b].should be_satisfied_by('a:b:c:d:1')
174
+ artifact_ns[:b].should_not be_satisfied_by('a:b:c:d:2')
175
+ artifact_ns[:b].should_not be_satisfied_by('d:b:c:d:1')
176
+ artifact_ns[:b].version.should == '1'
177
+ end
178
+ end
179
+
180
+ it 'should accept a requirement_spec' do
181
+ define 'one' do
182
+ artifact_ns.need 'thing -> a:b:c:2.1 -> ~>2.0'
183
+ # referenced by spec
184
+ artifact_ns['a:b:c'].should_not be_selected
185
+
186
+ # referenced by name
187
+ artifact_ns.key?(:b).should be_false
188
+ artifact_ns[:thing].should_not be_selected
189
+ artifact_ns[:thing].should be_satisfied_by('a:b:c:2.5')
190
+ artifact_ns[:thing].should_not be_satisfied_by('a:b:c:3')
191
+ artifact_ns[:thing].version.should == '2.1'
192
+ end
193
+ end
194
+
195
+ it 'should accept a hash :name -> requirement_spec' do
196
+ define 'one' do
197
+ artifact_ns.need :thing => 'a:b:c:2.1 -> ~>2.0'
198
+ artifact_ns[:thing].should be_satisfied_by('a:b:c:2.5')
199
+ artifact_ns[:thing].should_not be_satisfied_by('a:b:c:3')
200
+ artifact_ns[:thing].version.should == '2.1'
201
+ end
202
+
203
+ define 'two' do
204
+ artifact_ns.need :thing => 'a:b:c:(~>2.0 | 2.1)'
205
+ artifact_ns[:thing].should be_satisfied_by('a:b:c:2.5')
206
+ artifact_ns[:thing].should_not be_satisfied_by('a:b:c:3')
207
+ artifact_ns[:thing].version.should == '2.1'
208
+ end
209
+ end
210
+
211
+ it 'should take a hash :name -> specs_array' do
212
+ define 'one' do
213
+ artifact_ns.need :things => %w[foo:bar:jar:1.0 foo:baz:jar:2.0]
214
+ artifact_ns['foo:bar:jar'].should_not be_selected
215
+ artifact_ns['foo:baz:jar'].should_not be_selected
216
+ artifact_ns[:bar, :baz].should == [nil, nil]
217
+ artifact_ns[:things].map(&:unversioned_spec).should include('foo:bar:jar', 'foo:baz:jar')
218
+ artifact_ns.alias :baz, 'foo:baz:jar'
219
+ artifact_ns[:baz].should == artifact_ns['foo:baz:jar']
220
+ end
221
+ end
222
+
223
+ it 'should select best matching version if defined' do
224
+ define 'one' do
225
+ artifact_ns.use :a => 'foo:bar:jar:1.5'
226
+ artifact_ns.use :b => 'foo:baz:jar:2.0'
227
+ define 'two' do
228
+ artifact_ns[:a].requirement.should be_nil
229
+ artifact_ns[:a].should be_selected
230
+
231
+ artifact_ns.need :c => 'foo:bat:jar:3.0'
232
+ artifact_ns['foo:bat:jar'].should_not be_selected
233
+ artifact_ns[:c].should_not be_selected
234
+
235
+ artifact_ns.need :one => 'foo:bar:jar:>=1.0'
236
+ artifact_ns[:one].version.should == '1.5'
237
+ artifact_ns[:one].should be_selected
238
+ artifact_ns[:a].requirement.should be_nil
239
+
240
+ artifact_ns.need :two => 'foo:baz:jar:>2'
241
+ artifact_ns[:two].version.should be_nil
242
+ artifact_ns[:two].should_not be_selected
243
+ artifact_ns[:b].requirement.should be_nil
244
+ end
245
+ end
246
+ end
247
+ end
248
+
249
+ describe '#use' do
250
+ it 'should register the artifact on namespace' do
251
+ define 'one' do
252
+ artifact_ns.use :thing => 'a:b:c:1'
253
+ artifact_ns[:thing].requirement.should be_nil
254
+ artifact_ns[:thing].version.should == '1'
255
+ artifact_ns[:thing].id.should == 'b'
256
+ define 'one' do
257
+ artifact_ns.use :thing => 'a:d:c:2'
258
+ artifact_ns[:thing].requirement.should be_nil
259
+ artifact_ns[:thing].version.should == '2'
260
+ artifact_ns[:thing].id.should == 'd'
261
+
262
+ artifact_ns.use :copied => artifact_ns.parent[:thing]
263
+ artifact_ns[:copied].should_not == artifact_ns.parent[:thing]
264
+ artifact_ns[:copied].requirement.should be_nil
265
+ artifact_ns[:copied].version.should == '1'
266
+ artifact_ns[:copied].id.should == 'b'
267
+
268
+ artifact_ns.use :aliased => :copied
269
+ artifact_ns[:aliased].should == artifact_ns[:copied]
270
+
271
+ lambda { artifact_ns.use :invalid => :unknown }.should raise_error(NameError, /undefined/i)
272
+ end
273
+ artifact_ns[:copied].should be_nil
274
+ end
275
+ end
276
+
277
+ it 'should register two artifacts with different version on namespace' do
278
+ define 'one' do
279
+ artifact_ns.use :foo => 'a:b:c:1'
280
+ artifact_ns.use :bar => 'a:b:c:2'
281
+ artifact_ns[:foo].version.should == '1'
282
+ artifact_ns[:bar].version.should == '2'
283
+ # unversioned references the last version set.
284
+ artifact_ns['a:b:c'].version.should == '2'
285
+ end
286
+ end
287
+
288
+ it 'should complain if namespace requirement is not satisfied' do
289
+ define 'one' do
290
+ artifact_ns.need :bar => 'foo:bar:baz:~>1.5'
291
+ lambda { artifact_ns.use :bar => '1.4' }.should raise_error(Exception, /unsatisfied/i)
292
+ end
293
+ end
294
+
295
+ it 'should be able to register a group' do
296
+ specs = %w[its:me:here:1 its:you:there:2]
297
+ artifact_ns.use :them => specs
298
+ artifact_ns[:them].map(&:to_spec).should == specs
299
+ artifact_ns['its:me:here'].should_not be_nil
300
+ artifact_ns[:you].should be_nil
301
+ end
302
+
303
+ it 'should be able to assign sub namespaces' do
304
+ artifact_ns(:foo).bar = "foo:bar:baz:0"
305
+ artifact_ns(:moo).foo = artifact_ns(:foo)
306
+ artifact_ns(:moo).foo.should == artifact_ns(:foo)
307
+ artifact_ns(:moo).foo_bar.should == artifact_ns(:foo).bar
308
+ end
309
+
310
+ it 'should handle symbols with dashes and periods' do
311
+ [:'a-b', :'a.b'].each do |symbol|
312
+ artifact_ns.use symbol => 'a:b:c:1'
313
+ artifact_ns[symbol].version.should == '1'
314
+ artifact_ns[symbol].id.should == 'b'
315
+ end
316
+ end
317
+
318
+ it 'should handle version string' do
319
+ foo = artifact_ns do |ns|
320
+ ns.bar = 'a:b:c:1'
321
+ end
322
+ foo.use :bar => '2.0'
323
+ foo.bar.version.should == '2.0'
324
+ end
325
+ end
326
+
327
+ describe '#values' do
328
+ it 'returns the artifacts defined on namespace' do
329
+ define 'foo' do
330
+ artifact_ns.use 'foo:one:baz:1.0'
331
+ define 'bar' do
332
+ artifact_ns.use 'foo:two:baz:1.0'
333
+
334
+ specs = artifact_ns.values.map(&:to_spec)
335
+ specs.should include('foo:two:baz:1.0')
336
+ specs.should_not include('foo:one:baz:1.0')
337
+
338
+ specs = artifact_ns.values(true).map(&:to_spec)
339
+ specs.should include('foo:two:baz:1.0', 'foo:one:baz:1.0')
340
+ end
341
+ end
342
+ end
343
+ end
344
+
345
+ describe '#values_at' do
346
+ it 'returns the named artifacts' do
347
+ define 'foo' do
348
+ artifact_ns.use 'foo:one:baz:1.0'
349
+ define 'bar' do
350
+ artifact_ns.use :foo_baz => 'foo:two:baz:1.0'
351
+
352
+ specs = artifact_ns.values_at('one').map(&:to_spec)
353
+ specs.should include('foo:one:baz:1.0')
354
+ specs.should_not include('foo:two:baz:1.0')
355
+
356
+ specs = artifact_ns.values_at('foo_baz').map(&:to_spec)
357
+ specs.should include('foo:two:baz:1.0')
358
+ specs.should_not include('foo:one:baz:1.0')
359
+ end
360
+ end
361
+ end
362
+
363
+ it 'returns first artifacts by their unversioned spec' do
364
+ define 'foo' do
365
+ artifact_ns.use 'foo:one:baz:2.0'
366
+ define 'bar' do
367
+ artifact_ns.use :older => 'foo:one:baz:1.0'
368
+
369
+ specs = artifact_ns.values_at('foo:one:baz').map(&:to_spec)
370
+ specs.should include('foo:one:baz:1.0')
371
+ specs.should_not include('foo:one:baz:2.0')
372
+ end
373
+ specs = artifact_ns.values_at('foo:one:baz').map(&:to_spec)
374
+ specs.should include('foo:one:baz:2.0')
375
+ specs.should_not include('foo:one:baz:1.0')
376
+ end
377
+ end
378
+
379
+ it 'return first artifact satisfying a dependency' do
380
+ define 'foo' do
381
+ artifact_ns.use 'foo:one:baz:2.0'
382
+ define 'bar' do
383
+ artifact_ns.use :older => 'foo:one:baz:1.0'
384
+
385
+ specs = artifact_ns.values_at('foo:one:baz:>1.0').map(&:to_spec)
386
+ specs.should include('foo:one:baz:2.0')
387
+ specs.should_not include('foo:one:baz:1.0')
388
+ end
389
+ end
390
+ end
391
+ end
392
+
393
+ describe '#artifacts' do
394
+ it 'returns artifacts in namespace' do
395
+ define 'one' do
396
+ artifact_ns[:foo] = 'group:foo:jar:1'
397
+ artifact_ns[:bar] = 'group:bar:jar:1'
398
+ artifact_ns.artifacts.map{|a| a.to_spec}.should include('group:foo:jar:1', 'group:bar:jar:1')
399
+ end
400
+ end
401
+ end
402
+
403
+ describe '#keys' do
404
+ it 'returns names in namespace' do
405
+ define 'one' do
406
+ artifact_ns[:foo] = 'group:foo:jar:1'
407
+ artifact_ns[:bar] = 'group:bar:jar:1'
408
+ artifact_ns.keys.should include('foo', 'bar')
409
+ end
410
+ end
411
+ end
412
+
413
+ describe '#delete' do
414
+ it 'deletes corresponding artifact requirement' do
415
+ define 'one' do
416
+ artifact_ns[:foo] = 'group:foo:jar:1'
417
+ artifact_ns[:bar] = 'group:bar:jar:1'
418
+ artifact_ns.delete :bar
419
+ artifact_ns.artifacts.map{|a| a.to_spec}.should include('group:foo:jar:1')
420
+ artifact_ns[:foo].to_spec.should eql('group:foo:jar:1')
421
+ end
422
+ end
423
+ end
424
+
425
+ describe '#clear' do
426
+ it 'clears all artifact requirements in namespace' do
427
+ define 'one' do
428
+ artifact_ns[:foo] = 'group:foo:jar:1'
429
+ artifact_ns[:bar] = 'group:bar:jar:1'
430
+ artifact_ns.clear
431
+ artifact_ns.artifacts.should be_empty
432
+ end
433
+ end
434
+ end
435
+
436
+ describe '#method_missing' do
437
+ it 'should use cool_aid! to create a requirement' do
438
+ define 'foo' do
439
+ artifact_ns.cool_aid!('cool:aid:jar:2').should be_kind_of(ArtifactNamespace::ArtifactRequirement)
440
+ artifact_ns[:cool_aid].version.should == '2'
441
+ artifact_ns[:cool_aid].should_not be_selected
442
+ define 'bar' do
443
+ artifact_ns.cool_aid! 'cool:aid:man:3', '>2'
444
+ artifact_ns[:cool_aid].version.should == '3'
445
+ artifact_ns[:cool_aid].requirement.should be_satisfied_by('2.5')
446
+ artifact_ns[:cool_aid].should_not be_selected
447
+ end
448
+ end
449
+ end
450
+
451
+ it 'should use cool_aid= as shorhand for [:cool_aid]=' do
452
+ artifact_ns.cool_aid = 'cool:aid:jar:1'
453
+ artifact_ns[:cool_aid].should be_selected
454
+ end
455
+
456
+ it 'should use cool_aid as shorthand for [:cool_aid]' do
457
+ artifact_ns.need :cool_aid => 'cool:aid:jar:1'
458
+ artifact_ns.cool_aid.should_not be_selected
459
+ end
460
+
461
+ it 'should use cool_aid? to test if artifact has been defined and selected' do
462
+ artifact_ns.need :cool_aid => 'cool:aid:jar:>1'
463
+ artifact_ns.should_not have_cool_aid
464
+ artifact_ns.should_not have_unknown
465
+ artifact_ns.cool_aid = '2'
466
+ artifact_ns.should have_cool_aid
467
+ end
468
+ end
469
+
470
+ describe '#ns' do
471
+ it 'should create a sub namespace' do
472
+ artifact_ns.ns :foo
473
+ artifact_ns[:foo].should be_kind_of(ArtifactNamespace)
474
+ artifact_ns(:foo).should_not === artifact_ns.foo
475
+ artifact_ns.foo.parent.should == artifact_ns
476
+ end
477
+
478
+ it 'should take any use arguments' do
479
+ artifact_ns.ns :foo, :bar => 'foo:bar:jar:0', :baz => 'foo:baz:jar:0'
480
+ artifact_ns.foo.bar.should be_selected
481
+ artifact_ns.foo[:baz].should be_selected
482
+ end
483
+
484
+ it 'should access sub artifacts using with foo_bar like syntax' do
485
+ artifact_ns.ns :foo, :bar => 'foo:bar:jar:0', :baz => 'foo:baz:jar:0'
486
+ artifact_ns[:foo_baz].should be_selected
487
+ artifact_ns.foo_bar.should be_selected
488
+
489
+ artifact_ns.foo.ns :bat, 'bat:man:jar:>1'
490
+ batman = artifact_ns.foo.bat.man
491
+ batman.should be_selected
492
+ artifact_ns[:foo_bat_man] = '3'
493
+ artifact_ns[:foo_bat_man].should == batman
494
+ artifact_ns[:foo_bat_man].version.should == '3'
495
+ end
496
+
497
+ it 'should include sub artifacts when calling #values' do
498
+ artifact_ns.ns :bat, 'bat:man:jar:>1'
499
+ artifact_ns.values.should_not be_empty
500
+ artifact_ns.values.first.unversioned_spec.should == 'bat:man:jar'
501
+ end
502
+
503
+ it 'should reopen a sub-namespace' do
504
+ artifact_ns.ns :bat, 'bat:man:jar:>1'
505
+ bat = artifact_ns[:bat]
506
+ bat.should == artifact_ns.ns(:bat)
507
+ end
508
+
509
+ it 'should fail reopening if not a sub-namespace' do
510
+ artifact_ns.foo = 'foo:bar:baz:0'
511
+ lambda { artifact_ns.ns(:foo) }.should raise_error(TypeError, /not a sub/i)
512
+ end
513
+
514
+ it 'should clone artifacts when assigned' do
515
+ artifact_ns(:foo).bar = "foo:bar:jar:0"
516
+ artifact_ns(:moo).ns :muu, :miu => artifact_ns(:foo).bar
517
+ artifact_ns(:moo).muu.miu.should_not == artifact_ns(:foo).bar
518
+ artifact_ns(:moo).muu.miu.to_spec.should == artifact_ns(:foo).bar.to_spec
519
+ end
520
+
521
+ it 'should clone parent artifacts by name' do
522
+ define 'foo' do
523
+ artifact_ns.bar = "foo:bar:jar:0"
524
+ define 'moo' do
525
+ artifact_ns.ns(:muu).use :bar
526
+ artifact_ns.muu_bar.should be_selected
527
+ artifact_ns.muu.bar.should_not == artifact_ns.bar
528
+ end
529
+ end
530
+ end
531
+ end
532
+
533
+ it 'should be an Enumerable' do
534
+ artifact_ns.should be_kind_of(Enumerable)
535
+ artifact_ns.use 'foo:bar:baz:1.0'
536
+ artifact_ns.map(&:artifact).should include(artifact('foo:bar:baz:1.0'))
537
+ end
538
+
539
+ end # ArtifactNamespace
540
+
541
+ describe Buildr::ArtifactNamespace::ArtifactRequirement do
542
+ before(:each) { Buildr::ArtifactNamespace.clear }
543
+ it 'should be created from artifact_ns' do
544
+ foo = artifact_ns do |ns|
545
+ ns.bar = 'a:b:c:1.0'
546
+ end
547
+ foo.bar.should be_kind_of(ArtifactNamespace::ArtifactRequirement)
548
+ end
549
+
550
+ it 'should handle version as string' do
551
+ foo = artifact_ns do |ns|
552
+ ns.bar = 'a:b:c:1.0'
553
+ end
554
+ foo.bar.version = '2.0'
555
+ foo.bar.version.should == '2.0'
556
+ end
557
+
558
+ it 'should handle version string directly' do
559
+ foo = artifact_ns do |ns|
560
+ ns.bar = 'a:b:c:1.0'
561
+ end
562
+ foo.bar = '2.0'
563
+ foo.bar.version.should == '2.0'
564
+ end
565
+
566
+ end # ArtifactRequirement
567
+
568
+ describe Buildr do
569
+ before(:each) { Buildr::ArtifactNamespace.clear }
570
+
571
+ describe '.artifacts' do
572
+ it 'should take ruby symbols and ask the current namespace for them' do
573
+ define 'foo' do
574
+ artifact_ns.cool = 'cool:aid:jar:1.0'
575
+ artifact_ns.use 'some:other:jar:1.0'
576
+ artifact_ns.use 'bat:man:jar:1.0'
577
+ compile.with :cool, :other, :'bat:man:jar'
578
+ compile.dependencies.map(&:to_spec).should include('cool:aid:jar:1.0', 'some:other:jar:1.0', 'bat:man:jar:1.0')
579
+ end
580
+ end
581
+
582
+ it 'should take a namespace' do
583
+ artifact_ns(:moo).muu = 'moo:muu:jar:1.0'
584
+ define 'foo' do
585
+ compile.with artifact_ns(:moo)
586
+ compile.dependencies.map(&:to_spec).should include('moo:muu:jar:1.0')
587
+ end
588
+ end
589
+ end
590
+
591
+ describe '.artifact' do
592
+ it 'should search current namespace if given a symbol' do
593
+ define 'foo' do
594
+ artifact_ns.use :cool => 'cool:aid:jar:1.0'
595
+ define 'bar' do
596
+ artifact(:cool).should == artifact_ns[:cool].artifact
597
+ end
598
+ end
599
+ end
600
+
601
+ it 'should search current namespace if given a symbol spec' do
602
+ define 'foo' do
603
+ artifact_ns.use 'cool:aid:jar:1.0'
604
+ define 'bar' do
605
+ artifact(:'cool:aid:jar').should == artifact_ns[:aid].artifact
606
+ end
607
+ end
608
+ end
609
+
610
+ it 'should fail when no artifact by that name is found' do
611
+ define 'foo' do
612
+ artifact_ns.use 'cool:aid:jar:1.0'
613
+ define 'bar' do
614
+ lambda { artifact(:cool) }.should raise_error(IndexError, /artifact/)
615
+ end
616
+ end
617
+ end
618
+ end
619
+ end
620
+
621
+ describe "Extension using ArtifactNamespace" do
622
+ before(:each) { Buildr::ArtifactNamespace.clear }
623
+
624
+ def abc_module
625
+ Object.module_eval 'module A; module B; module C; end; end; end'
626
+ yield
627
+ ensure
628
+ Object.send :remove_const, :A
629
+ end
630
+
631
+ it 'can register namespace listeners' do
632
+ abc_module do
633
+ # An example extension to illustrate namespace listeners and method forwarding
634
+ class A::Example
635
+
636
+ module Ext
637
+ include Buildr::Extension
638
+ def example; @example ||= A::Example.new; end
639
+ before_define do |p|
640
+ Rake::Task.define_task('example') { p.example.doit }
641
+ end
642
+ end
643
+
644
+ REQUIRES = ArtifactNamespace.for(self) do |ns|
645
+ ns.xmlbeans! 'org.apache.xmlbeans:xmlbeans:jar:2.3.0', '>2'
646
+ ns.stax_api! 'stax:stax-api:jar:>=1.0.1'
647
+ end
648
+
649
+ attr_reader :options, :requires
650
+
651
+ def initialize
652
+ # We could actually use the REQUIRES namespace, but to make things
653
+ # a bit more interesting, suppose each Example instance can have its
654
+ # own artifact requirements in adition to those specified on REQUIRES.
655
+ # To achieve this we create an anonymous namespace.
656
+ @requires = ArtifactNamespace.new # a namespace per instance
657
+ REQUIRES.each { |requirement| @requires.need requirement }
658
+
659
+ # For user convenience, we make the options object respond to
660
+ # :xmlbeans, :xmlbeans=, :xmlbeans?
661
+ # forwarding them to the namespace.
662
+ @options = OpenObject.new.extend(@requires.accessor(:xmlbeans, :stax_api))
663
+ # Register callbacks so we can perform some logic when an artifact
664
+ # is selected by the user.
665
+ options.xmlbeans.add_listener &method(:selected_xmlbeans)
666
+ options.stax_api.add_listener do |stax|
667
+ # Now using a proc
668
+ stax.should be_selected
669
+ stax.version.should == '1.6180'
670
+ options[:math] = :golden # customize our options for this version
671
+ # In this example we set the stax version when running outside
672
+ # a project definition. This means we have no access to the project
673
+ # namespace unless we had a reference to the project or knew it's name
674
+ Buildr.artifact_ns(:current).name.should == 'root'
675
+ end
676
+ end
677
+
678
+ include RSpec::Matchers # for assertions
679
+
680
+ # Called with the ArtifactRequirement that has just been selected
681
+ # by a user. This allows extension author to selectively perform
682
+ # some action by inspecting the requirement state.
683
+ def selected_xmlbeans(xmlbeans)
684
+ xmlbeans.should be_selected
685
+ xmlbeans.version.should == '3.1415'
686
+ options[:math] = :pi
687
+ # This example just sets xmlbeans for foo:bar project
688
+ # So the currently running namespace should have the foo:bar name
689
+ Buildr.artifact_ns(:current).name.should == 'foo:bar'
690
+ end
691
+
692
+ # Suppose we invoke an ant task here or something else.
693
+ def doit
694
+ # Now call ant task with our selected artifact and options
695
+ classpath = requires.map(&:artifact).map(&:to_s).join(File::PATH_SEPARATOR)
696
+ lambda { ant('thing') { |ant| ant.classpath classpath, :math => options[:math] } }
697
+
698
+ # We are not a Project instance, hence we have no artifact_ns
699
+ lambda { artifact_ns }.should raise_error(NameError)
700
+
701
+ # Extension authors may NOT rely project's namespaces.
702
+ # However the ruby-way gives you power and at the same time
703
+ # makes you dangerous, (think open-modules, monkey-patching)
704
+ # Given that buildr is pure ruby, consider it a sharp-edged sword.
705
+ # Having said that, you may actually inspect a project's
706
+ # namespace, but don't write on it without letting your users
707
+ # know you will.
708
+ # This example obtains the current project namespace to make
709
+ # some assertions.
710
+
711
+ # To obtain a project's namespace we need either
712
+ # 1) a reference to the project, and call artifact_ns on it
713
+ # project.artifact_ns # the namespace for project
714
+ # 2) know the project name
715
+ # Buildr.artifact_ns('the:project')
716
+ # 3) Use :current to reference the currently running project
717
+ # Buildr.artifact_ns(:current)
718
+ name = Buildr.artifact_ns(:current).name
719
+ case name
720
+ when 'foo:bar'
721
+ options[:math].should == :pi
722
+ requires.xmlbeans.version.should == '3.1415'
723
+ requires.stax_api.version.should == '1.0.1'
724
+ when 'foo:baz'
725
+ options[:math].should == :golden
726
+ requires.xmlbeans.version.should == '2.3.0'
727
+ requires.stax_api.version.should == '1.6180'
728
+ else
729
+ fail "This example expects foo:bar or foo:baz projects not #{name.inspect}"
730
+ end
731
+ end
732
+ end
733
+
734
+ define 'foo' do
735
+ define 'bar' do
736
+ extend A::Example::Ext
737
+ task('setup') do
738
+ example.options.xmlbeans = '3.1415'
739
+ end
740
+ task('run' => [:setup, :example])
741
+ end
742
+ define 'baz' do
743
+ extend A::Example::Ext
744
+ end
745
+ end
746
+
747
+ project('foo:bar').example.requires.should_not == project('foo:baz').example.requires
748
+ project('foo:bar').example.requires.xmlbeans.should_not == project('foo:baz').example.requires.xmlbeans
749
+
750
+ # current namespace outside a project is :root, see the stax callback
751
+ project('foo:baz').example.options.stax_api = '1.6180'
752
+ # we call the task outside the project, see #doit
753
+ lambda { task('foo:bar:run').invoke }.should run_task('foo:bar:example')
754
+ lambda { task('foo:baz:example').invoke }.should run_task('foo:baz:example')
755
+ end
756
+ end
757
+ end