lib/java/idea.rb in buildr-1.1.3 vs lib/java/idea.rb in buildr-1.2.0
- old
+ new
@@ -1,8 +1,10 @@
require "pathname"
require "core/project"
require "java/artifact"
+require 'stringio'
+require 'rexml/document'
module Buildr
# Global task "idea" generates artifacts for all projects.
desc "Generate Idea artifacts for all projects"
@@ -13,112 +15,145 @@
project.enhance do |project|
# 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 Rakefile changes, but also anything loaded by
- # the Rakefile (buildr.rb, separate file listing dependencies, etc), so we add anything required
- # after the Rakefile. So which don't know where Buildr shows up exactly, ignore files that show
+ # 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 = ($LOADED_FEATURES - Buildr.instance_eval("@loaded_features_to_ignore")).
map { |file| File.expand_path(file) }.select { |file| File.exist?(file) }
sources << File.expand_path(Rake.application.rakefile, root_path) if Rake.application.rakefile
- # Only for projects that are packagable.
- if project.packages.detect { |pkg| pkg.type.to_s =~ /(jar)|(war)|(rar)|(mar)|(aar)/ }
- task_name = project.path_to("#{project.name.sub(':', '-')}.iml")
- idea.enhance [ file(task_name) ]
-
- # The only thing we need to look for is a change in the Rakefile.
- file(task_name=>sources) do |task|
- puts "Writing #{task.name}" # if verbose
+ # Find a path relative to the project's root directory.
+ relative = lambda do |path|
+ msg = [:to_path, :to_str, :to_s].find { |msg| path.respond_to? msg }
+ path = path.__send__(msg)
+ Pathname.new(path).relative_path_from(Pathname.new(project.path_to)).to_s
+ end
- # Find a path relative to the project's root directory.
- relative = lambda do |path|
- msg = [:to_path, :to_str, :to_s].find { |msg| path.respond_to? msg }
- path = path.__send__(msg)
- Pathname.new(path).relative_path_from(Pathname.new(project.path_to)).to_s
- end
+ m2repo = Buildr::Repositories.instance.local
+ excludes = [ '**/.svn/', '**/CVS/' ].join('|')
- m2repo = Buildr::Repositories.instance.local
- excludes = [ '**/.svn/', '**/CVS/' ].join('|')
+ # Only for projects that are packageable.
+ task_name = project.path_to("#{project.name.sub(':', '-')}.iml")
+ idea.enhance [ file(task_name) ]
- # Idea handles modules slightly differently if they're WARs
- idea_types = {"jar"=>"JAVA_MODULE", "war"=>"J2EE_WEB_MODULE"}
- idea_types["rar"] = idea_types["mar"] = idea_types["jar"]
+ # The only thing we need to look for is a change in the Buildfile.
+ file(task_name=>sources) do |task|
+ puts "Writing #{task.name}" if verbose
- # Note: Use the test classpath since Eclipse compiles both "main" and "test" classes using the same classpath
- cp = project.test.compile.classpath.map(&:to_s) - [ project.compile.target.to_s ]
+ # Idea handles modules slightly differently if they're WARs
+ idea_types = Hash.new("JAVA_MODULE")
+ idea_types["war"] = "J2EE_WEB_MODULE"
- # Convert classpath elements into applicable Project objects
- cp.collect! { |path| projects.detect { |prj| prj.packages.detect { |pkg| pkg.to_s == path } } || path }
+ # Note: Use the test classpath since Eclipse compiles both "main" and "test" classes using the same classpath
+ cp = project.test.compile.classpath.map(&:to_s) - [ project.compile.target.to_s ]
- # project_libs: artifacts created by other projects
- project_libs, others = cp.partition { |path| path.is_a?(Project) }
+ # Convert classpath elements into applicable Project objects
+ cp.collect! { |path| projects.detect { |prj| prj.packages.detect { |pkg| pkg.to_s == path } } || path }
- # Separate artifacts from Maven2 repository
- m2_libs, others = others.partition { |path| path.to_s.index(m2repo) == 0 }
+ # project_libs: artifacts created by other projects
+ project_libs, others = cp.partition { |path| path.is_a?(Project) }
- # 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 }
+ # Separate artifacts from Maven2 repository
+ m2_libs, others = others.partition { |path| path.to_s.index(m2repo) == 0 }
- File.open(task.name, "w") do |file|
- xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
- # Project type is going to be the first package type
- xml.module(:version=>"4", :relativePaths=>"false", :type=>idea_types[project.packages.first.type.to_s]) do
+ # 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 }
- xml.component :name=>"ModuleRootManager"
- xml.component "name"=>"NewModuleRootManager", "inherit-compiler-output"=>"false" do
- xml.output :url=>"file://$MODULE_DIR$/#{relative[project.compile.target]}"
+ File.open(task.name, "w") do |file|
+ xml = Builder::XmlMarkup.new(:target=>file, :indent=>2)
+ # Project type is going to be the first package type
+ xml.module(:version=>"4", :relativePaths=>"false", :type=>idea_types[project.packages.first.type.to_s]) do
- # TODO project.test.target isn't recognized, what's the proper way to get the test compile path?
- xml.tag! "output-test", :url=>"file://$MODULE_DIR$/target/test-classes"
- xml.tag! "exclude-output"
+ xml.component :name=>"ModuleRootManager"
+ xml.component "name"=>"NewModuleRootManager", "inherit-compiler-output"=>"false" do
+ xml.output :url=>"file://$MODULE_DIR$/#{relative[project.compile.target]}"
+ xml.tag! "exclude-output"
- xml.content do
- srcs = project.compile.sources.map { |src| relative[src] } + generated.map { |src| relative[src] }
- srcs.sort.uniq.each do |path|
- xml.sourceFolder :url=>"file://$MODULE_DIR$/#{path}", :isTestSource=>"false"
+ # TODO project.test.target isn't recognized, what's the proper way to get the test compile path?
+ xml.tag! "output-test", :url=>"file://$MODULE_DIR$/target/test-classes"
+
+ xml.content(:url=>"file://$MODULE_DIR$") do
+ srcs = project.compile.sources.map { |src| relative[src] } + generated.map { |src| relative[src] }
+ srcs.sort.uniq.each do |path|
+ xml.sourceFolder :url=>"file://$MODULE_DIR$/#{path}", :isTestSource=>"false"
+ end
+ test_sources = project.test.compile.sources.map { |src| relative[src] }
+ test_sources.each do |paths|
+ paths.sort.uniq.each do |path|
+ xml.sourceFolder :url=>"file://$MODULE_DIR$/#{path}", :isTestSource=>"true"
end
- test_sources = project.test.compile.sources.map { |src| relative[src] }
- test_sources.each do |paths|
- paths.sort.uniq.each do |path|
- xml.sourceFolder :url=>"file://$MODULE_DIR$/#{path}", :isTestSource=>"true"
- end
- end
- xml.excludeFolder :url=>"file://$MODULE_DIR$/#{relative[project.compile.target]}"
end
+ {"src/main/resources"=>false, "src/test/resources"=>true}.each do |key, value|
+ xml.sourceFolder :url=>"file://$MODULE_DIR$/#{key}", :isTestSource=>"#{value}" if File.exist?(project.path_to(key))
+ end
+ xml.excludeFolder :url=>"file://$MODULE_DIR$/#{relative[project.compile.target]}"
+ end
- xml.orderEntry :type=>"sourceFolder", :forTests=>"false"
- xml.orderEntry :type=>"inheritedJdk"
+ xml.orderEntry :type=>"sourceFolder", :forTests=>"false"
+ xml.orderEntry :type=>"inheritedJdk"
- # Classpath elements from other projects
- project_libs.map(&:id).sort.uniq.each do |project_id|
- xml.orderEntry :type=>'module', :name=>project_id
- end
+ # Classpath elements from other projects
+ project_libs.map(&:id).sort.uniq.each do |project_id|
+ xml.orderEntry :type=>'module', "module-name"=>project_id
+ end
- # Libraries
- ext_libs = libs.map {|path| "$MODULE_DIR$/#{path.to_s}" } +
- m2_libs.map { |path| path.to_s.sub(m2repo, "$M2_REPO$") }
- ext_libs.each do |path|
- xml.orderEntry :type=>"module-library" do
- xml.library do
- xml.CLASSES do
- xml.root :url=>"jar://#{path}!/"
- end
- xml.JAVADOC
- xml.SOURCES
+ # Libraries
+ ext_libs = libs.map {|path| "$MODULE_DIR$/#{path.to_s}" } +
+ m2_libs.map { |path| path.to_s.sub(m2repo, "$M2_REPO$") }
+ ext_libs.each do |path|
+ xml.orderEntry :type=>"module-library" do
+ xml.library do
+ xml.CLASSES do
+ xml.root :url=>"jar://#{path}!/"
end
+ xml.JAVADOC
+ xml.SOURCES
end
end
-
- xml.orderEntryProperties
end
+
+ xml.orderEntryProperties
end
end
end
+ end
+ # Root project aggregates all the subprojects.
+ if project.parent == nil
+ task_name = project.path_to("#{project.name.sub(':', '-')}.ipr")
+ idea.enhance [ file(task_name) ]
+
+ file(task_name=>sources) do |task|
+ puts "Writing #{task.name}" if verbose
+
+ # Generating just the little stanza that chanages from one project to another
+ partial = StringIO.new
+ xml = Builder::XmlMarkup.new(:target=>partial, :indent=>2)
+ xml.component(:name=>"ProjectModuleManager") do
+ xml.modules do
+ project.projects.each do |subp|
+ module_name = subp.name.gsub(":", "-")
+ module_path = subp.name[/:(.*)/][1..-1]
+ path = "#{module_path}/#{module_name}.iml"
+ xml.module :fileurl=>"file://$PROJECT_DIR$/#{path}", :filepath=>"$PROJECT_DIR$/#{path}"
+ end
+ xml.module :fileurl=>"file://$PROJECT_DIR$/#{project.name}.iml", :filepath=>"$PROJECT_DIR$/#{project.name}.iml"
+ end
+ end
+
+ # Loading the whole fairly constant crap
+ template_xml = REXML::Document.new(File.open(File.dirname(__FILE__)+"/idea.ipr.template"))
+ include_xml = REXML::Document.new(partial.string)
+ template_xml.root.add_element(include_xml.root)
+ template_xml.write(File.new(task.name, "w"))
+
+ end
end
+
end
end
end # module Buildr