mguymon-buildr 1.4.5-java

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 (220) hide show
  1. data/CHANGELOG +1291 -0
  2. data/LICENSE +176 -0
  3. data/NOTICE +26 -0
  4. data/README.rdoc +134 -0
  5. data/Rakefile +44 -0
  6. data/_buildr +35 -0
  7. data/_jbuildr +35 -0
  8. data/addon/buildr/antlr.rb +65 -0
  9. data/addon/buildr/bnd.rb +147 -0
  10. data/addon/buildr/cobertura.rb +22 -0
  11. data/addon/buildr/drb.rb +281 -0
  12. data/addon/buildr/emma.rb +22 -0
  13. data/addon/buildr/hibernate.rb +149 -0
  14. data/addon/buildr/javacc.rb +85 -0
  15. data/addon/buildr/jaxb_xjc.rb +72 -0
  16. data/addon/buildr/jdepend.rb +60 -0
  17. data/addon/buildr/jetty.rb +248 -0
  18. data/addon/buildr/jibx.rb +86 -0
  19. data/addon/buildr/nailgun.rb +221 -0
  20. data/addon/buildr/openjpa.rb +88 -0
  21. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  22. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  23. data/addon/buildr/org/apache/buildr/BuildrNail.java +41 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  25. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  26. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  27. data/addon/buildr/org/apache/buildr/JettyWrapper.java +144 -0
  28. data/addon/buildr/protobuf.rb +88 -0
  29. data/addon/buildr/xmlbeans.rb +93 -0
  30. data/bin/buildr +19 -0
  31. data/buildr.buildfile +58 -0
  32. data/buildr.gemspec +78 -0
  33. data/doc/_config.yml +1 -0
  34. data/doc/_layouts/default.html +90 -0
  35. data/doc/_layouts/preface.html +22 -0
  36. data/doc/artifacts.textile +217 -0
  37. data/doc/building.textile +276 -0
  38. data/doc/contributing.textile +268 -0
  39. data/doc/css/default.css +236 -0
  40. data/doc/css/print.css +101 -0
  41. data/doc/css/syntax.css +23 -0
  42. data/doc/download.textile +151 -0
  43. data/doc/extending.textile +212 -0
  44. data/doc/images/1442160941-frontcover.jpg +0 -0
  45. data/doc/images/asf-logo.gif +0 -0
  46. data/doc/images/asf-logo.png +0 -0
  47. data/doc/images/buildr-hires.png +0 -0
  48. data/doc/images/buildr.png +0 -0
  49. data/doc/images/favicon.png +0 -0
  50. data/doc/images/growl-icon.tiff +0 -0
  51. data/doc/images/note.png +0 -0
  52. data/doc/images/project-structure.png +0 -0
  53. data/doc/images/tip.png +0 -0
  54. data/doc/images/zbuildr.png +0 -0
  55. data/doc/images/zbuildr.tif +0 -0
  56. data/doc/index.textile +109 -0
  57. data/doc/installing.textile +284 -0
  58. data/doc/languages.textile +599 -0
  59. data/doc/mailing_lists.textile +29 -0
  60. data/doc/more_stuff.textile +845 -0
  61. data/doc/packaging.textile +618 -0
  62. data/doc/preface.textile +54 -0
  63. data/doc/projects.textile +276 -0
  64. data/doc/quick_start.textile +210 -0
  65. data/doc/releasing.textile +117 -0
  66. data/doc/scripts/buildr-git.rb +512 -0
  67. data/doc/scripts/gitflow.rb +296 -0
  68. data/doc/scripts/install-jruby.sh +44 -0
  69. data/doc/scripts/install-linux.sh +73 -0
  70. data/doc/scripts/install-osx.sh +52 -0
  71. data/doc/settings_profiles.textile +287 -0
  72. data/doc/testing.textile +247 -0
  73. data/etc/KEYS +189 -0
  74. data/lib/buildr.rb +44 -0
  75. data/lib/buildr/clojure.rb +34 -0
  76. data/lib/buildr/clojure/shell.rb +52 -0
  77. data/lib/buildr/core.rb +34 -0
  78. data/lib/buildr/core/application.rb +700 -0
  79. data/lib/buildr/core/build.rb +516 -0
  80. data/lib/buildr/core/cc.rb +166 -0
  81. data/lib/buildr/core/checks.rb +253 -0
  82. data/lib/buildr/core/common.rb +151 -0
  83. data/lib/buildr/core/compile.rb +622 -0
  84. data/lib/buildr/core/doc.rb +276 -0
  85. data/lib/buildr/core/environment.rb +129 -0
  86. data/lib/buildr/core/filter.rb +404 -0
  87. data/lib/buildr/core/generate.rb +197 -0
  88. data/lib/buildr/core/help.rb +119 -0
  89. data/lib/buildr/core/jrebel.rb +42 -0
  90. data/lib/buildr/core/linux.rb +30 -0
  91. data/lib/buildr/core/osx.rb +46 -0
  92. data/lib/buildr/core/progressbar.rb +161 -0
  93. data/lib/buildr/core/project.rb +975 -0
  94. data/lib/buildr/core/run.rb +43 -0
  95. data/lib/buildr/core/shell.rb +137 -0
  96. data/lib/buildr/core/test.rb +843 -0
  97. data/lib/buildr/core/transports.rb +575 -0
  98. data/lib/buildr/core/util.rb +537 -0
  99. data/lib/buildr/groovy.rb +20 -0
  100. data/lib/buildr/groovy/bdd.rb +106 -0
  101. data/lib/buildr/groovy/compiler.rb +153 -0
  102. data/lib/buildr/groovy/doc.rb +76 -0
  103. data/lib/buildr/groovy/shell.rb +57 -0
  104. data/lib/buildr/ide.rb +19 -0
  105. data/lib/buildr/ide/eclipse.rb +427 -0
  106. data/lib/buildr/ide/eclipse/java.rb +53 -0
  107. data/lib/buildr/ide/eclipse/plugin.rb +71 -0
  108. data/lib/buildr/ide/eclipse/scala.rb +68 -0
  109. data/lib/buildr/ide/idea.rb +576 -0
  110. data/lib/buildr/java.rb +25 -0
  111. data/lib/buildr/java/ant.rb +94 -0
  112. data/lib/buildr/java/bdd.rb +460 -0
  113. data/lib/buildr/java/cobertura.rb +297 -0
  114. data/lib/buildr/java/commands.rb +223 -0
  115. data/lib/buildr/java/compiler.rb +135 -0
  116. data/lib/buildr/java/deprecated.rb +141 -0
  117. data/lib/buildr/java/doc.rb +86 -0
  118. data/lib/buildr/java/ecj.rb +69 -0
  119. data/lib/buildr/java/emma.rb +244 -0
  120. data/lib/buildr/java/external.rb +73 -0
  121. data/lib/buildr/java/jruby.rb +122 -0
  122. data/lib/buildr/java/jtestr_result.rb +295 -0
  123. data/lib/buildr/java/jtestr_runner.rb.erb +116 -0
  124. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  125. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +142 -0
  126. data/lib/buildr/java/packaging.rb +734 -0
  127. data/lib/buildr/java/pom.rb +178 -0
  128. data/lib/buildr/java/rjb.rb +154 -0
  129. data/lib/buildr/java/test_result.rb +101 -0
  130. data/lib/buildr/java/tests.rb +362 -0
  131. data/lib/buildr/java/version_requirement.rb +172 -0
  132. data/lib/buildr/packaging.rb +25 -0
  133. data/lib/buildr/packaging/archive.rb +535 -0
  134. data/lib/buildr/packaging/artifact.rb +904 -0
  135. data/lib/buildr/packaging/artifact_namespace.rb +984 -0
  136. data/lib/buildr/packaging/artifact_search.rb +140 -0
  137. data/lib/buildr/packaging/gems.rb +105 -0
  138. data/lib/buildr/packaging/package.rb +249 -0
  139. data/lib/buildr/packaging/repository_array.rb +108 -0
  140. data/lib/buildr/packaging/tar.rb +189 -0
  141. data/lib/buildr/packaging/version_requirement.rb +192 -0
  142. data/lib/buildr/packaging/zip.rb +178 -0
  143. data/lib/buildr/packaging/ziptask.rb +356 -0
  144. data/lib/buildr/resources/buildr.icns +0 -0
  145. data/lib/buildr/resources/completed.png +0 -0
  146. data/lib/buildr/resources/failed.png +0 -0
  147. data/lib/buildr/resources/icons-license.txt +17 -0
  148. data/lib/buildr/run.rb +195 -0
  149. data/lib/buildr/scala.rb +26 -0
  150. data/lib/buildr/scala/bdd.rb +118 -0
  151. data/lib/buildr/scala/compiler.rb +242 -0
  152. data/lib/buildr/scala/doc.rb +142 -0
  153. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.class +0 -0
  154. data/lib/buildr/scala/org/apache/buildr/SpecsSingletonRunner.java +57 -0
  155. data/lib/buildr/scala/shell.rb +52 -0
  156. data/lib/buildr/scala/tests.rb +171 -0
  157. data/lib/buildr/shell.rb +185 -0
  158. data/lib/buildr/version.rb +18 -0
  159. data/rakelib/all-in-one.rake +113 -0
  160. data/rakelib/checks.rake +57 -0
  161. data/rakelib/doc.rake +137 -0
  162. data/rakelib/metrics.rake +39 -0
  163. data/rakelib/package.rake +73 -0
  164. data/rakelib/release.rake +160 -0
  165. data/rakelib/rspec.rake +91 -0
  166. data/rakelib/setup.rake +66 -0
  167. data/rakelib/stage.rake +220 -0
  168. data/spec/addon/bnd_spec.rb +330 -0
  169. data/spec/addon/drb_spec.rb +328 -0
  170. data/spec/addon/jaxb_xjc_spec.rb +125 -0
  171. data/spec/core/application_spec.rb +631 -0
  172. data/spec/core/build_spec.rb +837 -0
  173. data/spec/core/cc_spec.rb +224 -0
  174. data/spec/core/checks_spec.rb +519 -0
  175. data/spec/core/common_spec.rb +725 -0
  176. data/spec/core/compile_spec.rb +658 -0
  177. data/spec/core/doc_spec.rb +195 -0
  178. data/spec/core/extension_spec.rb +201 -0
  179. data/spec/core/generate_spec.rb +33 -0
  180. data/spec/core/project_spec.rb +772 -0
  181. data/spec/core/run_spec.rb +93 -0
  182. data/spec/core/shell_spec.rb +146 -0
  183. data/spec/core/test_spec.rb +1320 -0
  184. data/spec/core/transport_spec.rb +544 -0
  185. data/spec/core/util_spec.rb +141 -0
  186. data/spec/groovy/bdd_spec.rb +80 -0
  187. data/spec/groovy/compiler_spec.rb +251 -0
  188. data/spec/groovy/doc_spec.rb +65 -0
  189. data/spec/ide/eclipse_spec.rb +739 -0
  190. data/spec/ide/idea_spec.rb +1145 -0
  191. data/spec/java/ant_spec.rb +37 -0
  192. data/spec/java/bdd_spec.rb +374 -0
  193. data/spec/java/cobertura_spec.rb +112 -0
  194. data/spec/java/commands_spec.rb +93 -0
  195. data/spec/java/compiler_spec.rb +252 -0
  196. data/spec/java/doc_spec.rb +56 -0
  197. data/spec/java/ecj_spec.rb +115 -0
  198. data/spec/java/emma_spec.rb +121 -0
  199. data/spec/java/external_spec.rb +56 -0
  200. data/spec/java/java_spec.rb +132 -0
  201. data/spec/java/packaging_spec.rb +1266 -0
  202. data/spec/java/run_spec.rb +78 -0
  203. data/spec/java/test_coverage_helper.rb +257 -0
  204. data/spec/java/tests_spec.rb +497 -0
  205. data/spec/packaging/archive_spec.rb +775 -0
  206. data/spec/packaging/artifact_namespace_spec.rb +743 -0
  207. data/spec/packaging/artifact_spec.rb +1074 -0
  208. data/spec/packaging/packaging_helper.rb +63 -0
  209. data/spec/packaging/packaging_spec.rb +719 -0
  210. data/spec/packaging/repository_array_spec.rb +109 -0
  211. data/spec/sandbox.rb +165 -0
  212. data/spec/scala/bdd_spec.rb +124 -0
  213. data/spec/scala/compiler_spec.rb +289 -0
  214. data/spec/scala/doc_spec.rb +88 -0
  215. data/spec/scala/scala.rb +38 -0
  216. data/spec/scala/tests_spec.rb +283 -0
  217. data/spec/spec_helpers.rb +369 -0
  218. data/spec/version_requirement_spec.rb +143 -0
  219. data/spec/xpath_matchers.rb +121 -0
  220. metadata +600 -0
