lib/buildr/ide/eclipse.rb in vic-buildr-1.3.1 vs lib/buildr/ide/eclipse.rb in vic-buildr-1.3.3

- old
+ new

@@ -33,20 +33,11 @@ project.recursive_task("eclipse") end after_define do |project| eclipse = project.task("eclipse") - # We need paths relative to the top project's base directory. - root_path = lambda { |p| f = lambda { |p| p.parent ? f[p.parent] : p.base_dir } ; f[p] }[project] - # We want the Eclipse files changed every time the Buildfile changes, but also anything loaded by - # the Buildfile (buildr.rb, separate file listing dependencies, etc), so we add anything required - # after the Buildfile. So which don't know where Buildr shows up exactly, ignore files that show - # in $LOADED_FEATURES that we cannot resolve. - sources = Buildr.application.build_files.map { |file| File.expand_path(file) }.select { |file| File.exist?(file) } - sources << File.expand_path(Buildr.application.buildfile, root_path) if Buildr.application.buildfile - # Check if project has scala facet scala = project.compile.language == :scala # Only for projects that we support supported_languages = [:java, :scala] @@ -54,27 +45,18 @@ if (supported_languages.include? project.compile.language || project.packages.detect { |pkg| supported_packaging.include?(pkg.type.to_s) }) eclipse.enhance [ file(project.path_to(".classpath")), file(project.path_to(".project")) ] # The only thing we need to look for is a change in the Buildfile. - file(project.path_to(".classpath")=>sources) do |task| - puts "Writing #{task.name}" if verbose + file(project.path_to(".classpath")=>Buildr.application.buildfile) do |task| + info "Writing #{task.name}" - # Find a path relative to the project's root directory. - relative = lambda do |path| - path or raise "Invalid path '#{path.inspect}'" - msg = [:to_path, :to_str, :to_s].find { |msg| path.respond_to? msg } - path = path.__send__(msg) - Util.relative_path(File.expand_path(path), project.path_to) - end - m2repo = Buildr::Repositories.instance.local - excludes = [ '**/.svn/', '**/CVS/' ].join('|') File.open(task.name, "w") do |file| - xml = Builder::XmlMarkup.new(:target=>file, :indent=>2) - xml.classpath do + classpathentry = ClasspathEntryWriter.new project, file + classpathentry.write do # Note: Use the test classpath since Eclipse compiles both "main" and "test" classes using the same classpath cp = project.test.compile.dependencies.map(&:to_s) - [ project.compile.target.to_s, project.resources.target.to_s ] cp = cp.uniq # Convert classpath elements into applicable Project objects @@ -87,90 +69,139 @@ m2_libs, others = others.partition { |path| path.to_s.index(m2repo) == 0 } # Generated: classpath elements in the project are assumed to be generated generated, libs = others.partition { |path| path.to_s.index(project.path_to.to_s) == 0 } - srcs = project.compile.sources + classpathentry.src project.compile.sources + generated + classpathentry.src project.resources - srcs = srcs.map { |src| relative[src] } + generated.map { |src| relative[src] } - srcs.sort.uniq.each do |path| - xml.classpathentry :kind=>'src', :path=>path, :excluding=>excludes - end - - # Main resources implicitly copied into project.compile.target - main_resource_sources = project.resources.sources.map { |src| relative[src] } - main_resource_sources.each do |path| - if File.exist? project.path_to(path) - xml.classpathentry :kind=>'src', :path=>path, :excluding=>excludes - end - end - if project.test.compile.target - # Test classes are generated in a separate output directory - test_sources = project.test.compile.sources.map { |src| relative[src] } - test_sources.each do |paths| - paths.sort.uniq.each do |path| - xml.classpathentry :kind=>'src', :path=>path, :output => relative[project.test.compile.target], :excluding=>excludes - end - end - - # Test resources go in separate output directory as well - project.test.resources.sources.each do |path| - if File.exist? project.path_to(path) - xml.classpathentry :kind=>'src', :path=>relative[path], :output => relative[project.test.compile.target], :excluding=>excludes - end - end + classpathentry.src project.test.compile + classpathentry.src project.test.resources end # Classpath elements from other projects - project_libs.map(&:id).sort.uniq.each do |project_id| - xml.classpathentry :kind=>'src', :combineaccessrules=>"false", :path=>"/#{project_id}" - end + classpathentry.src_projects project_libs - { :output => relative[project.compile.target], - :lib => libs.map(&:to_s), - :var => m2_libs.map { |path| path.to_s.sub(m2repo, 'M2_REPO') } - }.each do |kind, paths| - paths.sort.uniq.each do |path| - xml.classpathentry :kind=>kind, :path=>path - end - end + classpathentry.output project.compile.target + classpathentry.lib libs + classpathentry.var m2_libs, 'M2_REPO', m2repo - xml.classpathentry :kind=>'con', :path=>'org.eclipse.jdt.launching.JRE_CONTAINER' - xml.classpathentry :kind=>'con', :path=>'ch.epfl.lamp.sdt.launching.SCALA_CONTAINER' if scala + classpathentry.con 'ch.epfl.lamp.sdt.launching.SCALA_CONTAINER' if scala + classpathentry.con 'org.eclipse.jdt.launching.JRE_CONTAINER' end end end # The only thing we need to look for is a change in the Buildfile. - file(project.path_to(".project")=>sources) do |task| - puts "Writing #{task.name}" if verbose + file(project.path_to(".project")=>Buildr.application.buildfile) do |task| + info "Writing #{task.name}" File.open(task.name, "w") do |file| xml = Builder::XmlMarkup.new(:target=>file, :indent=>2) xml.projectDescription do xml.name project.id xml.projects xml.buildSpec do - xml.buildCommand do - xml.name "org.eclipse.jdt.core.javabuilder" - end if scala xml.buildCommand do xml.name "ch.epfl.lamp.sdt.core.scalabuilder" - #xml.name "scala.plugin.scalabuilder" end + else + xml.buildCommand do + xml.name "org.eclipse.jdt.core.javabuilder" + end end end xml.natures do - xml.nature "org.eclipse.jdt.core.javanature" xml.nature "ch.epfl.lamp.sdt.core.scalanature" if scala - #xml.nature "scala.plugin.scalanature" if scala + xml.nature "org.eclipse.jdt.core.javanature" end end end end end + end + + # Writes 'classpathentry' tags in an xml file. + # It converts tasks to paths. + # It converts absolute paths to relative paths. + # It ignores duplicate directories. + class ClasspathEntryWriter + def initialize project, target + @project = project + @xml = Builder::XmlMarkup.new(:target=>target, :indent=>2) + @excludes = [ '**/.svn/', '**/CVS/' ].join('|') + @paths_written = [] + end + + def write &block + @xml.classpath &block + end + + def con path + @xml.classpathentry :kind=>'con', :path=>path + end + + def lib libs + libs.map(&:to_s).sort.uniq.each do |path| + @xml.classpathentry :kind=>'lib', :path=>path + end + end + + # Write a classpathentry of kind 'src'. + # Accepts an array of absolute paths or a task. + def src arg + if [:sources, :target].all? { |message| arg.respond_to?(message) } + src_from_task arg + else + src_from_absolute_paths arg + end + end + + # Write a classpathentry of kind 'src' for dependent projects. + # Accepts an array of projects. + def src_projects project_libs + project_libs.map(&:id).sort.uniq.each do |project_id| + @xml.classpathentry :kind=>'src', :combineaccessrules=>"false", :path=>"/#{project_id}" + end + end + + def output target + @xml.classpathentry :kind=>'output', :path=>relative(target) + end + + def var libs, var_name, var_value + libs.map { |lib| lib.to_s.sub(var_value, var_name) }.sort.uniq.each do |path| + @xml.classpathentry :kind=>'var', :path=>path + end + end + + private + + # Find a path relative to the project's root directory. + def relative path + path or raise "Invalid path '#{path.inspect}'" + msg = [:to_path, :to_str, :to_s].find { |msg| path.respond_to? msg } + path = path.__send__(msg) + Util.relative_path(File.expand_path(path), @project.path_to) + end + + def src_from_task task + src_from_absolute_paths task.sources, task.target + end + + def src_from_absolute_paths absolute_paths, output=nil + relative_paths = absolute_paths.map { |src| relative(src) } + relative_paths.sort.uniq.each do |path| + unless @paths_written.include?(path) + attributes = { :kind=>'src', :path=>path, :excluding=>@excludes } + attributes[:output] = relative(output) if output + @xml.classpathentry attributes + @paths_written << path + end + end + end end end end # module Buildr