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,108 @@
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
+ module Buildr
17
+ # Extention of Array to standardize URLs into { :url => 'url', :username => 'username', :password => 'password' }.
18
+ # :url = url of remote repository
19
+ # :username = optional username for authentication
20
+ # :password = optional password for authentication
21
+ class RepositoryArray < Array
22
+
23
+ def initialize( *args )
24
+ if !args.nil? && args.is_a?(Array) && args.size == 1
25
+ args = args[0]
26
+ converted = args.map {|url| convert_remote_url(url) }
27
+ super(converted)
28
+ else
29
+ super(args)
30
+ end
31
+ end
32
+
33
+ # Concatenation—Returns a new array built by concatenating the two arrays together to produce a third array of standardized URL Hashes.
34
+ def +(urls)
35
+ concat(urls)
36
+ end
37
+
38
+ # Append—Pushes the given object on to the end of this array, as a standardize URL Hash. This expression returns the array itself, so several appends may be chained together.
39
+ def <<(url)
40
+ converted = convert_remote_url( url )
41
+ super( converted )
42
+ end
43
+
44
+ # Appends the elements in other_array to self, as standardized URL Hashes
45
+ def concat(urls)
46
+ if !urls.nil?
47
+ converted = urls.map { |url| convert_remote_url( url ) }
48
+ super(converted)
49
+ else
50
+ super(nil)
51
+ end
52
+ end
53
+
54
+ # :call-seq:
55
+ # url = url => hash
56
+ # url = Hash => hash
57
+ #
58
+ # With a String url, returns a standardize URL Hash.
59
+ #
60
+ # With a Hash argument { :url => 'url', :username => 'username', :password => 'password' }, returns a standardize URL Hash.
61
+ #
62
+ def convert_remote_url(url)
63
+ if url.is_a? String
64
+ return {:url => URI.parse(url)}
65
+ elsif url.is_a? Hash
66
+ hash = { :url => URI.parse((url[:url] || url['url'])) }
67
+ username = url[:username] || url['username']
68
+ hash[:username] = username if username
69
+
70
+ password = (url[:password] || url['password'])
71
+ hash[:password] = password if password
72
+
73
+ return hash
74
+ elsif url.is_a? URI
75
+ return { :url => url }
76
+ else
77
+ raise ArgumentError, "Unsupported :url, must be String, Hash, or URI: #{url.inspect}"
78
+ end
79
+ end
80
+
81
+ # Inserts the given values before the element with the given index (which may be negative), as standardized URL Hashes
82
+ def insert( index, *args)
83
+ if !args.nil?
84
+ pos = index
85
+ args.each do |url|
86
+ convert = convert_remote_url( url )
87
+ super( pos, convert )
88
+ if index >= 0
89
+ pos = pos + 1
90
+ end
91
+ end
92
+ else
93
+ super( index, nil )
94
+ end
95
+ end
96
+
97
+ # Replaces the contents of self with the contents of other_array, truncating or expanding if necessary. The contents of other_array
98
+ # is converted standardized URL Hashes.
99
+ def replace( other_array )
100
+ if !other_array.nil?
101
+ converted = other_array.map { |url| convert_remote_url( url ) }
102
+ super( converted )
103
+ else
104
+ super( nil )
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,189 @@
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/archive'
18
+ gem 'minitar' ; autoload :Archive, 'archive/tar/minitar'
19
+
20
+
21
+ module Buildr
22
+
23
+ # The TarTask creates a new Tar file. You can include any number of files and and directories,
24
+ # use exclusion patterns, and include files into specific directories.
25
+ #
26
+ # To create a GZipped Tar, either set the gzip option to true, or use the .tgz or .gz suffix.
27
+ #
28
+ # For example:
29
+ # tar("test.tgz").tap do |task|
30
+ # task.include "srcs"
31
+ # task.include "README", "LICENSE"
32
+ # end
33
+ #
34
+ # See Buildr#tar and ArchiveTask.
35
+ class TarTask < ArchiveTask
36
+
37
+ # To create a GZipped Tar, either set this option to true, or use the .tgz/.gz suffix.
38
+ attr_accessor :gzip
39
+ # Permission mode for files contained in the Tar. Defaults to 0755.
40
+ attr_accessor :mode
41
+
42
+ def initialize(*args, &block) #:nodoc:
43
+ super
44
+ self.gzip = name =~ /\.t?gz$/
45
+ self.mode = '0755'
46
+ end
47
+
48
+ # :call-seq:
49
+ # entry(name) => Entry
50
+ #
51
+ # Returns a Tar file entry. You can use this to check if the entry exists and its contents,
52
+ # for example:
53
+ # package(:tar).entry("src/LICENSE").should contain(/Apache Software License/)
54
+ def entry(entry_name)
55
+ Buildr::TarEntry.new(self, entry_name)
56
+ end
57
+
58
+ def entries() #:nodoc:
59
+ tar_entries = nil
60
+ with_uncompressed_tar { |tar| tar_entries = tar.entries }
61
+ tar_entries
62
+ end
63
+
64
+ # :call-seq:
65
+ # with_uncompressed_tar { |tar_entries| ... }
66
+ #
67
+ # Yields an Archive::Tar::Minitar::Input object to the provided block.
68
+ # Opening, closing and Gzip-decompressing is automatically taken care of.
69
+ def with_uncompressed_tar &block
70
+ if gzip
71
+ Zlib::GzipReader.open(name) { |tar| Archive::Tar::Minitar.open(tar, &block) }
72
+ else
73
+ Archive::Tar::Minitar.open(name, &block)
74
+ end
75
+ end
76
+
77
+ private
78
+
79
+ def create_from(file_map)
80
+ if gzip
81
+ StringIO.new.tap do |io|
82
+ create_tar io, file_map
83
+ io.seek 0
84
+ Zlib::GzipWriter.open(name) { |gzip| gzip.write io.read }
85
+ end
86
+ else
87
+ File.open(name, 'wb') { |file| create_tar file, file_map }
88
+ end
89
+ end
90
+
91
+ def create_tar(out, file_map)
92
+ Archive::Tar::Minitar::Writer.open(out) do |tar|
93
+ options = { :mode=>mode || '0755', :mtime=>Time.now }
94
+
95
+ file_map.each do |path, content|
96
+ if content.respond_to?(:call)
97
+ tar.add_file(path, options) { |os, opts| content.call os }
98
+ elsif content.nil?
99
+ elsif File.directory?(content.to_s)
100
+ stat = File.stat(content.to_s)
101
+ tar.mkdir(path, options.merge(:mode=>stat.mode, :mtime=>stat.mtime))
102
+ else
103
+ File.open content.to_s, 'rb' do |is|
104
+ tar.add_file path, options.merge(:mode=>is.stat.mode, :mtime=>is.stat.mtime, :uid=>is.stat.uid, :gid=>is.stat.gid) do |os, opts|
105
+ while data = is.read(4096)
106
+ os.write(data)
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+
115
+ end
116
+
117
+
118
+ class TarEntry #:nodoc:
119
+
120
+ def initialize(tar_task, entry_name)
121
+ @tar_task = tar_task
122
+ @entry_name = entry_name
123
+ end
124
+
125
+ # :call-seq:
126
+ # contain?(*patterns) => boolean
127
+ #
128
+ # Returns true if this Tar file entry matches against all the arguments. An argument may be
129
+ # a string or regular expression.
130
+ def contain?(*patterns)
131
+ content = read_content_from_tar
132
+ patterns.map { |pattern| Regexp === pattern ? pattern : Regexp.new(Regexp.escape(pattern.to_s)) }.
133
+ all? { |pattern| content =~ pattern }
134
+ end
135
+
136
+ # :call-seq:
137
+ # empty?() => boolean
138
+ #
139
+ # Returns true if this entry is empty.
140
+ def empty?()
141
+ read_content_from_tar.nil?
142
+ end
143
+
144
+ # :call-seq:
145
+ # exist() => boolean
146
+ #
147
+ # Returns true if this entry exists.
148
+ def exist?()
149
+ exist = false
150
+ @tar_task.with_uncompressed_tar { |tar| exist = tar.any? { |entry| entry.name == @entry_name } }
151
+ exist
152
+ end
153
+
154
+ def to_s #:nodoc:
155
+ @entry_name
156
+ end
157
+
158
+ private
159
+
160
+ def read_content_from_tar
161
+ content = Errno::ENOENT.new("No such file or directory - #{@entry_name}")
162
+ @tar_task.with_uncompressed_tar do |tar|
163
+ content = tar.inject(content) { |content, entry| entry.name == @entry_name ? entry.read : content }
164
+ end
165
+ raise content if Exception === content
166
+ content
167
+ end
168
+ end
169
+
170
+ end
171
+
172
+
173
+ # :call-seq:
174
+ # tar(file) => TarTask
175
+ #
176
+ # The TarTask creates a new Tar file. You can include any number of files and
177
+ # and directories, use exclusion patterns, and include files into specific
178
+ # directories.
179
+ #
180
+ # To create a GZipped Tar, either set the gzip option to true, or use the .tgz or .gz suffix.
181
+ #
182
+ # For example:
183
+ # tar("test.tgz").tap do |tgz|
184
+ # tgz.include "srcs"
185
+ # tgz.include "README", "LICENSE"
186
+ # end
187
+ def tar(file)
188
+ TarTask.define_task(file)
189
+ end
@@ -0,0 +1,192 @@
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
+ # Rubygems 1.3.6 removed the 'version' accessor so monkey-patch it back to
18
+ # circumvent version validation. This is needed because Gem::Version doesn't
19
+ # accept version specs with dashes.
20
+ unless Gem::Version.new(0).respond_to?(:version=)
21
+ class Gem::Version
22
+ def version=(version)
23
+ @version = version.to_s
24
+ @version.strip!
25
+
26
+ # re-prime @segments
27
+ @segments = nil
28
+ segments
29
+ end
30
+ end
31
+ end
32
+
33
+ module Buildr
34
+
35
+ #
36
+ # See ArtifactNamespace#need
37
+ class VersionRequirement
38
+
39
+ CMP_PROCS = Gem::Requirement::OPS.dup
40
+ CMP_REGEX = if defined?(Gem::Requirement::OP_RE)
41
+ Gem::Requirement::OP_RE
42
+ else
43
+ Gem::Requirement::OPS.keys.map { |k| Regexp.quote k }.join "|"
44
+ end
45
+ CMP_CHARS = CMP_PROCS.keys.join
46
+ BOOL_CHARS = '\|\&\!'
47
+ VER_CHARS = '\w\.\-'
48
+
49
+ class << self
50
+ # is +str+ a version string?
51
+ def version?(str)
52
+ /^\s*\d[#{VER_CHARS}]*\s*$/ === str
53
+ end
54
+
55
+ # is +str+ a version requirement?
56
+ def requirement?(str)
57
+ /[#{BOOL_CHARS}#{CMP_CHARS}\(\)]/ === str
58
+ end
59
+
60
+ # :call-seq:
61
+ # VersionRequirement.create(" >1 <2 !(1.5) ") -> requirement
62
+ #
63
+ # parse the +str+ requirement
64
+ def create(str)
65
+ instance_eval normalize(str)
66
+ rescue StandardError => e
67
+ raise "Failed to parse #{str.inspect} due to: #{e}"
68
+ end
69
+
70
+ private
71
+ def requirement(req)
72
+ unless req =~ /^\s*(#{CMP_REGEX})?\s*([#{VER_CHARS}]+)\s*$/
73
+ raise "Invalid requirement string: #{req}"
74
+ end
75
+ comparator, version = $1, $2
76
+ version = Gem::Version.new(0).tap { |v| v.version = version }
77
+ VersionRequirement.new(nil, [$1, version])
78
+ end
79
+
80
+ def negate(vreq)
81
+ vreq.negative = !vreq.negative
82
+ vreq
83
+ end
84
+
85
+ def normalize(str)
86
+ str = str.strip
87
+ if str[/[^\s\(\)#{BOOL_CHARS + VER_CHARS + CMP_CHARS}]/]
88
+ raise "version string #{str.inspect} contains invalid characters"
89
+ end
90
+ str.gsub!(/\s+(and|\&\&)\s+/, ' & ')
91
+ str.gsub!(/\s+(or|\|\|)\s+/, ' | ')
92
+ str.gsub!(/(^|\s*)not\s+/, ' ! ')
93
+ pattern = /(#{CMP_REGEX})?\s*[#{VER_CHARS}]+/
94
+ left_pattern = /[#{VER_CHARS}\)]$/
95
+ right_pattern = /^(#{pattern}|\()/
96
+ str = str.split.inject([]) do |ary, i|
97
+ ary << '&' if ary.last =~ left_pattern && i =~ right_pattern
98
+ ary << i
99
+ end
100
+ str = str.join(' ')
101
+ str.gsub!(/!([^=])?/, ' negate \1')
102
+ str.gsub!(pattern) do |expr|
103
+ case expr.strip
104
+ when 'not', 'negate' then 'negate '
105
+ else 'requirement("' + expr + '")'
106
+ end
107
+ end
108
+ str.gsub!(/negate\s+\(/, 'negate(')
109
+ str
110
+ end
111
+ end
112
+
113
+ def initialize(op, *requirements) #:nodoc:
114
+ @op, @requirements = op, requirements
115
+ end
116
+
117
+ # Is this object a composed requirement?
118
+ # VersionRequirement.create('1').composed? -> false
119
+ # VersionRequirement.create('1 | 2').composed? -> true
120
+ # VersionRequirement.create('1 & 2').composed? -> true
121
+ def composed?
122
+ requirements.size > 1
123
+ end
124
+
125
+ # Return the last requirement on this object having an = operator.
126
+ def default
127
+ default = nil
128
+ requirements.reverse.find do |r|
129
+ if Array === r
130
+ if !negative && (r.first.nil? || r.first.include?('='))
131
+ default = r.last.to_s
132
+ end
133
+ else
134
+ default = r.default
135
+ end
136
+ end
137
+ default
138
+ end
139
+
140
+ # Test if this requirement can be satisfied by +version+
141
+ def satisfied_by?(version)
142
+ return false unless version
143
+ unless version.kind_of?(Gem::Version)
144
+ raise "Invalid version: #{version.inspect}" unless self.class.version?(version)
145
+ version = Gem::Version.new(0).tap { |v| v.version = version.strip }
146
+ end
147
+ message = op == :| ? :any? : :all?
148
+ result = requirements.send message do |req|
149
+ if Array === req
150
+ cmp, rv = *req
151
+ CMP_PROCS[cmp || '='].call(version, rv)
152
+ else
153
+ req.satisfied_by?(version)
154
+ end
155
+ end
156
+ negative ? !result : result
157
+ end
158
+
159
+ # Either modify the current requirement (if it's already an or operation)
160
+ # or create a new requirement
161
+ def |(other)
162
+ operation(:|, other)
163
+ end
164
+
165
+ # Either modify the current requirement (if it's already an and operation)
166
+ # or create a new requirement
167
+ def &(other)
168
+ operation(:&, other)
169
+ end
170
+
171
+ # return the parsed expression
172
+ def to_s
173
+ str = requirements.map(&:to_s).join(" " + @op.to_s + " ").to_s
174
+ str = "( " + str + " )" if negative || requirements.size > 1
175
+ str = "!" + str if negative
176
+ str
177
+ end
178
+
179
+ attr_accessor :negative
180
+ protected
181
+ attr_reader :requirements, :op
182
+ def operation(op, other)
183
+ @op ||= op
184
+ if negative == other.negative && @op == op && other.requirements.size == 1
185
+ @requirements << other.requirements.first
186
+ self
187
+ else
188
+ self.class.new(op, self, other)
189
+ end
190
+ end
191
+ end # VersionRequirement
192
+ end