Tuesday, November 5, 2013

Automating IntelliJ IDEA Plug-in Development

In the previous post I wrote about managing the dependencies for IntelliJ IDEA plugin development and generating the project files. This was pretty simple and here's the full script:

apply plugin: "java"
apply plugin: "idea"

repositories {
    maven {
        credentials {
            username 'username'
            password 'password'
        url "http://my.repository.url

dependencies {
    compile('org.zeroturnaround:jr-sdk:5.4.1') {
        transitive = false
    compile 'org.ow2.asm:asm-all:4.1'
    compile 'org.slf4j:slf4j-nop:1.6.3'
    compile 'org.apache.commons:commons-compress:1.2'

defaultTasks 'setup'

idea.project.ipr {
    beforeMerged { project ->

idea.module.iml {
    withXml {
        it.node.@type = "PLUGIN_MODULE"

task setup {
   description = "crete .idea based project structure"
   dependsOn ideaModule, ideaProject
   doLast {
     copy {
        from '.'
        into '.idea/'
        include '*.ipr'
        rename { "modules.xml" }
     project.delete "${}.ipr"

task wrapper(type: Wrapper) {
    gradleVersion = '1.8'

The script is only limited to pulling down the dependencies from binary repository and generating the project files. However, one really big thing is missing here, is the SDK setup. Adding the new SDK for plugin development is simple enough, but I still have a good reason to automate that. In my plugin, there's a dependency on some SDK artifacts that are not included into SDK classpath by default. So adding the dependencies one by one into the SDK via the UI is a bit tedious and not really encouraging for the team work.

It would be cool if the script could register the IntelliJ Platform Plugin SDK and add it into the project files. It turns out that it should be doable as the SDK definitions are stored in options/jdk.table.xml file in IntelliJ IDEA's configuration directory.

It might be a bit brittle to go tinkering with the file directly, so maybe JPS API could actually be used to add a new entry for the SDK. (just an idea)

Those would be the steps for automating the setup:

  1. Fetch dependencies and generate .idea directory based project
  2. Generate Platform SDK entry to options/jdk.table.xml and add the reference to project *.iml file and .idea/misc.xml file
  3. Optionally, add more dependencies to Platform SDK definition
  4. The final step is the to add the build and release logic to the script

Now, a little bit of dreaming :-)

In the ideal world, the steps could be described as properties in build.gradle file:

  1. idea.module.type="PLUGIN_MODULE" - resolve as plugin module
  2. idea.project.sdk=auto (and idea.module.sdk=auto) - auto-generate the SDK entry (with good defaults) and add it to the project and module
  3. The extra SDK dependencies are probably something that needs a special care. Don't know what could be the best workaround, but maybe something like this:
    idea.project.sdk.dependencies {
  4. Build script would basically mimic the autogenerated the Ant file, and release step actually requires a bit more than just changing the version of the artifact: the version in META-INF/plugin.xml has to be updated as well.

Dreaming aside, I think that the steps described above could be automated with a reasonable effort.

Disqus for Code Impossible