JetBrains / sbt-idea-plugin

Develop IntelliJ plugins with Scala and SBT
Apache License 2.0
97 stars 28 forks source link

Plugin dependency as URL doesn't work #114

Closed iuliand-db closed 2 years ago

iuliand-db commented 2 years ago

I need to depend on a custom IntelliJ plugin, one that is not published on the IDEA market place. I figured out that I could use the direct URL, like this:

intellijPlugins ++= Seq(
        "org.intellij.scala:2021.2.30".toPlugin,
        "https://intellij.dev.databricks.com/plugin_v16.0.6.zip".toPlugin
      ),

However:

Is there another way to depend on a plugin that's not on the marketplace?

jastice commented 2 years ago

It looks like the logic for this isn't really implemented (see here) so that's something we'd need to fix

iuliand-db commented 2 years ago

Alternatively, can we use a custom repo instead of the public one? Maybe that's the simplest workaround for the moment.

Edit: Looks like this could be added in https://github.com/JetBrains/sbt-idea-plugin/blob/master/ideaSupport/src/main/scala/org/jetbrains/sbtidea/download/plugin/PluginRepoUtils.scala#L11 (perhaps by attaching a repo URL to the PluginInfo class)

iuliand-db commented 2 years ago

@jastice can you provide some pointers on how this could be fixed? I'm not very familiar with how IntelliJ installs its plugins, if there's something in particular we need to do to make this work? We have this dependency on an internal plugin that we need to pull, either from a custom repo, or as a downloadable URL.

iuliand-db commented 2 years ago

@jastice gentle ping.

jastice commented 2 years ago

Thanks for the ping.

So if I see this right, we'd just need to implement the resolveUrlPlugin method to make your original idea work, or is that wrong @mutcianm ?

iuliand-db commented 2 years ago

So if I see this right, we'd just need to implement the resolveUrlPlugin method to make your original idea work, or is that wrong @mutcianm ?

I took a stab at this, but something is still off. Not sure if there's an additional "install" step that needs some work, since it seems to "work", but on restart it re-resolves and re-dowloads the plugin again.

iuliand-db commented 2 years ago

This is a bit more complex than first thought. A URL is not enough to decide if the plugin is installed, since we need the plugin id for deciding that. Do get the plugin ID, we need to download the plugin and find plugin.xml to retrieve it.

We could add the plugin ID as part of the IntellijPlugin.Url case class, but that's duplicating the information and there could be inconsistencies. Not sure if there's another way though.

jastice commented 2 years ago

I see, so the issue is that the plugin index is persisted only with the id from the metadata as key, so the url gets lost? It looks like a simple workaround would be to add the source url to the plugin descriptor, and add the plugin to the index both under plugin id and url. What do you think?

iuliand-db commented 2 years ago

I'm not sure the index is persisted explicitly by this plugin. The index reads up plugin.xmls from all plugins in the local plugin directory. If you're suggesting to modify the descriptor on the fly and add the URL in there, I guess that might work, but it would be fairly involved (we'd need to unzip the plugin, find the jar, unzip the jar, modify the plugin.xml file, re-jar it, re-zip) and then go through the usual install path.

I think the PluginId with optionl URL might be a bit easier to implement, and even to reason about. In a sense, it's expressing a shortcut in resolving the plugin ("I want to depend on this pluginID, and here's where you can find it").

mutcianm commented 2 years ago

Hi! Sorry, I'm in the process of relocation with too much stuff going on, can't keep up with all notifications.

Regarding the URL hint approach: yes, this indeed looks like a reasonable solution. This sbt plugin relies heavily on retrieving remote metadata from the plugin repo for various stuff like dependency resolution, up-to-date and IDE compatibility checks. And the plugin repo API requests require a plugin ID. So, if you only have the URL, all those features cease to work, because you cannot get the metadata unless you download a zip and manually extract it.