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