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,670 @@
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.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helpers'))
18
+
19
+ describe Buildr.method(:struct) do
20
+ before do
21
+ @hash = { :foo=>'foo:jar', :bar=>'bar:jar' }
22
+ @struct = struct(@hash)
23
+ end
24
+
25
+ it 'should be object with key-value pairs' do
26
+ @struct.foo.should eql('foo:jar')
27
+ @struct.bar.should eql('bar:jar')
28
+ end
29
+
30
+ it 'should fail when requesting non-existent key' do
31
+ lambda { @struct.foobar }.should raise_error(NoMethodError)
32
+ end
33
+
34
+ it 'should return members when requested' do
35
+ @struct.members.map(&:to_s).sort.should eql(@hash.keys.map(&:to_s).sort)
36
+ end
37
+
38
+ it 'should return valued when requested' do
39
+ @struct.values.sort.should eql(@hash.values.sort)
40
+ end
41
+ end
42
+
43
+
44
+ describe Buildr.method(:write) do
45
+ it 'should create path' do
46
+ write 'foo/test'
47
+ File.directory?('foo').should be_true
48
+ File.exist?('foo/test').should be_true
49
+ end
50
+
51
+ it 'should write content to file' do
52
+ write 'test', 'content'
53
+ File.read('test').should eql('content')
54
+ end
55
+
56
+ it 'should retrieve content from block, if block given' do
57
+ write('test') { 'block' }
58
+ File.read('test').should eql('block')
59
+ end
60
+
61
+ it 'should write empty file if no content provided' do
62
+ write 'test'
63
+ File.read('test').should eql('')
64
+ end
65
+
66
+ it 'should return content as a string' do
67
+ write('test', 'content').should eql('content')
68
+ end
69
+
70
+ it 'should return empty string if no content provided' do
71
+ write('test').should eql('')
72
+ end
73
+ end
74
+
75
+
76
+ describe Buildr.method(:read) do
77
+ before do
78
+ write @file = 'test', @content = 'content'
79
+ end
80
+
81
+ it 'should return contents of named file' do
82
+ read(@file).should eql(@content)
83
+ end
84
+
85
+ it 'should yield to block if block given' do
86
+ read @file do |content|
87
+ content.should eql(@content)
88
+ end
89
+ end
90
+
91
+ it 'should return block response if block given' do
92
+ read(@file) { 5 }.should be(5)
93
+ end
94
+ end
95
+
96
+
97
+ describe Buildr.method(:download) do
98
+ before do
99
+ @content = 'we has download!'
100
+ @http = double('http')
101
+ @http.stub(:request).and_return(Net::HTTPNotModified.new(nil, nil, nil))
102
+ end
103
+
104
+ def tasks()
105
+ [ download('http://localhost/download'), download('downloaded'=>'http://localhost/download') ]
106
+ end
107
+
108
+ it 'should be a file task' do
109
+ tasks.each { |task| task.should be_kind_of(Rake::FileTask) }
110
+ end
111
+
112
+ it 'should accept a String and download from that URL' do
113
+ content = @content
114
+ define 'foo' do
115
+ download('http://localhost/download').tap do |task|
116
+ task.source.should_receive(:read).and_yield [content]
117
+ task.invoke
118
+ task.should contain(content)
119
+ end
120
+ end
121
+ end
122
+
123
+ it 'should accept a URI and download from that URL' do
124
+ content = @content
125
+ define 'foo' do
126
+ download(URI.parse('http://localhost/download')).tap do |task|
127
+ task.source.should_receive(:read).and_yield [content]
128
+ task.invoke
129
+ task.should contain(content)
130
+ end
131
+ end
132
+ end
133
+
134
+ it 'should accept a path and String and download from that URL' do
135
+ content = @content
136
+ define 'foo' do
137
+ download('downloaded'=>'http://localhost/download').tap do |task|
138
+ task.source.should_receive(:read).and_yield [content]
139
+ task.invoke
140
+ task.should contain(content)
141
+ end
142
+ end
143
+ end
144
+
145
+ it 'should accept an artifact and String and download from that URL' do
146
+ content = @content
147
+ define 'foo' do
148
+ artifact('com.example:library:jar:2.0').tap do |artifact|
149
+ download(artifact=>'http://localhost/download').source.should_receive(:read).and_yield [content]
150
+ artifact.invoke
151
+ artifact.should contain(content)
152
+ end
153
+ end
154
+ end
155
+
156
+ it 'should accept a path and URI and download from that URL' do
157
+ content = @content
158
+ define 'foo' do
159
+ download('downloaded'=>URI.parse('http://localhost/download')).tap do |task|
160
+ task.source.should_receive(:read).and_yield [content]
161
+ task.invoke
162
+ task.should contain(content)
163
+ end
164
+ end
165
+ end
166
+
167
+ it 'should create path for download' do
168
+ content = @content
169
+ define 'foo' do
170
+ download('path/downloaded'=>URI.parse('http://localhost/download')).tap do |task|
171
+ task.source.should_receive(:read).and_yield [content]
172
+ task.invoke
173
+ task.should contain(content)
174
+ end
175
+ end
176
+ end
177
+
178
+ it 'should fail if resource not found' do
179
+ tasks.each do |task|
180
+ task.source.should_receive(:read).and_raise URI::NotFoundError
181
+ lambda { task.invoke }.should raise_error(URI::NotFoundError)
182
+ end
183
+ tasks.last.should_not exist
184
+ end
185
+
186
+ it 'should fail on any other error' do
187
+ tasks.each do |task|
188
+ task.source.should_receive(:read).and_raise RuntimeError
189
+ lambda { task.invoke }.should raise_error(RuntimeError)
190
+ end
191
+ tasks.last.should_not exist
192
+ end
193
+
194
+ it 'should execute only if file does not already exist' do
195
+ define 'foo' do
196
+ download('downloaded'=>'http://localhost/download').tap do |task|
197
+ task.source.should_not_receive(:read)
198
+ write task.to_s, 'not really'
199
+ task.invoke
200
+ end
201
+ end
202
+ end
203
+
204
+ it 'should execute without a proxy if none specified' do
205
+ Net::HTTP.should_receive(:new).with('localhost', 80).twice.and_return(@http)
206
+ tasks.each(&:invoke)
207
+ end
208
+
209
+ it 'should pass Buildr proxy options' do
210
+ Buildr.options.proxy.http = 'http://proxy:8080'
211
+ Net::HTTP.should_receive(:new).with('localhost', 80, 'proxy', 8080, nil, nil).twice.and_return(@http)
212
+ tasks.each(&:invoke)
213
+ end
214
+
215
+ it 'should set HTTP proxy from HTTP_PROXY environment variable' do
216
+ ENV['HTTP_PROXY'] = 'http://proxy:8080'
217
+ Net::HTTP.should_receive(:new).with('localhost', 80, 'proxy', 8080, nil, nil).twice.and_return(@http)
218
+ tasks.each(&:invoke)
219
+ end
220
+ end
221
+
222
+
223
+ describe Buildr.method(:filter) do
224
+ def source
225
+ File.expand_path('src')
226
+ end
227
+
228
+ it 'should return a Filter for the source' do
229
+ filter(source).should be_kind_of(Filter)
230
+ end
231
+
232
+ it 'should use the source directory' do
233
+ filter(source).sources.should include(file(source))
234
+ end
235
+
236
+ it 'should use the source directories' do
237
+ dirs = %w[first second]
238
+ filter('first', 'second').sources.should include(*dirs.map { |dir| file(File.expand_path(dir)) })
239
+ end
240
+
241
+ it 'should accept a file task' do
242
+ task = file(source)
243
+ filter(task).sources.each { |source| source.should be(task) }
244
+ end
245
+ end
246
+
247
+
248
+ describe Buildr::Filter do
249
+ before do
250
+ @filter = Filter.new
251
+ 1.upto(4) do |i|
252
+ write "src/file#{i}", "file#{i} raw"
253
+ end
254
+ @early = Time.now - 1000
255
+ end
256
+
257
+ it 'should respond to :from and return self' do
258
+ @filter.from('src').should be(@filter)
259
+ end
260
+
261
+ it 'should respond to :from and add source directory' do
262
+ lambda { @filter.from('src') }.should change { @filter.sources }
263
+ end
264
+
265
+ it 'should respond to :from and add source directories' do
266
+ dirs = %w[first second]
267
+ @filter.from(*dirs)
268
+ @filter.sources.should include(*dirs.map { |dir| file(File.expand_path(dir)) })
269
+ end
270
+
271
+ it 'should return source directories as file task' do
272
+ @filter.from('src').sources.each { |source| source.should be_kind_of(Rake::FileTask) }
273
+ end
274
+
275
+ it 'should return source directories as expanded path' do
276
+ @filter.from('src').sources.each { |source| source.to_s.should eql(File.expand_path('src')) }
277
+ end
278
+
279
+ it 'should respond to :into and return self' do
280
+ @filter.into('target').should be(@filter)
281
+ end
282
+
283
+ it 'should respond to :into and set target directory' do
284
+ lambda { @filter.into('src') }.should change { @filter.target }
285
+ @filter.into('target').target.should be(file(File.expand_path('target')))
286
+ end
287
+
288
+ it 'should return target directory as file task' do
289
+ @filter.into('target').target.should be_kind_of(Rake::FileTask)
290
+ end
291
+
292
+ it 'should return target directory as expanded path' do
293
+ @filter.into('target').target.to_s.should eql(File.expand_path('target'))
294
+ end
295
+
296
+ it 'should respond to :using and return self' do
297
+ @filter.using().should be(@filter)
298
+ end
299
+
300
+ it 'should respond to :using and set mapping from the argument' do
301
+ mapping = { 'foo'=>'bar' }
302
+ lambda { @filter.using mapping }.should change { @filter.mapping }.to(mapping)
303
+ end
304
+
305
+ it 'should respond to :using and set mapping from the block' do
306
+ @filter.using { 5 }.mapping.call.should be(5)
307
+ end
308
+
309
+ it 'should respond to :include and return self' do
310
+ @filter.include('file').should be(@filter)
311
+ end
312
+
313
+ it 'should respond to :include and use these inclusion patterns' do
314
+ @filter.from('src').into('target').include('file2', 'file3').run
315
+ Dir['target/*'].sort.should eql(%w[target/file2 target/file3])
316
+ end
317
+
318
+ it 'should respond to :include with regular expressions and use these inclusion patterns' do
319
+ @filter.from('src').into('target').include(/file[2|3]/).run
320
+ Dir['target/*'].sort.should eql(%w[target/file2 target/file3])
321
+ end
322
+
323
+ it 'should respond to :include with a Proc and use these inclusion patterns' do
324
+ @filter.from('src').into('target').include(lambda {|file| file[-1, 1].to_i%2 == 0}).run
325
+ Dir['target/*'].sort.should eql(%w[target/file2 target/file4])
326
+ end
327
+
328
+ it 'should respond to :include with a FileTask and use these inclusion patterns' do
329
+ @filter.from('src').into('target').include(file('target/file2'), file('target/file4')).run
330
+ Dir['target/*'].sort.should eql(%w[target/file2 target/file4])
331
+ end
332
+
333
+ it 'should respond to :exclude and return self' do
334
+ @filter.exclude('file').should be(@filter)
335
+ end
336
+
337
+ it 'should respond to :exclude and use these exclusion patterns' do
338
+ @filter.from('src').into('target').exclude('file2', 'file3').run
339
+ Dir['target/*'].sort.should eql(%w[target/file1 target/file4])
340
+ end
341
+
342
+ it 'should respond to :exclude with regular expressions and use these exclusion patterns' do
343
+ @filter.from('src').into('target').exclude(/file[2|3]/).run
344
+ Dir['target/*'].sort.should eql(%w[target/file1 target/file4])
345
+ end
346
+
347
+ it 'should respond to :exclude with a Proc and use these exclusion patterns' do
348
+ @filter.from('src').into('target').exclude(lambda {|file| file[-1, 1].to_i%2 == 0}).run
349
+ Dir['target/*'].sort.should eql(%w[target/file1 target/file3])
350
+ end
351
+
352
+ it 'should respond to :exclude with a FileTask and use these exclusion patterns' do
353
+ @filter.from('src').into('target').exclude(file('target/file1'), file('target/file3')).run
354
+ Dir['target/*'].sort.should eql(%w[target/file2 target/file4])
355
+ end
356
+
357
+ it 'should respond to :exclude with a FileTask, use these exclusion patterns and depend on those tasks' do
358
+ file1 = false
359
+ file2 = false
360
+ @filter.from('src').into('target').exclude(file('target/file1').enhance { file1 = true }, file('target/file3').enhance {file2 = true }).run
361
+ Dir['target/*'].sort.should eql(%w[target/file2 target/file4])
362
+ @filter.target.invoke
363
+ file1.should be_true
364
+ file2.should be_true
365
+ end
366
+
367
+ it 'should copy files over' do
368
+ @filter.from('src').into('target').run
369
+ Dir['target/*'].sort.each do |file|
370
+ read(file).should eql("#{File.basename(file)} raw")
371
+ end
372
+ end
373
+
374
+ it 'should copy dot files over' do
375
+ write 'src/.config', '# configuration'
376
+ @filter.from('src').into('target').run
377
+ read('target/.config').should eql('# configuration')
378
+ end
379
+
380
+ it 'should copy empty directories as well' do
381
+ mkpath 'src/empty'
382
+ @filter.from('src').into('target').run
383
+ File.directory?('target/empty').should be_true
384
+ end
385
+
386
+ it 'should copy files from multiple source directories' do
387
+ 4.upto(6) { |i| write "src2/file#{i}", "file#{i} raw" }
388
+ @filter.from('src', 'src2').into('target').run
389
+ Dir['target/*'].each do |file|
390
+ read(file).should eql("#{File.basename(file)} raw")
391
+ end
392
+ Dir['target/*'].should include(*(1..6).map { |i| "target/file#{i}" })
393
+ end
394
+
395
+ it 'should copy files recursively' do
396
+ mkpath 'src/path1' ; write 'src/path1/left'
397
+ mkpath 'src/path2' ; write 'src/path2/right'
398
+ @filter.from('src').into('target').run
399
+ Dir['target/**/*'].should include(*(1..4).map { |i| "target/file#{i}" })
400
+ Dir['target/**/*'].should include('target/path1/left', 'target/path2/right')
401
+ end
402
+
403
+ it 'should apply hash mapping using Maven style' do
404
+ 1.upto(4) { |i| write "src/file#{i}", "file#{i} with ${key1} and ${key2}" }
405
+ @filter.from('src').into('target').using('key1'=>'value1', 'key2'=>'value2').run
406
+ Dir['target/*'].each do |file|
407
+ read(file).should eql("#{File.basename(file)} with value1 and value2")
408
+ end
409
+ end
410
+
411
+ it 'should not apply filters to binary files' do
412
+ %w[jpg jpeg gif png].each { |ext| write "images/file.#{ext}", 'something' }
413
+ filter = @filter.from('images').into('target').using('key1'=>'value1', 'key2'=>'value2')
414
+ filter.instance_variable_get("@mapper").should_not_receive(:maven_transform)
415
+ filter.run
416
+ end
417
+
418
+ it 'should apply hash mapping using Ant style' do
419
+ 1.upto(4) { |i| write "src/file#{i}", "file#{i} with @key1@ and @key2@" }
420
+ @filter.from('src').into('target').using(:ant, 'key1'=>'value1', 'key2'=>'value2').run
421
+ Dir['target/*'].each do |file|
422
+ read(file).should eql("#{File.basename(file)} with value1 and value2")
423
+ end
424
+ end
425
+
426
+ it 'should apply hash mapping using Ruby style' do
427
+ 1.upto(4) { |i| write "src/file#{i}", "file#{i} with \#{key1} and \#{key2}" }
428
+ @filter.from('src').into('target').using(:ruby, 'key1'=>'value1', 'key2'=>'value2').run
429
+ Dir['target/*'].each do |file|
430
+ read(file).should eql("#{File.basename(file)} with value1 and value2")
431
+ end
432
+ end
433
+
434
+ it 'should use erb when given a binding' do
435
+ 1.upto(4) { |i| write "src/file#{i}", "file#{i} with <%= key1 %> and <%= key2 * 2 %>" }
436
+ key1 = 'value1'
437
+ key2 = 12
438
+ @filter.from('src').into('target').using(binding).run
439
+ Dir['target/*'].each do |file|
440
+ read(file).should eql("#{File.basename(file)} with value1 and 24")
441
+ end
442
+ end
443
+
444
+ it 'should apply hash mapping using erb' do
445
+ 1.upto(4) { |i| write "src/file#{i}", "file#{i} with <%= key1 %> and <%= key2 * 2 %>" }
446
+ @filter.from('src').into('target').using(:erb, 'key1'=>'value1', 'key2'=> 12).run
447
+ Dir['target/*'].each do |file|
448
+ read(file).should eql("#{File.basename(file)} with value1 and 24")
449
+ end
450
+ end
451
+
452
+ it 'should use an object binding when using erb' do
453
+ 1.upto(4) { |i| write "src/file#{i}", "file#{i} with <%= key1 %> and <%= key2 * 2 %>" }
454
+ obj = Struct.new(:key1, :key2).new('value1', 12)
455
+ @filter.from('src').into('target').using(:erb, obj).run
456
+ Dir['target/*'].each do |file|
457
+ read(file).should eql("#{File.basename(file)} with value1 and 24")
458
+ end
459
+ end
460
+
461
+ it 'should use a given block context when using erb' do
462
+ 1.upto(4) { |i| write "src/file#{i}", "file#{i} with <%= key1 %> and <%= key2 * 2 %>" }
463
+ key1 = 'value1'
464
+ key2 = 12
465
+ @filter.from('src').into('target').using(:erb){}.run
466
+ Dir['target/*'].each do |file|
467
+ read(file).should eql("#{File.basename(file)} with value1 and 24")
468
+ end
469
+ end
470
+
471
+ it 'should using Maven mapper by default' do
472
+ @filter.using('key1'=>'value1', 'key2'=>'value2').mapper.should eql(:maven)
473
+ end
474
+
475
+ it 'should apply hash mapping with boolean values' do
476
+ write "src/file", "${key1} and ${key2}"
477
+ @filter.from('src').into('target').using(:key1=>true, :key2=>false).run
478
+ read("target/file").should eql("true and false")
479
+ end
480
+
481
+ it 'should apply hash mapping using regular expression' do
482
+ 1.upto(4) { |i| write "src/file#{i}", "file#{i} with #key1# and #key2#" }
483
+ @filter.from('src').into('target').using(/#(.*?)#/, 'key1'=>'value1', 'key2'=>'value2').run
484
+ Dir['target/*'].each do |file|
485
+ read(file).should eql("#{File.basename(file)} with value1 and value2")
486
+ end
487
+ end
488
+
489
+ it 'should apply proc mapping' do
490
+ @filter.from('src').into('target').using { |file, content| 'proc mapped' }.run
491
+ Dir['target/*'].each do |file|
492
+ read(file).should eql('proc mapped')
493
+ end
494
+ end
495
+
496
+ it 'should apply proc mapping with relative file name' do
497
+ @filter.from('src').into('target').using { |file, content| file.should =~ /^file\d$/ }.run
498
+ end
499
+
500
+ it 'should apply proc mapping with file content' do
501
+ @filter.from('src').into('target').using { |file, content| content.should =~ /^file\d raw/ }.run
502
+ end
503
+
504
+ it 'should make target directory' do
505
+ lambda { @filter.from('src').into('target').run }.should change { File.exist?('target') }.to(true)
506
+ end
507
+
508
+ it 'should touch target directory' do
509
+ mkpath 'target' ; File.utime @early, @early, 'target'
510
+ @filter.from('src').into('target').run
511
+ File.stat('target').mtime.should be_within(10).of(Time.now)
512
+ end
513
+
514
+ it 'should not touch target directory unless running' do
515
+ mkpath 'target' ; File.utime @early, @early, 'target'
516
+ @filter.from('src').into('target').exclude('*').run
517
+ File.mtime('target').should be_within(10).of(@early)
518
+ end
519
+
520
+ it 'should run only on new files' do
521
+ # Make source files older so they're not copied twice.
522
+ Dir['src/**/*'].each { |file| File.utime(@early, @early, file) }
523
+ @filter.from('src').into('target').run
524
+ @filter.from('src').into('target').using { |file, content| file.should eql('file2') }.run
525
+ end
526
+
527
+ it 'should return true when run copies any files' do
528
+ @filter.from('src').into('target').run.should be(true)
529
+ end
530
+
531
+ it 'should return false when run does not copy any files' do
532
+ # Make source files older so they're not copied twice.
533
+ Dir['src/**/*'].each { |file| File.utime(@early, @early, file) }
534
+ @filter.from('src').into('target').run
535
+ @filter.from('src').into('target').run.should be(false)
536
+ end
537
+
538
+ it 'should not fail if source directory does not exist' do
539
+ lambda { Filter.new.from('srced').into('target').run }.should_not raise_error#(RuntimeError)
540
+ end
541
+
542
+ it 'should fail is target directory not set' do
543
+ lambda { Filter.new.from('src').run }.should raise_error(RuntimeError, /No target directory/)
544
+ end
545
+
546
+ it 'should copy read-only files as writeable' do
547
+ Dir['src/*'].each { |file| File.chmod(0444, file) }
548
+ @filter.from('src').into('target').run
549
+ Dir['target/*'].sort.each do |file|
550
+ File.readable?(file).should be_true
551
+ File.writable?(file).should be_true
552
+ (File.stat(file).mode & 0o200).should == 0o200
553
+ end
554
+ end
555
+
556
+ it 'should preserve mode bits except readable' do
557
+ mode = 0o600
558
+ Dir['src/*'].each { |file| File.chmod(mode, file) }
559
+ @filter.from('src').into('target').run
560
+ Dir['target/*'].sort.each do |file|
561
+ (File.stat(file).mode & mode).should == mode
562
+ end
563
+ end
564
+ end
565
+
566
+ describe Filter::Mapper do
567
+
568
+ module MooMapper
569
+ def moo_config(*args, &block)
570
+ raise ArgumentError, "Expected moo block" unless block_given?
571
+ { :moos => args, :callback => block }
572
+ end
573
+
574
+ def moo_transform(content, path = nil)
575
+ content.gsub(/moo+/i) do |str|
576
+ moos = yield :moos # same than config[:moos]
577
+ moo = moos[str.size - 3] || str
578
+ config[:callback].call(moo)
579
+ end
580
+ end
581
+ end
582
+
583
+ it 'should allow plugable mapping types' do
584
+ mapper = Filter::Mapper.new.extend(MooMapper)
585
+ mapper.using(:moo, 'ooone', 'twoo') do |str|
586
+ i = nil; str.capitalize.gsub(/\w/) { |s| s.send( (i = !i) ? 'upcase' : 'downcase' ) }
587
+ end
588
+ mapper.transform('Moo cow, mooo cows singing mooooo').should == 'OoOnE cow, TwOo cows singing MoOoOo'
589
+ end
590
+
591
+ end
592
+
593
+ describe Buildr.method(:options) do
594
+ it 'should return an Options object' do
595
+ options.should be_kind_of(Options)
596
+ end
597
+
598
+ it 'should return an Options object each time' do
599
+ options.should be(options)
600
+ end
601
+
602
+ it 'should return the same Options object when called on Object, Buildr or Project' do
603
+ options.should be(Buildr.options)
604
+ define('foo') { options.should be(Buildr.options) }
605
+ end
606
+ end
607
+
608
+ describe Buildr::Options, 'proxy.exclude' do
609
+ before do
610
+ options.proxy.http = 'http://myproxy:8080'
611
+ options.proxy.exclude.clear
612
+ @domain = 'domain'
613
+ @host = "host.#{@domain}"
614
+ @uri = URI("http://#{@host}")
615
+ @no_proxy_args = [@host, 80]
616
+ @proxy_args = @no_proxy_args + ['myproxy', 8080, nil, nil]
617
+ @http = double('http')
618
+ @http.stub(:request).and_return(Net::HTTPNotModified.new(nil, nil, nil))
619
+ end
620
+
621
+ it 'should be an array' do
622
+ options.proxy.exclude.should be_empty
623
+ options.proxy.exclude = @domain
624
+ options.proxy.exclude.should include(@domain)
625
+ end
626
+
627
+ it 'should support adding to array' do
628
+ options.proxy.exclude << @domain
629
+ options.proxy.exclude.should include(@domain)
630
+ end
631
+
632
+ it 'should support resetting array' do
633
+ options.proxy.exclude = @domain
634
+ options.proxy.exclude = nil
635
+ options.proxy.exclude.should be_empty
636
+ end
637
+
638
+ it 'should use proxy when not excluded' do
639
+ Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
640
+ @uri.read :proxy=>options.proxy
641
+ end
642
+
643
+ it 'should use proxy unless excluded' do
644
+ options.proxy.exclude = "not.#{@domain}"
645
+ Net::HTTP.should_receive(:new).with(*@proxy_args).and_return(@http)
646
+ @uri.read :proxy=>options.proxy
647
+ end
648
+
649
+ it 'should not use proxy if excluded' do
650
+ options.proxy.exclude = @host
651
+ Net::HTTP.should_receive(:new).with(*@no_proxy_args).and_return(@http)
652
+ @uri.read :proxy=>options.proxy
653
+ end
654
+
655
+ it 'should support multiple host names' do
656
+ options.proxy.exclude = %w[optimus prime]
657
+ Net::HTTP.should_receive(:new).with('optimus', 80).and_return(@http)
658
+ URI('http://optimus').read :proxy=>options.proxy
659
+ Net::HTTP.should_receive(:new).with('prime', 80).and_return(@http)
660
+ URI('http://prime').read :proxy=>options.proxy
661
+ Net::HTTP.should_receive(:new).with('bumblebee', *@proxy_args[1..-1]).and_return(@http)
662
+ URI('http://bumblebee').read :proxy=>options.proxy
663
+ end
664
+
665
+ it 'should support glob pattern on host name' do
666
+ options.proxy.exclude = "*.#{@domain}"
667
+ Net::HTTP.should_receive(:new).with(*@no_proxy_args).and_return(@http)
668
+ @uri.read :proxy=>options.proxy
669
+ end
670
+ end