2019-05-13 22:32:03 -07:00

17 KiB

title
Configuring Gradle for IntelliJ Platform Plugins

This page serves as a guide to Gradle-based plugin configuration for IntelliJ Platform projects. The IntelliJ IDEA Ultimate and Community editions bundle the Gradle and Plugin DevKit plugins to support Gradle-based development. The Getting Started with Gradle page provides a tutorial for creating Gradle-based IntelliJ Platform plugins. It may be useful to review the IntelliJ Platform page, particularly the description of versioning in the Open Source section.

  • bullet list {:toc}

Overview of the IntelliJ IDEA Gradle Plugin

The IntelliJ IDEA Gradle plugin is built from the open-source project gradle-intellij-plugin. The plugin adds Gradle tasks for the build.gradle file that enable developing IntelliJ Platform plugins. The README file for the gradle-intellij-plugin project is the reference for configuring these tasks.

When getting started, there are several items to note on the README page:

  • At the top of the page, the latest production version (e.g. 0.4.8) of the IntelliJ IDEA Gradle plugin is listed.
  • Also at the top is the minimum version of Gradle required to support the IntelliJ IDEA Gradle plugin.
  • The table of extended Gradle Tasks has a succinct description for each task added by the plugin.
  • Examples are always a helpful resource, and at the bottom of the page are links to example open source IntelliJ Platform plugin projects based on Gradle.
  • Almost every Gradle plugin attribute has a default value that will work to get started on a Gradle-based IntelliJ Platform plugin project.

The remainder of this section is a summary of the build.gradle Configuration tasks, and their DSL attributes.

Setup DSL

The intellij{} task (Setup DSL) has the most attributes, and it may be helpful to think of them in terms of groups. See the Setup portion of the reference page for more details about each attribute:

  • Configuration for the plugin project build:
    • Attributes that specify the version of the IntelliJ Platform to be used for building the plugin project:
      • version and type,
      • or localPath
    • Attribute that specifies the plugin project's dependencies on JetBrains repository plugins.
      • plugins
    • Build output: project artifact name and instrumentation directive.
      • pluginName
      • instrumentCode
  • Management of downloads to support building and running against IntelliJ Platform (IDE) versions:
    • Control source code download for the IntelliJ Platform-based IDE
      • downloadSources
    • Where to store IDE downloads locally
      • independencyCachePath
    • Where to get IDE, plugins, and JetBrains JRE
      • intellijRepo
      • pluginsRepo
      • jreRepo
  • Control of PatchPluginXml substitution for since-build and until-build attribute values of <idea-version> in plugin.xml:
    • updateSinceUntilBuild
    • sameSinceUntilBuild
  • Manage aspects of the IDE Development Instance for running and debugging the plugin project:
    • sandboxDirectory
    • alternativeIdePath

Running DSL

The runIde{} task extends the Gradle JavaExec task for building an IntelliJ Platform plugin project. See the Running DSL section of the reference page for more details about each attribute. The attributes fall into two groups:

  • Manage the version of the JetBrains JRE and location of the IDE to use as the IDE Development Instance:
    • jbrVersion
    • ideaDirectory
  • Modify the locations of the sandbox subdirectories:
    • configDirectory
    • pluginsDirectory
    • systemDirectory

Patching DSL

The patchPluginXml{} task replaces a subset of element and attribute values in a plugin project's plugin.xml file(s). See the Patching DSL section of the reference page for more details about each attribute. The behavior of this task depends in part on the attributes in the Setup DSL task.

The attributes fall into two groups:

  • Values to be substituted:
    • version
    • sinceBuild
    • untilBuild
    • pluginDescription
    • changeNotes
  • Control of which plugin.xml files to patch, and where to store them after they are patched:
    • pluginXmlFiles
    • destinationDir

Publishing DSL

The publishPlugin{} task enables Gradle to upload a plugin to a repository, most commonly the JetBrains Plugin Repository. See the guide section below for more information about using these attributes. The attributes in this task can be considered to fall into two groups:

  • Credential-related:
    • token
    • username
    • password
  • Details of the upload:
    • distributionFile
    • host
    • channels

Guide to Configuring Gradle Plugin Functionality

This section presents a guided tour of Gradle plugin attributes to achieve commonly desired functionality.

Configuring the IntelliJ Platform Used for Building Plugin Projects

