C0 code coverage information
Generated on Wed Oct 07 08:34:02 -0700 2009 with rcov 0.8.2.1
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.
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 module Buildr
18 class POM
19
20 POM_TO_SPEC_MAP = { :group=>"groupId", :id=>"artifactId", :type=>"type",
21 :version=>"version", :classifier=>"classifier", :scope=>"scope" }
22 SCOPES_TRANSITIVE = [nil, "compile", "runtime"]
23 SCOPES_WE_USE = SCOPES_TRANSITIVE + ["provided"]
24
25 # POM project as Hash (using XmlSimple).
26 attr_reader :project
27 # Parent POM if referenced by this POM.
28 attr_reader :parent
29
30 class << self
31
32 # :call-seq:
33 # POM.load(arg)
34 #
35 # Load new POM object form various kind of sources such as artifact, hash representing spec, filename, XML.
36 def load(source)
37 case source
38 when Hash
39 load(Buildr.artifact(source).pom)
40 when Artifact
41 pom = source.pom
42 pom.invoke
43 load(pom.to_s)
44 when Rake::FileTask
45 source.invoke
46 load(source.to_s)
47 when String
48 filename = File.expand_path(source)
49 unless pom = cache[filename]
50 trace "Loading m2 pom file from #{filename}"
51 pom = POM.new(IO.read(filename))
52 cache[filename] = pom
53 end
54 pom
55 else
56 raise ArgumentError, "Expecting Hash spec, Artifact, file name or file task"
57 end
58 end
59
60 private
61
62 def cache()
63 @cache ||= {}
64 end
65
66 end
67
68 def initialize(xml) #:nodoc:
69 @project = XmlSimple.xml_in(xml)
70 @parent = POM.load(pom_to_hash(project["parent"].first).merge(:type=>'pom')) if project['parent']
71 end
72
73 # :call-seq:
74 # dependencies(scopes?) => artifacts
75 #
76 # Returns list of required dependencies as specified by the POM. You can specify which scopes
77 # to use (e.g. "compile", "runtime"); use +nil+ for dependencies with unspecified scope.
78 # The default scopes are +nil+, "compile" and "runtime" (aka SCOPES_WE_USE).
79 def dependencies(scopes = SCOPES_WE_USE)
80 #try to cache dependencies also
81 @depends_for_scopes ||= {}
82 unless depends = @depends_for_scopes[scopes]
83 declared = project["dependencies"].first["dependency"] rescue nil
84 depends = (declared || []).reject { |dep| value_of(dep["optional"]) =~ /true/ }.
85 map { |dep|
86 spec = pom_to_hash(dep, properties)
87 apply = managed(spec)
88 spec = apply.merge(spec) if apply
89
90 #calculate transitive dependencies
91 if scopes.include?(spec[:scope])
92 spec.delete(:scope)
93
94 exclusions = dep["exclusions"]["exclusion"] rescue nil
95 transitive_deps = POM.load(spec).dependencies(SCOPES_TRANSITIVE)
96 transitive_deps = transitive_deps.reject{|dep|
97 exclusions.find {|ex| dep.index("#{dep['groupdId'].first}:#{dep['artifactId'].first}:") == 0}
98 } if exclusions
99
100 [Artifact.to_spec(spec)] + transitive_deps
101 end
102 }.flatten.compact #.uniq_by{|spec| art = spec.split(':'); "#{art[0]}:#{art[1]}"}
103
104 @depends_for_scopes[scopes] = depends
105 end
106 depends
107 end
108
109 # :call-seq:
110 # properties() => hash
111 #
112 # Returns properties available to this POM as hash. Includes explicit properties and pom.xxx/project.xxx
113 # properties for groupId, artifactId, version and packaging.
114 def properties()
115 @properties ||= begin
116 pom = ["groupId", "artifactId", "version", "packaging"].inject({}) { |hash, key|
117 value = project[key] || (parent ? parent.project[key] : nil)
118 hash["pom.#{key}"] = hash["project.#{key}"] = value_of(value) if value
119 hash
120 }
121 props = project["properties"].first rescue {}
122 props = props.inject({}) { |mapped, pair| mapped[pair.first] = value_of(pair.last, pom) ; mapped }
123 (parent ? parent.properties.merge(props) : props).merge(pom)
124 end
125 end
126
127 # :call-seq:
128 # managed() => hash
129 # managed(hash) => hash
130 #
131 # The first form returns all the managed dependencies specified by this POM in dependencyManagement.
132 # The second form uses a single spec hash and expands it from the current/parent POM. Used to determine
133 # the version number if specified in dependencyManagement instead of dependencies.
134 def managed(spec = nil)
135 if spec
136 managed.detect { |dep| [:group, :id, :type, :classifier].all? { |key| spec[key] == dep[key] } } ||
137 (parent ? parent.managed(spec) : nil)
138 else
139 @managed ||= begin
140 managed = project["dependencyManagement"].first["dependencies"].first["dependency"] rescue nil
141 managed ? managed.map { |dep| pom_to_hash(dep, properties) } : []
142 end
143 end
144 end
145
146 private
147
148 # :call-seq:
149 # value_of(element) => string
150 # value_of(element, true) => string
151 #
152 # Returns the normalized text value of an element from its XmlSimple value. The second form performs
153 # property substitution.
154 def value_of(element, substitute = nil)
155 value = element.to_a.join.strip
156 substitute ? value.gsub(/\$\{([^}]+)\}/) { |key| substitute[$1] } : value
157 end
158
159 # :call-seq:
160 # pom_to_hash(element) => hash
161 # pom_to_hash(element, true) => hash
162 #
163 # Return the spec hash from an XmlSimple POM referencing element (e.g. project, parent, dependency).
164 # The second form performs property substitution.
165 def pom_to_hash(element, substitute = nil)
166 hash = POM_TO_SPEC_MAP.inject({}) { |spec, pair|
167 spec[pair.first] = value_of(element[pair.last], substitute) if element[pair.last]
168 spec
169 }
170 { :type=>"jar" }.merge(hash)
171 end
172
173 end
174 end
Generated using the rcov code coverage analysis tool for Ruby
version 0.8.2.1.