How to deal with the fact where only parts of the plug-in (optionally) require a newer Platform version



I am currently working on a plugin that supports various VCSes. Unfortunately, for SVN the AbstractVcs abstraction is not expressive enough for my needs; I have to use underlying SvnVcs instead. This is not in itself a problem.

But with the 2019.1 release of the Subversion plug-in, some of its API has changed (for the better, IMHO). The method signature of StatusClient.doStatus is one such example. On the surface, this means that my entire plug-in will only be compatible with 2019.1 or later.

But SVN is not the only VCS my plug-in supports and for other VCSes running on, say, a 2018.x version is fine. I am hence pondering how to change my plugin such that the SVN support is conditional on running on 2019.1+.

I could simply check (via reflection) for the signature of StatusClient.doStatus and, if it doesn't match the 2019 one, disable SVN support in my plug-in. This would mean that my plug-in runs on 2018.1 as well, just without SVN support, of course. (That is fine.)

But regardless of theidea-version/@since-build of 181, the calls to the 2019.1 API are still present in the bytecode. Thus, the intellij-plugin-verifier will complain, barring the entrance to the Plugins Repository. While I know that the probablematic doStatus call is unreachable of 2018.x, hidden after the reflective check, the intellij-plugin-verifier doesn't know that.

So what is the recommended practice to make some functionality dependent on a certain Platform version?

Splitting the plug-in in two (with different sinceVersion requirements) and linking them via an extension point would be possible, but a user with both IntelliJ 2019 and SVN installed would the need to perform two installs rather than just one to use all features of my plug-in. Is there any better way?


You could extract "problematic" parts via some "internal" EPs in your plugin. Then package correct version of problematic parts into main plugin distribution and publish two separate releases (in one plugin) with since/until-build set accordingly.


Hi Yann.

I am not sure I understand what you mean by "two separate releases (in one plugin)".

Do you mean that I can publish two versions, say, "1.0" with different (non-overlapping) since/until-build ranges to the Plugin Repository, and that IntelliJ will only show the user one version of the plug-in but automatically install the right release? That would indeed be nice from the user's perspective, but I don't quite understand how it would work on the build side of things. How can I use the intellij-gradle-plugin to build two different releases and publish them for the same version?

But maybe my misunderstanding is bigger (still viewing things through an Eclipse-lense of bundles and features, I am afraid. ;-).


First, forget everything about Eclipse :)


Project structure would be like:

- MainPlugin

--- SVN 2018.x

--- SVN 2019.x

Where SVN 2018.x and SVN 2019.x compile against respective target platform - without using any reflection etc.

Then you'll have to add some code to your MainPlugin's build.gradle to compose the distribution of your plugin depending on the release "channel" (2018 vs 2019) by picking respective SVN sub-project and set since/until-build accordingly, set version attribute to "xx.-201X" and upload both versions.


Can't do that, I'm afraid. ;-) In fact, I have to think about IntelliJ, Eclipse, and even NetBeans all the time, as our plug-in targets all of them. (It's quite interesting to see how different IDEs approach essentially the same issues.)

Anyway, I think I have understood how I can publish to different channels with the gradle-intellij-plugin.

But what is not yet clear to me whether "SVN 2018.x" and "SVN 2019.x" are IntelliJ plug-ins in their own right (with META-INF/plugin.xml) or whether they are merely "normal" JARs that get bundled with the MainPlugin like, say, Guava. I suspect that they must at least have aspects of the former, so that I can use DSL properties like intellij.version and intellij.plugins in my build.gradle and have Gradle fetch the correct compile dependency. Is this correct?



They would be "plain" JARs with a bundled META-INF/svn-extension.xml (referred from your master plugin's plugin.xml via <depends>) that just get packaged in your MainPlugin's ZIP distribution.

Obviously another solution would be to have two branches targeting each base platform version only.


Please sign in to leave a comment.