realityforge-buildr 1.5.9

Sign up to get free protection for your applications and to get access to all the features.
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,1351 @@
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
+ require 'fileutils'
18
+
19
+ describe Artifact do
20
+ before do
21
+ Buildr.repositories.instance_eval do
22
+ @local = @remote = @release_to = nil
23
+ end
24
+ @spec = { :group=>'com.example', :id=>'library', :type=>:jar, :version=>'2.0' }
25
+ @artifact = artifact(@spec)
26
+ @classified = artifact(@spec.merge(:classifier=>'all'))
27
+ @snapshot = artifact(@spec.merge({ :version=>'2.1-SNAPSHOT' }))
28
+ end
29
+
30
+
31
+ it 'should act as one' do
32
+ @artifact.should respond_to(:to_spec)
33
+ end
34
+
35
+ it 'should have an artifact identifier' do
36
+ @artifact.id.should eql('library')
37
+ end
38
+
39
+ it 'should have a group identifier' do
40
+ @artifact.group.should eql('com.example')
41
+ end
42
+
43
+ it 'should have a version number' do
44
+ @artifact.version.should eql('2.0')
45
+ end
46
+
47
+ it 'should know if it is a snapshot' do
48
+ @artifact.should_not be_snapshot
49
+ @classified.should_not be_snapshot
50
+ @snapshot.should be_snapshot
51
+ end
52
+
53
+ it 'should have a file type' do
54
+ @artifact.type.should eql(:jar)
55
+ end
56
+
57
+ it 'should understand classifier' do
58
+ @artifact.classifier.should be_nil
59
+ @classified.classifier.should eql('all')
60
+ end
61
+
62
+ it 'should return hash specification' do
63
+ @artifact.to_hash.should == @spec
64
+ @artifact.to_spec_hash.should == @spec
65
+ @classified.to_hash.should == @spec.merge(:classifier=>'all')
66
+ end
67
+
68
+ it 'should return string specification' do
69
+ @artifact.to_spec.should eql('com.example:library:jar:2.0')
70
+ @classified.to_spec.should eql('com.example:library:jar:all:2.0')
71
+ end
72
+
73
+ it 'should have associated POM artifact' do
74
+ @artifact.pom.to_hash.should == @artifact.to_hash.merge(:type=>:pom)
75
+ end
76
+
77
+ it 'should have one POM artifact for all classifiers' do
78
+ spec_hash = @classified.to_hash.merge(:type => :pom)
79
+ spec_hash.delete(:classifier)
80
+ @classified.pom.to_hash.should == spec_hash
81
+ end
82
+
83
+ it 'should have associated sources artifact' do
84
+ @artifact.sources_artifact.to_hash.should == @artifact.to_hash.merge(:classifier=>'sources')
85
+ end
86
+
87
+ it 'should have associated javadoc artifact' do
88
+ @artifact.javadoc_artifact.to_hash.should == @artifact.to_hash.merge(:classifier=>'javadoc')
89
+ end
90
+
91
+ it 'should download file if file does not exist' do
92
+ lambda { @artifact.invoke }.should raise_error(Exception, /No remote repositories/)
93
+ lambda { @classified.invoke }.should raise_error(Exception, /No remote repositories/)
94
+ end
95
+
96
+ it 'should not download file if file exists' do
97
+ write repositories.locate(@artifact)
98
+ lambda { @artifact.invoke }.should_not raise_error
99
+ write repositories.locate(@classified)
100
+ lambda { @classified.invoke }.should_not raise_error
101
+ end
102
+
103
+ it 'should handle lack of POM gracefully' do
104
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
105
+ URI.should_receive(:download).twice { |*args| raise URI::NotFoundError if args[0].to_s.end_with?('.pom') }
106
+ lambda { @artifact.invoke }.should_not raise_error
107
+ end
108
+
109
+ it 'should pass if POM provided' do
110
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
111
+ @artifact.pom.enhance { |task| write task.name, @artifact.pom_xml.call }
112
+ write repositories.locate(@artifact)
113
+ lambda { @artifact.invoke }.should_not raise_error
114
+ end
115
+
116
+ it 'should pass if POM not required' do
117
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
118
+ class << @artifact ; def pom() ; end ; end
119
+ write repositories.locate(@artifact)
120
+ lambda { @artifact.invoke }.should_not raise_error
121
+ end
122
+
123
+ it 'should not download file if dry-run' do
124
+ dryrun do
125
+ lambda { @artifact.invoke }.should_not raise_error
126
+ lambda { @classified.invoke }.should_not raise_error
127
+ end
128
+ end
129
+
130
+ it 'should resolve to path in local repository' do
131
+ @artifact.to_s.should == File.join(repositories.local, 'com/example/library/2.0/library-2.0.jar')
132
+ @classified.to_s.should == File.join(repositories.local, 'com/example/library/2.0/library-2.0-all.jar')
133
+ end
134
+
135
+ it 'should return a list of all registered artifact specifications' do
136
+ define('foo', :version=>'1.0') { package :jar }
137
+ Artifact.list.should include(@artifact.to_spec)
138
+ Artifact.list.should include(@classified.to_spec)
139
+ Artifact.list.should include('foo:foo:jar:1.0')
140
+ end
141
+
142
+ it 'should accept user-defined string content' do
143
+ a = artifact(@spec)
144
+ a.content 'foo'
145
+ install a
146
+ lambda { install.invoke }.should change { File.exist?(a.to_s) && File.exist?(repositories.locate(a)) }.to(true)
147
+ read(repositories.locate(a)).should eql('foo')
148
+ end
149
+ end
150
+
151
+
152
+ describe Repositories, 'local' do
153
+ before do
154
+ Buildr.repositories.instance_eval do
155
+ @local = @remote = @release_to = nil
156
+ end
157
+ end
158
+
159
+ it 'should default to .m2 path' do
160
+ # For convenience, sandbox actually sets the local repository to a temp directory
161
+ repositories.local = nil
162
+ repositories.local.should eql(File.expand_path('.m2/repository', ENV['HOME']))
163
+ end
164
+
165
+ it 'should be settable' do
166
+ repositories.local = '.m2/local'
167
+ repositories.local.should eql(File.expand_path('.m2/local'))
168
+ end
169
+
170
+ it 'should reset to default' do
171
+ repositories.local = '.m2/local'
172
+ repositories.local = nil
173
+ repositories.local.should eql(File.expand_path('~/.m2/repository'))
174
+ end
175
+
176
+ it 'should locate file from string specification' do
177
+ repositories.local = nil
178
+ repositories.locate('com.example:library:jar:2.0').should eql(
179
+ File.expand_path('~/.m2/repository/com/example/library/2.0/library-2.0.jar'))
180
+ end
181
+
182
+ it 'should locate file from hash specification' do
183
+ repositories.local = nil
184
+ repositories.locate(:group=>'com.example', :id=>'library', :version=>'2.0').should eql(
185
+ File.expand_path('~/.m2/repository/com/example/library/2.0/library-2.0.jar'))
186
+ end
187
+
188
+ it 'should load path from settings file' do
189
+ write 'home/.buildr/settings.yaml', <<-YAML
190
+ repositories:
191
+ local: my_repo
192
+ YAML
193
+ repositories.local.should eql(File.expand_path('my_repo'))
194
+ end
195
+
196
+ it 'should not override custom install methods defined when extending an object' do
197
+ class MyOwnInstallTask
198
+
199
+ attr_accessor :result
200
+
201
+ def install
202
+ result = true
203
+ end
204
+
205
+ end
206
+ task = MyOwnInstallTask.new
207
+ task.result = "maybe"
208
+ task.extend ActsAsArtifact
209
+ task.install
210
+ task.result.should be_true
211
+ end
212
+ end
213
+
214
+ describe Repositories, 'remote_uri' do
215
+ before do
216
+ Buildr.repositories.instance_eval do
217
+ @local = @remote = @release_to = nil
218
+ end
219
+
220
+ @repos = [ 'https://oss.sonatype.org/', { :url => 'https://repo1.maven.org/maven2', :username => 'user', :password => 'password' } ]
221
+ end
222
+
223
+ it 'should convert remote to array of uri' do
224
+ uri = URI.parse( 'https://repo1.maven.org/maven2' )
225
+ uri.user = 'user'
226
+ uri.password = 'password'
227
+
228
+ uris = [ URI.parse( 'https://oss.sonatype.org/'), uri ]
229
+
230
+ repositories.remote = @repos
231
+ repositories.remote_uri.should eql(uris)
232
+ end
233
+ end
234
+
235
+ describe Repositories, 'mirrors' do
236
+ before do
237
+ Buildr.repositories.instance_eval do
238
+ @local = @remote = @release_to = @mirrors = nil
239
+ end
240
+
241
+ @repos = %w(http://www.ibiblio.org/maven2 https://repo1.maven.org/maven2)
242
+ end
243
+
244
+ it 'should be empty initially' do
245
+ repositories.mirrors.should be_empty
246
+ end
247
+
248
+ it 'should be settable' do
249
+ repositories.mirrors = @repos.first
250
+ repositories.mirrors.should eql([@repos.first])
251
+ end
252
+
253
+ it 'should be settable from array' do
254
+ repositories.mirrors = @repos
255
+ repositories.mirrors.should eql(@repos)
256
+ end
257
+
258
+ it 'should add and return repositories in order' do
259
+ @repos.each { |url| repositories.mirrors << url }
260
+ repositories.mirrors.should eql(@repos)
261
+ end
262
+
263
+ it 'should log that it is overridding the remote repositories with the mirrors' do
264
+ @repos.each { |url| repositories.mirrors << url }
265
+ lambda { repositories.remote }.should show_info /Remote repositories overridden by mirrors /
266
+ end
267
+
268
+ it 'should load with all repositories specified in settings file' do
269
+ write 'home/.buildr/settings.yaml', <<-YAML
270
+ repositories:
271
+ mirrors:
272
+ - http://example.com/repository/noexist
273
+ remote:
274
+ - http://foobar.com
275
+ YAML
276
+ repositories.mirrors.should include('http://example.com/repository/noexist')
277
+ end
278
+
279
+ it 'should load with all repositories specified in build.yaml file' do
280
+ write 'build.yaml', <<-YAML
281
+ repositories:
282
+ mirrors:
283
+ - http://example.com/repository/noexist
284
+ remote:
285
+ - http://foobar.com
286
+ YAML
287
+ repositories.mirrors.should include('http://example.com/repository/noexist')
288
+ end
289
+
290
+ it 'should load with all repositories specified in settings and build.yaml files' do
291
+ write 'home/.buildr/settings.yaml', <<-YAML
292
+ repositories:
293
+ mirrors:
294
+ - http://example.com/repository/noexist
295
+ remote:
296
+ - http://foobar.com
297
+ YAML
298
+ write 'build.yaml', <<-YAML
299
+ repositories:
300
+ mirrors:
301
+ - http://example.com/repo2
302
+ remote:
303
+ - http://foobar.com
304
+ YAML
305
+ repositories.mirrors.should include('http://example.com/repository/noexist', 'http://example.com/repo2')
306
+ end
307
+ end
308
+
309
+ describe Repositories, 'remote' do
310
+ before do
311
+ Buildr.repositories.instance_eval do
312
+ @local = @remote = @release_to = nil
313
+ end
314
+
315
+ @repos = %w(http://www.ibiblio.org/maven2 https://repo1.maven.org/maven2)
316
+ end
317
+
318
+ it 'should be empty initially' do
319
+ repositories.remote.should be_empty
320
+ end
321
+
322
+ it 'should be settable' do
323
+ repositories.remote = @repos.first
324
+ repositories.remote.should eql([@repos.first])
325
+ end
326
+
327
+ it 'should be settable from array' do
328
+ repositories.remote = @repos
329
+ repositories.remote.should eql(@repos)
330
+ end
331
+
332
+ it 'should add and return repositories in order' do
333
+ @repos.each { |url| repositories.remote << url }
334
+ repositories.remote.should eql(@repos)
335
+ end
336
+
337
+ it 'should be used to download artifact' do
338
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
339
+ URI.should_receive(:download).twice.and_return { |uri, target, options| write target }
340
+ lambda { artifact('com.example:library:jar:2.0').invoke }.
341
+ should change { File.exist?(File.join(repositories.local, 'com/example/library/2.0/library-2.0.jar')) }.to(true)
342
+ end
343
+
344
+ it 'should lookup in array order' do
345
+ repositories.remote = %w[http://buildr.apache.org/repository/noexist http://example.org]
346
+ order = %w[com org]
347
+ URI.stub(:download) do |uri, target, options|
348
+ order.shift if order.first && uri.to_s[order.first]
349
+ fail URI::NotFoundError unless order.empty?
350
+ write target
351
+ end
352
+ lambda { artifact('com.example:library:jar:2.0').invoke }.should change { order.empty? }
353
+ end
354
+
355
+ it 'should fail if artifact not found' do
356
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
357
+ URI.should_receive(:download).once.ordered.and_return { fail URI::NotFoundError }
358
+ lambda { artifact('com.example:library:jar:2.0').invoke }.should raise_error(RuntimeError, /Failed to download/)
359
+ File.exist?(File.join(repositories.local, 'com/example/library/2.0/library-2.0.jar')).should be_false
360
+ end
361
+
362
+ it 'should support artifact classifier' do
363
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
364
+ URI.should_receive(:download).once.and_return { |uri, target, options| write target }
365
+ lambda { artifact('com.example:library:jar:all:2.0').invoke }.
366
+ should change { File.exist?(File.join(repositories.local, 'com/example/library/2.0/library-2.0-all.jar')) }.to(true)
367
+ end
368
+
369
+ it 'should deal well with repositories URL that lack the last slash' do
370
+ repositories.remote = 'http://buildr.apache.org/repository/noexist/base'
371
+ uri = nil
372
+ URI.should_receive(:download).twice.and_return { |_uri, args| uri = _uri }
373
+ artifact('group:id:jar:1.0').invoke
374
+ uri.to_s.should eql('http://buildr.apache.org/repository/noexist/base/group/id/1.0/id-1.0.pom')
375
+ end
376
+
377
+ it 'should deal well with repositories URL that have the last slash' do
378
+ repositories.remote = 'http://buildr.apache.org/repository/noexist/base/'
379
+ uri = nil
380
+ URI.should_receive(:download).twice.and_return { |_uri, args| uri = _uri }
381
+ artifact('group:id:jar:1.0').invoke
382
+ uri.to_s.should eql('http://buildr.apache.org/repository/noexist/base/group/id/1.0/id-1.0.pom')
383
+ end
384
+
385
+ it 'should resolve m2-style deployed snapshots' do
386
+ metadata = <<-XML
387
+ <?xml version='1.0' encoding='UTF-8'?>
388
+ <metadata>
389
+ <groupId>com.example</groupId>
390
+ <artifactId>library</artifactId>
391
+ <version>2.1-SNAPSHOT</version>
392
+ <versioning>
393
+ <snapshot>
394
+ <timestamp>20071012.190008</timestamp>
395
+ <buildNumber>8</buildNumber>
396
+ </snapshot>
397
+ <lastUpdated>20071012190008</lastUpdated>
398
+ </versioning>
399
+ </metadata>
400
+ XML
401
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
402
+ URI.should_receive(:download).twice.with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.(jar|pom)$/), anything()).
403
+ and_return { fail URI::NotFoundError }
404
+ URI.should_receive(:download).twice.with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
405
+ and_return { |uri, target, options| target.write(metadata) }
406
+ URI.should_receive(:download).twice.with(uri(/2.1-SNAPSHOT\/library-2.1-20071012.190008-8.(jar|pom)$/), /2.1-SNAPSHOT\/library-2.1-SNAPSHOT.(jar|pom).(\d){1,}$/).
407
+ and_return { |uri, target, options| write target }
408
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.
409
+ should change { File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')) }.to(true)
410
+ end
411
+
412
+ it 'should resolve m2-style deployed snapshots with classifiers' do
413
+ metadata = <<-XML
414
+ <?xml version='1.0' encoding='UTF-8'?>
415
+ <metadata>
416
+ <groupId>com.example</groupId>
417
+ <artifactId>library</artifactId>
418
+ <version>2.1-SNAPSHOT</version>
419
+ <versioning>
420
+ <snapshot>
421
+ <timestamp>20071012.190008</timestamp>
422
+ <buildNumber>8</buildNumber>
423
+ </snapshot>
424
+ <lastUpdated>20071012190008</lastUpdated>
425
+ </versioning>
426
+ </metadata>
427
+ XML
428
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
429
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/library-2.1-20071012.190008-8-classifier.jar$/), anything()).
430
+ and_return { |uri, target, options| write target }
431
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
432
+ and_return { |uri, target, options| target.write(metadata) }
433
+ puts repositories.local
434
+ lambda { artifact('com.example:library:jar:classifier:2.1-SNAPSHOT').invoke}.
435
+ should change {File.exists?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT-classifier.jar')) }.to(true)
436
+ end
437
+
438
+ it 'should fail resolving m2-style deployed snapshots if a timestamp is missing' do
439
+ metadata = <<-XML
440
+ <?xml version='1.0' encoding='UTF-8'?>
441
+ <metadata>
442
+ <groupId>com.example</groupId>
443
+ <artifactId>library</artifactId>
444
+ <version>2.1-SNAPSHOT</version>
445
+ <versioning>
446
+ <snapshot>
447
+ <buildNumber>8</buildNumber>
448
+ </snapshot>
449
+ <lastUpdated>20071012190008</lastUpdated>
450
+ </versioning>
451
+ </metadata>
452
+ XML
453
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
454
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.(jar|pom)$/), anything()).
455
+ and_return { fail URI::NotFoundError }
456
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
457
+ and_return { |uri, target, options| target.write(metadata) }
458
+ lambda {
459
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.should raise_error(RuntimeError, /Failed to download/)
460
+ }.should show_error "No timestamp provided for the snapshot com.example:library:jar:2.1-SNAPSHOT"
461
+ File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')).should be_false
462
+ end
463
+
464
+ it 'should fail resolving m2-style deployed snapshots if a build number is missing' do
465
+ metadata = <<-XML
466
+ <?xml version='1.0' encoding='UTF-8'?>
467
+ <metadata>
468
+ <groupId>com.example</groupId>
469
+ <artifactId>library</artifactId>
470
+ <version>2.1-SNAPSHOT</version>
471
+ <versioning>
472
+ <snapshot>
473
+ <timestamp>20071012.190008</timestamp>
474
+ </snapshot>
475
+ <lastUpdated>20071012190008</lastUpdated>
476
+ </versioning>
477
+ </metadata>
478
+ XML
479
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
480
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.(jar|pom)$/), anything()).
481
+ and_return { fail URI::NotFoundError }
482
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
483
+ and_return { |uri, target, options| target.write(metadata) }
484
+ lambda {
485
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.should raise_error(RuntimeError, /Failed to download/)
486
+ }.should show_error "No build number provided for the snapshot com.example:library:jar:2.1-SNAPSHOT"
487
+ File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')).should be_false
488
+ end
489
+
490
+ it 'should handle missing maven metadata by reporting the artifact unavailable' do
491
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
492
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.jar$/), anything()).
493
+ and_return { fail URI::NotFoundError }
494
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
495
+ and_return { fail URI::NotFoundError }
496
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.should raise_error(RuntimeError, /Failed to download/)
497
+ File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')).should be_false
498
+ end
499
+
500
+ it 'should handle missing m2 snapshots by reporting the artifact unavailable' do
501
+ metadata = <<-XML
502
+ <?xml version='1.0' encoding='UTF-8'?>
503
+ <metadata>
504
+ <groupId>com.example</groupId>
505
+ <artifactId>library</artifactId>
506
+ <version>2.1-SNAPSHOT</version>
507
+ <versioning>
508
+ <snapshot>
509
+ <timestamp>20071012.190008</timestamp>
510
+ <buildNumber>8</buildNumber>
511
+ </snapshot>
512
+ <lastUpdated>20071012190008</lastUpdated>
513
+ </versioning>
514
+ </metadata>
515
+ XML
516
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
517
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.jar$/), anything()).
518
+ and_return { fail URI::NotFoundError }
519
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
520
+ and_return { |uri, target, options| target.write(metadata) }
521
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/library-2.1-20071012.190008-8.jar$/), anything()).
522
+ and_return { fail URI::NotFoundError }
523
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.should raise_error(RuntimeError, /Failed to download/)
524
+ File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')).should be_false
525
+ end
526
+
527
+ it 'should load with all repositories specified in settings file' do
528
+ write 'home/.buildr/settings.yaml', <<-YAML
529
+ repositories:
530
+ remote:
531
+ - http://buildr.apache.org/repository/noexist
532
+ - http://example.org
533
+ YAML
534
+ repositories.remote.should include('http://buildr.apache.org/repository/noexist', 'http://example.org')
535
+ end
536
+
537
+ it 'should load with all repositories specified in build.yaml file' do
538
+ write 'build.yaml', <<-YAML
539
+ repositories:
540
+ remote:
541
+ - http://buildr.apache.org/repository/noexist
542
+ - http://example.org
543
+ YAML
544
+ repositories.remote.should include('http://buildr.apache.org/repository/noexist', 'http://example.org')
545
+ end
546
+
547
+ it 'should load with all repositories specified in settings and build.yaml files' do
548
+ write 'home/.buildr/settings.yaml', <<-YAML
549
+ repositories:
550
+ remote:
551
+ - http://buildr.apache.org/repository/noexist
552
+ YAML
553
+ write 'build.yaml', <<-YAML
554
+ repositories:
555
+ remote:
556
+ - http://example.org
557
+ YAML
558
+ repositories.remote.should include('http://buildr.apache.org/repository/noexist', 'http://example.org')
559
+ end
560
+ end
561
+
562
+
563
+ describe Repositories, 'release_to' do
564
+ it 'should accept URL as first argument' do
565
+ repositories.release_to = 'http://buildr.apache.org/repository/noexist'
566
+ repositories.release_to.should == { :url=>'http://buildr.apache.org/repository/noexist' }
567
+ end
568
+
569
+ it 'should accept hash with options' do
570
+ repositories.release_to = { :url=>'http://buildr.apache.org/repository/noexist', :username=>'john' }
571
+ repositories.release_to.should == { :url=>'http://buildr.apache.org/repository/noexist', :username=>'john' }
572
+ end
573
+
574
+ it 'should allow the hash to be manipulated' do
575
+ repositories.release_to = 'http://buildr.apache.org/repository/noexist'
576
+ repositories.release_to.should == { :url=>'http://buildr.apache.org/repository/noexist' }
577
+ repositories.release_to[:username] = 'john'
578
+ repositories.release_to.should == { :url=>'http://buildr.apache.org/repository/noexist', :username=>'john' }
579
+ end
580
+
581
+ it 'should load URL from settings file' do
582
+ write 'home/.buildr/settings.yaml', <<-YAML
583
+ repositories:
584
+ release_to: http://john:secret@buildr.apache.org/repository/noexist
585
+ YAML
586
+ repositories.release_to.should == { :url=>'http://john:secret@buildr.apache.org/repository/noexist' }
587
+ end
588
+
589
+ it 'should load URL from build settings file' do
590
+ write 'build.yaml', <<-YAML
591
+ repositories:
592
+ release_to: http://john:secret@buildr.apache.org/repository/noexist
593
+ YAML
594
+ repositories.release_to.should == { :url=>'http://john:secret@buildr.apache.org/repository/noexist' }
595
+ end
596
+
597
+ it 'should load URL, username and password from settings file' do
598
+ write 'home/.buildr/settings.yaml', <<-YAML
599
+ repositories:
600
+ release_to:
601
+ url: http://buildr.apache.org/repository/noexist
602
+ username: john
603
+ password: secret
604
+ YAML
605
+ repositories.release_to.should == { :url=>'http://buildr.apache.org/repository/noexist', :username=>'john', :password=>'secret' }
606
+ end
607
+ end
608
+
609
+ describe Repositories, 'snapshot_to' do
610
+ it 'should accept URL as first argument' do
611
+ repositories.snapshot_to = 'http://buildr.apache.org/repository/noexist'
612
+ repositories.snapshot_to.should == { :url=>'http://buildr.apache.org/repository/noexist' }
613
+ end
614
+
615
+ it 'should accept hash with options' do
616
+ repositories.snapshot_to = { :url=>'http://buildr.apache.org/repository/noexist', :username=>'john' }
617
+ repositories.snapshot_to.should == { :url=>'http://buildr.apache.org/repository/noexist', :username=>'john' }
618
+ end
619
+
620
+ it 'should allow the hash to be manipulated' do
621
+ repositories.snapshot_to = 'http://buildr.apache.org/repository/noexist'
622
+ repositories.snapshot_to.should == { :url=>'http://buildr.apache.org/repository/noexist' }
623
+ repositories.snapshot_to[:username] = 'john'
624
+ repositories.snapshot_to.should == { :url=>'http://buildr.apache.org/repository/noexist', :username=>'john' }
625
+ end
626
+
627
+ it 'should load URL from settings file' do
628
+ write 'home/.buildr/settings.yaml', <<-YAML
629
+ repositories:
630
+ snapshot_to: http://john:secret@buildr.apache.org/repository/noexist
631
+ YAML
632
+ repositories.snapshot_to.should == { :url=>'http://john:secret@buildr.apache.org/repository/noexist' }
633
+ end
634
+
635
+ it 'should load URL from build settings file' do
636
+ write 'build.yaml', <<-YAML
637
+ repositories:
638
+ snapshot_to: http://john:secret@buildr.apache.org/repository/noexist
639
+ YAML
640
+ repositories.snapshot_to.should == { :url=>'http://john:secret@buildr.apache.org/repository/noexist' }
641
+ end
642
+
643
+ it 'should load URL, username and password from settings file' do
644
+ write 'home/.buildr/settings.yaml', <<-YAML
645
+ repositories:
646
+ snapshot_to:
647
+ url: http://buildr.apache.org/repository/noexist
648
+ username: john
649
+ password: secret
650
+ YAML
651
+ repositories.snapshot_to.should == { :url=>'http://buildr.apache.org/repository/noexist', :username=>'john', :password=>'secret' }
652
+ end
653
+ end
654
+
655
+ describe Buildr, '#artifact' do
656
+ before do
657
+ @spec = { :group=>'com.example', :id=>'library', :type=>'jar', :version=>'2.0' }
658
+ @snapshot_spec = 'group:id:jar:1.0-SNAPSHOT'
659
+ write @file = 'testartifact.jar'
660
+ end
661
+
662
+ it 'should accept hash specification' do
663
+ artifact(:group=>'com.example', :id=>'library', :type=>'jar', :version=>'2.0').should respond_to(:invoke)
664
+ end
665
+
666
+ it 'should reject partial hash specifier' do
667
+ lambda { artifact(@spec.merge(:group=>nil)) }.should raise_error
668
+ lambda { artifact(@spec.merge(:id=>nil)) }.should raise_error
669
+ lambda { artifact(@spec.merge(:version=>nil)) }.should raise_error
670
+ end
671
+
672
+ it 'should complain about invalid key' do
673
+ lambda { artifact(@spec.merge(:error=>true)) }.should raise_error(ArgumentError, /no such option/i)
674
+ end
675
+
676
+ it 'should use JAR type by default' do
677
+ artifact(@spec.merge(:type=>nil)).should respond_to(:invoke)
678
+ end
679
+
680
+ it 'should use JAR type if type is set to bundle' do
681
+ artifact(@spec.merge(:type=>:bundle)).to_s.should match('\.jar$')
682
+ end
683
+
684
+ it 'should accept string specification' do
685
+ artifact('com.example:library:jar:2.0').should respond_to(:invoke)
686
+ end
687
+
688
+ it 'should reject partial string specifier' do
689
+ artifact('com.example:library::2.0')
690
+ lambda { artifact('com.example:library:jar') }.should raise_error
691
+ lambda { artifact('com.example:library:jar:') }.should raise_error
692
+ lambda { artifact('com.example:library::2.0') }.should_not raise_error
693
+ lambda { artifact('com.example::jar:2.0') }.should raise_error
694
+ lambda { artifact(':library:jar:2.0') }.should raise_error
695
+ end
696
+
697
+ it 'should create a task naming the artifact in the local repository' do
698
+ file = File.join(repositories.local, 'com', 'example', 'library', '2.0', 'library-2.0.jar')
699
+ Rake::Task.task_defined?(file).should be_false
700
+ artifact('com.example:library:jar:2.0').name.should eql(file)
701
+ end
702
+
703
+ it 'should use from method to install artifact from existing file' do
704
+ write 'test.jar'
705
+ artifact = artifact('group:id:jar:1.0').from('test.jar')
706
+ lambda { artifact.invoke }.should change { File.exist?(artifact.to_s) }.to(true)
707
+ end
708
+
709
+ it 'should use from method to install artifact from a file task' do
710
+ test_jar = file('test.jar')
711
+ test_jar.enhance do
712
+ #nothing...
713
+ end
714
+ write 'test.jar'
715
+ artifact = artifact('group:id:jar:1.0').from(test_jar)
716
+ lambda { artifact.invoke }.should change { File.exist?(artifact.to_s) }.to(true)
717
+ end
718
+
719
+ it 'should invoke the artifact associated file task if the file doesnt exist' do
720
+ test_jar = file('test.jar')
721
+ called = false
722
+ test_jar.enhance do
723
+ write 'test.jar'
724
+ called = true
725
+ end
726
+ artifact = artifact('group:id:jar:1.0').from(test_jar)
727
+ artifact.invoke
728
+ unless called
729
+ raise "The file task was not called."
730
+ end
731
+ end
732
+
733
+ it 'should not invoke the artifact associated file task if the file already exists' do
734
+ test_jar = file('test.jar')
735
+ test_jar.enhance do
736
+ raise 'the test.jar file is created again!'
737
+ end
738
+ write 'test.jar'
739
+ artifact = artifact('group:id:jar:1.0').from(test_jar)
740
+ artifact.invoke
741
+ end
742
+
743
+ it 'should reference artifacts defined on build.yaml by using ruby symbols' do
744
+ write 'build.yaml', <<-YAML
745
+ artifacts:
746
+ j2ee: geronimo-spec:geronimo-spec-j2ee:jar:1.4-rc4
747
+ YAML
748
+ Buildr.application.send(:load_artifact_ns)
749
+ artifact(:j2ee).to_s.pathmap('%f').should == 'geronimo-spec-j2ee-1.4-rc4.jar'
750
+ end
751
+
752
+ it 'should try to download snapshot artifact' do
753
+ run_with_repo
754
+ snapshot = artifact(@snapshot_spec)
755
+
756
+ URI.should_receive(:download).at_least(:twice).and_return { |uri, target, options| write target }
757
+ FileUtils.should_receive(:mv).at_least(:twice)
758
+ snapshot.invoke
759
+ end
760
+
761
+ it 'should not try to update snapshot in offline mode if it exists' do
762
+ run_with_repo
763
+ snapshot = artifact(@snapshot_spec)
764
+ write snapshot.to_s
765
+ Buildr.application.options.work_offline = true
766
+ URI.should_receive(:download).exactly(0).times
767
+ snapshot.invoke
768
+ end
769
+
770
+ it 'should download snapshot even in offline mode if it doesn''t exist' do
771
+ run_with_repo
772
+ snapshot = artifact(@snapshot_spec)
773
+ Buildr.application.options.work_offline = true
774
+ URI.should_receive(:download).exactly(2).times
775
+ snapshot.invoke
776
+ end
777
+
778
+ it 'should update snapshots if --update-snapshots' do
779
+ run_with_repo
780
+ snapshot = artifact(@snapshot_spec)
781
+ write snapshot.to_s
782
+ Buildr.application.options.update_snapshots = true
783
+
784
+ URI.should_receive(:download).at_least(:twice).and_return { |uri, target, options| write target }
785
+ FileUtils.should_receive(:mv).at_least(:twice)
786
+ snapshot.invoke
787
+ end
788
+
789
+ it 'should update snapshot if it''s older than 24 hours' do
790
+ run_with_repo
791
+ snapshot = artifact(@snapshot_spec)
792
+ write snapshot.to_s
793
+ time = Time.at((Time.now - (60 * 60 * 24) - 10 ).to_i)
794
+ File.utime(time, time, snapshot.to_s)
795
+ URI.should_receive(:download).at_least(:once).and_return { |uri, target, options| write target }
796
+ snapshot.invoke
797
+ end
798
+
799
+ def run_with_repo
800
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
801
+ end
802
+
803
+ end
804
+
805
+
806
+ describe Buildr, '#artifacts' do
807
+ it 'should return a list of artifacts from all its arguments' do
808
+ specs = %w[saxon:saxon:jar:8.4 saxon:saxon-dom:jar:8.4 saxon:saxon-xpath:jar:8.4]
809
+ artifacts(*specs).should eql(specs.map { |spec| artifact(spec) })
810
+ end
811
+
812
+ it 'should accept nested arrays' do
813
+ specs = %w[saxon:saxon:jar:8.4 saxon:saxon-dom:jar:8.4 saxon:saxon-xpath:jar:8.4]
814
+ artifacts([[specs[0]]], [[specs[1]], specs[2]]).should eql(specs.map { |spec| artifact(spec) })
815
+ end
816
+
817
+ it 'should accept struct' do
818
+ specs = struct(:main=>'saxon:saxon:jar:8.4', :dom=>'saxon:saxon-dom:jar:8.4', :xpath=>'saxon:saxon-xpath:jar:8.4')
819
+ artifacts(specs).should eql(specs.values.map { |spec| artifact(spec) })
820
+ end
821
+
822
+ it 'should ignore duplicates' do
823
+ artifacts('saxon:saxon:jar:8.4', 'saxon:saxon:jar:8.4').size.should be(1)
824
+ end
825
+
826
+ it 'should accept and return existing tasks' do
827
+ artifacts(task('foo'), task('bar')).should eql([task('foo'), task('bar')])
828
+ end
829
+
830
+ it 'should accept filenames and expand them' do
831
+ artifacts('test').map(&:to_s).should eql([File.expand_path('test')])
832
+ end
833
+
834
+ it 'should accept filenames and return filenames' do
835
+ artifacts('c:test').first.should be_kind_of(String)
836
+ end
837
+
838
+ it 'should accept any object responding to :to_spec' do
839
+ obj = Object.new
840
+ class << obj
841
+ def to_spec; "org.example:artifact:jar:1.1"; end
842
+ end
843
+ artifacts(obj).size.should be(1)
844
+ end
845
+
846
+ it 'should accept project and return all its packaging tasks' do
847
+ define 'foobar', :group=>'group', :version=>'1.0' do
848
+ package :jar, :id=>'code'
849
+ package :war, :id=>'webapp'
850
+ end
851
+ foobar = project('foobar')
852
+ artifacts(foobar).should eql([
853
+ task(foobar.path_to('target/code-1.0.jar')),
854
+ task(foobar.path_to('target/webapp-1.0.war'))
855
+ ])
856
+ end
857
+
858
+ it 'should complain about an invalid specification' do
859
+ lambda { artifacts(5) }.should raise_error
860
+ lambda { artifacts('group:no:version:') }.should raise_error
861
+ end
862
+ end
863
+
864
+
865
+ describe Buildr, '#group' do
866
+ it 'should accept list of artifact identifiers' do
867
+ list = group('saxon', 'saxon-dom', 'saxon-xpath', :under=>'saxon', :version=>'8.4')
868
+ list.should include(artifact('saxon:saxon:jar:8.4'))
869
+ list.should include(artifact('saxon:saxon-dom:jar:8.4'))
870
+ list.should include(artifact('saxon:saxon-xpath:jar:8.4'))
871
+ list.size.should be(3)
872
+ end
873
+
874
+ it 'should accept array with artifact identifiers' do
875
+ list = group(%w{saxon saxon-dom saxon-xpath}, :under=>'saxon', :version=>'8.4')
876
+ list.should include(artifact('saxon:saxon:jar:8.4'))
877
+ list.should include(artifact('saxon:saxon-dom:jar:8.4'))
878
+ list.should include(artifact('saxon:saxon-xpath:jar:8.4'))
879
+ list.size.should be(3)
880
+ end
881
+
882
+ it 'should accept a type' do
883
+ list = group('struts-bean', 'struts-html', :under=>'struts', :type=>'tld', :version=>'1.1')
884
+ list.should include(artifact('struts:struts-bean:tld:1.1'))
885
+ list.should include(artifact('struts:struts-html:tld:1.1'))
886
+ list.size.should be(2)
887
+ end
888
+
889
+ it 'should accept a classifier' do
890
+ list = group('camel-core', :under=>'org.apache.camel', :version=>'2.2.0', :classifier=>'spring3')
891
+ list.should include(artifact('org.apache.camel:camel-core:jar:spring3:2.2.0'))
892
+ list.size.should be(1)
893
+ end
894
+
895
+ end
896
+
897
+ describe Buildr, '#install' do
898
+ before do
899
+ @spec = 'group:id:jar:1.0'
900
+ write @file = 'test.jar'
901
+ @snapshot_spec = 'group:id:jar:1.0-SNAPSHOT'
902
+ end
903
+
904
+ it 'should return the install task' do
905
+ install.should be(task('install'))
906
+ end
907
+
908
+ it 'should accept artifacts to install' do
909
+ install artifact(@spec)
910
+ lambda { install @file }.should raise_error(ArgumentError)
911
+ end
912
+
913
+ it 'should install artifact when install task is run' do
914
+ write @file
915
+ install artifact(@spec).from(@file)
916
+ lambda { install.invoke }.should change { File.exist?(artifact(@spec).to_s) }.to(true)
917
+ end
918
+
919
+ it 'should re-install artifact when "from" is newer' do
920
+ install artifact(@spec).from(@file)
921
+ write artifact(@spec).to_s # install a version of the artifact
922
+ old_mtime = File.mtime(artifact(@spec).to_s)
923
+ sleep 1; write @file # make sure the "from" file has newer modification time
924
+ lambda { install.invoke }.should change { modified?(old_mtime, @spec) }.to(true)
925
+ end
926
+
927
+ it 'should re-install snapshot artifact when "from" is newer' do
928
+ install artifact(@snapshot_spec).from(@file)
929
+ write artifact(@snapshot_spec).to_s # install a version of the artifact
930
+ old_mtime = File.mtime(artifact(@snapshot_spec).to_s)
931
+ sleep 1; write @file # make sure the "from" file has newer modification time
932
+ lambda { install.invoke }.should change { modified?(old_mtime, @snapshot_spec) }.to(true)
933
+ end
934
+
935
+ it 'should download snapshot to temporary location' do
936
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
937
+ snapshot = artifact(@snapshot_spec)
938
+ same_time = Time.new
939
+ download_file = "#{Dir.tmpdir}/#{File.basename(snapshot.name)}#{same_time.to_i}"
940
+
941
+ Time.should_receive(:new).twice.and_return(same_time)
942
+ URI.should_receive(:download).at_least(:twice).and_return { |uri, target, options| write target }
943
+ FileUtils.should_receive(:mv).at_least(:twice)
944
+ snapshot.invoke
945
+ end
946
+
947
+ it 'should install POM alongside artifact (if artifact has no classifier)' do
948
+ pom = artifact(@spec).pom
949
+ write @file
950
+ install artifact(@spec).from(@file)
951
+ lambda { install.invoke }.should change { File.exist?(repositories.locate(pom)) }.to(true)
952
+ end
953
+
954
+ it 'should not install POM alongside artifact if artifact has classifier' do
955
+ @spec = 'group:id:jar:all:1.0'
956
+ pom = artifact(@spec).pom
957
+ write @file
958
+ install artifact(@spec).from(@file)
959
+ lambda { install.invoke }.should_not change { File.exist?(repositories.locate(pom)) }.to(true)
960
+ end
961
+
962
+ it 'should reinstall POM alongside artifact' do
963
+ pom = artifact(@spec).pom
964
+ write @file
965
+ write repositories.locate(pom)
966
+ sleep 1
967
+
968
+ install artifact(@spec).from(@file)
969
+ lambda { install.invoke }.should change { File.mtime(repositories.locate(pom)) }
970
+ end
971
+ end
972
+
973
+
974
+ describe Buildr, '#upload' do
975
+ before do
976
+ @spec = 'group:id:jar:1.0'
977
+ write @file = 'test.jar'
978
+ repositories.release_to = 'https://buildr.apache.org/repository/noexist/base'
979
+ end
980
+
981
+ it 'should return the upload task' do
982
+ upload.should be(task('upload'))
983
+ end
984
+
985
+ it 'should accept artifacts to upload' do
986
+ upload artifact(@spec)
987
+ lambda { upload @file }.should raise_error(ArgumentError)
988
+ end
989
+
990
+ it 'should upload artifact when upload task is run' do
991
+ write @file
992
+ upload artifact(@spec).from(@file)
993
+ URI.should_receive(:upload).once.
994
+ with(URI.parse('https://buildr.apache.org/repository/noexist/base/group/id/1.0/id-1.0.jar'), artifact(@spec).to_s, anything)
995
+ URI.should_receive(:upload).once.
996
+ with(URI.parse('https://buildr.apache.org/repository/noexist/base/group/id/1.0/id-1.0.pom'), artifact(@spec).pom.to_s, anything)
997
+ upload.invoke
998
+ end
999
+ end
1000
+
1001
+
1002
+ describe ActsAsArtifact, '#upload' do
1003
+
1004
+ it 'should be used to upload artifact' do
1005
+ artifact = artifact('com.example:library:jar:2.0')
1006
+ # Prevent artifact from downloading anything.
1007
+ write repositories.locate(artifact)
1008
+ write repositories.locate(artifact.pom)
1009
+ URI.should_receive(:upload).once.
1010
+ with(URI.parse('https://buildr.apache.org/repository/noexist/base/com/example/library/2.0/library-2.0.pom'), artifact.pom.to_s, anything)
1011
+ URI.should_receive(:upload).once.
1012
+ with(URI.parse('https://buildr.apache.org/repository/noexist/base/com/example/library/2.0/library-2.0.jar'), artifact.to_s, anything)
1013
+ verbose(false) { artifact.upload(:url=>'https://buildr.apache.org/repository/noexist/base') }
1014
+ end
1015
+
1016
+ it 'should support artifact classifier and should not upload pom if artifact has classifier' do
1017
+ artifact = artifact('com.example:library:jar:all:2.0')
1018
+ # Prevent artifact from downloading anything.
1019
+ write repositories.locate(artifact)
1020
+ URI.should_receive(:upload).exactly(:once).
1021
+ with(URI.parse('https://buildr.apache.org/repository/noexist/base/com/example/library/2.0/library-2.0-all.jar'), artifact.to_s, anything)
1022
+ verbose(false) { artifact.upload(:url=>'https://buildr.apache.org/repository/noexist/base') }
1023
+ end
1024
+
1025
+ it 'should complain without any repository configuration' do
1026
+ artifact = artifact('com.example:library:jar:2.0')
1027
+ # Prevent artifact from downloading anything.
1028
+ write repositories.locate(artifact)
1029
+ write repositories.locate(artifact.pom)
1030
+ lambda { artifact.upload }.should raise_error(Exception, /where to upload/)
1031
+ end
1032
+
1033
+ it 'should upload SNAPSHOT with timestamped unique version and maven metadata' do
1034
+ artifact = artifact('com.example:library:jar:2.0-SNAPSHOT')
1035
+ # Prevent artifact from downloading anything.
1036
+ write repositories.locate(artifact)
1037
+ write repositories.locate(artifact.pom)
1038
+
1039
+ time = Time.gm(2011,"mar",11,14,02,36,123)
1040
+ Time.stub(:now).and_return(time)
1041
+
1042
+ URI.should_receive(:upload).once.
1043
+ with(URI.parse('https://example.com/base/com/example/library/2.0-SNAPSHOT/library-2.0-20110311.140236-1.pom'), artifact.pom.to_s, anything)
1044
+ URI.should_receive(:upload).once.
1045
+ with(URI.parse('https://example.com/base/com/example/library/2.0-SNAPSHOT/library-2.0-20110311.140236-1.jar'), artifact.to_s, anything)
1046
+ URI.should_receive(:write).once.
1047
+ with(URI.parse('https://example.com/base/com/example/library/2.0-SNAPSHOT/maven-metadata.xml'), anything, anything)
1048
+ verbose(false) { artifact.upload(:url=>'https://example.com/base') }
1049
+ end
1050
+
1051
+ it 'should accept repositories.release_to setting' do
1052
+ artifact = artifact('com.example:library:jar:2.0')
1053
+ # Prevent artifact from downloading anything.
1054
+ write repositories.locate(artifact)
1055
+ write repositories.locate(artifact.pom)
1056
+ URI.should_receive(:upload).at_least(:once)
1057
+ repositories.release_to = 'https://buildr.apache.org/repository/noexist/base'
1058
+ artifact.upload
1059
+ lambda { artifact.upload }.should_not raise_error
1060
+ end
1061
+
1062
+ it 'should use repositories.release_to setting even for snapshots when snapshot_to is not set' do
1063
+ time = Time.gm(2016,"nov",11,14,02,36,123)
1064
+ Time.stub(:now).and_return(time)
1065
+ artifact = artifact('com.example:library:jar:2.0-SNAPSHOT')
1066
+ # Prevent artifact from downloading anything.
1067
+ write repositories.locate(artifact)
1068
+ write repositories.locate(artifact.pom)
1069
+ URI.should_receive(:upload).once.
1070
+ with(URI.parse('https://buildr.apache.org/repository/noexist/base/com/example/library/2.0-SNAPSHOT/library-2.0-20161111.140236-1.pom'), artifact.pom.to_s, anything)
1071
+ URI.should_receive(:upload).once.
1072
+ with(URI.parse('https://buildr.apache.org/repository/noexist/base/com/example/library/2.0-SNAPSHOT/library-2.0-20161111.140236-1.jar'), artifact.to_s, anything)
1073
+ URI.should_receive(:write).once.
1074
+ with(URI.parse('https://buildr.apache.org/repository/noexist/base/com/example/library/2.0-SNAPSHOT/maven-metadata.xml'), anything, anything)
1075
+ repositories.release_to = 'https://buildr.apache.org/repository/noexist/base'
1076
+ artifact.upload
1077
+ lambda { artifact.upload }.should_not raise_error
1078
+ end
1079
+
1080
+ it 'should use repositories.snapshot_to setting when snapshot_to is set' do
1081
+ time = Time.gm(2016,"nov",11,14,02,36,123)
1082
+ Time.stub(:now).and_return(time)
1083
+ artifact = artifact('com.example:library:jar:2.0-SNAPSHOT')
1084
+ # Prevent artifact from downloading anything.
1085
+ write repositories.locate(artifact)
1086
+ write repositories.locate(artifact.pom)
1087
+ URI.should_receive(:upload).once.
1088
+ with(URI.parse('https://buildr.apache.org/repository/noexist/snapshot/com/example/library/2.0-SNAPSHOT/library-2.0-20161111.140236-1.pom'), artifact.pom.to_s, anything)
1089
+ URI.should_receive(:upload).once.
1090
+ with(URI.parse('https://buildr.apache.org/repository/noexist/snapshot/com/example/library/2.0-SNAPSHOT/library-2.0-20161111.140236-1.jar'), artifact.to_s, anything)
1091
+ URI.should_receive(:write).once.
1092
+ with(URI.parse('https://buildr.apache.org/repository/noexist/snapshot/com/example/library/2.0-SNAPSHOT/maven-metadata.xml'), anything, anything)
1093
+ repositories.release_to = 'https://buildr.apache.org/repository/noexist/base'
1094
+ repositories.snapshot_to = 'https://buildr.apache.org/repository/noexist/snapshot'
1095
+ artifact.upload
1096
+ lambda { artifact.upload }.should_not raise_error
1097
+ end
1098
+
1099
+ it 'should complain when only a snapshot repo is set but the artifact is not a snapshot' do
1100
+ artifact = artifact('com.example:library:jar:2.0')
1101
+ # Prevent artifact from downloading anything.
1102
+ write repositories.locate(artifact)
1103
+ write repositories.locate(artifact.pom)
1104
+ repositories.snapshot_to = 'https://buildr.apache.org/repository/noexist/snapshot'
1105
+ lambda { artifact.upload }.should raise_error(Exception, /where to upload/)
1106
+ end
1107
+ end
1108
+
1109
+
1110
+ describe Rake::Task, ' artifacts' do
1111
+ before do
1112
+ Buildr.repositories.instance_eval do
1113
+ @local = @remote = @release_to = nil
1114
+ end
1115
+ end
1116
+
1117
+ it 'should download all specified artifacts' do
1118
+ artifact 'group:id:jar:1.0'
1119
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
1120
+ URI.should_receive(:download).twice.and_return { |uri, target, options| write target }
1121
+ task('artifacts').invoke
1122
+ end
1123
+
1124
+ it 'should fail if failed to download an artifact' do
1125
+ artifact 'group:id:jar:1.0'
1126
+ lambda { task('artifacts').invoke }.should raise_error(RuntimeError, /No remote repositories/)
1127
+ end
1128
+
1129
+ it 'should succeed if artifact already exists' do
1130
+ write repositories.locate(artifact('group:id:jar:1.0'))
1131
+ suppress_stdout do
1132
+ lambda { task('artifacts').invoke }.should_not raise_error
1133
+ end
1134
+ end
1135
+ end
1136
+
1137
+
1138
+ describe Rake::Task, ' artifacts:sources' do
1139
+
1140
+ before do
1141
+ Buildr.repositories.instance_eval do
1142
+ @local = @remote = @release_to = nil
1143
+ end
1144
+ task('artifacts:sources').clear
1145
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
1146
+ end
1147
+
1148
+ it 'should download sources for all specified artifacts' do
1149
+ artifact 'group:id:jar:1.0'
1150
+ URI.stub(:download).and_return { |uri, target| write target }
1151
+ lambda { task('artifacts:sources').invoke }.should change { File.exist?('home/.m2/repository/group/id/1.0/id-1.0-sources.jar') }.to(true)
1152
+ end
1153
+
1154
+ it "should not try to download sources for the project's artifacts" do
1155
+ define('foo', :version=>'1.0') { package(:jar) }
1156
+ URI.should_not_receive(:download)
1157
+ task('artifacts:sources').invoke
1158
+ end
1159
+
1160
+ describe 'when the source artifact does not exist' do
1161
+
1162
+ before do
1163
+ artifact 'group:id:jar:1.0'
1164
+ URI.should_receive(:download).and_raise(URI::NotFoundError)
1165
+ end
1166
+
1167
+ it 'should not fail' do
1168
+ lambda { task('artifacts:sources').invoke }.should_not raise_error
1169
+ end
1170
+
1171
+ it 'should inform the user' do
1172
+ lambda { task('artifacts:sources').invoke }.should show_info('Failed to download group:id:jar:sources:1.0. Skipping it.')
1173
+ end
1174
+ end
1175
+ end
1176
+
1177
+ describe Rake::Task, ' artifacts:javadoc' do
1178
+
1179
+ before do
1180
+ Buildr.repositories.instance_eval do
1181
+ @local = @remote = @release_to = nil
1182
+ end
1183
+ task('artifacts:javadoc').clear
1184
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
1185
+ end
1186
+
1187
+ it 'should download javadoc for all specified artifacts' do
1188
+ artifact 'group:id:jar:1.0'
1189
+ URI.should_receive(:download).and_return { |uri, target| write target }
1190
+ lambda { task('artifacts:javadoc').invoke }.should change { File.exist?('home/.m2/repository/group/id/1.0/id-1.0-javadoc.jar') }.to(true)
1191
+ end
1192
+
1193
+ it "should not try to download javadoc for the project's artifacts" do
1194
+ define('foo', :version=>'1.0') { package(:jar) }
1195
+ URI.should_not_receive(:download)
1196
+ task('artifacts:javadoc').invoke
1197
+ end
1198
+
1199
+ describe 'when the javadoc artifact does not exist' do
1200
+
1201
+ before do
1202
+ artifact 'group:id:jar:1.0'
1203
+ URI.should_receive(:download).and_raise(URI::NotFoundError)
1204
+ end
1205
+
1206
+ it 'should not fail' do
1207
+ lambda { task('artifacts:javadoc').invoke }.should_not raise_error
1208
+ end
1209
+
1210
+ it 'should inform the user' do
1211
+ lambda { task('artifacts:javadoc').invoke }.should show_info('Failed to download group:id:jar:javadoc:1.0. Skipping it.')
1212
+ end
1213
+ end
1214
+ end
1215
+
1216
+ describe Buildr, '#transitive' do
1217
+ before do
1218
+ repositories.remote = 'http://buildr.apache.org/repository/noexist'
1219
+
1220
+ @simple = %w(saxon:saxon:jar:8.4 saxon:saxon-dom:jar:8.4 saxon:saxon-xpath:jar:8.4)
1221
+ @simple.map { |spec| artifact(spec).pom }.each { |task| write task.name, task.pom_xml.call }
1222
+ @provided = @simple.first
1223
+ @complex = 'group:app:jar:1.0'
1224
+ write artifact(@complex).pom.to_s, <<-XML
1225
+ <project>
1226
+ <artifactId>app</artifactId>
1227
+ <groupId>group</groupId>
1228
+ <dependencies>
1229
+ <dependency>
1230
+ <artifactId>saxon</artifactId>
1231
+ <groupId>saxon</groupId>
1232
+ <version>8.4</version>
1233
+ <scope>provided</scope>
1234
+ </dependency>
1235
+ <dependency>
1236
+ <artifactId>saxon-dom</artifactId>
1237
+ <groupId>saxon</groupId>
1238
+ <version>8.4</version>
1239
+ <scope>runtime</scope>
1240
+ </dependency>
1241
+ <dependency>
1242
+ <artifactId>saxon-xpath</artifactId>
1243
+ <groupId>saxon</groupId>
1244
+ <version>8.4</version>
1245
+ </dependency>
1246
+ <dependency>
1247
+ <artifactId>saxon-nosuch</artifactId>
1248
+ <groupId>saxon</groupId>
1249
+ <version>8.4</version>
1250
+ <scope>test</scope>
1251
+ </dependency>
1252
+ <dependency>
1253
+ <artifactId>jlib-optional</artifactId>
1254
+ <groupId>jlib</groupId>
1255
+ <version>1.4</version>
1256
+ <scope>runtime</scope>
1257
+ <optional>true</optional>
1258
+ </dependency>
1259
+ </dependencies>
1260
+ </project>
1261
+ XML
1262
+ @transitive = 'master:app:war:1.0'
1263
+ write artifact(@transitive).pom.to_s, <<-XML
1264
+ <project>
1265
+ <artifactId>app</artifactId>
1266
+ <groupId>group</groupId>
1267
+ <dependencies>
1268
+ <dependency>
1269
+ <artifactId>app</artifactId>
1270
+ <groupId>group</groupId>
1271
+ <version>1.0</version>
1272
+ </dependency>
1273
+ </dependencies>
1274
+ </project>
1275
+ XML
1276
+ end
1277
+
1278
+ it 'should return a list of artifacts from all its arguments' do
1279
+ specs = %w[saxon:saxon:jar:8.4 saxon:saxon-dom:jar:8.4 saxon:saxon-xpath:jar:8.4]
1280
+ transitive(*specs).should eql(specs.map { |spec| artifact(spec) })
1281
+ end
1282
+
1283
+ it 'should accept nested arrays' do
1284
+ specs = %w[saxon:saxon:jar:8.4 saxon:saxon-dom:jar:8.4 saxon:saxon-xpath:jar:8.4]
1285
+ transitive([[specs[0]]], [[specs[1]], specs[2]]).should eql(specs.map { |spec| artifact(spec) })
1286
+ end
1287
+
1288
+ it 'should accept struct' do
1289
+ specs = struct(:main=>'saxon:saxon:jar:8.4', :dom=>'saxon:saxon-dom:jar:8.4', :xpath=>'saxon:saxon-xpath:jar:8.4')
1290
+ transitive(specs).should eql(specs.values.map { |spec| artifact(spec) })
1291
+ end
1292
+
1293
+ it 'should ignore duplicates' do
1294
+ transitive('saxon:saxon:jar:8.4', 'saxon:saxon:jar:8.4').size.should be(1)
1295
+ end
1296
+
1297
+ it 'should accept and return existing tasks' do
1298
+ transitive(task('foo'), task('bar')).should eql([task('foo'), task('bar')])
1299
+ end
1300
+
1301
+ it 'should accept filenames and expand them' do
1302
+ transitive('test').map(&:to_s).should eql([File.expand_path('test')])
1303
+ end
1304
+
1305
+ it 'should accept filenames and return file task' do
1306
+ transitive('c:test').first.should be_kind_of(Rake::FileTask)
1307
+ end
1308
+
1309
+ it 'should accept project and return all its packaging tasks' do
1310
+ define 'foobar', :group=>'group', :version=>'1.0' do
1311
+ package :jar, :id=>'code'
1312
+ package :war, :id=>'webapp'
1313
+ end
1314
+ foobar = project('foobar')
1315
+ transitive(foobar).should eql([
1316
+ task(foobar.path_to('target/code-1.0.jar')),
1317
+ task(foobar.path_to('target/webapp-1.0.war'))
1318
+ ])
1319
+ end
1320
+
1321
+ it 'should complain about an invalid specification' do
1322
+ lambda { transitive(5) }.should raise_error
1323
+ lambda { transitive('group:no:version:') }.should raise_error
1324
+ end
1325
+
1326
+ it 'should bring artifact and its dependencies' do
1327
+ transitive(@complex).should eql(artifacts(@complex, @simple - [@provided]))
1328
+ end
1329
+
1330
+ it 'should bring dependencies of POM without artifact itself' do
1331
+ transitive(@complex.sub(/jar/, 'pom')).should eql(artifacts(@simple - [@provided]))
1332
+ end
1333
+
1334
+ it 'should bring artifact and transitive depenencies' do
1335
+ transitive(@transitive).should eql(artifacts(@transitive, @complex, @simple - [@provided]))
1336
+ end
1337
+
1338
+ it 'should filter dependencies based on :scopes argument' do
1339
+ specs = [@complex, 'saxon:saxon-dom:jar:8.4']
1340
+ transitive(@complex, :scopes => [:runtime]).should eql(specs.map { |spec| artifact(spec) })
1341
+ end
1342
+
1343
+ it 'should filter dependencies based on :optional argument' do
1344
+ specs = [@complex, 'saxon:saxon-dom:jar:8.4', 'jlib:jlib-optional:jar:1.4']
1345
+ transitive(@complex, :scopes => [:runtime], :optional => true).should eql(specs.map { |spec| artifact(spec) })
1346
+ end
1347
+ end
1348
+
1349
+ def modified?(old_mtime, spec)
1350
+ File.exist?(artifact(spec).to_s) && old_mtime < File.mtime(artifact(spec).to_s)
1351
+ end