You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@buildr.apache.org by do...@apache.org on 2011/08/17 13:28:11 UTC

svn commit: r1158635 - in /buildr/trunk: CHANGELOG doc/more_stuff.textile lib/buildr/ide/idea.rb spec/ide/idea_spec.rb

Author: donaldp
Date: Wed Aug 17 11:28:11 2011
New Revision: 1158635

URL: http://svn.apache.org/viewvc?rev=1158635&view=rev
Log:
Enhance the Intellij IDEA extension to support the addition of "artifacts" and "configurations" to the generated project file.

Modified:
    buildr/trunk/CHANGELOG
    buildr/trunk/doc/more_stuff.textile
    buildr/trunk/lib/buildr/ide/idea.rb
    buildr/trunk/spec/ide/idea_spec.rb

Modified: buildr/trunk/CHANGELOG
URL: http://svn.apache.org/viewvc/buildr/trunk/CHANGELOG?rev=1158635&r1=1158634&r2=1158635&view=diff
==============================================================================
--- buildr/trunk/CHANGELOG (original)
+++ buildr/trunk/CHANGELOG Wed Aug 17 11:28:11 2011
@@ -1,5 +1,7 @@
 1.4.7 (Pending)
-* Change: Changed the default output directory for Intellij IDEA to be
+* Added:  Enhance the Intellij IDEA extension to support the addition of "artifacts"
+          and "configurations" to the generated project file.
+* Change: Changed the default output directory for Intellij IDEA extension to be
           _(:target, :main, :idea, :classes) from _(:target, :main, :java) and the
           default test output directory to be _(:target, :test, :idea, :classes)
           from _(:target, :test, :java)

Modified: buildr/trunk/doc/more_stuff.textile
URL: http://svn.apache.org/viewvc/buildr/trunk/doc/more_stuff.textile?rev=1158635&r1=1158634&r2=1158635&view=diff
==============================================================================
--- buildr/trunk/doc/more_stuff.textile (original)
+++ buildr/trunk/doc/more_stuff.textile Wed Aug 17 11:28:11 2011
@@ -591,6 +591,48 @@ define "foo" do
 end
 {% endhighlight %}
 
+h4. Project Configurations
+
+Configurations are IDEAs mechanism for running or debugging the project. Shared configurations are stored in the project file. The extension makes it possible to generate an @.ipr@ with specific configurations via the "ipr.add_configuration" method.
+
+h5. Example
+
+This example adds a configuration to invoke a GWT application.
+
+{% highlight ruby %}
+define "foo" do
+  ...
+  ipr.add_configuration("Run Contacts.html", "GWT.ConfigurationType", "GWT Configuration") do |xml|
+    xml.module(:name => project.iml.id)
+    xml.option(:name => "RUN_PAGE", :value => "Contacts.html")
+    xml.option(:name => "compilerParameters", :value => "-draftCompile -localWorkers 2")
+    xml.option(:name => "compilerMaxHeapSize", :value => "512")
+
+    xml.RunnerSettings(:RunnerId => "Run")
+    xml.ConfigurationWrapper(:RunnerId => "Run")
+    xml.method()
+  end
+end
+{% endhighlight %}
+
+h4. Project Artifacts
+
+IDEA can build artifacts such as jars and wars. The artifact configuration is stored in the project file. The extension makes it possible to generate an @.ipr@ with specific artifacts via the "ipr.add_artifact" method.
+
+h5. Example
+
+This example adds a jar artifact to the project.
+
+{% highlight ruby %}
+define "foo" do
+  ...
+  ipr.add_artifact("MyFancy.jar", "jar") do |xml|
+    xml.tag!('output-path', project._(:artifacts, "MyFancy.jar"))
+    xml.element :id => "module-output", :name => "foo"
+  end
+end
+{% endhighlight %}
+
 h4. Custom Component Sections
 
 If the extension does not provide capability to generate configuration for a particular IDEA plugin the user can provide their own configuration data via the "ipr.add_component" or "iml.add_component" methods.

Modified: buildr/trunk/lib/buildr/ide/idea.rb
URL: http://svn.apache.org/viewvc/buildr/trunk/lib/buildr/ide/idea.rb?rev=1158635&r1=1158634&r2=1158635&view=diff
==============================================================================
--- buildr/trunk/lib/buildr/ide/idea.rb (original)
+++ buildr/trunk/lib/buildr/ide/idea.rb Wed Aug 17 11:28:11 2011
@@ -22,11 +22,17 @@ module Buildr
     # Abstract base class for IdeaModule and IdeaProject
     class IdeaFile
       DEFAULT_SUFFIX = ""
+      DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE = "MAVEN_REPOSITORY"
 
       attr_reader :buildr_project
       attr_writer :suffix
       attr_writer :id
       attr_accessor :template
+      attr_reader :local_repository_env_override
+
+      def local_repository_env_override
+        @local_repository_env_override || DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE
+      end
 
       def suffix
         @suffix ||= DEFAULT_SUFFIX
