C0 code coverage information
Generated on Wed Oct 07 08:34:00 -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 require 'buildr/core/project'
18 require 'buildr/packaging'
19
20
21 module Buildr
22 module Eclipse #:nodoc:
23 include Extension
24
25 class Eclipse
26
27 attr_reader :options
28
29 def initialize(project)
30 @project = project
31 @options = Options.new(project)
32 end
33
34 # :call-seq:
35 # natures=(natures)
36 # Sets the Eclipse project natures on the project.
37 #
38 def natures=(var)
39 @natures = arrayfy(var)
40 end
41
42 # :call-seq:
43 # natures() => [n1, n2]
44 # Returns the Eclipse project natures on the project.
45 # They may be derived from the parent project if no specific natures have been set
46 # on the project.
47 #
48 # An Eclipse project nature is used internally by Eclipse to determine the aspects of a project.
49 def natures(*values)
50 if values.size > 0
51 @natures ||= []
52 @natures += values
53 else
54 @natures || (@project.parent ? @project.parent.eclipse.natures : [])
55 end
56 end
57
58 # :call-seq:
59 # classpath_containers=(cc)
60 # Sets the Eclipse project classpath containers on the project.
61 #
62 def classpath_containers=(var)
63 @classpath_containers = arrayfy(var)
64 end
65
66 # :call-seq:
67 # classpath_containers() => [con1, con2]
68 # Returns the Eclipse project classpath containers on the project.
69 # They may be derived from the parent project if no specific classpath containers have been set
70 # on the project.
71 #
72 # A classpath container is an Eclipse pre-determined ensemble of dependencies made available to
73 # the project classpath.
74 def classpath_containers(*values)
75 if values.size > 0
76 @classpath_containers ||= []
77 @classpath_containers += values
78 else
79 @classpath_containers || (@project.parent ? @project.parent.eclipse.classpath_containers : [])
80 end
81 end
82
83 # :call-seq:
84 # builders=(builders)
85 # Sets the Eclipse project builders on the project.
86 #
87 def builders=(var)
88 @builders = arrayfy(var)
89 end
90
91 # :call-seq:
92 # builders() => [b1, b2]
93 # Returns the Eclipse project builders on the project.
94 # They may be derived from the parent project if no specific builders have been set
95 # on the project.
96 #
97 # A builder is an Eclipse background job that parses the source code to produce built artifacts.
98 def builders(*values)
99 if values.size > 0
100 @builders ||= []
101 @builders += values
102 else
103 @builders || (@project.parent ? @project.parent.eclipse.builders : [])
104 end
105 end
106
107 private
108
109 def arrayfy(obj)
110 obj.is_a?(Array) ? obj : [obj]
111 end
112 end
113
114 class Options
115
116 attr_writer :m2_repo_var
117
118 def initialize(project)
119 @project = project
120 end
121
122 # The classpath variable used to point at the local maven2 repository.
123 # Example:
124 # eclipse.options.m2_repo_var = 'M2_REPO'
125 def m2_repo_var(*values)
126 fail "m2_repo_var can only accept one value: #{values}" if values.size > 1
127 if values.size > 0
128 @m2_repo_var = values[0]
129 else
130 @m2_repo_var || (@project.parent ? @project.parent.eclipse.options.m2_repo_var : 'M2_REPO')
131 end
132 end
133 end
134
135 def eclipse
136 @eclipse ||= Eclipse.new(self)
137 @eclipse
138 end
139
140 first_time do
141 # Global task "eclipse" generates artifacts for all projects.
142 desc 'Generate Eclipse artifacts for all projects'
143 Project.local_task('eclipse'=>'artifacts') { |name| "Generating Eclipse project for #{name}" }
144 end
145
146 before_define do |project|
147 project.recursive_task('eclipse')
148 end
149
150 after_define do |project|
151 eclipse = project.task('eclipse')
152
153 eclipse.enhance [ file(project.path_to('.classpath')), file(project.path_to('.project')) ]
154
155 # The only thing we need to look for is a change in the Buildfile.
156 file(project.path_to('.classpath')=>Buildr.application.buildfile) do |task|
157 if (project.eclipse.natures.reject { |x| x.is_a?(Symbol) }.size > 0)
158 info "Writing #{task.name}"
159
160 m2repo = Buildr::Repositories.instance.local
161
162 File.open(task.name, 'w') do |file|
163 classpathentry = ClasspathEntryWriter.new project, file
164 classpathentry.write do
165 # Note: Use the test classpath since Eclipse compiles both "main" and "test" classes using the same classpath
166 cp = project.test.compile.dependencies.map(&:to_s) - [ project.compile.target.to_s, project.resources.target.to_s ]
167 cp = cp.uniq
168
169 # Convert classpath elements into applicable Project objects
170 cp.collect! { |path| Buildr.projects.detect { |prj| prj.packages.detect { |pkg| pkg.to_s == path } } || path }
171
172 # project_libs: artifacts created by other projects
173 project_libs, others = cp.partition { |path| path.is_a?(Project) }
174
175 # Separate artifacts from Maven2 repository
176 m2_libs, others = others.partition { |path| path.to_s.index(m2repo) == 0 }
177
178 # Generated: Any non-file classpath elements in the project are assumed to be generated
179 libs, generated = others.partition { |path| File.file?(path.to_s) }
180
181 classpathentry.src project.compile.sources + generated
182 classpathentry.src project.resources
183
184 if project.test.compile.target
185 classpathentry.src project.test.compile
186 classpathentry.src project.test.resources
187 end
188
189 # Classpath elements from other projects
190 classpathentry.src_projects project_libs
191
192 classpathentry.output project.compile.target if project.compile.target
193 classpathentry.lib libs
194 classpathentry.var m2_libs, project.eclipse.options.m2_repo_var, m2repo
195
196 project.eclipse.classpath_containers.each { |container|
197 classpathentry.con container
198 }
199 end
200 end
201 end
202 end
203
204 # The only thing we need to look for is a change in the Buildfile.
205 file(project.path_to('.project')=>Buildr.application.buildfile) do |task|
206 if (project.eclipse.natures.reject { |x| x.is_a?(Symbol) }.size > 0)
207 info "Writing #{task.name}"
208 File.open(task.name, 'w') do |file|
209 xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
210 xml.projectDescription do
211 xml.name project.id
212 xml.projects
213 xml.buildSpec do
214 project.eclipse.builders.each { |builder|
215 xml.buildCommand do
216 xml.name builder
217 end
218 }
219 end
220 xml.natures do
221 project.eclipse.natures.each { |nature|
222 xml.nature nature unless nature.is_a? Symbol
223 }
224 end
225 end
226 end
227 end
228 end
229 end
230
231
232 # Writes 'classpathentry' tags in an xml file.
233 # It converts tasks to paths.
234 # It converts absolute paths to relative paths.
235 # It ignores duplicate directories.
236 class ClasspathEntryWriter #:nodoc:
237 def initialize project, target
238 @project = project
239 @xml = Builder::XmlMarkup.new(:target=>target, :indent=>2)
240 @excludes = [ '**/.svn/', '**/CVS/' ].join('|')
241 @paths_written = []
242 end
243
244 def write &block
245 @xml.classpath &block
246 end
247
248 def con path
249 @xml.classpathentry :kind=>'con', :path=>path
250 end
251
252 def lib libs
253 libs.map(&:to_s).sort.uniq.each do |path|
254 @xml.classpathentry :kind=>'lib', :path=>path
255 end
256 end
257
258 # Write a classpathentry of kind 'src'.
259 # Accept an array of absolute paths or a task.
260 def src arg
261 if [:sources, :target].all? { |message| arg.respond_to?(message) }
262 src_from_task arg
263 else
264 src_from_absolute_paths arg
265 end
266 end
267
268 # Write a classpathentry of kind 'src' for dependent projects.
269 # Accept an array of projects.
270 def src_projects project_libs
271 project_libs.map(&:id).sort.uniq.each do |project_id|
272 @xml.classpathentry :kind=>'src', :combineaccessrules=>'false', :path=>"/#{project_id}"
273 end
274 end
275
276 def output target
277 @xml.classpathentry :kind=>'output', :path=>relative(target)
278 end
279
280 # Write a classpathentry of kind 'var' (variable) for a library in a local repo.
281 # * +libs+ is an array of library paths.
282 # * +var_name+ is a variable name as defined in Eclipse (e.g., 'M2_REPO').
283 # * +var_value+ is the value of this variable (e.g., '/home/me/.m2').
284 # E.g., <tt>var([lib1, lib2], 'M2_REPO', '/home/me/.m2/repo')</tt>
285 def var libs, var_name, var_value
286 libs.each do |lib_path|
287 lib_artifact = file(lib_path)
288 source_path = lib_artifact.sources_artifact.to_s
289 relative_lib_path = lib_path.sub(var_value, var_name)
290 relative_source_path = source_path.sub(var_value, var_name)
291 @xml.classpathentry :kind=>'var', :path=>relative_lib_path, :sourcepath=>relative_source_path
292 end
293 end
294
295 private
296
297 # Find a path relative to the project's root directory.
298 def relative path
299 path or raise "Invalid path '#{path.inspect}'"
300 msg = [:to_path, :to_str, :to_s].find { |msg| path.respond_to? msg }
301 path = path.__send__(msg)
302 Util.relative_path(File.expand_path(path), @project.path_to)
303 end
304
305 def src_from_task task
306 src_from_absolute_paths task.sources, task.target
307 end
308
309 def src_from_absolute_paths absolute_paths, output=nil
310 relative_paths = absolute_paths.map { |src| relative(src) }
311 relative_paths.sort.uniq.each do |path|
312 unless @paths_written.include?(path)
313 attributes = { :kind=>'src', :path=>path, :excluding=>@excludes }
314 attributes[:output] = relative(output) if output
315 @xml.classpathentry attributes
316 @paths_written << path
317 end
318 end
319 end
320 end
321
322 end
323
324 end # module Buildr
325
326 class Buildr::Project
327 include Buildr::Eclipse
328 end
329
330 # Order is significant for auto-detection, from most specific to least
331 require 'buildr/ide/eclipse/plugin'
332 require 'buildr/ide/eclipse/scala'
333 require 'buildr/ide/eclipse/java'
334
Generated using the rcov code coverage analysis tool for Ruby
version 0.8.2.1.