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,984 @@
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 'buildr/packaging/version_requirement'
18
+
19
+
20
+ module Buildr
21
+
22
+ # An ArtifactNamespace is a hierarchical dictionary used to manage ArtifactRequirements.
23
+ # It can be used to have different artifact versions per project
24
+ # or to allow users to select a version for addons or modules.
25
+ #
26
+ # Namespaces are opened using the Buildr.artifact_ns method, most important methods are:
27
+ # [need] Used to create a requirement on the namespace.
28
+ # [use] Set the artifact version to use for a requirement.
29
+ # [values_at] Reference requirements by name.
30
+ # [each] Return each ArtifactRequirement in the namespace.
31
+ # The method_missing method for instances provides some syntactic sugar to these.
32
+ # See the following examples, and the methods for ArtifactRequirement.
33
+ #
34
+ # = Avoiding constant pollution on buildfile
35
+ #
36
+ # Each project has its own ArtifactNamespace inheriting the one from the
37
+ # parent project up to the root namespace.
38
+ #
39
+ # Consider the following snippet, as project grows, each subproject
40
+ # may need different artifact combinations and/or versions. Assigning
41
+ # artifact specifications to constants can make it painful to maintain
42
+ # their references even if using structs/hashes.
43
+ #
44
+ # -- buildfile --
45
+ # SPRING = 'org.springframework:spring:jar:2.5'
46
+ # SPRING_OLD = 'org.springframework:spring:jar:1.0'
47
+ # LOGGING = ['comons-logging:commons-logging:jar:1.1.1',
48
+ # 'log4j:log4j:jar:1.2.15']
49
+ # WL_LOGGING = artifact('bea:wlcommons-logging:jar:8.1').from('path/to/wlcommons-logging.jar')
50
+ # LOGGING_WEBLOGIC = ['comons-logging:commons-logging:jar:1.1.1',
51
+ # WL_LOGGING]
52
+ # COMMONS = struct :collections => 'commons-collection:commons-collection:jar:3.1',
53
+ # :net => 'commons-net:commons-net:jar:1.4.0'
54
+ #
55
+ # define 'example1' do
56
+ # define 'one' do
57
+ # compile.with SPRING, LOGGING_WEBLOGIC, COMMONS
58
+ # end
59
+ # define 'two' do
60
+ # compile.with SPRING_OLD, LOGGING, COMMONS
61
+ # end
62
+ # define 'three' do
63
+ # compile.with "commons-collections:commons-collections:jar:2.2"
64
+ # end
65
+ # end
66
+ #
67
+ #
68
+ # With ArtifactNamespace you can do some more advanced stuff, the following
69
+ # annotated snipped could still be reduced if default artifact definitions were
70
+ # loaded from yaml file (see section below and ArtifactNamespace.load).
71
+ #
72
+ # -- buildfile --
73
+ # artifact_ns do |ns| # the current namespace (root if called outside a project)
74
+ # # default artifacts
75
+ # ns.spring = 'org.springframework:spring:jar:2.5'
76
+ # # default logger is log4j
77
+ # ns.logger = 'log4j:log4j:jar:1.2.15'
78
+ #
79
+ # # create a sub namespace by calling the #ns method,
80
+ # # artifacts defined on the sub-namespace can be referenced by
81
+ # # name :commons_net or by calling commons.net
82
+ # ns.ns :commons, :net => 'commons-net:commons-net:jar:1.4.0',
83
+ # :logging => 'comons-logging:commons-logging:jar:1.1.1'
84
+ #
85
+ #
86
+ # # When a child namespace asks for the :log artifact,
87
+ # # these artifacts will be searched starting from the :current namespace.
88
+ # ns.virtual :log, :logger, :commons_logging
89
+ # end
90
+ #
91
+ # artifact_ns('example2:one') do |ns| # namespace for the one subproject
92
+ # ns.logger = artifact('bea:wlcommons-logging:jar:8.1').from('path/to/wlcommons-logging.jar')
93
+ # end
94
+ # artifact_ns('example2:two') do |ns|
95
+ # ns.spring = '1.0' # for project two use an older spring version (just for an example)
96
+ # end
97
+ # artifact_ns('example2:three').commons_collections = 2.2'
98
+ # artifact_ns('example2:four') do |ns|
99
+ # ns.beanutils = 'commons-beanutils:commons-beanutils:jar:1.5' # just for this project
100
+ # ns.ns(:compilation).use :commons_logging, :beanutils, :spring # compile time dependencies
101
+ # ns.ns(:testing).use :log, :beanutils, 'cglib:cglib-nodep:jar:2.1.3' # run time dependencies
102
+ # end
103
+ #
104
+ # define 'example2' do
105
+ # define 'one' do
106
+ # compile.with :spring, :log, :commons # uses weblogic logging
107
+ # end
108
+ # define 'two' do
109
+ # compile.with :spring, :log, :commons # will take old spring
110
+ # end
111
+ # define 'three' do
112
+ # compile.with :commons_collections
113
+ # test.with artifact_ns('example2:two').spring # use spring from project two
114
+ # end
115
+ # define 'four' do
116
+ # compile.with artifact_ns.compilation
117
+ # test.with artifact_ns.testing
118
+ # end
119
+ # task(:down_them_all) do # again, just to fill this space with something ;)
120
+ # parent.projects.map(&method(:artifact_ns)).map(&:artifacts).map(&:invoke)
121
+ # end
122
+ # end
123
+ #
124
+ # = Loading from a yaml file (e. profiles.yaml)
125
+ #
126
+ # If your projects use lots of jars (after all we are using java ;) you may prefer
127
+ # to have constant artifact definitions on an external file.
128
+ # Doing so would allow an external tool (or future Buildr feature) to maintain
129
+ # an artifacts.yaml for you.
130
+ # An example usage is documented on the ArtifactNamespace.load method.
131
+ #
132
+ # = For addon/plugin writers & Customizing artifact versions
133
+ #
134
+ # Sometimes users would need to change the default artifact versions used by some
135
+ # module, for example, the XMLBeans compiler needs this, because of compatibility
136
+ # issues. Another example would be to select the groovy version to use on all our
137
+ # projects so that Buildr modules requiring groovy jars can use user prefered versions.
138
+ #
139
+ # To meet this goal, an ArtifactNamespace allows to specify ArtifactRequirement objects.
140
+ # In fact the only difference with the examples you have already seen is that requirements
141
+ # have an associated VersionRequirement, so that each time a user tries to select a version,
142
+ # buildr checks if it satisfies the requirements.
143
+ #
144
+ # Requirements are declared using the ArtifactNamespace#need method, but again,
145
+ # syntactic sugar is provided by ArtifactNamespace#method_missing.
146
+ #
147
+ # The following example is taken from the XMLBeans compiler module.
148
+ # And illustrates how addon authors should specify their requirements,
149
+ # provide default versions, and document the namespace for users to customize.
150
+ #
151
+ # module Buildr::XMLBeans
152
+ #
153
+ # # You need to document this constant, giving users some hints
154
+ # # about when are (maybe some of) these artifacts used. I mean,
155
+ # # some modules, add jars to the Buildr classpath when its file
156
+ # # is required, you would need to tell your users, so that they
157
+ # # can open the namespace and specify their defaults. Of course
158
+ # # when the requirements are defined, buildr checks if any compatible
159
+ # # version has been already defined, if so, uses it.
160
+ # #
161
+ # # Some things here have been changed to illustrate their meaning.
162
+ # REQUIRES = ArtifactNamespace.for(self).tap do |ns|
163
+ #
164
+ # # This jar requires a >2.0 version, default being 2.3.0
165
+ # ns.xmlbeans! 'org.apache.xmlbeans:xmlbeans:jar:2.3.0', '>2'
166
+ #
167
+ # # Users can customize with Buildr::XMLBeans::REQUIRES.stax_api = '1.2'
168
+ # # This is a non-flexible requirement, only satisfied by version 1.0.1
169
+ # ns.stax_api! 'stax:stax-api:jar:1.0.1'
170
+ #
171
+ # # This one is not part of XMLBeans, but is just another example
172
+ # # illustrating an `artifact requirement spec`.
173
+ #
174
+ # ns.need " some_name -> ar:ti:fact:3.2.5 -> ( >2 & <4)"
175
+ #
176
+ # # As you can see it's just an artifact spec, prefixed with
177
+ # # ' some_name -> ', this means users can use that name to
178
+ # # reference the requirement, also this string has a VersionRequirement
179
+ # # just after another ->.
180
+ # end
181
+ #
182
+ # # The REQUIRES constant is an ArtifactNamespace instance,
183
+ # # that means we can use it directly. Note that calling
184
+ # # Buildr.artifact_ns would lead to the currently executing context,
185
+ # # not the one for this module.
186
+ # def use
187
+ # # test if user specified his own version, if so, we could perform some
188
+ # # functionallity based on this.
189
+ # REQUIRES.some_name.selected? # => false
190
+ #
191
+ # REQUIRES.some_name.satisfied_by?('1.5') # => false
192
+ # puts REQUIRES.some_name.requirement # => ( >2 & <4 )
193
+ #
194
+ # REQUIRES.artifacts # get the Artifact tasks
195
+ # end
196
+ #
197
+ # end
198
+ #
199
+ # A more advanced example using ArtifactRequirement listeners is included
200
+ # in the artifact_namespace_spec.rb description for 'Extension using ArtifactNamespace'
201
+ # That's it for addon writers, now, users can select their prefered version with
202
+ # something like:
203
+ #
204
+ # require 'buildr/xmlbeans'
205
+ # Buildr::XMLBeans::REQUIRES.xmlbeans = '2.2.0'
206
+ #
207
+ # More advanced stuff, if users really need to select an xmlbeans version
208
+ # per project, they can do so letting :current (that is, the currently running
209
+ # namespace) be parent of the REQUIRES namespace:
210
+ #
211
+ # Buildr::XMLBeans::REQUIRES.parent = :current
212
+ #
213
+ # Now, provided that the compiler does not caches its artifacts, it will
214
+ # select the correct version. (See the first section for how to select per project
215
+ # artifacts).
216
+ #
217
+ #
218
+ class ArtifactNamespace
219
+ class << self
220
+ # Forget all namespaces, create a new ROOT
221
+ def clear
222
+ @instances = nil
223
+ remove_const(:ROOT) rescue nil
224
+ const_set(:ROOT, new('root'))
225
+ end
226
+
227
+ # Populate namespaces from a hash of hashes.
228
+ # The following example uses the profiles yaml to achieve this.
229
+ #
230
+ # -- profiles.yaml --
231
+ # development:
232
+ # artifacts:
233
+ # root: # root namespace
234
+ # spring: org.springframework:spring:jar:2.5
235
+ # groovy: org.codehaus.groovy:groovy:jar:1.5.4
236
+ # logging: # define a named group
237
+ # - log4j:log4j:jar:1.2.15
238
+ # - commons-logging:commons-logging:jar:1.1.1
239
+ #
240
+ # # open Buildr::XMLBeans namespace
241
+ # Buildr::XMLBeans:
242
+ # xmlbeans: 2.2
243
+ #
244
+ # # for subproject one:oldie
245
+ # one:oldie:
246
+ # spring: org.springframework:spring:jar:1.0
247
+ #
248
+ # -- buildfile --
249
+ # ArtifactNamespace.load(Buildr.settings.profile['artifacts'])
250
+ def load(namespaces = {})
251
+ namespaces.each_pair { |name, uses| instance(name).use(uses) }
252
+ end
253
+
254
+ # :call-seq:
255
+ # ArtifactNamespace.instance { |current_ns| ... } -> current_ns
256
+ # ArtifactNamespace.instance(name) { |ns| ... } -> ns
257
+ # ArtifactNamespace.instance(:current) { |current_ns| ... } -> current_ns
258
+ # ArtifactNamespace.instance(:root) { |root_ns| ... } -> root_ns
259
+ #
260
+ # Obtain an instance for the given name
261
+ def instance(name = nil)
262
+ case name
263
+ when :root, 'root' then return ROOT
264
+ when ArtifactNamespace then return name
265
+ when Array then name = name.join(':')
266
+ when Module, Project then name = name.name
267
+ when :current, 'current', nil then
268
+ task = Thread.current[:rake_chain]
269
+ task = task.instance_variable_get(:@value) if task
270
+ name = case task
271
+ when Project then task.name
272
+ when Rake::Task then task.scope.join(':')
273
+ when nil then Buildr.application.current_scope.join(':')
274
+ end
275
+ end
276
+ name = name.to_s
277
+ if name.size == 0
278
+ instance = ROOT
279
+ else
280
+ name = name.to_s
281
+ @instances ||= Hash.new { |h, k| h[k] = new(k) }
282
+ instance = @instances[name]
283
+ end
284
+ yield(instance) if block_given?
285
+ instance
286
+ end
287
+
288
+ alias_method :[], :instance
289
+ alias_method :for, :instance
290
+
291
+ # :call-seq:
292
+ # ArtifactNamespace.root { |ns| ... } -> ns
293
+ #
294
+ # Obtain the root namespace, returns the ROOT constant
295
+ def root
296
+ yield ROOT if block_given?
297
+ ROOT
298
+ end
299
+ end
300
+
301
+ module DClone #:nodoc:
302
+ def dclone
303
+ clone = self.clone
304
+ clone.instance_variables.each do |i|
305
+ value = clone.instance_variable_get(i)
306
+ value = value.dclone rescue
307
+ clone.instance_variable_set(i, value)
308
+ end
309
+ clone
310
+ end
311
+ end
312
+
313
+ class Registry < Hash #:nodoc:
314
+ include DClone
315
+
316
+ attr_accessor :parent
317
+ def alias(new_name, old_name)
318
+ new_name = new_name.to_sym
319
+ old_name = old_name.to_sym
320
+ if obj = get(old_name, true)
321
+ self[new_name] = obj
322
+ @aliases ||= []
323
+ group = @aliases.find { |a| a.include?(new_name) }
324
+ group.delete(new_name) if group
325
+ group = @aliases.find { |a| a.include?(old_name) }
326
+ @aliases << (group = [old_name]) unless group
327
+ group << new_name unless group.include?(new_name)
328
+ end
329
+ obj
330
+ end
331
+
332
+ def aliases(name)
333
+ return [] unless name
334
+ name = name.to_sym
335
+ ((@aliases ||= []).find { |a| a.include?(name) } || [name]).dup
336
+ end
337
+
338
+ def []=(key, value)
339
+ return unless key
340
+ super(key.to_sym, value)
341
+ end
342
+
343
+ def get(key, include_parent = nil)
344
+ [].tap { |a| aliases(key).select { |n| a[0] = self[n] } }.first ||
345
+ (include_parent && parent && parent.get(key, include_parent))
346
+ end
347
+
348
+ def keys(include_parent = nil)
349
+ (super() | (include_parent && parent && parent.keys(include_parent) || [])).uniq
350
+ end
351
+
352
+ def values(include_parent = nil)
353
+ (super() | (include_parent && parent && parent.values(include_parent) || [])).uniq
354
+ end
355
+
356
+ def key?(key, include_parent = nil)
357
+ return false unless key
358
+ super(key.to_sym) || (include_parent && parent && parent.key?(key, include_parent))
359
+ end
360
+
361
+ def delete(key, include_parent = nil)
362
+ aliases(key).map {|n| super(n) } && include_parent && parent && parent.delete(key, include_parent)
363
+ end
364
+ end
365
+
366
+ # An artifact requirement is an object that ActsAsArtifact and has
367
+ # an associated VersionRequirement. It also knows the name (some times equal to the
368
+ # artifact id) that is used to store it in an ArtifactNamespace.
369
+ class ArtifactRequirement
370
+ attr_accessor :version
371
+ attr_reader :name, :requirement
372
+
373
+ include DClone
374
+
375
+ # Create a requirement from an `artifact requirement spec`.
376
+ # This spec has three parts, separated by ->
377
+ #
378
+ # some_name -> ar:ti:fact:3.2.5 -> ( >2 & <4)
379
+ #
380
+ # As you can see it's just an artifact spec, prefixed with
381
+ # some_name ->
382
+ # the :some_name symbol becomes this object's name and
383
+ # is used to store it on an ArtifactNamespace.
384
+ #
385
+ # ar:ti:fact:3.2.5
386
+ #
387
+ # The second part is an artifact spec by itself, and specifies
388
+ # all remaining attributes, the version of this spec becomes
389
+ # the default version of this requirement.
390
+ #
391
+ # The last part consist of a VersionRequirement.
392
+ # -> ( >2 & <4)
393
+ #
394
+ # VersionRequirement supports RubyGem's comparision operators
395
+ # in adition to parens, logical and, logical or and negation.
396
+ # See the docs for VersionRequirement for more info on operators.
397
+ def initialize(spec)
398
+ self.class.send :include, ActsAsArtifact unless ActsAsArtifact === self
399
+ if ArtifactRequirement === spec
400
+ copy_attrs(spec)
401
+ else
402
+ spec = requirement_hash(spec)
403
+ apply_spec(spec[:spec])
404
+ self.name = spec[:name]
405
+ @requirement = spec[:requirement]
406
+ @version = @requirement.default if VersionRequirement.requirement?(@version)
407
+ end
408
+ end
409
+
410
+ # Copy attributes from other to this object
411
+ def copy_attrs(other)
412
+ (ActsAsArtifact::ARTIFACT_ATTRIBUTES + [:name, :requirement]).each do |attr|
413
+ value = other.instance_variable_get("@#{attr}")
414
+ value = value.dup if value && !value.kind_of?(Numeric) && !value.kind_of?(Symbol)
415
+ instance_variable_set("@#{attr}", value)
416
+ end
417
+ end
418
+
419
+ def name=(name)
420
+ @name = name.to_s
421
+ end
422
+
423
+ # Set a the requirement, this must be an string formatted for
424
+ # VersionRequirement#create to parse.
425
+ def requirement=(version_requirement)
426
+ @requirement = VersionRequirement.create(version_requirement.to_s)
427
+ end
428
+
429
+ # Return a hash consisting of :name, :spec, :requirement
430
+ def requirement_hash(spec = self)
431
+ result = {}
432
+ if String === spec
433
+ parts = spec.split(/\s*->\s*/, 3).map(&:strip)
434
+ case parts.size
435
+ when 1
436
+ result[:spec] = Artifact.to_hash(parts.first)
437
+ when 2
438
+ if /^\w+$/ === parts.first
439
+ result[:name] = parts.first
440
+ result[:spec] = Artifact.to_hash(parts.last)
441
+ else
442
+ result[:spec] = Artifact.to_hash(parts.first)
443
+ result[:requirement] = VersionRequirement.create(parts.last)
444
+ end
445
+ when 3
446
+ result[:name] = parts.first
447
+ result[:spec] = Artifact.to_hash(parts[1])
448
+ result[:requirement] = VersionRequirement.create(parts.last)
449
+ end
450
+ else
451
+ result[:spec] = Artifact.to_hash(spec)
452
+ end
453
+ result[:name] ||= result[:spec][:id].to_s.to_sym
454
+ result[:requirement] ||= VersionRequirement.create(result[:spec][:version])
455
+ result
456
+ end
457
+
458
+ # Test if this requirement is satisfied by an artifact spec.
459
+ def satisfied_by?(spec)
460
+ return false unless requirement
461
+ spec = Artifact.to_hash(spec)
462
+ hash = to_spec_hash
463
+ hash.delete(:version)
464
+ version = spec.delete(:version)
465
+ hash == spec && requirement.satisfied_by?(version)
466
+ end
467
+
468
+ # Has user selected a version for this requirement?
469
+ def selected?
470
+ @selected
471
+ end
472
+
473
+ def selected! #:nodoc:
474
+ @selected = true
475
+ @listeners.each { |l| l.call(self) } if @listeners
476
+ self
477
+ end
478
+
479
+ def add_listener(&callback)
480
+ (@listeners ||= []) << callback
481
+ end
482
+
483
+ # Return the Artifact object for the currently selected version
484
+ def artifact
485
+ ::Buildr.artifact(self)
486
+ end
487
+
488
+ # Format this requirement as an `artifact requirement spec`
489
+ def to_requirement_spec
490
+ result = to_spec
491
+ result = "#{name} -> #{result}" if name
492
+ result = "#{result} -> #{requirement}" if requirement
493
+ result
494
+ end
495
+
496
+ def to_s #:nodoc:
497
+ id ? to_requirement_spec : version
498
+ end
499
+
500
+ # Return an artifact spec without the version part.
501
+ def unversioned_spec
502
+ str = to_spec
503
+ return nil if str =~ /^:+/
504
+ ary = str.split(':')
505
+ ary = ary[0...-1] if ary.size > 3
506
+ ary.join(':')
507
+ end
508
+
509
+ class << self
510
+ # Return an artifact spec without the version part.
511
+ def unversioned_spec(spec)
512
+ str = spec.to_s
513
+ return nil if str =~ /^:+/
514
+ ary = str.split(':')
515
+ ary = ary[0...-1] if ary.size > 3
516
+ if ary.size > 2
517
+ ary.join(':')
518
+ else
519
+ new(spec).unversioned_spec
520
+ end
521
+ end
522
+ end
523
+ end
524
+
525
+ include DClone
526
+ include Enumerable
527
+ attr_reader :name
528
+
529
+ def initialize(name = nil) #:nodoc:
530
+ @name = name.to_s if name
531
+ end
532
+ clear
533
+
534
+ def root
535
+ yield ROOT if block_given?
536
+ ROOT
537
+ end
538
+
539
+ # ROOT namespace has no parent
540
+ def parent
541
+ if root?
542
+ nil
543
+ elsif @parent.kind_of?(ArtifactNamespace)
544
+ @parent
545
+ elsif @parent
546
+ ArtifactNamespace.instance(@parent)
547
+ elsif name
548
+ parent_name = name.gsub(/::?[^:]+$/, '')
549
+ parent_name == name ? root : ArtifactNamespace.instance(parent_name)
550
+ else
551
+ root
552
+ end
553
+ end
554
+
555
+ # Set the parent for the current namespace, except if it is ROOT
556
+ def parent=(other)
557
+ raise 'Cannot set parent of root namespace' if root?
558
+ @parent = other
559
+ @registry = nil
560
+ end
561
+
562
+ # Is this the ROOT namespace?
563
+ def root?
564
+ ROOT == self
565
+ end
566
+
567
+ # Create a named sub-namespace, sub-namespaces are themselves
568
+ # ArtifactNamespace instances but cannot be referenced by
569
+ # the Buildr.artifact_ns, ArtifactNamespace.instance methods.
570
+ # Reference needs to be through this object using the given +name+
571
+ #
572
+ # artifact_ns('foo').ns(:bar).need :thing => 'some:thing:jar:1.0'
573
+ # artifact_ns('foo').bar # => the sub-namespace 'foo.bar'
574
+ # artifact_ns('foo').bar.thing # => the some thing artifact
575
+ #
576
+ # See the top level ArtifactNamespace documentation for examples
577
+ def ns(name, *uses, &block)
578
+ name = name.to_sym
579
+ sub = registry[name]
580
+ if sub
581
+ raise TypeError.new("#{name} is not a sub namespace of #{self}") unless sub.kind_of?(ArtifactNamespace)
582
+ else
583
+ sub = ArtifactNamespace.new("#{self.name}.#{name}")
584
+ sub.parent = self
585
+ registry[name] = sub
586
+ end
587
+ sub.use(*uses)
588
+ yield sub if block_given?
589
+ sub
590
+ end
591
+
592
+ # Test if a sub-namespace by the given name exists
593
+ def ns?(name)
594
+ sub = registry[name.to_sym]
595
+ ArtifactNamespace === sub
596
+ end
597
+
598
+ # :call-seq:
599
+ # artifact_ns.need 'name -> org:foo:bar:jar:~>1.2.3 -> 1.2.5'
600
+ # artifact_ns.need :name => 'org.foo:bar:jar:1.0'
601
+ #
602
+ # Create a new ArtifactRequirement on this namespace.
603
+ # ArtifactNamespace#method_missing provides syntactic sugar for this.
604
+ def need(*specs)
605
+ named = specs.flatten.inject({}) do |seen, spec|
606
+ if Hash === spec && (spec.keys & ActsAsArtifact::ARTIFACT_ATTRIBUTES).empty?
607
+ spec.each_pair do |name, spec|
608
+ if Array === spec # a group
609
+ seen[name] ||= spec.map { |s| ArtifactRequirement.new(s) }
610
+ else
611
+ artifact = ArtifactRequirement.new(spec)
612
+ artifact.name = name
613
+ seen[artifact.name] ||= artifact
614
+ end
615
+ end
616
+ else
617
+ artifact = ArtifactRequirement.new(spec)
618
+ seen[artifact.name] ||= artifact
619
+ end
620
+ seen
621
+ end
622
+ named.each_pair do |name, artifact|
623
+ if Array === artifact # a group
624
+ artifact.each do |a|
625
+ unvers = a.unversioned_spec
626
+ previous = registry[unvers]
627
+ if previous && previous.selected? && a.satisfied_by?(previous)
628
+ a.version = previous.version
629
+ end
630
+ registry[unvers] = a
631
+ end
632
+ group(name, *(artifact.map { |a| a.unversioned_spec } + [{:namespace => self}]))
633
+ else
634
+ unvers = artifact.unversioned_spec
635
+ previous = registry.get(unvers, true)
636
+ if previous && previous.selected? && artifact.satisfied_by?(previous)
637
+ artifact.version = previous.version
638
+ artifact.selected!
639
+ end
640
+ registry[unvers] = artifact
641
+ registry.alias name, unvers unless name.to_s[/^\s*$/]
642
+ end
643
+ end
644
+ self
645
+ end
646
+
647
+ # :call-seq:
648
+ # artifact_ns.use 'name -> org:foo:bar:jar:1.2.3'
649
+ # artifact_ns.use :name => 'org:foo:bar:jar:1.2.3'
650
+ # artifact_ns.use :name => '2.5.6'
651
+ #
652
+ # First and second form are equivalent, the third is used when an
653
+ # ArtifactRequirement has been previously defined with :name, so it
654
+ # just selects the version.
655
+ #
656
+ # ArtifactNamespace#method_missing provides syntactic sugar for this.
657
+ def use(*specs)
658
+ named = specs.flatten.inject({}) do |seen, spec|
659
+ if Hash === spec && (spec.keys & ActsAsArtifact::ARTIFACT_ATTRIBUTES).empty?
660
+ spec.each_pair do |name, spec|
661
+ if ArtifactNamespace === spec # create as subnamespace
662
+ raise ArgumentError.new("Circular reference") if self == spec
663
+ registry[name.to_sym] = spec
664
+ elsif Numeric === spec || (String === spec && VersionRequirement.version?(spec))
665
+ artifact = ArtifactRequirement.allocate
666
+ artifact.name = name
667
+ artifact.version = spec.to_s
668
+ seen[artifact.name] ||= artifact
669
+ elsif Symbol === spec
670
+ self.alias name, spec
671
+ elsif Array === spec # a group
672
+ seen[name] ||= spec.map { |s| ArtifactRequirement.new(s) }
673
+ else
674
+ artifact = ArtifactRequirement.new(spec)
675
+ artifact.name = name
676
+ seen[artifact.name] ||= artifact
677
+ end
678
+ end
679
+ else
680
+ if Symbol === spec
681
+ artifact = get(spec).dclone
682
+ else
683
+ artifact = ArtifactRequirement.new(spec)
684
+ end
685
+ seen[artifact.name] ||= artifact
686
+ end
687
+ seen
688
+ end
689
+ named.each_pair do |name, artifact|
690
+ is_group = Array === artifact
691
+ artifact = [artifact].flatten.map do |artifact|
692
+ unvers = artifact.unversioned_spec
693
+ previous = get(unvers, false) || get(name, false)
694
+ if previous # have previous on current namespace
695
+ if previous.requirement # we must satisfy the requirement
696
+ unless unvers # we only have the version
697
+ satisfied = previous.requirement.satisfied_by?(artifact.version)
698
+ else
699
+ satisfied = previous.satisfied_by?(artifact)
700
+ end
701
+ raise "Unsatisfied dependency #{previous} " +
702
+ "not satisfied by #{artifact}" unless satisfied
703
+ previous.version = artifact.version # OK, set new version
704
+ artifact = previous # use the same object for aliases
705
+ else # not a requirement, set the new values
706
+ unless artifact.id == previous.id && name != previous.name
707
+ previous.copy_attrs(artifact)
708
+ artifact = previous
709
+ end
710
+ end
711
+ else
712
+ if unvers.nil? && # we only have the version
713
+ (previous = get(unvers, true, false, false))
714
+ version = artifact.version
715
+ artifact.copy_attrs(previous)
716
+ artifact.version = version
717
+ end
718
+ artifact.requirement = nil
719
+ end
720
+ artifact.selected!
721
+ end
722
+ artifact = artifact.first unless is_group
723
+ if is_group
724
+ names = artifact.map do |art|
725
+ unv = art.unversioned_spec
726
+ registry[unv] = art
727
+ unv
728
+ end
729
+ group(name, *(names + [{:namespace => self}]))
730
+ elsif artifact.id
731
+ unvers = artifact.unversioned_spec
732
+ registry[name] = artifact
733
+ registry.alias unvers, name
734
+ else
735
+ registry[name] = artifact
736
+ end
737
+ end
738
+ self
739
+ end
740
+
741
+ # Like Hash#fetch
742
+ def fetch(name, default = nil, &block)
743
+ block ||= proc { raise IndexError.new("No artifact found by name #{name.inspect} in namespace #{self}") }
744
+ real_name = name.to_s[/^[\w\-\.]+$/] ? name : ArtifactRequirement.unversioned_spec(name)
745
+ get(real_name.to_sym) || default || block.call(name)
746
+ end
747
+
748
+ # :call-seq:
749
+ # artifact_ns[:name] -> ArtifactRequirement
750
+ # artifact_ns[:many, :names] -> [ArtifactRequirement]
751
+ def [](*names)
752
+ ary = values_at(*names)
753
+ names.size == 1 ? ary.first : ary
754
+ end
755
+
756
+ # :call-seq:
757
+ # artifact_ns[:name] = 'some:cool:jar:1.0.2'
758
+ # artifact_ns[:name] = '1.0.2'
759
+ #
760
+ # Just like the use method
761
+ def []=(*names)
762
+ values = names.pop
763
+ values = [values] unless Array === values
764
+ names.each_with_index do |name, i|
765
+ use name => (values[i] || values.last)
766
+ end
767
+ end
768
+
769
+ # yield each ArtifactRequirement
770
+ def each(&block)
771
+ values.each(&block)
772
+ end
773
+
774
+ # return Artifact objects for each requirement
775
+ def artifacts(*names)
776
+ (names.empty? && values || values_at(*names)).map(&:artifact)
777
+ end
778
+
779
+ # Return all requirements for this namespace
780
+ def values(include_parents = false, include_groups = true)
781
+ seen, dict = {}, registry
782
+ while dict
783
+ dict.each do |k, v|
784
+ v = v.call if v.respond_to?(:call)
785
+ v = v.values if v.kind_of?(ArtifactNamespace)
786
+ if Array === v && include_groups
787
+ v.compact.each { |v| seen[v.name] = v unless seen.key?(v.name) }
788
+ else
789
+ seen[v.name] = v unless seen.key?(v.name)
790
+ end
791
+ end
792
+ dict = include_parents ? dict.parent : nil
793
+ end
794
+ seen.values
795
+ end
796
+
797
+ # Return only the named requirements
798
+ def values_at(*names)
799
+ names.map do |name|
800
+ catch :artifact do
801
+ unless name.to_s[/^[\w\-\.]+$/]
802
+ unvers = ArtifactRequirement.unversioned_spec(name)
803
+ unless unvers.to_s == name.to_s
804
+ req = ArtifactRequirement.new(name)
805
+ reg = self
806
+ while reg
807
+ candidate = reg.send(:get, unvers, false, false, true)
808
+ throw :artifact, candidate if req.satisfied_by?(candidate)
809
+ reg = reg.parent
810
+ end
811
+ end
812
+ end
813
+ get(name.to_sym)
814
+ end
815
+ end
816
+ end
817
+
818
+ def key?(name, include_parents = false)
819
+ name = ArtifactRequirement.unversioned_spec(name) unless name.to_s[/^[\w\-\.]+$/]
820
+ registry.key?(name, include_parents)
821
+ end
822
+
823
+ def keys
824
+ values.map(&:name)
825
+ end
826
+
827
+ def delete(name, include_parents = false)
828
+ registry.delete(name, include_parents)
829
+ self
830
+ end
831
+
832
+ def clear
833
+ keys.each { |k| delete(k) }
834
+ end
835
+
836
+ # :call-seq:
837
+ # group :who, :me, :you
838
+ # group :them, :me, :you, :namespace => ns
839
+ #
840
+ # Create a virtual group on this namespace. When the namespace
841
+ # is asked for the +who+ artifact, it's value is an array made from
842
+ # the remaining names. These names are searched by default from the current
843
+ # namespace.
844
+ # Second form specified the starting namespace to search from.
845
+ def group(group_name, *members)
846
+ namespace = (Hash === members.last && members.pop[:namespace]) || :current
847
+ registry[group_name] = lambda do
848
+ artifacts = self.class[namespace].values_at(*members)
849
+ artifacts = artifacts.first if members.size == 1
850
+ artifacts
851
+ end
852
+ self
853
+ end
854
+
855
+ alias_method :virtual, :group
856
+
857
+ # Create an alias for a named requirement.
858
+ def alias(new_name, old_name)
859
+ registry.alias(new_name, old_name) or
860
+ raise NameError.new("Undefined artifact name: #{old_name}")
861
+ end
862
+
863
+ def to_s #:nodoc:
864
+ name.to_s
865
+ end
866
+
867
+ # :call-seq:
868
+ # artifact_ns.cool_aid!('cool:aid:jar:2.3.4', '~>2.3') -> artifact_requirement
869
+ # artifact_ns.cool_aid = '2.3.5'
870
+ # artifact_ns.cool_aid -> artifact_requirement
871
+ # artifact_ns.cool_aid? -> true | false
872
+ #
873
+ # First form creates an ArtifactRequirement on the namespace.
874
+ # It is equivalent to providing a requirement_spec to the #need method:
875
+ # artifact_ns.need "cool_aid -> cool:aid:jar:2.3.4 -> ~>2.3"
876
+ # the second argument is optional.
877
+ #
878
+ # Second form can be used to select an artifact version
879
+ # and is equivalent to:
880
+ # artifact_ns.use :cool_aid => '1.0'
881
+ #
882
+ # Third form obtains the named ArtifactRequirement, can be
883
+ # used to test if a named requirement has been defined.
884
+ # It is equivalent to:
885
+ # artifact_ns.fetch(:cool_aid) { nil }
886
+ #
887
+ # Last form tests if the ArtifactRequirement has been defined
888
+ # and a version has been selected for use.
889
+ # It is equivalent to:
890
+ #
891
+ # artifact_ns.has_cool_aid?
892
+ # artifact_ns.values_at(:cool_aid).flatten.all? { |a| a && a.selected? }
893
+ #
894
+ def method_missing(name, *args, &block)
895
+ case name.to_s
896
+ when /!$/ then
897
+ name = $`.intern
898
+ if args.size < 1 || args.size > 2
899
+ raise ArgumentError.new("wrong number of arguments for #{name}!(spec, version_requirement?)")
900
+ end
901
+ need name => args.first
902
+ get(name).tap { |r| r.requirement = args.last if args.size == 2 }
903
+ when /=$/ then use $` => args.first
904
+ when /\?$/ then
905
+ name = $`.gsub(/^(has|have)_/, '').intern
906
+ [get(name)].flatten.all? { |a| a && a.selected? }
907
+ else
908
+ if block || args.size > 0
909
+ raise ArgumentError.new("wrong number of arguments #{args.size} for 0 or block given")
910
+ end
911
+ get(name)
912
+ end
913
+ end
914
+
915
+ # Return an anonymous module
916
+ # # first create a requirement
917
+ # artifact_ns.cool_aid! 'cool:aid:jar:>=1.0'
918
+ #
919
+ # # extend an object as a cool_aid delegator
920
+ # jars = Object.new.extend(artifact_ns.accessor(:cool_aid))
921
+ # jars.cool_aid = '2.0'
922
+ #
923
+ # artifact_ns.cool_aid.version # -> '2.0'
924
+ def accessor(*names)
925
+ ns = self
926
+ Module.new do
927
+ names.each do |name|
928
+ define_method("#{name}") { ns.send("#{name}") }
929
+ define_method("#{name}?") { ns.send("#{name}?") }
930
+ define_method("#{name}=") { |vers| ns.send("#{name}=", vers) }
931
+ end
932
+ end
933
+ end
934
+
935
+ private
936
+ def get(name, include_parents = true, include_subs = true, include_self = true) #:nodoc:
937
+ if include_subs && name.to_s[/_/] # try sub namespaces first
938
+ sub, parts = self, name.to_s.split('_')
939
+ sub_name = parts.shift.to_sym
940
+ until sub != self || parts.empty?
941
+ if registry[sub_name].kind_of?(ArtifactNamespace)
942
+ sub = registry[sub_name]
943
+ artifact = sub[parts.join('_')]
944
+ else
945
+ sub_name = [sub_name, parts.shift].join('_').to_sym
946
+ end
947
+ end
948
+ end
949
+ unless artifact
950
+ if include_self
951
+ artifact = registry.get(name, include_parents)
952
+ elsif include_parents && registry.parent
953
+ artifact = registry.parent.get(name, true)
954
+ end
955
+ end
956
+ artifact = artifact.call if artifact.respond_to?(:call)
957
+ artifact
958
+ end
959
+
960
+ def registry
961
+ @registry ||= Registry.new.tap do |m|
962
+ m.parent = parent.send(:registry) unless root?
963
+ end
964
+ end
965
+
966
+ end # ArtifactNamespace
967
+
968
+ # :call-seq:
969
+ # project.artifact_ns -> ArtifactNamespace
970
+ # Buildr.artifact_ns(name) -> ArtifactNamespace
971
+ # Buildr.artifact_ns -> ArtifactNamespace for the currently running Project
972
+ #
973
+ # Open an ArtifactNamespace.
974
+ # If a block is provided, the namespace is yielded to it.
975
+ #
976
+ # See also ArtifactNamespace.instance
977
+ def artifact_ns(name = nil, &block)
978
+ name = self if name.nil? && self.kind_of?(Project)
979
+ ArtifactNamespace.instance(name, &block)
980
+ end
981
+
982
+ end
983
+
984
+