intellij-sdk-code-samples/topics/basics/bundling_plugin_openapi_sources.md
Karol Lewandowski 95aca84917 Cleanups
- get rid of the old [//]: # (title: ...) format
- reorder copyright notice and title where applicable
- fix grammar and other minor issues
2023-04-07 15:47:20 +02:00

4.3 KiB

Bundling Plugin API Sources

Exposing plugin's API sources for other plugins.

If a plugin exposes its own API that is meant to be used by other plugins, it is worth considering bundling the plugin's API sources in the ZIP distribution.

If a third-party plugin uses and adds a dependency to the plugin which bundles sources in the ZIP distribution, sources will be automatically attached to the plugin library and visible in IDE when developers navigate to the API classes. Being able to see API sources drastically improves the development experience, and it is highly recommended to bundle them.

Attaching bundled plugin sources in IDE is available starting with Gradle IntelliJ Plugin 1.7.0.

{style="note"}

API Sources Location

The API source JARs must be located in the example-plugin.zip!/plugin/lib/src directory in the plugin ZIP distribution, e.g.:

example-plugin.zip
└── example-plugin
    └── lib
        ├── example-plugin.jar
        └── src
            └── example-plugin-api-src.jar

The plugin ZIP can contain multiple source JARs, and there are no strict rules for the source JAR names.

Defining Plugin API

Usually, the following classes are considered as plugin API:

Keep in mind that API should be stable and change very rarely as every incompatible change will break the client plugins. It is also recommended to organize the plugin code in multiple modules with clear responsibilities, e.g.:

  • example-plugin-api - a module containing API
  • example-plugin-impl - a module containing plugin features code that are not meant to be extended or used by client plugins

General rule to define API is to include classes that are likely to be consumed by the client plugins code.

Of course, more complex plugins may require more fine-grained structure. See Gradle IntelliJ Plugin - Usage Examples.

Bundling API Sources in Gradle Build Script

In the simplest case, if a project consists of a single module and plugin API is clearly isolated in a package, e.g. com.example.plugin.openapi, including the source JAR can be achieved by adding the following snippet to the tasks section of the Gradle build script:

tasks {
  val createOpenApiSourceJar by registering(Jar::class) {
    // Java sources
    from(sourceSets.main.get().java) {
      include("**/com/example/plugin/openapi/**/*.java")
    }
    // Kotlin sources
    from(kotlin.sourceSets.main.get().kotlin) {
      include("**/com/example/plugin/openapi/**/*.kt")
    }
    destinationDirectory.set(layout.buildDirectory.dir("libs"))
    archiveClassifier.set("src")
  }

  buildPlugin {
    dependsOn(createOpenApiSourceJar)
    from(createOpenApiSourceJar) { into("lib/src") }
  }
}
task createOpenApiSourceJar(type: Jar) {
  // Java sources
  from(sourceSets.main.java) {
    include '**/com/example/plugin/openapi/**/*.java'
  }
  // Kotlin sources
  from(sourceSets.main.kotlin) {
    include '**/com/example/plugin/openapi/**/*.kt'
  }
  destinationDirectory = layout.buildDirectory.dir('libs')
  archiveClassifier = 'src'
}

buildPlugin {
  dependsOn(createOpenApiSourceJar)
  from(createOpenApiSourceJar) { into 'lib/src' }
}

The above configuration will create a source JAR containing Java and Kotlin source files from the com.example.plugin.openapi package and add it to the final plugin ZIP distribution in the required example-plugin.zip!/example-plugin/lib/src directory.

If your plugin is a Gradle project and there is no clear open API package separation, it is recommended to restructure the plugin project to a Gradle multi-project variant and create a dedicated open API subproject that contains all API sources to be included in the final distribution created by the main plugin Gradle project.