Buildr C0 Coverage Information - RCov

lib/buildr/packaging/version_requirement.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
lib/buildr/packaging/version_requirement.rb 192 135
43.23%
53.33%

Key

Code reported as executed by Ruby looks like this...and this: this line is also marked as covered.Lines considered as run by rcov, but not reported by Ruby, look like this,and this: these lines were inferred by rcov (using simple heuristics).Finally, here's a line marked as not executed.

Coverage Details

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

Generated on 2011-07-06 23:35:38 -0700 with rcov 0.9.8