Buildr C0 Coverage Information - RCov

lib/buildr/ide/idea.rb

Name Total Lines Lines of Code Total Coverage Code Coverage
lib/buildr/ide/idea.rb 592 478
28.21%
30.96%

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 require 'buildr/core/project'
18 require 'buildr/packaging'
19 require 'stringio'
20 
21 
22 module Buildr
23   module IntellijIdea
24     def self.new_document(value)
25       REXML::Document.new(value, :attribute_quote => :quote)
26     end
27 
28     # Abstract base class for IdeaModule and IdeaProject
29     class IdeaFile
30       DEFAULT_SUFFIX = ""
31 
32       attr_reader :buildr_project
33       attr_writer :suffix
34       attr_writer :id
35       attr_accessor :template
36 
37       def suffix
38         @suffix ||= DEFAULT_SUFFIX
39       end
40 
41       def filename
42         buildr_project.path_to("#{name}.#{extension}")
43       end
44 
45       def id
46         @id ||= buildr_project.name.split(':').last
47       end
48 
49       def add_component(name, attrs = {}, &xml)
50         self.components << create_component(name, attrs, &xml)
51       end
52 
53       def write(f)
54         document.write(f, 2, false, true)
55       end
56 
57       protected
58 
59       def name
60         "#{self.id}#{suffix}"
61       end
62 
63       def create_component(name, attrs = {})
64         target = StringIO.new
65         Builder::XmlMarkup.new(:target => target, :indent => 2).component(attrs.merge({:name => name})) do |xml|
66           yield xml if block_given?
67         end
68         Buildr::IntellijIdea.new_document(target.string).root
69       end
70 
71       def components
72         @components ||= self.default_components.compact
73       end
74 
75       def load_document(filename)
76         Buildr::IntellijIdea.new_document(File.read(filename))
77       end
78 
79       def document
80         if File.exist?(self.filename)
81           doc = load_document(self.filename)
82         else
83           doc = base_document
84           inject_components(doc, self.initial_components)
85         end
86         if self.template
87           template_doc = load_document(self.template)
88           REXML::XPath.each(template_doc, "//component") do |element|
89             inject_component(doc, element)
90           end
91         end
92         inject_components(doc, self.components)
93         doc
94       end
95 
96       def inject_components(doc, components)
97         components.each do |component|
98           # execute deferred components
99           component = component.call if Proc === component
100           inject_component(doc, component) if component
101         end
102       end
103 
104       # replace overridden component (if any) with specified component
105       def inject_component(doc, component)
106         doc.root.delete_element("//component[@name='#{component.attributes['name']}']")
107         doc.root.add_element component
108       end
109     end
110 
111     # IdeaModule represents an .iml file
112     class IdeaModule < IdeaFile
113       DEFAULT_TYPE = "JAVA_MODULE"
114       DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE = "MAVEN_REPOSITORY"
115 
116       attr_accessor :type
117       attr_accessor :local_repository_env_override
118       attr_accessor :group
119       attr_reader :facets
120 
121       def initialize
122         @type = DEFAULT_TYPE
123         @local_repository_env_override = DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE
124       end
125 
126       def buildr_project=(buildr_project)
127         @id = nil
128         @facets = []
129         @skip_content = false
130         @buildr_project = buildr_project
131       end
132 
133       def extension
134         "iml"
135       end
136 
137       def main_source_directories
138         @main_source_directories ||= [
139           buildr_project.compile.sources,
140           buildr_project.resources.sources
141         ].flatten.compact
142       end
143 
144       def test_source_directories
145         @test_source_directories ||= [
146           buildr_project.test.compile.sources,
147           buildr_project.test.resources.sources
148         ].flatten.compact
149       end
150 
151       def excluded_directories
152         @excluded_directories ||= [
153           buildr_project.resources.target,
154           buildr_project.test.resources.target,
155           buildr_project.path_to(:target, :main),
156           buildr_project.path_to(:target, :test),
157           buildr_project.path_to(:reports)
158         ].flatten.compact
159       end
160 
161       attr_writer :main_output_dir
162 
163       def main_output_dir
164         @main_output_dir ||= buildr_project._(:target, :main, :java)
165       end
166 
167       attr_writer :test_output_dir
168 
169       def test_output_dir
170         @test_output_dir ||= buildr_project._(:target, :test, :java)
171       end
172 
173       def main_dependencies
174         @main_dependencies ||=  buildr_project.compile.dependencies
175       end
176 
177       def test_dependencies
178         @test_dependencies ||=  buildr_project.test.compile.dependencies
179       end
180 
181       def add_facet(name, type)
182         target = StringIO.new
183         Builder::XmlMarkup.new(:target => target, :indent => 2).facet(:name => name, :type => type) do |xml|
184           yield xml if block_given?
185         end
186         self.facets << Buildr::IntellijIdea.new_document(target.string).root
187       end
188 
189       def skip_content?
190         !!@skip_content
191       end
192 
193       def skip_content!
194         @skip_content = true
195       end
196 
197       protected
198 
199       def test_dependency_details
200         main_dependencies_paths = main_dependencies.map(&:to_s)
201         target_dir = buildr_project.compile.target.to_s
202         test_dependencies.select { |d| d.to_s != target_dir }.collect do |d|
203           dependency_path = d.to_s
204           export = main_dependencies_paths.include?(dependency_path)
205           source_path = nil
206           if d.respond_to?(:to_spec_hash)
207             source_spec = d.to_spec_hash.merge(:classifier => 'sources')
208             source_path = Buildr.artifact(source_spec).to_s
209             source_path = nil unless File.exist?(source_path)
210           end
211           [dependency_path, export, source_path]
212         end
213       end
214 
215       def base_directory
216         buildr_project.path_to
217       end
218 
219       def base_document
220         target = StringIO.new
221         Builder::XmlMarkup.new(:target => target).module(:version => "4", :relativePaths => "true", :type => self.type)
222         Buildr::IntellijIdea.new_document(target.string)
223       end
224 
225       def initial_components
226         []
227       end
228 
229       def default_components
230         [
231           lambda { module_root_component },
232           lambda { facet_component }
233         ]
234       end
235 
236       def facet_component
237         return nil if self.facets.empty?
238         fm = self.create_component("FacetManager")
239         self.facets.each do |facet|
240           fm.add_element facet
241         end
242         fm
243       end
244 
245       def module_root_component
246         create_component("NewModuleRootManager", "inherit-compiler-output" => "false") do |xml|
247           generate_compile_output(xml)
248           generate_content(xml) unless skip_content?
249           generate_initial_order_entries(xml)
250           project_dependencies = []
251 
252 
253           self.test_dependency_details.each do |dependency_path, export, source_path|
254             next unless export
255             generate_lib(xml, dependency_path, export, source_path, project_dependencies)
256           end
257 
258           self.test_dependency_details.each do |dependency_path, export, source_path|
259             next if export
260             generate_lib(xml, dependency_path, export, source_path, project_dependencies)
261           end
262 
263           xml.orderEntryProperties
264         end
265       end
266 
267       def generate_lib(xml, dependency_path, export, source_path, project_dependencies)
268         project_for_dependency = Buildr.projects.detect do |project|
269           [project.packages, project.compile.target, project.resources.target, project.test.compile.target, project.test.resources.target].flatten.
270             detect { |artifact| artifact.to_s == dependency_path }
271         end
272         if project_for_dependency
273           if project_for_dependency.iml? &&
274             !project_dependencies.include?(project_for_dependency) &&
275             project_for_dependency != self.buildr_project
276             generate_project_dependency(xml, project_for_dependency.iml.name, export, !export)
277           end
278           project_dependencies << project_for_dependency
279         else
280           generate_module_lib(xml, url_for_path(dependency_path), export, (source_path ? url_for_path(source_path) : nil), !export)
281         end
282       end
283 
284       def jar_path(path)
285         "jar://#{resolve_path(path)}!/"
286       end
287 
288       def file_path(path)
289         "file://#{resolve_path(path)}"
290       end
291 
292       def url_for_path(path)
293         if path =~ /jar$/i
294           jar_path(path)
295         else
296           file_path(path)
297         end
298       end
299 
300       def resolve_path(path)
301         m2repo = Buildr::Repositories.instance.local
302         if path.to_s.index(m2repo) == 0 && !self.local_repository_env_override.nil?
303           return path.sub(m2repo, "$#{self.local_repository_env_override}$")
304         else
305           begin
306             return "$MODULE_DIR$/#{relative(path)}"
307           rescue ArgumentError
308             # ArgumentError happens on windows when self.base_directory and path are on different drives
309             return path
310           end
311         end
312       end
313 
314       def relative(path)
315         ::Buildr::Util.relative_path(File.expand_path(path.to_s), self.base_directory)
316       end
317 
318       def generate_compile_output(xml)
319         xml.output(:url => file_path(self.main_output_dir.to_s))
320         xml.tag!("output-test", :url => file_path(self.test_output_dir.to_s))
321         xml.tag!("exclude-output")
322       end
323 
324       def generate_content(xml)
325         xml.content(:url => "file://$MODULE_DIR$") do
326           # Source folders
327           {
328             :main => self.main_source_directories,
329             :test => self.test_source_directories
330           }.each do |kind, directories|
331             directories.map { |dir| dir.to_s }.compact.sort.uniq.each do |dir|
332               xml.sourceFolder :url => file_path(dir), :isTestSource => (kind == :test ? 'true' : 'false')
333             end
334           end
335 
336           # Exclude target directories
337           self.net_excluded_directories.
338             collect { |dir| file_path(dir) }.
339             select { |dir| relative_dir_inside_dir?(dir) }.
340             sort.each do |dir|
341             xml.excludeFolder :url => dir
342           end
343         end
344       end
345 
346       def relative_dir_inside_dir?(dir)
347         !dir.include?("../")
348       end
349 
350       def generate_initial_order_entries(xml)
351         xml.orderEntry :type => "sourceFolder", :forTests => "false"
352         xml.orderEntry :type => "inheritedJdk"
353       end
354 
355       def generate_project_dependency(xml, other_project, export, test = false)
356         attribs = {:type => 'module', "module-name" => other_project}
357         attribs[:exported] = '' if export
358         attribs[:scope] = 'TEST' if test
359         xml.orderEntry attribs
360       end
361 
362       def generate_module_lib(xml, path, export, source_path, test = false)
363         attribs = {:type => 'module-library'}
364         attribs[:exported] = '' if export
365         attribs[:scope] = 'TEST' if test
366         xml.orderEntry attribs do
367           xml.library do
368             xml.CLASSES do
369               xml.root :url => path
370             end
371             xml.JAVADOC
372             xml.SOURCES do
373               if source_path
374                 xml.root :url => source_path
375               end
376             end
377           end
378         end
379       end
380 
381       # Don't exclude things that are subdirectories of other excluded things
382       def net_excluded_directories
383         net = []
384         all = self.excluded_directories.map { |dir| buildr_project._(dir.to_s) }.sort_by { |d| d.size }
385         all.each_with_index do |dir, i|
386           unless all[0 ... i].find { |other| dir =~ /^#{other}/ }
387             net << dir
388           end
389         end
390         net
391       end
392     end
393 
394     # IdeaModule represents an .ipr file
395     class IdeaProject < IdeaFile
396       attr_accessor :vcs
397       attr_accessor :extra_modules
398       attr_writer :jdk_version
399 
400       def initialize(buildr_project)
401         @buildr_project = buildr_project
402         @vcs = detect_vcs
403         @extra_modules = []
404       end
405 
406       def jdk_version
407         @jdk_version ||= buildr_project.compile.options.source || "1.6"
408       end
409 
410       protected
411 
412       def extension
413         "ipr"
414       end
415 
416       def detect_vcs
417         if File.directory?(buildr_project._('.svn'))
418           "svn"
419         elsif File.directory?(buildr_project._('.git'))
420           "Git"
421         end
422       end
423 
424       def base_document
425         target = StringIO.new
426         Builder::XmlMarkup.new(:target => target).project(:version => "4", :relativePaths => "false")
427         Buildr::IntellijIdea.new_document(target.string)
428       end
429 
430       def default_components
431         [
432           lambda { modules_component },
433           vcs_component
434         ]
435       end
436 
437       def initial_components
438         [
439           lambda { project_root_manager_component },
440           lambda { project_details_component }
441         ]
442       end
443 
444       def project_root_manager_component
445         attribs = {"version" => "2",
446                    "assert-keyword" => "true",
447                    "jdk-15" => "true",
448                    "project-jdk-name" => self.jdk_version,
449                    "project-jdk-type" => "JavaSDK",
450                    "languageLevel" => "JDK_#{self.jdk_version.gsub('.', '_')}"}
451         create_component("ProjectRootManager", attribs) do |xml|
452           xml.output("url" => "file://$PROJECT_DIR$/out")
453         end
454       end
455 
456       def project_details_component
457         create_component("ProjectDetails") do |xml|
458           xml.option("name" => "projectName", "value" => self.name)
459         end
460       end
461 
462       def modules_component
463         create_component("ProjectModuleManager") do |xml|
464           xml.modules do
465             buildr_project.projects.select { |subp| subp.iml? }.each do |subproject|
466               module_path = subproject.base_dir.gsub(/^#{buildr_project.base_dir}\//, '')
467               path = "#{module_path}/#{subproject.iml.name}.iml"
468               attribs = {:fileurl => "file://$PROJECT_DIR$/#{path}", :filepath => "$PROJECT_DIR$/#{path}"}
469               if subproject.iml.group == true
470                 attribs[:group] = subproject.parent.name.gsub(':', '/')
471               elsif !subproject.iml.group.nil?
472                 attribs[:group] = subproject.group.to_s
473               end
474               xml.module attribs
475             end
476             self.extra_modules.each do |iml_file|
477               xml.module :fileurl => "file://$PROJECT_DIR$/#{iml_file}",
478                          :filepath => "$PROJECT_DIR$/#{iml_file}"
479             end
480             if buildr_project.iml?
481               xml.module :fileurl => "file://$PROJECT_DIR$/#{buildr_project.iml.name}.iml",
482                          :filepath => "$PROJECT_DIR$/#{buildr_project.iml.name}.iml"
483             end
484           end
485         end
486       end
487 
488       def vcs_component
489         if vcs
490           create_component("VcsDirectoryMappings") do |xml|
491             xml.mapping :directory => "", :vcs => vcs
492           end
493         end
494       end
495     end
496 
497     module ProjectExtension
498       include Extension
499 
500       first_time do
501         desc "Generate Intellij IDEA artifacts for all projects"
502         Project.local_task "idea" => "artifacts"
503 
504         desc "Delete the generated Intellij IDEA artifacts"
505         Project.local_task "idea:clean"
506       end
507 
508       before_define do |project|
509         project.recursive_task("idea")
510         project.recursive_task("idea:clean")
511       end
512 
513       after_define do |project|
514         idea = project.task("idea")
515 
516         files = [
517           (project.iml if project.iml?),
518           (project.ipr if project.ipr?)
519         ].compact
520 
521         files.each do |ideafile|
522           module_dir =  File.dirname(ideafile.filename)
523           # Need to clear the actions else the extension included as part of buildr will run
524           file(ideafile.filename).clear_actions
525           idea.enhance [file(ideafile.filename)]
526           file(ideafile.filename => [Buildr.application.buildfile]) do |task|
527             mkdir_p module_dir
528             info "Writing #{task.name}"
529             t = Tempfile.open("buildr-idea")
530             temp_filename = t.path
531             t.close!
532             File.open(temp_filename, "w") do |f|
533               ideafile.write f
534             end
535             mv temp_filename, ideafile.filename
536           end
537         end
538 
539         project.task("idea:clean") do
540           files.each do |f|
541             info "Removing #{f.filename}" if File.exist?(f.filename)
542             rm_rf f.filename
543           end
544         end
545       end
546 
547       def ipr
548         if ipr?
549           @ipr ||= IdeaProject.new(self)
550         else
551           raise "Only the root project has an IPR"
552         end
553       end
554 
555       def ipr?
556         !@no_ipr && self.parent.nil?
557       end
558 
559       def iml
560         if iml?
561           unless @iml
562             inheritable_iml_source = self.parent
563             while inheritable_iml_source && !inheritable_iml_source.iml?
564               inheritable_iml_source = inheritable_iml_source.parent;
565             end
566             @iml = inheritable_iml_source ? inheritable_iml_source.iml.clone : IdeaModule.new
567             @iml.buildr_project = self
568           end
569           return @iml
570         else
571           raise "IML generation is disabled for #{self.name}"
572         end
573       end
574 
575       def no_ipr
576         @no_ipr = true
577       end
578 
579       def no_iml
580         @has_iml = false
581       end
582 
583       def iml?
584         @has_iml = @has_iml.nil? ? true : @has_iml
585       end
586     end
587   end
588 end
589 
590 class Buildr::Project
591   include Buildr::IntellijIdea::ProjectExtension
592 end

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