By default, the Gradle plugin will build the plugin project against the IntelliJ Platform defined by the latest EAP snapshot of the IntelliJ IDEA Community Edition.

If a correct version of the specified IntelliJ Platform is not available on the local machine, the Gradle plugin downloads the correct version and type. IntelliJ IDEA then indexes the build and any associated source code and JetBrains Java Runtime.

IntelliJ Platform Version

Explicitly setting intellij.version and intellij.type instructs the Gradle plugin to use that configuration of the IntelliJ Platform to build the plugin project. If a local installation of IntelliJ IDEA is the desired type and version of the IntelliJ Platform, use intellij.localPath to point to that installation. If the intellij.localPath attribute is set, do not set the intellij.version and intellij.type attributes as this could result in undefined behavior. The Gradle plugin will use the version and type installed at intellij.localPath.

Plugin Dependencies

IntelliJ Platform plugin projects may depend on either bundled or third-party plugins. In that case, a project should build against a version of those plugins that match the IntelliJ Platform version used to build the plugin project. The Gradle plugin will fetch any plugins in the list defined by intellij.plugins. See the Gradle plugin README for information about specifying the plugin and version.

Note that this attribute describes an environment dependency so that the Gradle plugin can fetch the required artifacts. The IntelliJ Platform plugin project is still required to declare these dependencies in its plugin.xml file.

Configuring the Gradle Plugin for Running IntelliJ Platform Plugins

By default, the Gradle plugin will use the same version of the IntelliJ Platform for the IDE Development Instance as was used for building the plugin. Using the corresponding JetBrains Java runtime is also the default, so for this use case no further configuration is required.

Running Against Alternate Versions of the IntelliJ Platform

However, the version of the IntelliJ Platform used for the IDE Development Instance can be different from that used to build the plugin project. Two Gradle plugin attributes control the version used for the IDE Development Instance:

  • Setting intellij.alternativeIdePath to the path of the locally installed IDE to use for running the plugin. This attribute is used when running the plugin in an alternate IntelliJ Platform-based IDE.
  • Setting runIde.ideaDirectory to the path of the locally installed (different version) IntelliJ IDEA to use for running the plugin.

Running Against Alternate Versions of the Java Runtime

Every version of the IntelliJ Platform has a corresponding version of the JetBrains Java runtime. A different version of the runtime can be used by specifying the runIde.jbrVersion attribute, describing a version of the JetBrains Java runtime that should be used by the IDE Development Instance.

Managing Directories used by the Gradle Plugin

There are several attributes to control where the Gradle plugin places directories for downloads and for use by the IDE Development Instance.

The location of the sandbox home directory and its subdirectories can be controlled with Gradle plugin attributes. The intellij.sandboxDirectory attribute is used to set the path for the sandbox directory to be used while running the plugin in an IDE Development Instance. Locations of the sandbox subdirectories can be controlled using the runIde.configDirectory, runIde.pluginsDirectory, and runIde.systemDirectory attributes. If the intellij.sandboxDirectory path is explicitly set, the subdirectory attributes default to the new sandbox directory.

The storage location of downloaded IDE versions and components defaults to the Gradle cache directory. However, it can be controlled by setting the intellij.ideaDependencyCachePath attribute.

Controlling Downloads by the Gradle Plugin

As mentioned in the section about configuring the intellij platform used for building plugin projects, the Gradle plugin will fetch the version of the IntelliJ Platform specified by the default or by the intellij attributes. Whether to download source code is controlled by the attribute intellij.downloadSources. If source code isn't needed, then this is one download (and indexing) step that can be saved.

Standardizing the versions of the Gradle plugin and Gradle system across projects will minimize the time spent downloading versions. There are controls for managing the IntelliJ IDEA Gradle plugin version, and the version of Gradle itself. The Gradle plugin version is defined in the plugins {} section of a project's build.gradle file. The Gradle version is in defined in a project's gradle-wrapper.properties.

Patching the Plugin.XML File

With the exception of the since-build and until-build attributes of the <idea-version> element, all of the substitution attributes in the Patching DSL will be patched into the corresponding element values in a plugin project's plugin.xml file. The since-build and until-build substitution can be inhibited by setting intellij.updateSinceUntilBuild to false. Substitution of at least the default value for the other attributes cannot be inhibited.

