ittayd-buildr 1.3.4 → 1.3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. data/CHANGELOG +62 -9
  2. data/NOTICE +1 -1
  3. data/README.rdoc +9 -21
  4. data/Rakefile +20 -39
  5. data/_buildr +1 -0
  6. data/{spec/java/ant.rb → _jbuildr} +11 -15
  7. metadata +30 -210
  8. data/DISCLAIMER +0 -7
  9. data/addon/buildr/antlr.rb +0 -65
  10. data/addon/buildr/cobertura.rb +0 -22
  11. data/addon/buildr/drb.rb +0 -281
  12. data/addon/buildr/emma.rb +0 -22
  13. data/addon/buildr/hibernate.rb +0 -142
  14. data/addon/buildr/javacc.rb +0 -85
  15. data/addon/buildr/jdepend.rb +0 -60
  16. data/addon/buildr/jetty.rb +0 -248
  17. data/addon/buildr/jibx.rb +0 -86
  18. data/addon/buildr/nailgun.rb +0 -221
  19. data/addon/buildr/openjpa.rb +0 -90
  20. data/addon/buildr/org/apache/buildr/BuildrNail$Main.class +0 -0
  21. data/addon/buildr/org/apache/buildr/BuildrNail.class +0 -0
  22. data/addon/buildr/org/apache/buildr/BuildrNail.java +0 -41
  23. data/addon/buildr/org/apache/buildr/JettyWrapper$1.class +0 -0
  24. data/addon/buildr/org/apache/buildr/JettyWrapper$BuildrHandler.class +0 -0
  25. data/addon/buildr/org/apache/buildr/JettyWrapper.class +0 -0
  26. data/addon/buildr/org/apache/buildr/JettyWrapper.java +0 -144
  27. data/addon/buildr/path.rb +0 -136
  28. data/addon/buildr/xmlbeans.rb +0 -93
  29. data/buildr.buildfile +0 -53
  30. data/buildr.gemspec +0 -58
  31. data/doc/css/default.css +0 -228
  32. data/doc/css/print.css +0 -100
  33. data/doc/css/syntax.css +0 -52
  34. data/doc/images/apache-incubator-logo.png +0 -0
  35. data/doc/images/buildr-hires.png +0 -0
  36. data/doc/images/buildr.png +0 -0
  37. data/doc/images/favicon.png +0 -0
  38. data/doc/images/growl-icon.tiff +0 -0
  39. data/doc/images/note.png +0 -0
  40. data/doc/images/project-structure.png +0 -0
  41. data/doc/images/tip.png +0 -0
  42. data/doc/images/zbuildr.tif +0 -0
  43. data/doc/pages/artifacts.textile +0 -207
  44. data/doc/pages/building.textile +0 -240
  45. data/doc/pages/contributing.textile +0 -208
  46. data/doc/pages/download.textile +0 -62
  47. data/doc/pages/extending.textile +0 -175
  48. data/doc/pages/getting_started.textile +0 -273
  49. data/doc/pages/index.textile +0 -42
  50. data/doc/pages/languages.textile +0 -407
  51. data/doc/pages/mailing_lists.textile +0 -17
  52. data/doc/pages/more_stuff.textile +0 -314
  53. data/doc/pages/packaging.textile +0 -427
  54. data/doc/pages/projects.textile +0 -274
  55. data/doc/pages/recipes.textile +0 -103
  56. data/doc/pages/settings_profiles.textile +0 -274
  57. data/doc/pages/testing.textile +0 -212
  58. data/doc/pages/troubleshooting.textile +0 -103
  59. data/doc/pages/whats_new.textile +0 -323
  60. data/doc/print.haml +0 -51
  61. data/doc/print.toc.yaml +0 -29
  62. data/doc/scripts/buildr-git.rb +0 -412
  63. data/doc/scripts/install-jruby.sh +0 -44
  64. data/doc/scripts/install-linux.sh +0 -64
  65. data/doc/scripts/install-osx.sh +0 -52
  66. data/doc/site.haml +0 -56
  67. data/doc/site.toc.yaml +0 -47
  68. data/etc/KEYS +0 -151
  69. data/etc/git-svn-authors +0 -16
  70. data/lib/buildr.rb +0 -33
  71. data/lib/buildr/core.rb +0 -29
  72. data/lib/buildr/core/application.rb +0 -665
  73. data/lib/buildr/core/build.rb +0 -311
  74. data/lib/buildr/core/checks.rb +0 -254
  75. data/lib/buildr/core/common.rb +0 -150
  76. data/lib/buildr/core/compile.rb +0 -590
  77. data/lib/buildr/core/environment.rb +0 -117
  78. data/lib/buildr/core/filter.rb +0 -366
  79. data/lib/buildr/core/generate.rb +0 -195
  80. data/lib/buildr/core/help.rb +0 -119
  81. data/lib/buildr/core/osx.rb +0 -49
  82. data/lib/buildr/core/progressbar.rb +0 -156
  83. data/lib/buildr/core/project.rb +0 -923
  84. data/lib/buildr/core/test.rb +0 -715
  85. data/lib/buildr/core/transports.rb +0 -560
  86. data/lib/buildr/core/util.rb +0 -294
  87. data/lib/buildr/groovy.rb +0 -18
  88. data/lib/buildr/groovy/bdd.rb +0 -106
  89. data/lib/buildr/groovy/compiler.rb +0 -138
  90. data/lib/buildr/ide.rb +0 -19
  91. data/lib/buildr/ide/eclipse.rb +0 -222
  92. data/lib/buildr/ide/idea.ipr.template +0 -300
  93. data/lib/buildr/ide/idea.rb +0 -190
  94. data/lib/buildr/ide/idea7x.ipr.template +0 -290
  95. data/lib/buildr/ide/idea7x.rb +0 -212
  96. data/lib/buildr/java.rb +0 -23
  97. data/lib/buildr/java/ant.rb +0 -92
  98. data/lib/buildr/java/bdd.rb +0 -451
  99. data/lib/buildr/java/cobertura.rb +0 -236
  100. data/lib/buildr/java/commands.rb +0 -211
  101. data/lib/buildr/java/compiler.rb +0 -348
  102. data/lib/buildr/java/deprecated.rb +0 -141
  103. data/lib/buildr/java/emma.rb +0 -238
  104. data/lib/buildr/java/jruby.rb +0 -117
  105. data/lib/buildr/java/jtestr_runner.rb.erb +0 -116
  106. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.class +0 -0
  107. data/lib/buildr/java/org/apache/buildr/JavaTestFilter.java +0 -119
  108. data/lib/buildr/java/packaging.rb +0 -717
  109. data/lib/buildr/java/pom.rb +0 -174
  110. data/lib/buildr/java/rjb.rb +0 -155
  111. data/lib/buildr/java/test_result.rb +0 -307
  112. data/lib/buildr/java/tests.rb +0 -329
  113. data/lib/buildr/java/version_requirement.rb +0 -172
  114. data/lib/buildr/packaging.rb +0 -24
  115. data/lib/buildr/packaging/archive.rb +0 -488
  116. data/lib/buildr/packaging/artifact.rb +0 -759
  117. data/lib/buildr/packaging/artifact_namespace.rb +0 -972
  118. data/lib/buildr/packaging/artifact_search.rb +0 -140
  119. data/lib/buildr/packaging/gems.rb +0 -102
  120. data/lib/buildr/packaging/package.rb +0 -233
  121. data/lib/buildr/packaging/tar.rb +0 -186
  122. data/lib/buildr/packaging/version_requirement.rb +0 -172
  123. data/lib/buildr/packaging/zip.rb +0 -64
  124. data/lib/buildr/packaging/ziptask.rb +0 -313
  125. data/lib/buildr/resources/buildr.icns +0 -0
  126. data/lib/buildr/scala.rb +0 -19
  127. data/lib/buildr/scala/compiler.rb +0 -109
  128. data/lib/buildr/scala/tests.rb +0 -203
  129. data/rakelib/apache.rake +0 -191
  130. data/rakelib/changelog.rake +0 -57
  131. data/rakelib/doc.rake +0 -103
  132. data/rakelib/package.rake +0 -76
  133. data/rakelib/release.rake +0 -65
  134. data/rakelib/rspec.rake +0 -83
  135. data/rakelib/rubyforge.rake +0 -56
  136. data/rakelib/scm.rake +0 -49
  137. data/rakelib/setup.rake +0 -81
  138. data/rakelib/stage.rake +0 -48
  139. data/spec/addon/drb_spec.rb +0 -328
  140. data/spec/core/application_spec.rb +0 -419
  141. data/spec/core/build_spec.rb +0 -423
  142. data/spec/core/checks_spec.rb +0 -519
  143. data/spec/core/common_spec.rb +0 -670
  144. data/spec/core/compile_spec.rb +0 -582
  145. data/spec/core/generate_spec.rb +0 -33
  146. data/spec/core/project_spec.rb +0 -776
  147. data/spec/core/test_spec.rb +0 -1098
  148. data/spec/core/transport_spec.rb +0 -500
  149. data/spec/groovy/bdd_spec.rb +0 -80
  150. data/spec/groovy/compiler_spec.rb +0 -239
  151. data/spec/ide/eclipse_spec.rb +0 -311
  152. data/spec/java/bdd_spec.rb +0 -358
  153. data/spec/java/cobertura_spec.rb +0 -77
  154. data/spec/java/compiler_spec.rb +0 -446
  155. data/spec/java/emma_spec.rb +0 -120
  156. data/spec/java/java_spec.rb +0 -96
  157. data/spec/java/packaging_spec.rb +0 -1120
  158. data/spec/java/test_coverage_spec.rb +0 -255
  159. data/spec/java/tests_spec.rb +0 -471
  160. data/spec/packaging/archive_spec.rb +0 -503
  161. data/spec/packaging/artifact_namespace_spec.rb +0 -646
  162. data/spec/packaging/artifact_spec.rb +0 -795
  163. data/spec/packaging/packaging_helper.rb +0 -63
  164. data/spec/packaging/packaging_spec.rb +0 -589
  165. data/spec/sandbox.rb +0 -139
  166. data/spec/scala/compiler_spec.rb +0 -228
  167. data/spec/scala/tests_spec.rb +0 -215
  168. data/spec/spec_helpers.rb +0 -327
  169. data/spec/version_requirement_spec.rb +0 -123