@@ -0,0 +1,1074 @@
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
+ @spec = { :group=>'com.example', :id=>'library', :type=>:jar, :version=>'2.0' }
22
+ @artifact = artifact(@spec)
23
+ @classified = artifact(@spec.merge(:classifier=>'all'))
24
+ @snapshot = artifact(@spec.merge({ :version=>'2.1-SNAPSHOT' }))
25
+ end
26
+
27
+
28
+ it 'should act as one' do
29
+ @artifact.should respond_to(:to_spec)
30
+ end
31
+
32
+ it 'should have an artifact identifier' do
33
+ @artifact.id.should eql('library')
34
+ end
35
+
36
+ it 'should have a group identifier' do
37
+ @artifact.group.should eql('com.example')
38
+ end
39
+
40
+ it 'should have a version number' do
41
+ @artifact.version.should eql('2.0')
42
+ end
43
+
44
+ it 'should know if it is a snapshot' do
45
+ @artifact.should_not be_snapshot
46
+ @classified.should_not be_snapshot
47
+ @snapshot.should be_snapshot
48
+ end
49
+
50
+ it 'should have a file type' do
51
+ @artifact.type.should eql(:jar)
52
+ end
53
+
54
+ it 'should understand classifier' do
55
+ @artifact.classifier.should be_nil
56
+ @classified.classifier.should eql('all')
57
+ end
58
+
59
+ it 'should return hash specification' do
60
+ @artifact.to_hash.should == @spec
61
+ @artifact.to_spec_hash.should == @spec
62
+ @classified.to_hash.should == @spec.merge(:classifier=>'all')
63
+ end
64
+
65
+ it 'should return string specification' do
66
+ @artifact.to_spec.should eql('com.example:library:jar:2.0')
67
+ @classified.to_spec.should eql('com.example:library:jar:all:2.0')
68
+ end
69
+
70
+ it 'should have associated POM artifact' do
71
+ @artifact.pom.to_hash.should == @artifact.to_hash.merge(:type=>:pom)
72
+ end
73
+
74
+ it 'should have one POM artifact for all classifiers' do
75
+ @classified.pom.to_hash.should == @classified.to_hash.merge(:type=>:pom).except(:classifier)
76
+ end
77
+
78
+ it 'should have associated sources artifact' do
79
+ @artifact.sources_artifact.to_hash.should == @artifact.to_hash.merge(:classifier=>'sources')
80
+ end
81
+
82
+ it 'should have associated javadoc artifact' do
83
+ @artifact.javadoc_artifact.to_hash.should == @artifact.to_hash.merge(:classifier=>'javadoc')
84
+ end
85
+
86
+ it 'should download file if file does not exist' do
87
+ lambda { @artifact.invoke }.should raise_error(Exception, /No remote repositories/)
88
+ lambda { @classified.invoke }.should raise_error(Exception, /No remote repositories/)
89
+ end
90
+
91
+ it 'should not download file if file exists' do
92
+ write repositories.locate(@artifact)
93
+ lambda { @artifact.invoke }.should_not raise_error
94
+ write repositories.locate(@classified)
95
+ lambda { @classified.invoke }.should_not raise_error
96
+ end
97
+
98
+ it 'should handle lack of POM gracefully' do
99
+ repositories.remote = 'http://example.com'
100
+ URI.should_receive(:download).twice { |uri, target, options| raise URI::NotFoundError if uri.to_s.ends_with('.pom') }
101
+ lambda { @artifact.invoke }.should_not raise_error
102
+ end
103
+
104
+ it 'should pass if POM provided' do
105
+ repositories.remote = 'http://example.com'
106
+ @artifact.pom.enhance { |task| write task.name, @artifact.pom_xml }
107
+ write repositories.locate(@artifact)
108
+ lambda { @artifact.invoke }.should_not raise_error
109
+ end
110
+
111
+ it 'should pass if POM not required' do
112
+ repositories.remote = 'http://example.com'
113
+ class << @artifact ; def pom() ; end ; end
114
+ write repositories.locate(@artifact)
115
+ lambda { @artifact.invoke }.should_not raise_error
116
+ end
117
+
118
+ it 'should not download file if dry-run' do
119
+ dryrun do
120
+ lambda { @artifact.invoke }.should_not raise_error
121
+ lambda { @classified.invoke }.should_not raise_error
122
+ end
123
+ end
124
+
125
+ it 'should resolve to path in local repository' do
126
+ @artifact.to_s.should == File.join(repositories.local, 'com/example/library/2.0/library-2.0.jar')
127
+ @classified.to_s.should == File.join(repositories.local, 'com/example/library/2.0/library-2.0-all.jar')
128
+ end
129
+
130
+ it 'should return a list of all registered artifact specifications' do
131
+ define('foo', :version=>'1.0') { package :jar }
132
+ Artifact.list.should include(@artifact.to_spec)
133
+ Artifact.list.should include(@classified.to_spec)
134
+ Artifact.list.should include('foo:foo:jar:1.0')
135
+ end
136
+
137
+ it 'should accept user-defined string content' do
138
+ a = artifact(@spec)
139
+ a.content 'foo'
140
+ install a
141
+ lambda { install.invoke }.should change { File.exist?(a.to_s) && File.exist?(repositories.locate(a)) }.to(true)
142
+ read(repositories.locate(a)).should eql('foo')
143
+ end
144
+ end
145
+
146
+
147
+ describe Repositories, 'local' do
148
+ it 'should default to .m2 path' do
149
+ # For convenience, sandbox actually sets the local repository to a temp directory
150
+ repositories.local = nil
151
+ repositories.local.should eql(File.expand_path('.m2/repository', ENV['HOME']))
152
+ end
153
+
154
+ it 'should be settable' do
155
+ repositories.local = '.m2/local'
156
+ repositories.local.should eql(File.expand_path('.m2/local'))
157
+ end
158
+
159
+ it 'should reset to default' do
160
+ repositories.local = '.m2/local'
161
+ repositories.local = nil
162
+ repositories.local.should eql(File.expand_path('~/.m2/repository'))
163
+ end
164
+
165
+ it 'should locate file from string specification' do
166
+ repositories.local = nil
167
+ repositories.locate('com.example:library:jar:2.0').should eql(
168
+ File.expand_path('~/.m2/repository/com/example/library/2.0/library-2.0.jar'))
169
+ end
170
+
171
+ it 'should locate file from hash specification' do
172
+ repositories.local = nil
173
+ repositories.locate(:group=>'com.example', :id=>'library', :version=>'2.0').should eql(
174
+ File.expand_path('~/.m2/repository/com/example/library/2.0/library-2.0.jar'))
175
+ end
176
+
177
+ it 'should load path from settings file' do
178
+ write 'home/.buildr/settings.yaml', <<-YAML
179
+ repositories:
180
+ local: my_repo
181
+ YAML
182
+ repositories.local.should eql(File.expand_path('my_repo'))
183
+ end
184
+
185
+ it 'should not override custom install methods defined when extending an object' do
186
+ class MyOwnInstallTask
187
+
188
+ attr_accessor :result
189
+
190
+ def install
191
+ result = true
192
+ end
193
+
194
+ end
195
+ task = MyOwnInstallTask.new
196
+ task.result = "maybe"
197
+ task.extend ActsAsArtifact
198
+ task.install
199
+ task.result.should be_true
200
+ end
201
+ end
202
+
203
+
204
+ describe Repositories, 'remote' do
205
+ before do
206
+ @repos = [ 'http://www.ibiblio.org/maven2', 'http://repo1.maven.org/maven2' ]
207
+ end
208
+
209
+ it 'should be empty initially' do
210
+ repositories.remote.should be_empty
211
+ end
212
+
213
+ it 'should be settable' do
214
+ repositories.remote = @repos.first
215
+ repositories.remote.should eql(RepositoryArray.new([@repos.first]))
216
+ end
217
+
218
+ it 'should be settable from array' do
219
+ repositories.remote = @repos
220
+ repositories.remote.should eql(RepositoryArray.new(@repos))
221
+ end
222
+
223
+ it 'should add and return repositories in order' do
224
+ @repos.each { |url| repositories.remote << url }
225
+ repositories.remote.should eql(@repos)
226
+ end
227
+
228
+ it 'should be used to download artifact' do
229
+ repositories.remote = 'http://example.com'
230
+ URI.should_receive(:download).twice.and_return { |uri, target, options| write target }
231
+ lambda { artifact('com.example:library:jar:2.0').invoke }.
232
+ should change { File.exist?(File.join(repositories.local, 'com/example/library/2.0/library-2.0.jar')) }.to(true)
233
+ end
234
+
235
+ it 'should be used to download artifact with auth' do
236
+ repositories.remote = { :url => 'http://example.com', :username => 'username', :password => 'password' }
237
+
238
+ URI.should_receive(:download).twice.with(uri(/com\/example\/library\/2.0\/library-2.0.(jar|pom)$/), anything(), repositories.remote.first ).and_return { |uri, target, options| write target }
239
+ lambda { artifact('com.example:library:jar:2.0').invoke }.
240
+ should change { File.exist?(File.join(repositories.local, 'com/example/library/2.0/library-2.0.jar')) }.to(true)
241
+ end
242
+
243
+ it 'should lookup in array order' do
244
+ repositories.remote = [ 'http://example.com', 'http://example.org' ]
245
+ order = ['com', 'org']
246
+ URI.should_receive(:download).any_number_of_times do |uri, target, options|
247
+ order.shift if order.first && uri.to_s[order.first]
248
+ fail URI::NotFoundError unless order.empty?
249
+ write target
250
+ end
251
+ lambda { artifact('com.example:library:jar:2.0').invoke }.should change { order.empty? }
252
+ end
253
+
254
+ it 'should fail if artifact not found' do
255
+ repositories.remote = 'http://example.com'
256
+ URI.should_receive(:download).once.ordered.and_return { fail URI::NotFoundError }
257
+ lambda { artifact('com.example:library:jar:2.0').invoke }.should raise_error(RuntimeError, /Failed to download/)
258
+ File.exist?(File.join(repositories.local, 'com/example/library/2.0/library-2.0.jar')).should be_false
259
+ end
260
+
261
+ it 'should support artifact classifier' do
262
+ repositories.remote = 'http://example.com'
263
+ URI.should_receive(:download).once.and_return { |uri, target, options| write target }
264
+ lambda { artifact('com.example:library:jar:all:2.0').invoke }.
265
+ should change { File.exist?(File.join(repositories.local, 'com/example/library/2.0/library-2.0-all.jar')) }.to(true)
266
+ end
267
+
268
+ it 'should deal well with repositories URL that lack the last slash' do
269
+ repositories.remote = 'http://example.com/base'
270
+ uri = nil
271
+ URI.should_receive(:download).twice.and_return { |_uri, args| uri = _uri }
272
+ artifact('group:id:jar:1.0').invoke
273
+ uri.to_s.should eql('http://example.com/base/group/id/1.0/id-1.0.pom')
274
+ end
275
+
276
+ it 'should deal well with repositories URL that have the last slash' do
277
+ repositories.remote = 'http://example.com/base/'
278
+ uri = nil
279
+ URI.should_receive(:download).twice.and_return { |_uri, args| uri = _uri }
280
+ artifact('group:id:jar:1.0').invoke
281
+ uri.to_s.should eql('http://example.com/base/group/id/1.0/id-1.0.pom')
282
+ end
283
+
284
+ it 'should resolve m2-style deployed snapshots' do
285
+ metadata = <<-XML
286
+ <?xml version='1.0' encoding='UTF-8'?>
287
+ <metadata>
288
+ <groupId>com.example</groupId>
289
+ <artifactId>library</artifactId>
290
+ <version>2.1-SNAPSHOT</version>
291
+ <versioning>
292
+ <snapshot>
293
+ <timestamp>20071012.190008</timestamp>
294
+ <buildNumber>8</buildNumber>
295
+ </snapshot>
296
+ <lastUpdated>20071012190008</lastUpdated>
297
+ </versioning>
298
+ </metadata>
299
+ XML
300
+ repositories.remote = 'http://example.com'
301
+ URI.should_receive(:download).twice.with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.(jar|pom)$/), anything(), anything()).
302
+ and_return { fail URI::NotFoundError }
303
+ URI.should_receive(:download).twice.with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
304
+ and_return { |uri, target, options| target.write(metadata) }
305
+ 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,}$/, anything()).
306
+ and_return { |uri, target, options| write target }
307
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.
308
+ should change { File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')) }.to(true)
309
+ end
310
+
311
+ it 'should fail resolving m2-style deployed snapshots if a timestamp is missing' do
312
+ metadata = <<-XML
313
+ <?xml version='1.0' encoding='UTF-8'?>
314
+ <metadata>
315
+ <groupId>com.example</groupId>
316
+ <artifactId>library</artifactId>
317
+ <version>2.1-SNAPSHOT</version>
318
+ <versioning>
319
+ <snapshot>
320
+ <buildNumber>8</buildNumber>
321
+ </snapshot>
322
+ <lastUpdated>20071012190008</lastUpdated>
323
+ </versioning>
324
+ </metadata>
325
+ XML
326
+ repositories.remote = 'http://example.com'
327
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.(jar|pom)$/), anything(), anything()).
328
+ and_return { fail URI::NotFoundError }
329
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
330
+ and_return { |uri, target, options| target.write(metadata) }
331
+ lambda {
332
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.should raise_error(RuntimeError, /Failed to download/)
333
+ }.should show_error "No timestamp provided for the snapshot com.example:library:jar:2.1-SNAPSHOT"
334
+ File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')).should be_false
335
+ end
336
+
337
+ it 'should fail resolving m2-style deployed snapshots if a build number is missing' do
338
+ metadata = <<-XML
339
+ <?xml version='1.0' encoding='UTF-8'?>
340
+ <metadata>
341
+ <groupId>com.example</groupId>
342
+ <artifactId>library</artifactId>
343
+ <version>2.1-SNAPSHOT</version>
344
+ <versioning>
345
+ <snapshot>
346
+ <timestamp>20071012.190008</timestamp>
347
+ </snapshot>
348
+ <lastUpdated>20071012190008</lastUpdated>
349
+ </versioning>
350
+ </metadata>
351
+ XML
352
+ repositories.remote = 'http://example.com'
353
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.(jar|pom)$/), anything(), anything()).
354
+ and_return { fail URI::NotFoundError }
355
+ URI.should_receive(:download).once.with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
356
+ and_return { |uri, target, options| target.write(metadata) }
357
+ lambda {
358
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.should raise_error(RuntimeError, /Failed to download/)
359
+ }.should show_error "No build number provided for the snapshot com.example:library:jar:2.1-SNAPSHOT"
360
+ File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')).should be_false
361
+ end
362
+
363
+ it 'should handle missing maven metadata by reporting the artifact unavailable' do
364
+ repositories.remote = 'http://example.com'
365
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.jar$/), anything(), anything()).
366
+ and_return { fail URI::NotFoundError }
367
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
368
+ and_return { fail URI::NotFoundError }
369
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.should raise_error(RuntimeError, /Failed to download/)
370
+ File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')).should be_false
371
+ end
372
+
373
+ it 'should handle missing m2 snapshots by reporting the artifact unavailable' do
374
+ metadata = <<-XML
375
+ <?xml version='1.0' encoding='UTF-8'?>
376
+ <metadata>
377
+ <groupId>com.example</groupId>
378
+ <artifactId>library</artifactId>
379
+ <version>2.1-SNAPSHOT</version>
380
+ <versioning>
381
+ <snapshot>
382
+ <timestamp>20071012.190008</timestamp>
383
+ <buildNumber>8</buildNumber>
384
+ </snapshot>
385
+ <lastUpdated>20071012190008</lastUpdated>
386
+ </versioning>
387
+ </metadata>
388
+ XML
389
+ repositories.remote = 'http://example.com'
390
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/library-2.1-SNAPSHOT.jar$/), anything(),anything()).
391
+ and_return { fail URI::NotFoundError }
392
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/maven-metadata.xml$/), duck_type(:write)).
393
+ and_return { |uri, target, options| target.write(metadata) }
394
+ URI.should_receive(:download).with(uri(/2.1-SNAPSHOT\/library-2.1-20071012.190008-8.jar$/), anything(), anything()).
395
+ and_return { fail URI::NotFoundError }
396
+ lambda { artifact('com.example:library:jar:2.1-SNAPSHOT').invoke }.should raise_error(RuntimeError, /Failed to download/)
397
+ File.exist?(File.join(repositories.local, 'com/example/library/2.1-SNAPSHOT/library-2.1-SNAPSHOT.jar')).should be_false
398
+ end
399
+
400
+ it 'should load with all repositories specified in settings file' do
401
+ write 'home/.buildr/settings.yaml', <<-YAML
402
+ repositories:
403
+ remote:
404
+ - http://example.com
405
+ - http://example.org
406
+ YAML
407
+ repositories.remote.should include('http://example.com', 'http://example.org')
408
+ end
409
+
410
+ it 'should load with all repositories specified in build.yaml file' do
411
+ write 'build.yaml', <<-YAML
412
+ repositories:
413
+ remote:
414
+ - http://example.com
415
+ - http://example.org
416
+ YAML
417
+ repositories.remote.should include('http://example.com', 'http://example.org')
418
+ end
419
+
420
+ it 'should load with all repositories specified in settings and build.yaml files' do
421
+ write 'home/.buildr/settings.yaml', <<-YAML
422
+ repositories:
423
+ remote:
424
+ - http://example.com
425
+ YAML
426
+ write 'build.yaml', <<-YAML
427
+ repositories:
428
+ remote:
429
+ - http://example.org
430
+ YAML
431
+ repositories.remote.should include( {:url => URI.parse('http://example.com')}, {:url => URI.parse('http://example.org')} )
432
+ end
433
+ end
434
+
435
+
436
+ describe Repositories, 'release_to' do
437
+ it 'should accept URL as first argument' do
438
+ repositories.release_to = 'http://example.com'
439
+ repositories.release_to.should == { :url=>'http://example.com' }
440
+ end
441
+
442
+ it 'should accept hash with options' do
443
+ repositories.release_to = { :url=>'http://example.com', :username=>'john' }
444
+ repositories.release_to.should == { :url=>'http://example.com', :username=>'john' }
445
+ end
446
+
447
+ it 'should allow the hash to be manipulated' do
448
+ repositories.release_to = 'http://example.com'
449
+ repositories.release_to.should == { :url=>'http://example.com' }
450
+ repositories.release_to[:username] = 'john'
451
+ repositories.release_to.should == { :url=>'http://example.com', :username=>'john' }
452
+ end
453
+
454
+ it 'should load URL from settings file' do
455
+ write 'home/.buildr/settings.yaml', <<-YAML
456
+ repositories:
457
+ release_to: http://john:secret@example.com
458
+ YAML
459
+ repositories.release_to.should == { :url=>'http://john:secret@example.com' }
460
+ end
461
+
462
+ it 'should load URL from build settings file' do
463
+ write 'build.yaml', <<-YAML
464
+ repositories:
465
+ release_to: http://john:secret@example.com
466
+ YAML
467
+ repositories.release_to.should == { :url=>'http://john:secret@example.com' }
468
+ end
469
+
470
+ it 'should load URL, username and password from settings file' do
471
+ write 'home/.buildr/settings.yaml', <<-YAML
472
+ repositories:
473
+ release_to:
474
+ url: http://example.com
475
+ username: john
476
+ password: secret
477
+ YAML
478
+ repositories.release_to.should == { :url=>'http://example.com', :username=>'john', :password=>'secret' }
479
+ end
480
+ end
481
+
482
+
483
+ describe Buildr, '#artifact' do
484
+ before do
485
+ @spec = { :group=>'com.example', :id=>'library', :type=>'jar', :version=>'2.0' }
486
+ @snapshot_spec = 'group:id:jar:1.0-SNAPSHOT'
487
+ write @file = 'testartifact.jar'
488
+ end
489
+
490
+ it 'should accept hash specification' do
491
+ artifact(:group=>'com.example', :id=>'library', :type=>'jar', :version=>'2.0').should respond_to(:invoke)
492
+ end
493
+
494
+ it 'should reject partial hash specifier' do
495
+ lambda { artifact(@spec.merge(:group=>nil)) }.should raise_error
496
+ lambda { artifact(@spec.merge(:id=>nil)) }.should raise_error
497
+ lambda { artifact(@spec.merge(:version=>nil)) }.should raise_error
498
+ end
499
+
500
+ it 'should complain about invalid key' do
501
+ lambda { artifact(@spec.merge(:error=>true)) }.should raise_error(ArgumentError, /no such option/i)
502
+ end
503
+
504
+ it 'should use JAR type by default' do
505
+ artifact(@spec.merge(:type=>nil)).should respond_to(:invoke)
506
+ end
507
+
508
+ it 'should accept string specification' do
509
+ artifact('com.example:library:jar:2.0').should respond_to(:invoke)
510
+ end
511
+
512
+ it 'should reject partial string specifier' do
513
+ artifact('com.example:library::2.0')
514
+ lambda { artifact('com.example:library:jar') }.should raise_error
515
+ lambda { artifact('com.example:library:jar:') }.should raise_error
516
+ lambda { artifact('com.example:library::2.0') }.should_not raise_error
517
+ lambda { artifact('com.example::jar:2.0') }.should raise_error
518
+ lambda { artifact(':library:jar:2.0') }.should raise_error
519
+ end
520
+
521
+ it 'should create a task naming the artifact in the local repository' do
522
+ file = File.join(repositories.local, 'com', 'example', 'library', '2.0', 'library-2.0.jar')
523
+ Rake::Task.task_defined?(file).should be_false
524
+ artifact('com.example:library:jar:2.0').name.should eql(file)
525
+ end
526
+
527
+ it 'should use from method to install artifact from existing file' do
528
+ write 'test.jar'
529
+ artifact = artifact('group:id:jar:1.0').from('test.jar')
530
+ lambda { artifact.invoke }.should change { File.exist?(artifact.to_s) }.to(true)
531
+ end
532
+
533
+ it 'should use from method to install artifact from a file task' do
534
+ test_jar = file('test.jar')
535
+ test_jar.enhance do
536
+ #nothing...
537
+ end
538
+ write 'test.jar'
539
+ artifact = artifact('group:id:jar:1.0').from(test_jar)
540
+ lambda { artifact.invoke }.should change { File.exist?(artifact.to_s) }.to(true)
541
+ end
542
+
543
+ it 'should invoke the artifact associated file task if the file doesnt exist' do
544
+ test_jar = file('test.jar')
545
+ called = false
546
+ test_jar.enhance do
547
+ write 'test.jar'
548
+ called = true
549
+ end
550
+ artifact = artifact('group:id:jar:1.0').from(test_jar)
551
+ artifact.invoke
552
+ unless called
553
+ raise "The file task was not called."
554
+ end
555
+ end
556
+
557
+ it 'should not invoke the artifact associated file task if the file already exists' do
558
+ test_jar = file('test.jar')
559
+ test_jar.enhance do
560
+ raise 'the test.jar file is created again!'
561
+ end
562
+ write 'test.jar'
563
+ artifact = artifact('group:id:jar:1.0').from(test_jar)
564
+ artifact.invoke
565
+ end
566
+
567
+ it 'should reference artifacts defined on build.yaml by using ruby symbols' do
568
+ write 'build.yaml', <<-YAML
569
+ artifacts:
570
+ j2ee: geronimo-spec:geronimo-spec-j2ee:jar:1.4-rc4
571
+ YAML
572
+ Buildr.application.send(:load_artifact_ns)
573
+ artifact(:j2ee).to_s.pathmap('%f').should == 'geronimo-spec-j2ee-1.4-rc4.jar'
574
+ end
575
+
576
+ it 'should try to download snapshot artifact' do
577
+ run_with_repo
578
+ snapshot = artifact(@snapshot_spec)
579
+
580
+ URI.should_receive(:download).at_least(:twice).and_return { |uri, target, options| write target }
581
+ FileUtils.should_receive(:mv).at_least(:twice)
582
+ snapshot.invoke
583
+ end
584
+
585
+ it 'should not try to update snapshot in offline mode if it exists' do
586
+ run_with_repo
587
+ snapshot = artifact(@snapshot_spec)
588
+ write snapshot.to_s
589
+ Buildr.application.options.work_offline = true
590
+ URI.should_receive(:download).exactly(0).times
591
+ snapshot.invoke
592
+ end
593
+
594
+ it 'should download snapshot even in offline mode if it doesn''t exist' do
595
+ run_with_repo
596
+ snapshot = artifact(@snapshot_spec)
597
+ Buildr.application.options.work_offline = true
598
+ URI.should_receive(:download).exactly(2).times
599
+ snapshot.invoke
600
+ end
601
+
602
+ it 'should update snapshots if --update-snapshots' do
603
+ run_with_repo
604
+ snapshot = artifact(@snapshot_spec)
605
+ write snapshot.to_s
606
+ Buildr.application.options.update_snapshots = true
607
+
608
+ URI.should_receive(:download).at_least(:twice).and_return { |uri, target, options| write target }
609
+ FileUtils.should_receive(:mv).at_least(:twice)
610
+ snapshot.invoke
611
+ end
612
+
613
+ it 'should update snapshot if it''s older than 24 hours' do
614
+ run_with_repo
615
+ snapshot = artifact(@snapshot_spec)
616
+ write snapshot.to_s
617
+ time = Time.at((Time.now - (60 * 60 * 24) - 10 ).to_i)
618
+ File.utime(time, time, snapshot.to_s)
619
+ URI.should_receive(:download).at_least(:once).and_return { |uri, target, options| write target }
620
+ snapshot.invoke
621
+ end
622
+
623
+ def run_with_repo
624
+ repositories.remote = 'http://example.com'
625
+ end
626
+
627
+ end
628
+
629
+
630
+ describe Buildr, '#artifacts' do
631
+ it 'should return a list of artifacts from all its arguments' do
632
+ specs = [ 'saxon:saxon:jar:8.4', 'saxon:saxon-dom:jar:8.4', 'saxon:saxon-xpath:jar:8.4' ]
633
+ artifacts(*specs).should eql(specs.map { |spec| artifact(spec) })
634
+ end
635
+
636
+ it 'should accept nested arrays' do
637
+ specs = [ 'saxon:saxon:jar:8.4', 'saxon:saxon-dom:jar:8.4', 'saxon:saxon-xpath:jar:8.4' ]
638
+ artifacts([[specs[0]]], [[specs[1]], specs[2]]).should eql(specs.map { |spec| artifact(spec) })
639
+ end
640
+
641
+ it 'should accept struct' do
642
+ specs = struct(:main=>'saxon:saxon:jar:8.4', :dom=>'saxon:saxon-dom:jar:8.4', :xpath=>'saxon:saxon-xpath:jar:8.4')
643
+ artifacts(specs).should eql(specs.values.map { |spec| artifact(spec) })
644
+ end
645
+
646
+ it 'should ignore duplicates' do
647
+ artifacts('saxon:saxon:jar:8.4', 'saxon:saxon:jar:8.4').size.should be(1)
648
+ end
649
+
650
+ it 'should accept and return existing tasks' do
651
+ artifacts(task('foo'), task('bar')).should eql([task('foo'), task('bar')])
652
+ end
653
+
654
+ it 'should accept filenames and expand them' do
655
+ artifacts('test').map(&:to_s).should eql([File.expand_path('test')])
656
+ end
657
+
658
+ it 'should accept filenames and return filenames' do
659
+ artifacts('c:test').first.should be_kind_of(String)
660
+ end
661
+
662
+ it 'should accept project and return all its packaging tasks' do
663
+ define 'foobar', :group=>'group', :version=>'1.0' do
664
+ package :jar, :id=>'code'
665
+ package :war, :id=>'webapp'
666
+ end
667
+ foobar = project('foobar')
668
+ artifacts(foobar).should eql([
669
+ task(foobar.path_to('target/code-1.0.jar')),
670
+ task(foobar.path_to('target/webapp-1.0.war'))
671
+ ])
672
+ end
673
+
674
+ it 'should complain about an invalid specification' do
675
+ lambda { artifacts(5) }.should raise_error
676
+ lambda { artifacts('group:no:version:') }.should raise_error
677
+ end
678
+ end
679
+
680
+
681
+ describe Buildr, '#group' do
682
+ it 'should accept list of artifact identifiers' do
683
+ list = group('saxon', 'saxon-dom', 'saxon-xpath', :under=>'saxon', :version=>'8.4')
684
+ list.should include(artifact('saxon:saxon:jar:8.4'))
685
+ list.should include(artifact('saxon:saxon-dom:jar:8.4'))
686
+ list.should include(artifact('saxon:saxon-xpath:jar:8.4'))
687
+ list.size.should be(3)
688
+ end
689
+
690
+ it 'should accept array with artifact identifiers' do
691
+ list = group(%w{saxon saxon-dom saxon-xpath}, :under=>'saxon', :version=>'8.4')
692
+ list.should include(artifact('saxon:saxon:jar:8.4'))
693
+ list.should include(artifact('saxon:saxon-dom:jar:8.4'))
694
+ list.should include(artifact('saxon:saxon-xpath:jar:8.4'))
695
+ list.size.should be(3)
696
+ end
697
+
698
+ it 'should accept a type' do
699
+ list = group('struts-bean', 'struts-html', :under=>'struts', :type=>'tld', :version=>'1.1')
700
+ list.should include(artifact('struts:struts-bean:tld:1.1'))
701
+ list.should include(artifact('struts:struts-html:tld:1.1'))
702
+ list.size.should be(2)
703
+ end
704
+
705
+ it 'should accept a classifier' do
706
+ list = group('camel-core', :under=>'org.apache.camel', :version=>'2.2.0', :classifier=>'spring3')
707
+ list.should include(artifact('org.apache.camel:camel-core:jar:spring3:2.2.0'))
708
+ list.size.should be(1)
709
+ end
710
+
711
+ end
712
+
713
+ describe Buildr, '#install' do
714
+ before do
715
+ @spec = 'group:id:jar:1.0'
716
+ write @file = 'test.jar'
717
+ @snapshot_spec = 'group:id:jar:1.0-SNAPSHOT'
718
+ end
719
+
720
+ it 'should return the install task' do
721
+ install.should be(task('install'))
722
+ end
723
+
724
+ it 'should accept artifacts to install' do
725
+ install artifact(@spec)
726
+ lambda { install @file }.should raise_error(ArgumentError)
727
+ end
728
+
729
+ it 'should install artifact when install task is run' do
730
+ write @file
731
+ install artifact(@spec).from(@file)
732
+ lambda { install.invoke }.should change { File.exist?(artifact(@spec).to_s) }.to(true)
733
+ end
734
+
735
+ it 'should re-install artifact when "from" is newer' do
736
+ install artifact(@spec).from(@file)
737
+ write artifact(@spec).to_s # install a version of the artifact
738
+ old_mtime = File.mtime(artifact(@spec).to_s)
739
+ sleep 1; write @file # make sure the "from" file has newer modification time
740
+ lambda { install.invoke }.should change { modified?(old_mtime, @spec) }.to(true)
741
+ end
742
+
743
+ it 'should re-install snapshot artifact when "from" is newer' do
744
+ install artifact(@snapshot_spec).from(@file)
745
+ write artifact(@snapshot_spec).to_s # install a version of the artifact
746
+ old_mtime = File.mtime(artifact(@snapshot_spec).to_s)
747
+ sleep 1; write @file # make sure the "from" file has newer modification time
748
+ lambda { install.invoke }.should change { modified?(old_mtime, @snapshot_spec) }.to(true)
749
+ end
750
+
751
+ it 'should download snapshot to temporary location' do
752
+ repositories.remote = 'http://example.com'
753
+ snapshot = artifact(@snapshot_spec)
754
+ same_time = Time.new
755
+ download_file = "#{Dir.tmpdir}/#{File.basename(snapshot.name)}#{same_time.to_i}"
756
+
757
+ Time.should_receive(:new).twice.and_return(same_time)
758
+ URI.should_receive(:download).at_least(:twice).and_return { |uri, target, options| write target }
759
+ FileUtils.should_receive(:mv).at_least(:twice)
760
+ snapshot.invoke
761
+ end
762
+
763
+ it 'should install POM alongside artifact (if artifact has no classifier)' do
764
+ pom = artifact(@spec).pom
765
+ write @file
766
+ install artifact(@spec).from(@file)
767
+ lambda { install.invoke }.should change { File.exist?(repositories.locate(pom)) }.to(true)
768
+ end
769
+
770
+ it 'should not install POM alongside artifact if artifact has classifier' do
771
+ @spec = 'group:id:jar:all:1.0'
772
+ pom = artifact(@spec).pom
773
+ write @file
774
+ p method(:install)
775
+ install artifact(@spec).from(@file)
776
+ lambda { install.invoke }.should_not change { File.exist?(repositories.locate(pom)) }.to(true)
777
+ end
778
+
779
+ it 'should reinstall POM alongside artifact' do
780
+ pom = artifact(@spec).pom
781
+ write @file
782
+ write repositories.locate(pom)
783
+ sleep 1
784
+
785
+ install artifact(@spec).from(@file)
786
+ lambda { install.invoke }.should change { File.mtime(repositories.locate(pom)) }
787
+ end
788
+ end
789
+
790
+
791
+ describe Buildr, '#upload' do
792
+ before do
793
+ @spec = 'group:id:jar:1.0'
794
+ write @file = 'test.jar'
795
+ repositories.release_to = 'sftp://example.com/base'
796
+ end
797
+
798
+ it 'should return the upload task' do
799
+ upload.should be(task('upload'))
800
+ end
801
+
802
+ it 'should accept artifacts to upload' do
803
+ upload artifact(@spec)
804
+ lambda { upload @file }.should raise_error(ArgumentError)
805
+ end
806
+
807
+ it 'should upload artifact when upload task is run' do
808
+ write @file
809
+ upload artifact(@spec).from(@file)
810
+ URI.should_receive(:upload).once.
811
+ with(URI.parse('sftp://example.com/base/group/id/1.0/id-1.0.jar'), artifact(@spec).to_s, anything)
812
+ URI.should_receive(:upload).once.
813
+ with(URI.parse('sftp://example.com/base/group/id/1.0/id-1.0.pom'), artifact(@spec).pom.to_s, anything)
814
+ upload.invoke
815
+ end
816
+ end
817
+
818
+
819
+ describe ActsAsArtifact, '#upload' do
820
+ it 'should be used to upload artifact' do
821
+ artifact = artifact('com.example:library:jar:2.0')
822
+ # Prevent artifact from downloading anything.
823
+ write repositories.locate(artifact)
824
+ write repositories.locate(artifact.pom)
825
+ URI.should_receive(:upload).once.
826
+ with(URI.parse('sftp://example.com/base/com/example/library/2.0/library-2.0.pom'), artifact.pom.to_s, anything)
827
+ URI.should_receive(:upload).once.
828
+ with(URI.parse('sftp://example.com/base/com/example/library/2.0/library-2.0.jar'), artifact.to_s, anything)
829
+ verbose(false) { artifact.upload(:url=>'sftp://example.com/base') }
830
+ end
831
+
832
+ it 'should support artifact classifier and should not upload pom if artifact has classifier' do
833
+ artifact = artifact('com.example:library:jar:all:2.0')
834
+ # Prevent artifact from downloading anything.
835
+ write repositories.locate(artifact)
836
+ URI.should_receive(:upload).exactly(:once).
837
+ with(URI.parse('sftp://example.com/base/com/example/library/2.0/library-2.0-all.jar'), artifact.to_s, anything)
838
+ verbose(false) { artifact.upload(:url=>'sftp://example.com/base') }
839
+ end
840
+
841
+ it 'should complain without any repository configuration' do
842
+ artifact = artifact('com.example:library:jar:2.0')
843
+ # Prevent artifact from downloading anything.
844
+ write repositories.locate(artifact)
845
+ write repositories.locate(artifact.pom)
846
+ lambda { artifact.upload }.should raise_error(Exception, /where to upload/)
847
+ end
848
+
849
+ it 'should accept repositories.upload setting' do
850
+ artifact = artifact('com.example:library:jar:2.0')
851
+ # Prevent artifact from downloading anything.
852
+ write repositories.locate(artifact)
853
+ write repositories.locate(artifact.pom)
854
+ URI.should_receive(:upload).at_least(:once)
855
+ repositories.release_to = 'sftp://example.com/base'
856
+ artifact.upload
857
+ lambda { artifact.upload }.should_not raise_error
858
+ end
859
+
860
+ end
861
+
862
+
863
+ describe Rake::Task, ' artifacts' do
864
+ it 'should download all specified artifacts' do
865
+ artifact 'group:id:jar:1.0'
866
+ repositories.remote = 'http://example.com'
867
+ URI.should_receive(:download).twice.and_return { |uri, target, options| write target }
868
+ task('artifacts').invoke
869
+ end
870
+
871
+ it 'should fail if failed to download an artifact' do
872
+ artifact 'group:id:jar:1.0'
873
+ lambda { task('artifacts').invoke }.should raise_error(RuntimeError, /No remote repositories/)
874
+ end
875
+
876
+ it 'should succeed if artifact already exists' do
877
+ write repositories.locate(artifact('group:id:jar:1.0'))
878
+ suppress_stdout do
879
+ lambda { task('artifacts').invoke }.should_not raise_error
880
+ end
881
+ end
882
+ end
883
+
884
+
885
+ describe Rake::Task, ' artifacts:sources' do
886
+
887
+ before do
888
+ task('artifacts:sources').clear
889
+ repositories.remote = 'http://example.com'
890
+ end
891
+
892
+ it 'should download sources for all specified artifacts' do
893
+ artifact 'group:id:jar:1.0'
894
+ URI.should_receive(:download).any_number_of_times.and_return { |uri, target| write target }
895
+ lambda { task('artifacts:sources').invoke }.should change { File.exist?('home/.m2/repository/group/id/1.0/id-1.0-sources.jar') }.to(true)
896
+ end
897
+
898
+ it "should not try to download sources for the project's artifacts" do
899
+ define('foo', :version=>'1.0') { package(:jar) }
900
+ URI.should_not_receive(:download)
901
+ task('artifacts:sources').invoke
902
+ end
903
+
904
+ describe 'when the source artifact does not exist' do
905
+
906
+ before do
907
+ artifact 'group:id:jar:1.0'
908
+ URI.should_receive(:download).any_number_of_times.and_raise(URI::NotFoundError)
909
+ end
910
+
911
+ it 'should not fail' do
912
+ lambda { task('artifacts:sources').invoke }.should_not raise_error
913
+ end
914
+
915
+ it 'should inform the user' do
916
+ lambda { task('artifacts:sources').invoke }.should show_info('Failed to download group:id:jar:sources:1.0. Skipping it.')
917
+ end
918
+ end
919
+ end
920
+
921
+ describe Rake::Task, ' artifacts:javadoc' do
922
+
923
+ before do
924
+ task('artifacts:javadoc').clear
925
+ repositories.remote = 'http://example.com'
926
+ end
927
+
928
+ it 'should download javadoc for all specified artifacts' do
929
+ artifact 'group:id:jar:1.0'
930
+ URI.should_receive(:download).any_number_of_times.and_return { |uri, target| write target }
931
+ lambda { task('artifacts:javadoc').invoke }.should change { File.exist?('home/.m2/repository/group/id/1.0/id-1.0-javadoc.jar') }.to(true)
932
+ end
933
+
934
+ it "should not try to download javadoc for the project's artifacts" do
935
+ define('foo', :version=>'1.0') { package(:jar) }
936
+ URI.should_not_receive(:download)
937
+ task('artifacts:javadoc').invoke
938
+ end
939
+
940
+ describe 'when the javadoc artifact does not exist' do
941
+
942
+ before do
943
+ artifact 'group:id:jar:1.0'
944
+ URI.should_receive(:download).any_number_of_times.and_raise(URI::NotFoundError)
945
+ end
946
+
947
+ it 'should not fail' do
948
+ lambda { task('artifacts:javadoc').invoke }.should_not raise_error
949
+ end
950
+
951
+ it 'should inform the user' do
952
+ lambda { task('artifacts:javadoc').invoke }.should show_info('Failed to download group:id:jar:javadoc:1.0. Skipping it.')
953
+ end
954
+ end
955
+ end
956
+
957
+ describe Buildr, '#transitive' do
958
+ before do
959
+ repositories.remote = 'http://example.com'
960
+ @simple = [ 'saxon:saxon:jar:8.4', 'saxon:saxon-dom:jar:8.4', 'saxon:saxon-xpath:jar:8.4' ]
961
+ @simple.map { |spec| artifact(spec).pom }.each { |task| write task.name, task.pom_xml }
962
+ @provided = @simple.first
963
+ @complex = 'group:app:jar:1.0'
964
+ write artifact(@complex).pom.to_s, <<-XML
965
+ <project>
966
+ <artifactId>app</artifactId>
967
+ <groupId>group</groupId>
968
+ <dependencies>
969
+ <dependency>
970
+ <artifactId>saxon</artifactId>
971
+ <groupId>saxon</groupId>
972
+ <version>8.4</version>
973
+ <scope>provided</scope>
974
+ </dependency>
975
+ <dependency>
976
+ <artifactId>saxon-dom</artifactId>
977
+ <groupId>saxon</groupId>
978
+ <version>8.4</version>
979
+ <scope>runtime</scope>
980
+ </dependency>
981
+ <dependency>
982
+ <artifactId>saxon-xpath</artifactId>
983
+ <groupId>saxon</groupId>
984
+ <version>8.4</version>
985
+ </dependency>
986
+ <dependency>
987
+ <artifactId>saxon-nosuch</artifactId>
988
+ <groupId>saxon</groupId>
989
+ <version>8.4</version>
990
+ <scope>test</scope>
991
+ </dependency>
992
+ </dependencies>
993
+ </project>
994
+ XML
995
+ @transitive = 'master:app:war:1.0'
996
+ write artifact(@transitive).pom.to_s, <<-XML
997
+ <project>
998
+ <artifactId>app</artifactId>
999
+ <groupId>group</groupId>
1000
+ <dependencies>
1001
+ <dependency>
1002
+ <artifactId>app</artifactId>
1003
+ <groupId>group</groupId>
1004
+ <version>1.0</version>
1005
+ </dependency>
1006
+ </dependencies>
1007
+ </project>
1008
+ XML
1009
+ end
1010
+
1011
+ it 'should return a list of artifacts from all its arguments' do
1012
+ specs = [ 'saxon:saxon:jar:8.4', 'saxon:saxon-dom:jar:8.4', 'saxon:saxon-xpath:jar:8.4' ]
1013
+ transitive(*specs).should eql(specs.map { |spec| artifact(spec) })
1014
+ end
1015
+
1016
+ it 'should accept nested arrays' do
1017
+ specs = [ 'saxon:saxon:jar:8.4', 'saxon:saxon-dom:jar:8.4', 'saxon:saxon-xpath:jar:8.4' ]
1018
+ transitive([[specs[0]]], [[specs[1]], specs[2]]).should eql(specs.map { |spec| artifact(spec) })
1019
+ end
1020
+
1021
+ it 'should accept struct' do
1022
+ specs = struct(:main=>'saxon:saxon:jar:8.4', :dom=>'saxon:saxon-dom:jar:8.4', :xpath=>'saxon:saxon-xpath:jar:8.4')
1023
+ transitive(specs).should eql(specs.values.map { |spec| artifact(spec) })
1024
+ end
1025
+
1026
+ it 'should ignore duplicates' do
1027
+ transitive('saxon:saxon:jar:8.4', 'saxon:saxon:jar:8.4').size.should be(1)
1028
+ end
1029
+
1030
+ it 'should accept and return existing tasks' do
1031
+ transitive(task('foo'), task('bar')).should eql([task('foo'), task('bar')])
1032
+ end
1033
+
1034
+ it 'should accept filenames and expand them' do
1035
+ transitive('test').map(&:to_s).should eql([File.expand_path('test')])
1036
+ end
1037
+
1038
+ it 'should accept filenames and return file task' do
1039
+ transitive('c:test').first.should be_kind_of(Rake::FileTask)
1040
+ end
1041
+
1042
+ it 'should accept project and return all its packaging tasks' do
1043
+ define 'foobar', :group=>'group', :version=>'1.0' do
1044
+ package :jar, :id=>'code'
1045
+ package :war, :id=>'webapp'
1046
+ end
1047
+ foobar = project('foobar')
1048
+ transitive(foobar).should eql([
1049
+ task(foobar.path_to('target/code-1.0.jar')),
1050
+ task(foobar.path_to('target/webapp-1.0.war'))
1051
+ ])
1052
+ end
1053
+
1054
+ it 'should complain about an invalid specification' do
1055
+ lambda { transitive(5) }.should raise_error
1056
+ lambda { transitive('group:no:version:') }.should raise_error
1057
+ end
1058
+
1059
+ it 'should bring artifact and its dependencies' do
1060
+ transitive(@complex).should eql(artifacts(@complex, @simple))
1061
+ end
1062
+
1063
+ it 'should bring dependencies of POM without artifact itself' do
1064
+ transitive(@complex.sub(/jar/, 'pom')).should eql(artifacts(@simple))
1065
+ end
1066
+
1067
+ it 'should bring artifact and transitive depenencies' do
1068
+ transitive(@transitive).should eql(artifacts(@transitive, @complex, @simple - [@provided]))
1069
+ end
1070
+ end
1071
+
1072
+ def modified?(old_mtime, spec)
1073
+ File.exist?(artifact(spec).to_s) && old_mtime < File.mtime(artifact(spec).to_s)
1074
+ end