@@ -54,6 +60,32 @@ module Buildr
         "#{self.id}#{suffix}"
       end
 
+      def relative(path)
+        ::Buildr::Util.relative_path(File.expand_path(path.to_s), self.base_directory)
+      end
+
+      def base_directory
+        buildr_project.path_to
+      end
+
+      def resolve_path_from_base(path, base_variable)
+        m2repo = Buildr::Repositories.instance.local
+        if path.to_s.index(m2repo) == 0 && !self.local_repository_env_override.nil?
+          return path.sub(m2repo, "$#{self.local_repository_env_override}$")
+        else
+          begin
+            return "#{base_variable}/#{relative(path)}"
+          rescue ArgumentError
+            # ArgumentError happens on windows when self.base_directory and path are on different drives
+            return path
+          end
+        end
+      end
+
+      def file_path(path)
+        "file://#{resolve_path(path)}"
+      end
+
       def create_component(name, attrs = {})
         target = StringIO.new
         Builder::XmlMarkup.new(:target => target, :indent => 2).component(attrs.merge({:name => name})) do |xml|
@@ -66,6 +98,24 @@ module Buildr
         @components ||= self.default_components.compact
       end
 
+      def create_composite_component(name, components)
+        return nil if components.empty?
+        component = self.create_component(name)
+        components.each do |element|
+          element = element.call if element.is_a?(Proc)
+          component.add_element element
+        end
+        component
+      end
+
+      def add_to_composite_component(components)
+        components << lambda do
+          target = StringIO.new
+          yield Builder::XmlMarkup.new(:target => target, :indent => 2)
+          Buildr::IntellijIdea.new_document(target.string).root
+        end
+      end
+
       def load_document(filename)
         Buildr::IntellijIdea.new_document(File.read(filename))
       end
@@ -105,16 +155,13 @@ module Buildr
     # IdeaModule represents an .iml file
     class IdeaModule < IdeaFile
       DEFAULT_TYPE = "JAVA_MODULE"
-      DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE = "MAVEN_REPOSITORY"
 
       attr_accessor :type
-      attr_accessor :local_repository_env_override
       attr_accessor :group
       attr_reader :facets
 
       def initialize
         @type = DEFAULT_TYPE
-        @local_repository_env_override = DEFAULT_LOCAL_REPOSITORY_ENV_OVERRIDE
       end
 
       def buildr_project=(buildr_project)
@@ -173,11 +220,11 @@ module Buildr
       end
 
       def add_facet(name, type)
-        target = StringIO.new
-        Builder::XmlMarkup.new(:target => target, :indent => 2).facet(:name => name, :type => type) do |xml|
-          yield xml if block_given?
+        add_to_composite_component(self.facets) do |xml|
+          xml.facet(:name => name, :type => type) do |xml|
+            yield xml if block_given?
+          end
         end
-        self.facets << Buildr::IntellijIdea.new_document(target.string).root
       end
 
       def skip_content?
@@ -206,10 +253,6 @@ module Buildr
         end
       end
 
-      def base_directory
-        buildr_project.path_to
-      end
-
       def base_document
         target = StringIO.new
         Builder::XmlMarkup.new(:target => target).module(:version => "4", :relativePaths => "true", :type => self.type)
@@ -228,12 +271,7 @@ module Buildr
       end
 
       def facet_component
-        return nil if self.facets.empty?
-        fm = self.create_component("FacetManager")
-        self.facets.each do |facet|
-          fm.add_element facet
-        end
-        fm
+        create_composite_component("FacetManager", self.facets)
       end
 
       def module_root_component
@@ -279,10 +317,6 @@ module Buildr
         "jar://#{resolve_path(path)}!/"
       end
 
-      def file_path(path)
-        "file://#{resolve_path(path)}"
-      end
-
       def url_for_path(path)
         if path =~ /jar$/i
           jar_path(path)
@@ -292,21 +326,7 @@ module Buildr
       end
 
       def resolve_path(path)
-        m2repo = Buildr::Repositories.instance.local
-        if path.to_s.index(m2repo) == 0 && !self.local_repository_env_override.nil?
-          return path.sub(m2repo, "$#{self.local_repository_env_override}$")
-        else
-          begin
-            return "$MODULE_DIR$/#{relative(path)}"
-          rescue ArgumentError
-            # ArgumentError happens on windows when self.base_directory and path are on different drives
-            return path
-          end
-        end
-      end
-
-      def relative(path)
-        ::Buildr::Util.relative_path(File.expand_path(path.to_s), self.base_directory)
+        resolve_path_from_base(path, "$MODULE_DIR$")
       end
 
       def generate_compile_output(xml)
@@ -389,18 +409,38 @@ module Buildr
     class IdeaProject < IdeaFile
       attr_accessor :vcs
       attr_accessor :extra_modules
+      attr_accessor :artifacts
+      attr_accessor :configurations
       attr_writer :jdk_version
 
       def initialize(buildr_project)
         @buildr_project = buildr_project
         @vcs = detect_vcs
         @extra_modules = []
