| Name | Total Lines | Lines of Code | Total Coverage | Code Coverage |
|---|---|---|---|---|
| lib/buildr/java/pom.rb | 178 | 105 | 13.48%
|
13.33%
|
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 begin |
52 pom = POM.new(IO.read(filename)) |
53 rescue REXML::ParseException => e |
54 fail "Could not parse #{filename}, #{e.continued_exception}" |
55 end |
56 cache[filename] = pom |
57 end |
58 pom |
59 else |
60 raise ArgumentError, "Expecting Hash spec, Artifact, file name or file task" |
61 end |
62 end |
63 |
64 private |
65 |
66 def cache() |
67 @cache ||= {} |
68 end |
69 |
70 end |
71 |
72 def initialize(xml) #:nodoc: |
73 @project = XmlSimple.xml_in(xml) |
74 @parent = POM.load(pom_to_hash(project["parent"].first).merge(:type=>'pom')) if project['parent'] |
75 end |
76 |
77 # :call-seq: |
78 # dependencies(scopes?) => artifacts |
79 # |
80 # Returns list of required dependencies as specified by the POM. You can specify which scopes |
81 # to use (e.g. "compile", "runtime"); use +nil+ for dependencies with unspecified scope. |
82 # The default scopes are +nil+, "compile" and "runtime" (aka SCOPES_WE_USE). |
83 def dependencies(scopes = SCOPES_WE_USE) |
84 #try to cache dependencies also |
85 @depends_for_scopes ||= {} |
86 unless depends = @depends_for_scopes[scopes] |
87 declared = project["dependencies"].first["dependency"] rescue nil |
88 depends = (declared || []).reject { |dep| value_of(dep["optional"]) =~ /true/ }. |
89 map { |dep| |
90 spec = pom_to_hash(dep, properties) |
91 apply = managed(spec) |
92 spec = apply.merge(spec) if apply |
93 |
94 #calculate transitive dependencies |
95 if scopes.include?(spec[:scope]) |
96 spec.delete(:scope) |
97 |
98 exclusions = dep["exclusions"]["exclusion"] rescue nil |
99 transitive_deps = POM.load(spec).dependencies(SCOPES_TRANSITIVE) |
100 transitive_deps = transitive_deps.reject{|dep| |
101 exclusions.find {|ex| dep.index("#{dep['groupdId'].first}:#{dep['artifactId'].first}:") == 0} |
102 } if exclusions |
103 |
104 [Artifact.to_spec(spec)] + transitive_deps |
105 end |
106 }.flatten.compact #.uniq_by{|spec| art = spec.split(':'); "#{art[0]}:#{art[1]}"} |
107 |
108 @depends_for_scopes[scopes] = depends |
109 end |
110 depends |
111 end |
112 |
113 # :call-seq: |
114 # properties() => hash |
115 # |
116 # Returns properties available to this POM as hash. Includes explicit properties and pom.xxx/project.xxx |
117 # properties for groupId, artifactId, version and packaging. |
118 def properties() |
119 @properties ||= begin |
120 pom = ["groupId", "artifactId", "version", "packaging"].inject({}) { |hash, key| |
121 value = project[key] || (parent ? parent.project[key] : nil) |
122 hash[key] = hash["pom.#{key}"] = hash["project.#{key}"] = value_of(value) if value |
123 hash |
124 } |
125 props = project["properties"].first rescue {} |
126 props = props.inject({}) { |mapped, pair| mapped[pair.first] = value_of(pair.last, pom) ; mapped } |
127 (parent ? parent.properties.merge(props) : props).merge(pom) |
128 end |
129 end |
130 |
131 # :call-seq: |
132 # managed() => hash |
133 # managed(hash) => hash |
134 # |
135 # The first form returns all the managed dependencies specified by this POM in dependencyManagement. |
136 # The second form uses a single spec hash and expands it from the current/parent POM. Used to determine |
137 # the version number if specified in dependencyManagement instead of dependencies. |
138 def managed(spec = nil) |
139 if spec |
140 managed.detect { |dep| [:group, :id, :type, :classifier].all? { |key| spec[key] == dep[key] } } || |
141 (parent ? parent.managed(spec) : nil) |
142 else |
143 @managed ||= begin |
144 managed = project["dependencyManagement"].first["dependencies"].first["dependency"] rescue nil |
145 managed ? managed.map { |dep| pom_to_hash(dep, properties) } : [] |
146 end |
147 end |
148 end |
149 |
150 private |
151 |
152 # :call-seq: |
153 # value_of(element) => string |
154 # value_of(element, true) => string |
155 # |
156 # Returns the normalized text value of an element from its XmlSimple value. The second form performs |
157 # property substitution. |
158 def value_of(element, substitute = nil) |
159 value = element.to_a.join.strip |
160 substitute ? value.gsub(/\$\{([^}]+)\}/) { |key| substitute[$1] } : value |
161 end |
162 |
163 # :call-seq: |
164 # pom_to_hash(element) => hash |
165 # pom_to_hash(element, true) => hash |
166 # |
167 # Return the spec hash from an XmlSimple POM referencing element (e.g. project, parent, dependency). |
168 # The second form performs property substitution. |
169 def pom_to_hash(element, substitute = nil) |
170 hash = POM_TO_SPEC_MAP.inject({}) { |spec, pair| |
171 spec[pair.first] = value_of(element[pair.last], substitute) if element[pair.last] |
172 spec |
173 } |
174 { :type=>"jar" }.merge(hash) |
175 end |
176 |
177 end |
178 end |
Generated on 2011-07-06 23:35:37 -0700 with rcov 0.9.8