@@ -1,972 +0,0 @@
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 polution 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 diferent artifact combinations and/or versions. Asigning
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 bellow 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 ArgumentRequirement objects.
140
- # In fact the only diference 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) if const_defined?(:ROOT)
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: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.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
- return ROOT if name.size == 0
278
- name = name.to_s
279
- @instances ||= Hash.new { |h, k| h[k] = new(k) }
280
- instance = @instances[name]
281
- yield(instance) if block_given?
282
- instance
283
- end
284
-
285
- alias_method :[], :instance
286
- alias_method :for, :instance
287
-
288
- # :call-seq:
289
- # ArtifactNamespace.root { |ns| ... } -> ns
290
- #
291
- # Obtain the root namespace, returns the ROOT constant
292
- def root
293
- yield ROOT if block_given?
294
- ROOT
295
- end
296
- end
297
-
298
- module DClone #:nodoc:
299
- def dclone
300
- clone = self.clone
301
- clone.instance_variables.each do |i|
302
- value = clone.instance_variable_get(i)
303
- value = value.dclone rescue
304
- clone.instance_variable_set(i, value)
305
- end
306
- clone
307
- end
308
- end
309
-
310
- class Registry < Hash #:nodoc:
311
- include DClone
312
-
313
- attr_accessor :parent
314
- def alias(new_name, old_name)
315
- new_name = new_name.to_sym
316
- old_name = old_name.to_sym
317
- if obj = get(old_name, true)
318
- self[new_name] = obj
319
- @aliases ||= []
320
- group = @aliases.find { |a| a.include?(new_name) }
321
- group.delete(new_name) if group
322
- group = @aliases.find { |a| a.include?(old_name) }
323
- @aliases << (group = [old_name]) unless group
324
- group << new_name unless group.include?(new_name)
325
- end
326
- obj
327
- end
328
-
329
- def aliases(name)
330
- return [] unless name
331
- name = name.to_sym
332
- ((@aliases ||= []).find { |a| a.include?(name) } || [name]).dup
333
- end
334
-
335
- def []=(key, value)
336
- return unless key
337
- super(key.to_sym, value)
338
- end
339
-
340
- def get(key, include_parent = nil)
341
- [].tap { |a| aliases(key).select { |n| a[0] = self[n] } }.first ||
342
- (include_parent && parent && parent.get(key, include_parent))
343
- end
344
-
345
- def keys(include_parent = nil)
346
- (super() | (include_parent && parent && parent.keys(include_parent) || [])).uniq
347
- end
348
-
349
- def values(include_parent = nil)
350
- (super() | (include_parent && parent && parent.values(include_parent) || [])).uniq
351
- end
352
-
353
- def key?(key, include_parent = nil)
354
- return false unless key
355
- super(key.to_sym) || (include_parent && parent && parent.key?(key, include_parent))
356
- end
357
-
358
- def delete(key, include_parent = nil)
359
- aliases(key).map {|n| super(n) } && include_parent && parent && parent.delete(key, include_parent)
360
- end
361
- end
362
-
363
- # An artifact requirement is an object that ActsAsArtifact and has
364
- # an associated VersionRequirement. It also knows the name (some times equal to the
365
- # artifact id) that is used to store it in an ArtifactNamespace.
366
- class ArtifactRequirement
367
- attr_accessor :version
368
- attr_reader :name, :requirement
369
-
370
- include DClone
371
-
372
- # Create a requirement from an `artifact requirement spec`.
373
- # This spec has three parts, separated by ->
374
- #
375
- # some_name -> ar:ti:fact:3.2.5 -> ( >2 & <4)
376
- #
377
- # As you can see it's just an artifact spec, prefixed with
378
- # some_name ->
379
- # the :some_name symbol becomes this object's name and
380
- # is used to store it on an ArtifactNamespace.
381
- #
382
- # ar:ti:fact:3.2.5
383
- #
384
- # The second part is an artifact spec by itself, and specifies
385
- # all remaining attributes, the version of this spec becomes
386
- # the default version of this requirement.
387
- #
388
- # The last part consist of a VersionRequirement.
389
- # -> ( >2 & <4)
390
- #
391
- # VersionRequirement supports RubyGem's comparision operators
392
- # in adition to parens, logical and, logical or and negation.
393
- # See the docs for VersionRequirement for more info on operators.
394
- def initialize(spec)
395
- self.class.send :include, ActsAsArtifact unless ActsAsArtifact === self
396
- if ArtifactRequirement === spec
397
- copy_attrs(spec)
398
- else
399
- spec = requirement_hash(spec)
400
- apply_spec(spec[:spec])
401
- self.name = spec[:name]
402
- @requirement = spec[:requirement]
403
- @version = @requirement.default if VersionRequirement.requirement?(@version)
404
- end
405
- end
406
-
407
- # Copy attributes from other to this object
408
- def copy_attrs(other)
409
- (ActsAsArtifact::ARTIFACT_ATTRIBUTES + [:name, :requirement]).each do |attr|
410
- value = other.instance_variable_get("@#{attr}")
411
- value = value.dup if value && !value.kind_of?(Numeric) && !value.kind_of?(Symbol)
412
- instance_variable_set("@#{attr}", value)
413
- end
414
- end
415
-
416
- def name=(name)
417
- @name = name.to_s
418
- end
419
-
420
- # Set a the requirement, this must be an string formatted for
421
- # VersionRequirement#create to parse.
422
- def requirement=(version_requirement)
423
- @requirement = VersionRequirement.create(version_requirement.to_s)
424
- end
425
-
426
- # Return a hash consisting of :name, :spec, :requirement
427
- def requirement_hash(spec = self)
428
- result = {}
429
- if String === spec
430
- parts = spec.split(/\s*->\s*/, 3).map(&:strip)
431
- case parts.size
432
- when 1
433
- result[:spec] = Artifact.to_hash(parts.first)
434
- when 2
435
- if /^\w+$/ === parts.first
436
- result[:name] = parts.first
437
- result[:spec] = Artifact.to_hash(parts.last)
438
- else
439
- result[:spec] = Artifact.to_hash(parts.first)
440
- result[:requirement] = VersionRequirement.create(parts.last)
441
- end
442
- when 3
443
- result[:name] = parts.first
444
- result[:spec] = Artifact.to_hash(parts[1])
445
- result[:requirement] = VersionRequirement.create(parts.last)
446
- end
447
- else
448
- result[:spec] = Artifact.to_hash(spec)
449
- end
450
- result[:name] ||= result[:spec][:id].to_s.to_sym
451
- result[:requirement] ||= VersionRequirement.create(result[:spec][:version])
452
- result
453
- end
454
-
455
- # Test if this requirement is satisfied by an artifact spec.
456
- def satisfied_by?(spec)
457
- return false unless requirement
458
- spec = Artifact.to_hash(spec)
459
- hash = to_spec_hash
460
- hash.delete(:version)
461
- version = spec.delete(:version)
462
- hash == spec && requirement.satisfied_by?(version)
463
- end
464
-
465
- # Has user selected a version for this requirement?
466
- def selected?
467
- @selected
468
- end
469
-
470
- def selected! #:nodoc:
471
- @selected = true
472
- @listeners.each { |l| l.call(self) } if @listeners
473
- self
474
- end
475
-
476
- def add_listener(&callback)
477
- (@listeners ||= []) << callback
478
- end
479
-
480
- # Return the Artifact object for the currently selected version
481
- def artifact
482
- ::Buildr.artifact(self)
483
- end
484
-
485
- # Format this requirement as an `artifact requirement spec`
486
- def to_requirement_spec
487
- result = to_spec
488
- result = "#{name} -> #{result}" if name
489
- result = "#{result} -> #{requirement}" if requirement
490
- result
491
- end
492
-
493
- def to_s #:nodoc:
494
- id ? to_requirement_spec : version
495
- end
496
-
497
- # Return an artifact spec without the version part.
498
- def unversioned_spec
499
- str = to_spec
500
- return nil if str =~ /^:+/
501
- ary = str.split(':')
502
- ary = ary[0...-1] if ary.size > 3
503
- ary.join(':')
504
- end
505
-
506
- class << self
507
- # Return an artifact spec without the version part.
508
- def unversioned_spec(spec)
509
- str = spec.to_s
510
- return nil if str =~ /^:+/
511
- ary = str.split(':')
512
- ary = ary[0...-1] if ary.size > 3
513
- if ary.size > 2
514
- ary.join(':')
515
- else
516
- new(spec).unversioned_spec
517
- end
518
- end
519
- end
520
- end
521
-
522
- include DClone
523
- include Enumerable
524
- attr_reader :name
525
-
526
- def initialize(name = nil) #:nodoc:
527
- @name = name.to_s if name
528
- end
529
- clear
530
-
531
- def root
532
- ROOT
533
- end
534
-
535
- # ROOT namespace has no parent
536
- def parent
537
- if root?
538
- nil
539
- elsif @parent.kind_of?(ArtifactNamespace)
540
- @parent
541
- elsif @parent
542
- ArtifactNamespace.instance(@parent)
543
- elsif name
544
- parent_name = name.gsub(/::?[^:]+$/, '')
545
- parent_name == name ? root : ArtifactNamespace.instance(parent_name)
546
- else
547
- root
548
- end
549
- end
550
-
551
- # Set the parent for the current namespace, except if it is ROOT
552
- def parent=(other)
553
- raise 'Cannot set parent of root namespace' if root?
554
- @parent = other
555
- @registry = nil
556
- end
557
-
558
- # Is this the ROOT namespace?
559
- def root?
560
- ROOT == self
561
- end
562
-
563
- # Create a named sub-namespace, sub-namespaces are themselves
564
- # ArtifactNamespace instances but cannot be referenced by
565
- # the Buildr.artifact_ns, ArtifactNamespace.instance methods.
566
- # Reference needs to be through this object using the given +name+
567
- #
568
- # artifact_ns('foo').ns(:bar).need :thing => 'some:thing:jar:1.0'
569
- # artifact_ns('foo').bar # => the sub-namespace 'foo.bar'
570
- # artifact_ns('foo').bar.thing # => the some thing artifact
571
- #
572
- # See the top level ArtifactNamespace documentation for examples
573
- def ns(name, *uses, &block)
574
- name = name.to_sym
575
- sub = registry[name]
576
- if sub
577
- raise TypeError.new("#{name} is not a sub namespace of #{self}") unless sub.kind_of?(ArtifactNamespace)
578
- else
579
- sub = ArtifactNamespace.new("#{self.name}.#{name}")
580
- sub.parent = self
581
- registry[name] = sub
582
- end
583
- sub.use(*uses)
584
- yield sub if block_given?
585
- sub
586
- end
587
-
588
- # Test if a sub-namespace by the given name exists
589
- def ns?(name)
590
- sub = registry[name.to_sym]
591
- ArtifactNamespace === sub
592
- end
593
-
594
- # :call-seq:
595
- # artifact_ns.need 'name -> org:foo:bar:jar:~>1.2.3 -> 1.2.5'
596
- # artifact_ns.need :name => 'org.foo:bar:jar:1.0'
597
- #
598
- # Create a new ArtifactRequirement on this namespace.
599
- # ArtifactNamespace#method_missing provides syntactic sugar for this.
600
- def need(*specs)
601
- named = specs.flatten.inject({}) do |seen, spec|
602
- if Hash === spec && (spec.keys & ActsAsArtifact::ARTIFACT_ATTRIBUTES).empty?
603
- spec.each_pair do |name, spec|
604
- if Array === spec # a group
605
- seen[name] ||= spec.map { |s| ArtifactRequirement.new(s) }
606
- else
607
- artifact = ArtifactRequirement.new(spec)
608
- artifact.name = name
609
- seen[artifact.name] ||= artifact
610
- end
611
- end
612
- else
613
- artifact = ArtifactRequirement.new(spec)
614
- seen[artifact.name] ||= artifact
615
- end
616
- seen
617
- end
618
- named.each_pair do |name, artifact|
619
- if Array === artifact # a group
620
- artifact.each do |a|
621
- unvers = a.unversioned_spec
622
- previous = registry[unvers]
623
- if previous && previous.selected? && a.satisfied_by?(previous)
624
- a.version = previous.version
625
- end
626
- registry[unvers] = a
627
- end
628
- group(name, *(artifact.map { |a| a.unversioned_spec } + [{:namespace => self}]))
629
- else
630
- unvers = artifact.unversioned_spec
631
- previous = registry.get(unvers, true)
632
- if previous && previous.selected? && artifact.satisfied_by?(previous)
633
- artifact.version = previous.version
634
- artifact.selected!
635
- end
636
- registry[unvers] = artifact
637
- registry.alias name, unvers unless name.to_s[/^\s*$/]
638
- end
639
- end
640
- self
641
- end
642
-
643
- # :call-seq:
644
- # artifact_ns.use 'name -> org:foo:bar:jar:1.2.3'
645
- # artifact_ns.use :name => 'org:foo:bar:jar:1.2.3'
646
- # artifact_ns.use :name => '2.5.6'
647
- #
648
- # First and second form are equivalent, the third is used when an
649
- # ArtifactRequirement has been previously defined with :name, so it
650
- # just selects the version.
651
- #
652
- # ArtifactNamespace#method_missing provides syntactic sugar for this.
653
- def use(*specs)
654
- named = specs.flatten.inject({}) do |seen, spec|
655
- if Hash === spec && (spec.keys & ActsAsArtifact::ARTIFACT_ATTRIBUTES).empty?
656
- spec.each_pair do |name, spec|
657
- if ArtifactNamespace === spec # create as subnamespace
658
- raise ArgumentError.new("Circular reference") if self == spec
659
- registry[name.to_sym] = spec
660
- elsif Numeric === spec || (String === spec && VersionRequirement.version?(spec))
661
- artifact = ArtifactRequirement.allocate
662
- artifact.name = name
663
- artifact.version = spec.to_s
664
- seen[artifact.name] ||= artifact
665
- elsif Symbol === spec
666
- self.alias name, spec
667
- elsif Array === spec # a group
668
- seen[name] ||= spec.map { |s| ArtifactRequirement.new(s) }
669
- else
670
- artifact = ArtifactRequirement.new(spec)
671
- artifact.name = name
672
- seen[artifact.name] ||= artifact
673
- end
674
- end
675
- else
676
- if Symbol === spec
677
- artifact = get(spec).dclone
678
- else
679
- artifact = ArtifactRequirement.new(spec)
680
- end
681
- seen[artifact.name] ||= artifact
682
- end
683
- seen
684
- end
685
- named.each_pair do |name, artifact|
686
- is_group = Array === artifact
687
- artifact = [artifact].flatten.map do |artifact|
688
- unvers = artifact.unversioned_spec
689
- previous = get(unvers, false) || get(name, false)
690
- if previous # have previous on current namespace
691
- if previous.requirement # we must satisfy the requirement
692
- unless unvers # we only have the version
693
- satisfied = previous.requirement.satisfied_by?(artifact.version)
694
- else
695
- satisfied = previous.satisfied_by?(artifact)
696
- end
697
- raise "Unsatisfied dependency #{previous} " +
698
- "not satisfied by #{artifact}" unless satisfied
699
- previous.version = artifact.version # OK, set new version
700
- artifact = previous # use the same object for aliases
701
- else # not a requirement, set the new values
702
- unless artifact.id == previous.id && name != previous.name
703
- previous.copy_attrs(artifact)
704
- artifact = previous
705
- end
706
- end
707
- else
708
- if unvers.nil? && # we only have the version
709
- (previous = get(unvers, true, false, false))
710
- version = artifact.version
711
- artifact.copy_attrs(previous)
712
- artifact.version = version
713
- end
714
- artifact.requirement = nil
715
- end
716
- artifact.selected!
717
- end
718
- artifact = artifact.first unless is_group
719
- if is_group
720
- names = artifact.map do |art|
721
- unv = art.unversioned_spec
722
- registry[unv] = art
723
- unv
724
- end
725
- group(name, *(names + [{:namespace => self}]))
726
- elsif artifact.id
727
- unvers = artifact.unversioned_spec
728
- registry[name] = artifact
729
- registry.alias unvers, name
730
- else
731
- registry[name] = artifact
732
- end
733
- end
734
- self
735
- end
736
-
737
- # Like Hash#fetch
738
- def fetch(name, default = nil, &block)
739
- block ||= lambda { raise IndexError.new("No artifact found by name #{name.inspect} in namespace #{self}") }
740
- real_name = name.to_s[/^\w+$/] ? name : ArtifactRequirement.unversioned_spec(name)
741
- get(real_name.to_sym) || default || block.call(name)
742
- end
743
-
744
- # :call-seq:
745
- # artifact_ns[:name] -> ArtifactRequirement
746
- # artifact_ns[:many, :names] -> [ArtifactRequirement]
747
- def [](*names)
748
- ary = values_at(*names)
749
- names.size == 1 ? ary.first : ary
750
- end
751
-
752
- # :call-seq:
753
- # artifact_ns[:name] = 'some:cool:jar:1.0.2'
754
- # artifact_ns[:name] = '1.0.2'
755
- #
756
- # Just like the use method
757
- def []=(*names)
758
- values = names.pop
759
- values = [values] unless Array === values
760
- names.each_with_index do |name, i|
761
- use name => (values[i] || values.last)
762
- end
763
- end
764
-
765
- # yield each ArtifactRequirement
766
- def each(&block)
767
- values.each(&block)
768
- end
769
-
770
- # return Artifact objects for each requirement
771
- def artifacts(*names)
772
- (names.empty? && values || values_at(*names)).map(&:artifact)
773
- end
774
-
775
- # Return all requirements for this namespace
776
- def values(include_parents = false, include_groups = true)
777
- seen, dict = {}, registry
778
- while dict
779
- dict.each do |k, v|
780
- v = v.call if v.respond_to?(:call)
781
- v = v.values if v.kind_of?(ArtifactNamespace)
782
- if Array === v && include_groups
783
- v.compact.each { |v| seen[v.name] = v unless seen.key?(v.name) }
784
- else
785
- seen[v.name] = v unless seen.key?(v.name)
786
- end
787
- end
788
- dict = include_parents ? dict.parent : nil
789
- end
790
- seen.values
791
- end
792
-
793
- # Return only the named requirements
794
- def values_at(*names)
795
- names.map do |name|
796
- catch :artifact do
797
- unless name.to_s[/^\w+$/]
798
- unvers = ArtifactRequirement.unversioned_spec(name)
799
- unless unvers.to_s == name.to_s
800
- req = ArtifactRequirement.new(name)
801
- reg = self
802
- while reg
803
- candidate = reg.send(:get, unvers, false, false, true)
804
- throw :artifact, candidate if req.satisfied_by?(candidate)
805
- reg = reg.parent
806
- end
807
- end
808
- end
809
- get(name.to_sym)
810
- end
811
- end
812
- end
813
-
814
- def key?(name, include_parents = false)
815
- name = ArtifactRequirement.unversioned_spec(name) unless name.to_s[/^\w+$/]
816
- registry.key?(name, include_parents)
817
- end
818
-
819
- def delete(name, include_parents = false)
820
- registry.delete(name, include_parents)
821
- self
822
- end
823
-
824
- # :call-seq:
825
- # group :who, :me, :you
826
- # group :them, :me, :you, :namespace => ns
827
- #
828
- # Create a virtual group on this namespace. When the namespace
829
- # is asked for the +who+ artifact, it's value is an array made from
830
- # the remaining names. These names are searched by default from the current
831
- # namespace.
832
- # Second form specified the starting namespace to search from.
833
- def group(group_name, *members)
834
- namespace = (Hash === members.last && members.pop[:namespace]) || :current
835
- registry[group_name] = lambda do
836
- artifacts = self.class[namespace].values_at(*members)
837
- artifacts = artifacts.first if members.size == 1
838
- artifacts
839
- end
840
- self
841
- end
842
-
843
- alias_method :virtual, :group
844
-
845
- # Create an alias for a named requirement.
846
- def alias(new_name, old_name)
847
- registry.alias(new_name, old_name) or
848
- raise NameError.new("Undefined artifact name: #{old_name}")
849
- end
850
-
851
- def to_s #:nodoc:
852
- name.to_s
853
- end
854
-
855
- # :call-seq:
856
- # artifact_ns.cool_aid!('cool:aid:jar:2.3.4', '~>2.3') -> artifact_requirement
857
- # artifact_ns.cool_aid = '2.3.5'
858
- # artifact_ns.cool_aid -> artifact_requirement
859
- # artifact_ns.cool_aid? -> true | false
860
- #
861
- # First form creates an ArtifactRequirement on the namespace.
862
- # It is equivalent to providing a requirement_spec to the #need method:
863
- # artifact_ns.need "cool_aid -> cool:aid:jar:2.3.4 -> ~>2.3"
864
- # the second argument is optional.
865
- #
866
- # Second form can be used to select an artifact version
867
- # and is equivalent to:
868
- # artifact_ns.use :cool_aid => '1.0'
869
- #
870
- # Third form obtains the named ArtifactRequirement, can be
871
- # used to test if a named requirement has been defined.
872
- # It is equivalent to:
873
- # artifact_ns.fetch(:cool_aid) { nil }
874
- #
875
- # Last form tests if the ArtifactRequirement has been defined
876
- # and a version has been selected for use.
877
- # It is equivalent to:
878
- #
879
- # artifact_ns.has_cool_aid?
880
- # artifact_ns.values_at(:cool_aid).flatten.all? { |a| a && a.selected? }
881
- #
882
- def method_missing(name, *args, &block)
883
- case name.to_s
884
- when /!$/ then
885
- name = $`.intern
886
- if args.size < 1 || args.size > 2
887
- raise ArgumentError.new("wrong number of arguments for #{name}!(spec, version_requirement?)")
888
- end
889
- need name => args.first
890
- get(name).tap { |r| r.requirement = args.last if args.size == 2 }
891
- when /=$/ then use $` => args.first
892
- when /\?$/ then
893
- name = $`.gsub(/^(has|have)_/, '').intern
894
- [get(name)].flatten.all? { |a| a && a.selected? }
895
- else
896
- if block || args.size > 0
897
- raise ArgumentError.new("wrong number of arguments #{args.size} for 0 or block given")
898
- end
899
- get(name)
900
- end
901
- end
902
-
903
- # Return an anonymous module
904
- # # first create a requirement
905
- # artifact_ns.cool_aid! 'cool:aid:jar:>=1.0'
906
- #
907
- # # extend an object as a cool_aid delegator
908
- # jars = Object.new.extend(artifact_ns.accessor(:cool_aid))
909
- # jars.cool_aid = '2.0'
910
- #
911
- # artifact_ns.cool_aid.version # -> '2.0'
912
- def accessor(*names)
913
- ns = self
914
- Module.new do
915
- names.each do |name|
916
- define_method("#{name}") { ns.send("#{name}") }
917
- define_method("#{name}?") { ns.send("#{name}?") }
918
- define_method("#{name}=") { |vers| ns.send("#{name}=", vers) }
919
- end
920
- end
921
- end
922
-
923
- private
924
- def get(name, include_parents = true, include_subs = true, include_self = true) #:nodoc:
925
- if include_subs && name.to_s[/_/] # try sub namespaces first
926
- sub, parts = self, name.to_s.split('_')
927
- sub_name = parts.shift.to_sym
928
- until sub != self || parts.empty?
929
- if registry[sub_name].kind_of?(ArtifactNamespace)
930
- sub = registry[sub_name]
931
- artifact = sub[parts.join('_')]
932
- else
933
- sub_name = [sub_name, parts.shift].join('_').to_sym
934
- end
935
- end
936
- end
937
- unless artifact
938
- if include_self
939
- artifact = registry.get(name, include_parents)
940
- elsif include_parents && registry.parent
941
- artifact = registry.parent.get(name, true)
942
- end
943
- end
944
- artifact = artifact.call if artifact.respond_to?(:call)
945
- artifact
946
- end
947
-
948
- def registry
949
- @registry ||= Registry.new.tap do |m|
950
- m.parent = parent.send(:registry) unless root?
951
- end
952
- end
953
-
954
- end # ArtifactNamespace
955
-
956
- # :call-seq:
957
- # project.artifact_ns -> ArtifactNamespace
958
- # Buildr.artifact_ns(name) -> ArtifactNamespace
959
- # Buildr.artifact_ns -> ArtifactNamespace for the currently running Project
960
- #
961
- # Open an ArtifactNamespace.
962
- # If a block is provided, the namespace is yielded to it.
963
- #
964
- # See also ArtifactNamespace.instance
965
- def artifact_ns(name = nil, &block)
966
- name = self if name.nil? && self.kind_of?(Project)
967
- ArtifactNamespace.instance(name, &block)
968
- end
969
-
970
- end
971
-
972
-