Intellij IDEA support for buildr
This extension provides tasks to generate Intellij IDEA project files by issuing:
$ buildr iidea:generate
This task will generate an .iml file for every project (or sub-project) and a .ipr that you can directly open for the root project.
The generated project files can be removed by issuing;
$ buildr iidea:clean
The iidea task generates the project files based on the settings of each project and extension specific settings. The main and test source trees are added to the .iml file for each project as are the respective resource directories. The target and report directories are excluded from the project. If the project files exist on the file system the extension will replace specific component sections in the xml with the generated component configurations.
Dependencies come in two forms. Dependencies on other projects and dependencies on external jars. Dependencies on other projects are added as module dependencies in the .iml while jars are added as regular file dependencies. Dependencies are exported from the .iml file if they are compile dependencies. If a artifact that matches dependency but has a classifier of 'sources' is present then it is configured as the source for the dependency. Note: Use “buildr artifacts:sources” to download the source for dependencies.
The extension is packaged as a gem named “buildr-iidea”, consult the ruby gems installation steps but typically it is either
sudo gem install buildr-iidea
for MRI ruby or
jgem install buildr-iidea
The user then needs to add the following require into the build file:
The iidea task may generate project files that conflict with the files generated by the built-in 'idea' and 'idea7x' tasks. As a result the built-in tasks would fail if ran while the extension is present. To avoid this problem the extension removes these tasks.
Idea Specific Directives
The extension specific settings of sub-projects inherit the parent projects settings unless overwritten.
Project file naming
The extension will use the last element of the projects name when generating the .ipr and .iml files. i.e. A project named “foo” will generate “foo.iml” and “foo.ipr” while a project named “foo:bar” will generate “bar/bar.iml” and no ipr. (The .ipr project files are only generated for base project). The name can be modified by setting the “ipr.suffix” or “iml.suffix” settings which specifies the suffix appended to the file names. The user can also override the name completely by setting “ipr.id” or “iml.id”.
Example: Setting id
define "foo" do ipr.id = "beep" define "bar" do iml.id = "baz" end end
beep.ipr foo.iml bar/baz.iml
Example: Setting suffix
define "foo" do ipr.suffix = "-suffix1" iml.suffix = "-suffix2" define "bar" end
foo-suffix1.ipr foo-suffix2.iml bar/bar-suffix2.iml
Disabling project file generation
The extension will not generate an iml file for a project if the “project.no_iml” method is invoked. Generation of ipr files can be disabled by invoking the method “project.no_ipr”.
define "foo" do project.no_ipr define "bar" do project.no_iml end end
Disabling generation of content section in .iml file
The extension will not generate a content section in an iml file if the “iml.skip_content!” method is invoked. This can be useful if a project is just exporting dependencies and has no associated source code. This may also be of use in scenarios where the build is repackaging an existing jar with more meta-data or the project is just a container for other projects.
define "foo" do iml.skip_content! end
The extension will attempt to guess the VCS type of the project by looking for a .svn or .git directory in the base projects directory. If either of these are set it will configure the component as appropriate. Otherwise the user will need to manually specify the project to one of either 'Git' or 'svn' using the ipr.vcs setting.
define "foo" do ipr.vcs = 'Git' end
Adding main, test or exclude paths to the .iml file
The extension allows you to add source paths, test source paths or add paths to the excluded set by modifying the “iml.main_source_directories”, “iml.test_source_directories” or “iml.excluded_directories” settings respectively. This is only needed when the defaults inherited from project.compile or project.test are not sufficient.
define "foo" do # Add path for generated resources to .iml file iml.main_source_directories << _("generated/main/resources") # Add path for generated test resources to .iml file iml.test_source_directories << _("generated/test/resources") # Exclude the temp directory created during testing iml.excluded_directories << _("tmp") ... end
Adding main or test dependencies to the .iml file
The extension allows you to add main or test dependencies by modifying the “iml.main_dependencies” or “iml.test_dependencies” settings respectively. This is only needed when the defaults inherited from project.compile or project.test are not sufficient. Note: These dependencies are not included on compile path when running buildr.
define "foo" do # Add idea specific jar dependency to .iml file iml.main_dependencies << 'group:id:jar:1.0' # Add idea specific test jar dependency to .iml file iml.test_dependencies << 'group:id:jar:1.0' ... end
A file dependency that exists in the local maven 2 repository is stored in the IML file relative to the $MAVEN_REPOSITORY$ environment variable (that defaults to ~/.m2/repository). The user can override the environment variable by setting the “iml.local_repository_env_override” setting. If the dependency does not exist in to maven repository or the “iml.local_repository_env_override” setting is set to nil, then the path stored in the IML is relative to the IML file.
Example: Setting local_repository_env_override
define "foo" do iml.local_repository_env_override = nil compile.with 'group:id:jar:1.0' end
Will generate a dependency with a path like:
rather than the default
Example: A dependency outside the maven repository
define "foo" do compile.with _("foos-dep.jar") end
Will generate a dependency with a path like:
Facets are IDEAs mechanism for adding support for languages, tools and frameworks other than core java. A facet can be added to a project so that it can be deployed as a web application or a hibernate application. A facet can also be used t provide support for other languages such as ruby and scala. The extension makes it possible to generate .iml with the appropriate facets via the “iml.add_facet” method. It should be noted that facets are NOT inherited by sub-projects.
This example adds the web facet to a project.
define "foo" do iml.add_facet("Web","web") do |facet| facet.configuration do |conf| conf.descriptors do |desc| desc.deploymentDescriptor :name => 'web.xml', :url => "file://$MODULE_DIR$/src/main/webapp/WEB-INF/web.xml", :optional => "false", :version => "2.4" end conf.webroots do |webroots| webroots.root :url => "file://$MODULE_DIR$/src/main/webapp", :relative => "/" end end end end
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.
Example: Adding .ipr specific component
This example changes the compiler configuration for project.
define "foo" do ipr.add_component("CompilerConfiguration") do |component| component.option :name => 'DEFAULT_COMPILER', :value => 'Javac' component.option :name => 'DEPLOY_AFTER_MAKE', :value => '0' component.resourceExtensions do |xml| xml.entry :name => '.+\.nonexistent' end component.wildcardResourceExtensions do |xml| xml.entry :name => '?*.nonexistent' end end end
Example: Adding .iml specific component
This example adds the web facet to a project. Note: This overrides the facets defined by the “iml.add_facet” method.
define "foo" do iml.add_component("FacetManager") do |component| component.facet :type => 'web', :name => 'Web' do |facet| facet.configuration do |conf| conf.descriptors do |desc| desc.deploymentDescriptor :name => 'web.xml', :url => "file://$MODULE_DIR$/src/main/webapp/WEB-INF/web.xml", :optional => "false", :version => "2.4" end conf.webroots do |webroots| webroots.root :url => "file://$MODULE_DIR$/src/main/webapp", :relative => "/" end end end end end
The underlying project files are xml the contain elements for a number of “components”. The extension will load any existing project files and replace or add any component elements that are generated by the extension. The extension also allows the user to specify a template with either ipr.template or iml.template settings. If a template is specified it will be loaded and any component elements in these documents will be merged into the base document prior to merging in generated sections. Templates are useful if you want to enforce certain configuration options (i.e. project specific code style).
define "foo" do ipr.template = 'project.ipr.template' iml.template = 'module.iml.template' end
IDEA provides the facility to organise modules into groups. By default the extension does not do this but it can be enabled by iml.group setting. If that setting is set to true then the .iml file will be placed in a group based on the parent projects name. If the setting is a string then that is used as the name of the group.
define "foo" do iml.group = true define 'bar' do define 'baz' end define 'rab' do iml.group = "MyGroup" end end
Will place the generated .imls in the following groups:
foo.iml => '' bar/bar.iml => 'foo' bar/baz/baz.iml => 'foo/bar' rab/rab.iml => 'MyGroup'
Add Extra .iml files to .ipr
The 'ipr.extra_modules' setting makes it possible to add extra modules to the generated iml file. The setting is an array of file names relative to the base project directory.
define "foo" do ipr.extra_modules << 'other.iml' ipr.extra_modules << 'other_other.iml' end
Will add the 'other.iml' and 'other_other.iml' files to the .ipr project files.
It's been tested with IDEA 9.x.
The following is a list of feature requests for future versions of the extension. Feel free to jump in and supply a patch if you have gone ahead and implemented the feature.
Auto-generate Web Facet
Any project that defines a war package should have a web facet auto-generated for it.
Auto-generate Scala Facet
Any project that contains scala source code should have a scala facet autogenerated for it.
Support generation of IDEA files into separate hierarchy
Add the ability for the module and project files to be generated off into a different directory hierarchy. i.e. Generate project modules into .idea_project in projects base directory.