+        @artifacts = []
+        @configurations = []
       end
 
       def jdk_version
         @jdk_version ||= buildr_project.compile.options.source || "1.6"
       end
 
+      def add_artifact(name, type, build_on_make = true)
+        add_to_composite_component(self.artifacts) do |xml|
+          xml.artifact(:name => name, :type => type, :"build-on-make" => build_on_make) do |xml|
+            yield xml if block_given?
+          end
+        end
+      end
+
+      def add_configuration(name, type, factory_name, default = false)
+        add_to_composite_component(self.configurations) do |xml|
+          xml.configuration(:name => name, :type => type, :factoryName => factory_name, :default => default) do |xml|
+            yield xml if block_given?
+          end
+        end
+      end
+
       protected
 
       def extension
@@ -424,7 +464,9 @@ module Buildr
       def default_components
         [
           lambda { modules_component },
-          vcs_component
+          vcs_component,
+          artifacts_component,
+          configurations_component
         ]
       end
 
@@ -486,6 +528,18 @@ module Buildr
           end
         end
       end
+
+      def artifacts_component
+        create_composite_component("ArtifactManager", self.artifacts)
+      end
+
+      def configurations_component
+        create_composite_component("ProjectRunConfigurationManager", self.configurations)
+      end
+
+      def resolve_path(path)
+        resolve_path_from_base(path, "$PROJECT_DIR$")
+      end
     end
 
     module ProjectExtension

Modified: buildr/trunk/spec/ide/idea_spec.rb
URL: http://svn.apache.org/viewvc/buildr/trunk/spec/ide/idea_spec.rb?rev=1158635&r1=1158634&r2=1158635&view=diff
==============================================================================
--- buildr/trunk/spec/ide/idea_spec.rb (original)
+++ buildr/trunk/spec/ide/idea_spec.rb Wed Aug 17 11:28:11 2011
@@ -296,6 +296,66 @@ describe Buildr::IntellijIdea do
       end
     end
 
+    describe "with artifacts added to root project" do
+      before do
+        @foo = define "foo" do
+          ipr.add_artifact("MyFancy.jar", "jar") do |xml|
+            xml.tag!('output-path', project._(:artifacts, "MyFancy.jar"))
+            xml.element :id => "module-output", :name => "foo"
+          end
+          ipr.add_artifact("MyOtherFancy.jar", "jar") do |xml|
+            xml.tag!('output-path', project._(:artifacts, "MyOtherFancy.jar"))
+            xml.element :id => "module-output", :name => "foo"
+          end
+        end
+        invoke_generate_task
+      end
+
+      it "generates an IPR with multiple jar artifacts" do
+        doc = xml_document(@foo._("foo.ipr"))
+        facet_xpath = "/project/component[@name='ArtifactManager']/artifact"
+        doc.should have_nodes(facet_xpath, 2)
+        doc.should have_xpath("#{facet_xpath}[@type='jar', @name='MyFancy.jar']")
+        doc.should have_xpath("#{facet_xpath}[@type='jar', @name='MyOtherFancy.jar']")
+      end
+    end
+
+    describe "with configurations added to root project" do
+      before do
+        @foo = define "foo" do
+          ipr.add_configuration("Run Contacts.html", "GWT.ConfigurationType", "GWT Configuration") do |xml|
+            xml.module(:name => project.iml.id)
+            xml.option(:name => "RUN_PAGE", :value => "Contacts.html")
+            xml.option(:name => "compilerParameters", :value => "-draftCompile -localWorkers 2")
+            xml.option(:name => "compilerMaxHeapSize", :value => "512")
+
+            xml.RunnerSettings(:RunnerId => "Run")
+            xml.ConfigurationWrapper(:RunnerId => "Run")
+            xml.method()
+          end
+          ipr.add_configuration("Run Planner.html", "GWT.ConfigurationType", "GWT Configuration") do |xml|
+            xml.module(:name => project.iml.id)
+            xml.option(:name => "RUN_PAGE", :value => "Planner.html")
+            xml.option(:name => "compilerParameters", :value => "-draftCompile -localWorkers 2")
+            xml.option(:name => "compilerMaxHeapSize", :value => "512")
+
+            xml.RunnerSettings(:RunnerId => "Run")
+            xml.ConfigurationWrapper(:RunnerId => "Run")
+            xml.method()
+          end
+        end
+        invoke_generate_task
+      end
+
+      it "generates an IPR with multiple configurations" do
+        doc = xml_document(@foo._("foo.ipr"))
+        facet_xpath = "/project/component[@name='ProjectRunConfigurationManager']/configuration"
+        doc.should have_nodes(facet_xpath, 2)
+        doc.should have_xpath("#{facet_xpath}[@type='GWT.ConfigurationType', @name='Run Contacts.html']")
+        doc.should have_xpath("#{facet_xpath}[@type='GWT.ConfigurationType', @name='Run Planner.html']")
+      end
+    end
+
     describe "with iml.group specified" do
       before do
         @foo = define "foo" do