A best practice to avoid confusion is to replace the elements in plugin.xml that will be patched by the Gradle plugin with a comment. That way the values for these parameters do not appear two places in the source code. The Gradle plugin will add the necessary elements as part of the patching process. For those attributes that contain descriptions such as changeNotes and pluginDescription, a CDATA block is not necessary when using HTML elements.

As discussed in Components of a Wizard-Generated Gradle IntelliJ Platform Plugin, project.version, project.group, and rootProject.name are all generated based on the input to the Wizard. However, the IntelliJ IDEA Gradle plugin does not combine and substitute those values for the default <id> and <name> elements in the plugin.xml file. There is no IntelliJ Platform-related reason the value of those XML elements must match the Gradle plugin values, but it is considered a best practice to avoid confusion.

Smaller projects with only one plugin.xml file will likely use the defaults for which file to patch and where to store the patched file. Larger projects, with multiple modules and more than one plugin.xml file, will need to construct a collection of files to be patched and declare them in patchPluginXml.pluginXmlFiles.

Publishing with the Gradle Plugin

Please review the Publishing Plugins with Gradle page before using these attributes. That documentation explains three different ways to use Gradle for plugin uploads without exposing account credentials.

Common IntelliJ IDEA Gradle Plugin Configurations

Combinations of attributes in different Gradle plugin tasks are often needed to create the desired build or IDE Development Instance environment. This section review some of the more common configurations.

Plugins Targeting IntelliJ IDEA

IntelliJ Platform plugins targeting IntelliJ IDEA have the most straightforward Gradle plugin configuration.

  • Determine the version of IntelliJ IDEA to target; this is the version of the IntelliJ Platform. This can be EAP (default) or determined from the build number ranges.
  • If the plugin project should be run or debugged in an IDE Development Instance based on the same IntelliJ IDEA version, no attributes need to be set. This is the default behavior and is the most common use case.
    • If the plugin project should be run or debugged in an IDE Development Instance based on a different IntelliJ IDEA version, set the path to the desired version.
    • If the plugin project should be run using a JetBrains Java runtime other than the default for the IDE Development Instance, specify the JetBrains Java runtime version.

Plugins Targeting Other IntelliJ Platform-Based IDEs

The Gradle plugin can also be configured for developing plugins to run in IDEs that are based on the IntelliJ Platform but are not IntelliJ IDEA. This section uses the example of developing a plugin for PhpStorm. It will be helpful to review the PhpStorm Plugin Development section.

  • The Gradle plugin attributes describing the configuration of the IntelliJ Platform used to build the plugin project must be explicitly set. The type will be "IC" because the IntelliJ Platform is defined by the IntelliJ IDEA Community Edition. The BRANCH.BUILD number of the IntelliJ Platform (IntelliJ IDEA CE) is the same as for the PhpStorm target. Although the FIX (tertiary) number may differ between the same versions of the applications, it won't affect the match of the IntelliJ Platform.
  • All PhpStorm plugin projects have a dependency on the PhpStorm OpenAPI Library. Any plugin targeting PhpStorm must list a dependency on the PHP plugin, and its version must be compatible with the target version of PhpStorm. The plugin dependency must be declared using the Gradle plugin intellij.plugins attribute, which lists the FQN and version of the plugin dependency.
  • The best practice is to use the target version of PhpStorm as the IDE Development Instance. That enables running and debugging the plugin in the target (e.g., PhpStorm) application. The choice of application to use for the IDE Development Instance is configured using the Gradle plugin attribute intellij.alternativeIdePath.

The snippet below is an example of configuring the Setup DSL in a build.gradle file to develop a plugin targeted at PhpStorm. The configuration uses IntelliJ IDEA Community Edition v2019.1.2 (build 191.7141.44) as the IntelliJ Platform against which the plugin project is built. It uses PhpStorm v2019.1.2 (build 191.7141.52) as the IDE Development Instance in which the plugin project is run and debugged.

  intellij {
    // Define IntelliJ Platform against which to build the plugin project.
    version '191.7141.44'  // Same version (2019.1.2) as target PhpStorm   
    type 'IC'              // Use IntelliJ IDEA CE as basis of IntelliJ Platform   
    // Require the Php plugin, must be compatible with target v2019.1.2
    plugins 'com.jetbrains.php:191.6707.66'     
    // Path to installed v2019.1.2 PhpStorm to use as IDE Development Instance
    alternativeIdePath '/Applications/apps/PhpStorm/ch-0/191.7141.52/PhpStorm.app/Contents'
  }