Git Product home page Git Product logo

sbt-idea-plugin's Introduction

sbt-idea-plugin

Version Build Status JetBrains team project Discord Gitter

SBT plugin that makes development of IntelliJ Platform plugins in Scala easier by providing features such as:

  • Downloading and attaching IntelliJ Platform binaries
  • Setting up the environment for running tests
  • Flexible way to define plugin artifact structure
  • Publishing the plugin to JetBrains plugin repository

For a comprehensive usage example see Scala plugin or HOCON plugin build definition.

A complete list of public IJ plugins implemented in Scala/SBT can be found on IntelliJ Platform Explorer

Note that some features of this plugin may be used independently, i.e. if you only want to print project structure or package artifacts you can depend on:

"org.jetbrains" % "sbt-declarative-visualizer" % "LATEST_VERSION" or

"org.jetbrains" % "sbt-declarative-packaging" % "LATEST_VERSION"

Please see the Known Issues section if you come across a problem, and feel free file a bug on the Issues page of this repo if you find one.

Quickstart: IJ Plugin Template Project

To quickly create a Scala based IJ Plugin we provide a template project. Create your own repo on GitHub from the JetBrains / sbt-idea-example template by clicking the green Use this template button. Clone the sources and open the build.sbt via File | Open menu in IDEA by choosing Open as a project.

Manual Installation (adding to an already existing sbt build)

From version 1.0.0, this plugin is published for sbt 0.13 and 1.0. From version 3.17.0, this plugin is published for sbt 1.0 only.

  • Insert into project/plugins.sbt:
addSbtPlugin("org.jetbrains" % "sbt-idea-plugin" % "LATEST_VERSION")
  • Enable the plugin for your desired projects (your main plugin project and all its dependencies)

  • Run SBT and the plugin will automatically download and attach IntelliJ Platform dependencies.

  • Start coding

SBT Related Settings and Tasks

IntelliJ Platform and Plugin

intellijPluginName in ThisBuild :: SettingKey[String]

Default: name.in(LocalRootProject).value

Name of your plugin. Better set this beforehand since several other settings such as IntelliJ Platform directories and artifact names depend on it. Please see name troubleshooting for more info.

intellijBuild in ThisBuild :: SettingKey[String]

Default: LATEST-EAP-SNAPSHOT

Selected IDE's build number. Binaries and sources of this build will be downloaded from the repository and used in compilation and testing. You can find build number of your IntelliJ product in Help -> About dialog. However, it might be incomplete, so it is strongly recommended to verify it against available releases and available snapshots.

Note: minimum supported major IDEA version: 211.x (~2021.1.x)

intellijPlatform in ThisBuild :: SettingKey[IntelliJPlatform]

Default: IntelliJPlatform.IdeaCommunity

Edition of IntelliJ IDE to use in project. Currently available options are:

  • IdeaCommunity
  • IdeaUltimate
  • PyCharmCommunity
  • PyCharmProfessional
  • CLion
  • MPS

intellijPlugins :: SettingKey[IdeaPlugin]

Default: Seq.empty

IntelliJ plugins to depend on. Bundled(internal) plugins are specified by their plugin ID. Plugins from repo can be specified by the plugin's id, optional version and update channel. Plugins will be checked for compatibility against the intellijBuild you specified and updated to the latest version unless some specific version is given explicitly. Inter-plugin dependencies are also transitively resolved(e.g. depending on the Scala plugin will automatically attach Java and other plugin dependencies)

Plugin IDs can be either searched by plugin name with the help of searchPluginId task or manually

You can tune plugin resolving on individual plugin level by specifying several options to toPlugin method:

  • transitive - use transitive plugin resolution(default: true)
  • optionalDeps - resolve optional plugin dependencies(default: true)
  • excludedIds - blacklist certain plugins from transitive resolution(default: Set.empty)

โ— Please note that Java support in IJ is implemented by a plugin: com.intellij.java

โ— Please remember that you must declare plugin dependencies in plugin.xml or your plugin may fail to load.

// use properties plugin bundled with IDEA
intellijPlugins += "com.intellij.properties".toPlugin
// use Scala plugin as a dependency
intellijPlugins += "org.intellij.scala".toPlugin
// use Scala plugin version 2023.3.10
intellijPlugins += "org.intellij.scala:2023.3.10".toPlugin
// use latest nightly build from the repo
intellijPlugins += "org.intellij.scala::Nightly".toPlugin
// use specific version from Eap update channel
intellijPlugins += "org.intellij.scala:2023.3.10:Eap".toPlugin
// add JavaScript plugin but without its Grazie plugin dependency
intellijPlugins += "JavaScript".toPlugin(excludedIds = Set("tanvd.grazi"))
// add custom plugin with id `org.custom.plugin`, download it using the direct link https://org.example/path/to/your/plugin.zip
intellijPlugins += "org.custom.plugin:https://org.example/path/to/your/plugin.zip".toPlugin
// add custom plugin with id `org.custom.plugin` and resolve it from Marketplace.
//  if it fails to resolve it in Marketplace it will use the fallback download link
intellijPlugins += "org.custom.plugin".toPlugin.withFallbackDownloadUrl("https://org.example/path/to/your/plugin.zip")

intellijRuntimePlugins :: SettingKey[IdeaPlugin]

Default: Seq.empty

IntelliJ plugins to load at runtime (includes tests). These plugins are not a compile time dependencies and cannot be referenced in code. Useful for testing your plugin in the presence of other plugins.

The usage is the same as intellijPlugins.

searchPluginId :: Map[String, (String, Boolean)]

Usage: searchPluginId [--nobundled|--noremote] <plugin name regexp>

Searches and prints plugins across locally installed IJ sdk and plugin marketplace. Use provided flags to limit search scope to only bundled or marketplace plugins.

> searchPluginId Prop
[info] bundled          - Properties[com.intellij.properties]
[info] bundled          - Resource Bundle Editor[com.intellij.properties.bundle.editor]

jbrInfo :: Option[JbrInfo]

Default: AutoJbr()

JetBrains Java runtime version to use when running the IDE with the plugin. By default JBR version is extracted from IDE installation metadata. Only jbr 11 is supported. Available versions can be found on jbr bintray. To disable, set to NoJbr

patchPluginXml :: SettingKey[pluginXmlOptions]

Default: pluginXmlOptions.DISABLED

Define some plugin.xml fields to be patched when building the artifact. Only the file in target folder is patched, original sources are left intact. Available options are:

patchPluginXml := pluginXmlOptions { xml =>
  xml.version           = version.value
  xml.pluginDescription = "My cool IDEA plugin"
  xml.changeNotes       = sys.env("CHANGE_LOG_FROM_CI")
  xml.sinceBuild        = (intellijBuild in ThisBuild).value
  xml.untilBuild        = "193.*"
}

intellijVMOptions :: SettingKey[IntellijVMOptions]

Fine tune java VM options for running the plugin with runIDE task. Example:

intellijVMOptions := intellijVMOptions.value.copy(xmx = 2048, xms = 256) 

ideaConfigOptions :: SettingKey[IdeaConfigBuildingOptions]

Fine tune how IntelliJ run configurations are generated when importing the project in IDEA.

runIDE [noDebug] [suspend] [blocking] :: InputKey[Unit]

Runs IntelliJ IDE with current plugin. This task is non-blocking by default, so you can continue using SBT console.

By default, IDE is run with non-suspending debug agent on port 5005. This can be overridden by either optional arguments above, or by modifying default intellijVMOptions.

Publishing and Verification

publishPlugin [channel] :: InputKey[String]

Upload and publish your IntelliJ plugin on https://plugins.jetbrains.com. In order to publish to the repo you need to obtain permanent token and either place it into ~/.ij-plugin-repo-token file or pass via IJ_PLUGIN_REPO_TOKEN env or java property.

This task also expects an optional argument - a custom release channel. If omitted, plugin will be published to the default plugin repository channel (Stable)

runPluginVerifier :: TaskKey[File]

IntelliJ Plugin Verifier integration task allows to check the binary compatibility of the built plugin against the currently used or explicitly specified IntelliJ IDE builds. The task returns a folder with the verification reports.

The verification can be customized by changing the default options defined in the pluginVerifierOptions key.

pluginVerifierOptions := pluginVerifierOptions.value.copy(
  version = "1.254",        // use a specific verifier version
  offline = true,           // forbid the verifier from reaching the internet
  overrideIDEs  = Seq("IC-2019.3.5", "PS-2019.3.2"), // verify against specific products instead of 'intellijBuild'
  failureLevels = Set(FailureLevel.DEPRECATED_API_USAGES) // only fail if deprecated APIs are used
   // ...
)

signPlugin :: TaskKey[File]

Utility task that signs the plugin artifact before uploading to the JetBrains Marketplace. Signing is performed using the Marketplace zip signer library. To sign a plugin a valid certificate chain, and a private key are required.

Signing is disabled by default at the moment. To enable it and set the options, modify the signPluginOptions key:

signPluginOptions := signPluginOptions.value.copy(
  enabled = true,
  certFile = Some(file("/path/to/certificate")), // or via PLUGIN_SIGN_KEY env var
  privateKeyFile  = Some(file("/path/to/privateKey")), // or via PLUGIN_SIGN_CERT env var
  keyPassphrase = Some("keyPassword") // or None if password is not set(or via PLUGIN_SIGN_KEY_PWD env var)
)

If signing the plugin artifact zip is enabled via signPluginOptions, this task will be used a dependency of the publishPlugin task, so that the artifact is automatically signed before uploading to the JetBrains Marketplace

buildIntellijOptionsIndex :: TaskKey[Unit]

Builds index of options provided by the plugin to make them searchable via search everywhere action. This task should either be manually called instead of packageArtifact or before packageArtifactZip since it patches jars already built by packageArtifact.

Packaging

packageMethod :: SettingKey[PackagingMethod]

Default for root project: PackagingMethod.Standalone(targetPath = s"lib/${name.value}.jar")

Default for all other subprojects: PackagingMethod.MergeIntoParent()

Controls how current project will be treated when packaging the plugin artifact.

// produce standalone jar with the same name as the project:
packageMethod := PackagingMethod.Standalone()

// put all classes of this project into parent's jar
// NB: this option supports transitive dependencies on projects: it will walk up the dependency 
// tree to find the first Standalone() project, however if your project has multiple such parents
// this will result in an error - in this case use MergeIntoOther(project: Project) to expicitly
// specify in which project to merge into
packageMethod := PackagingMethod.MergeIntoParent()

// merge all dependencies of this project in a standalone jar
// being used together with assembleLibraries setting allows sbt-assembly like packaging
// the project may contain classes but they will be ignored during packaging
packageMethod := PackagingMethod.DepsOnly("lib/myProjectDeps.jar")
assembleLibraries := true

// skip project alltogether during packaging
packageMethod := PackagingMethod.Skip()

packageLibraryMappings :: SettingKey[Seq[(ModuleID, Option[String])]]

Default for root project: Seq.empty

Default for all other projects:

"org.scala-lang"  % "scala-.*" % ".*"        -> None ::
"org.scala-lang.modules" % "scala-.*" % ".*" -> None :: Nil

Sequence of rules to fine-tune how the library dependencies are packaged. By default all dependencies including transitive are placed in the subfolder defined by packageLibraryBaseDir(defaults to "lib") of the plugin artifact.

You can use the findLibraryMapping task to debug the library mappings

// merge all scalameta jars into a single jar
packageLibraryMappings += "org.scalameta" %% ".*" % ".*" -> Some("lib/scalameta.jar")

// skip packaging protobuf
packageLibraryMappings += "com.google.protobuf" % "protobuf-java" % ".*" -> None

// rename scala library(strip version suffix)
packageLibraryMappings += "org.scala-lang" % "scala-library" % scalaVersion -> Some("lib/scala-library.jar")

packageLibraryBaseDir :: SettingKey[File]

Default: file("lib")

Sets the per-project default sub-folder into which external libraries are packaged. Rules from packageLibraryMappings will override this setting.

NB!: This directory must be relative to the packageOutputDir so don't prepend values of the keys with absolute paths (such as target or baseDirectory) to it

NB!: IDEA plugin classloader only adds the lib folder to the classpath when loading your plugin. Modifying this setting will essentially exclude the libraries of a project from automatic classloading

packageLibraryBaseDir  := file("lib") / "third-party"

// protobuf will still be packaged into lib/protobuf.jar
packageLibraryMappings += "com.google.protobuf" % "protobuf-java" % ".*" -> Some("lib/protobuf.jar")

packageFileMappings :: TaskKey[Seq[(File, String)]]

Default: Seq.empty

Defines mappings for adding custom files to the artifact or even override files inside jars. Target path is considered to be relative to packageOutputDir.

// copy whole folder recursively to artifact root
packageFileMappings += target.value / "repo" -> "repo/"

// package single file info a jar
packageFileMappings += "resources" / "ILoopWrapperImpl.scala" ->
                            "lib/jps/repl-interface-sources.jar"
                            
// overwrite some file inside already existing jar of the artifact
packageFileMappings +=  "resources" / "META-INF" / "plugin.xml" ->
                            "lib/scalaUltimate.jar!/META-INF/plugin.xml"                            

packageAdditionalProjects :: SettingKey[Seq[Project]]

Default: Seq.empty

By default the plugin builds artifact structure based on internal classpath dependencies of the projects in an SBT build(dependsOn(...)). However, sometimes one may need to package a project that no other depends upon. This setting is used to explicitly tell the plugin which projects to package into the artifact without a need to introduce unwanted classpath dependency.

shadePatterns :: SettingKey[Seq[ShadePattern]]

Default: Seq.empty

Class shading patterns to be applied by JarJar library. Used to resolve name clashes with libraries from IntelliJ platform such as protobuf.

shadePatterns += ShadePattern("com.google.protobuf.**", "zinc.protobuf.@1")

bundleScalaLibrary in ThisBuild :: SettingKey[Boolean]

Trying to load the same classes in your plugin's classloader which have already been loaded by a parent classloader will result in classloader constraint violation. A vivid example of this scenario is depending on some other plugin, that bundles scala-library.jar(e.g. Scala plugin for IJ) and still bundling your own.

To workaround this issue sbt-idea-plugin tries to automatically detect if your plugin project has dependencies on other plugins with Scala and filter out scala-library.jar from the resulting artifact. However, the heuristic cannot cover all possible cases and thereby this setting is exposed to allow manual control over bundling the scala-library.jar

instrumentThreadingAnnotations :: SettingKey[Boolean]

Default: false

Generate JVM bytecode to assert that a method is called on the correct IDEA thread. The supported annotations are:

  1. com.intellij.util.concurrency.annotations.RequiresBackgroundThread
  2. com.intellij.util.concurrency.annotations.RequiresEdt
  3. com.intellij.util.concurrency.annotations.RequiresReadLock
  4. com.intellij.util.concurrency.annotations.RequiresReadLockAbsence
  5. com.intellij.util.concurrency.annotations.RequiresWriteLock

See: IntelliJ IDEA ThreadingAssertions.java

packageOutputDir :: SettingKey[File]

Default: target.value / "plugin" / intellijPluginName.in(ThisBuild).value.removeSpaces

Folder to place the assembled artifact into.

packageArtifact :: TaskKey[File]

Builds unpacked plugin distribution. This task traverses dependency graph of the build and uses settings described in the section above to create sub-artifact structure for each project. By default all child projects' classes are merged into the root project jar, which is placed into the "lib" folder of the plugin artifact, all library dependencies including transitive are placed in the "lib" folder as well.

packageArtifactZip :: TaskKey[File]

Produces ZIP file from the artifact produced by packageArtifact task. This is later used by publishPlugin as an artifact to upload.

Utils

findLibraryMapping :: InputKey[Seq[(String, Seq[(ModuleKey, Option[String])])]]

Returns detailed info about libraries and their mappings by a library substring. Helps to answer questions such as "Why is this jar in the artifact?" or "Which module introduced this jar?" Example:

sbt:scalaUltimate> show findMapping interface
[info] * (runtimeDependencies,ArrayBuffer((org.scala-sbt:compiler-interface:1.4.0-M12[],Some(lib/jps/compiler-interface.jar)), (org.scala-sbt:util-interface:1.3.0[],Some(lib/jps/sbt-interface.jar))))
[info] * (repackagedZinc,ArrayBuffer((org.scala-sbt:compiler-interface:1.4.0-M12[],Some(*)), (org.scala-sbt:launcher-interface:1.1.3[],Some(*)), (org.scala-sbt:util-interface:1.3.0[],Some(*))))
[info] * (compiler-jps,ArrayBuffer((org.scala-sbt:util-interface:1.3.0[],Some(*)), (org.scala-sbt:compiler-interface:1.4.0-M12[],Some(lib/jps/compiler-interface.jar))))
[info] * (compiler-shared,ArrayBuffer((org.scala-sbt:util-interface:1.3.0[],Some(*)), (org.scala-sbt:compiler-interface:1.4.0-M12[],Some(*))))

printProjectGraph :: TaskKey[Unit]

Prints ASCII graph of currently selected project to console. Useful for debugging complex builds.

Running the plugin

From SBT

To run the plugin from SBT simply use runIDE task. Your plugin will be automatically compiled, an artifact built and attached to new IntelliJ instance.

Debugger can later be attached to the process remotely - the default port is 5005.

From IDEA

  • sbt-idea-plugin generates IDEA-readable artifact xml and run configuration on project import
  • After artifact and run configuration have been created(they're located in .idea folder of the project) you can run or debug the new run configuration. This will compile the project, build the artifact and attach it to the new IDEA instance
  • โ— Note that doing an "SBT Refresh" is required after making changes to your build that affect the final artifact(i.e. changing libraryDependencies), in order to update IDEA configs
  • โ— You may need to manually build the artifact when running your plugin for the first time

Custom IntelliJ artifacts repo

Under some circumstances using a proxy may be required to access IntelliJ artifacts repo, or there even is a local artifact mirror set up. To use non-default repository for downloading IntelliJ product distributions set sbtidea.ijrepo jvm property. Example: -Dsbtidea.ijrepo=https://proxy.mycompany.com/intellij-repository

Auto enable the plugin

Sbt-idea-plugin currently breaks scalaJS compilation, and thereby has autoloading disabled. To enable it either add enablePlugins(SbtIdeaPlugin) to project definition. Example:

lazy val hocon = project.in(file(".")).settings(
  scalaVersion  := "2.12.8",
  version       := "2019.1.2",
  intellijInternalPlugins := Seq("properties"),
  libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test",
).enablePlugins(SbtIdeaPlugin)

If you with to automatically enable the plugin for all projects in your build, place the following class into top level project folder of your build.

import org.jetbrains.sbtidea.AbstractSbtIdeaPlugin

object AutoSbtIdeaPlugin extends AbstractSbtIdeaPlugin {
  override def trigger  = allRequirements
}

Grouping with qualified names is available from Scala plugin version 2024.1.4

In the Scala plugin 2024.1.4 a significant change has been made according to modules grouping and their naming. You can read more about this change here. Because of this change, it was necessary to change how the project names are generated in packageMapping tasks (packageMappings and packageMappingsOffline). To switch between the new and the old projects naming logic, grouping.with.qualified.names.enabled system property has been introduced. If your Scala plugin version is 2024.1.4 or higher, then in order to generate correct mappings you should set this property to true (-Dgrouping.with.qualified.names.enabled=true). Otherwise, there is no need to do anything as this value is set to false by default.

Known Issues and Limitations

name key in projects

Please do not explicitly set the name setting key for projects that have SbtIdeaPlugin attached. SBT will automatically set it from the lazy val's name of the project definition.

IDEA cannot correctly handle the sutuation when name key and lazy val's name of a project are different, thus making the generated artifact and run configuration xml's invalid.

Related issue: #72

Plugin artifact not built when running from IDEA after importing the project

The generated IDEA run configurations depend on the built artifact of the plugin, so it should be built automatically when running or debugging the generated configuration.

However, when the IDEA xml configuration file is created externally, like in the case of sbt-idea-plugin, it is sometimes not picked up immediately and requires an explicit loading.

It is recommended to explicitly invoke Build | Build Artifacts | Rebuild from IDEA after importing the project for the first time(i.e. when xmls are first generated).

Development notes

To publish a new version of sbt-idea-plugin, just add a new tag in format vA.B.C (e.g.v3.13.4) and push it to the main branch. TeamCity will automatically Build/Test/Deploy it in sbt-idea-plugin configuration.
(works in internal network only)

sbt-idea-plugin's People

Contributors

azdrojowa123 avatar eed3si9n avatar hmemcpy avatar iuliand-db avatar jastice avatar kellen avatar mlangc avatar mutcianm avatar niktrop avatar pavelfatin avatar psliwa avatar romanowski avatar srtobi avatar thangiee avatar timaliberdov avatar tpasternak avatar unkarjedy avatar vasilmkd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sbt-idea-plugin's Issues

Add plugin.xml dsl

Common plugin configuration options should be possible to define within the sbt build.

  • since-build and until-build could be inferred from ideaVersion
  • version can be shared with sbt's version setting key
  • changeNotes

ability to specify `ideaInternalPlugins` for Test scope

For now, the value of ideaInternalPlugins sbt key can only be specified for Global scope.
It would be nice to be able to refine it for Test scope only.
For example, I want to add "Kotlin" plugin to test the integration of some Scala plugin and Kotlin plugin modules (e.g. to test https://youtrack.jetbrains.com/issue/SCL-16093). I would like it to be added to tests classpath and I wouldn't like to pollute the Global scope, due to Kotlin classes are not required during compilation AFAIK.

NOTE: this is probably actual for other sbt keys:

  • ideaInternalPlugins
  • ideaExternalPlugins
  • ideaInternalPluginsJars
  • ideaExternalPluginsJars

Scala major version should be set automatically when depending on Scala plugin

Due to Scala's binary incompatibility between major release versions, a situation may occur when the user sets project's scalaVersion to a different major version from the one used in Scala plugin for IJ.
While the compilation may succeed user plugin project will fail to run with cryptic classloading errors because due to IJ classloading mechanism scala-library from parent's classloader will be used and the version won't match.
See #11

Still NumberFormatException in updateIntellij

#37 is resolved in b1e825d and released in version 3.3.1,
but now the below error shows up when rebooting sbt after successful installation.

(ThisBuild / updateIntellij) java.lang.NumberFormatException: For input string: "192-2147483647"

patched plugin.xml file not being included in jar

I just updated from plugin version 2.3.2 to version 3.6.3, and implemented the new patchPluginXml settings. After running packageArtifactZip, I checked to see if everything was correct, but the plugin.xml included in the jar was the original, unpatched file.

I did check that the file output to target/scala-2.12/classes/META-INF/plugin.xml DID get the patched values correctly, it just seems that the jar after bundling is using the original.

--- scala-2.12/classes/META-INF/plugin.xml	2020-04-13 14:47:04.000000000 -0400
+++ plugin-jar-unpacked/lib/META-INF/plugin.xml	2020-04-13 14:46:44.000000000 -0400
@@ -1,10 +1,10 @@
 <idea-plugin url="http://www.jetbrains.com/idea">
     <id>com.codmettle.plugin</id>
     <name>Plugin Name</name>
-    <version>1.5</version>
+    <version>1.4</version>
     <vendor url="http://www.codemettle.com">CodeMettle</vendor>
     <description>IntelliJ IDEA plugin to support Product Development</description>
-    <idea-version since-build="201.6668.121"/>
+    <idea-version since-build="183.0"/>
     <depends>org.intellij.scala</depends>
     <application-components>
         <!-- TODO put your components here -->

Attempt downloading external plugin sources

Some plugins on the IJ plugin marketplace provide a link to their sources in the plugin's description.
It would be very useful to be able to automatically download and attach them when using external plugin dependencies

PsiClass not found in 2019.x

Thanks for this plugin!

I'm trying to get the example project working for Intellij 2019.2.2 Community but I'm running into this compile error:

[error] C:\Users\WilliamCarter\workspace\ijext-sample-project\ijext\src\main\scala\org\jetbrains\scala\libextensions\test\MacroDynamicSupport.scala:12:89: Symbol 'type com.intellij.psi.PsiAnnotationMemberValue' is missing from the classpath.
[error] This symbol is required by 'trait org.jetbrains.plugins.scala.lang.psi.api.expr.ScExpression'.
[error] Make sure that type PsiAnnotationMemberValue is in your classpath and check for conflicting dependencies with `-Ylog-classpath`.
[error] A full rebuild may help if 'ScExpression.class' was compiled against an incompatible version of com.intellij.psi.
[error]   override def expandMacro(macros: ScFunction, context: MacroInvocationContext): Option[ScExpression] = {
[error]                                                                                         ^
[error] C:\Users\WilliamCarter\workspace\ijext-sample-project\ijext\src\main\scala\org\jetbrains\scala\libextensions\test\MacroFooableSupport.scala:14:17: object ScParameterizedType is not a case class, nor does it have an unapply/unapplySeq member
[error]       case Some(ScParameterizedType(_, Seq(tp))) => tp.canonicalText
[error]                 ^
[error] C:\Users\WilliamCarter\workspace\ijext-sample-project\ijext\src\main\scala\org\jetbrains\scala\libextensions\test\MySampleInjector.scala:8:9: Class com.intellij.psi.PsiClass not found - continuing with a stub.
[error]     if (source.findAnnotationNoAliases("org.jetbrains.scala.libextensions.test.MySampleAnnotation") != null) {
[error]         ^
[error] three errors found
[error] (support / Compile / compileIncremental) Compilation failed
[error] Total time: 14 s, completed 11-Sep-2019 14:36:26

We can ignore the error about ScParameterizedType no longer having an unapply because it doesn't but the other errors are more suprising because I would expect the Scala plugin jar to provide these implementations. I've checked my classpath as the error suggests and it does include the scala plugin jars:

  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\bcel-6.0.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\bsp4j-2.0.0-M4.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\commons-lang-2.6.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\compiler-shared.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\config-1.2.0.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\evo-inflector-1.2.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\fastparse_2.12-0.4.3.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\ipcsocket-1.0.0.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\ivy-2.4.0.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\jamm-0.3.1.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\org.eclipse.lsp4j.generator-0.5.0.jar,None)

  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\org.eclipse.lsp4j.jsonrpc-0.5.0.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\org.eclipse.xtend.lib-2.19.0.M2.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\org.eclipse.xtend.lib.macro-2.19.0.M2.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\org.eclipse.xtext.xbase.lib-2.19.0.M2.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\runners.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\sbt-structure-core_2.12-2018.2.1+4-88400d3f.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scala-compiler-indices-protocol_2.12-0.1.1.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scala-nailgun-runner.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scala-parser-combinators_2.12-1.0.6.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scala-play-2-jps-plugin.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scala-reflect.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scala-xml.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scalameta.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scalap.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scalariform_2.12-0.2.2.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scalastyle_2.12-1.0.0.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scalatest-finders-patched-0.9.9.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\scalaUltimate.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\sourcecode_2.12-0.1.3.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\spray-json_2.12-1.3.4.jar,None)
  ZipArchiveClassPath(C:\Users\WilliamCarter\.library-test-ijextPluginIC\sdk\192.6603.28\externalPlugins\Scala\lib\util-interface-1.1.2.jar,None)

The changes I've made to the example project can be found here: CarterWilliam/ijext-sample-project@1988606.

IDEA eap builds cannot be resolved

IDEA eap builds and snapshots have been extracted to a separate repository, namely
https://www.jetbrains.com/intellij-repository/snapshots

The plugin currently detects usage of this repo by looking at "-SNAPSHOT" suffix, which EAP builds don't have.

NPE in dumpDependencyStructure

java.lang.NullPointerException
[20:27:57]	at org.jetbrains.sbtidea.tasks.packaging.StructureBuilder$$anonfun$2.apply(StructureBuilder.scala:24)
[20:27:57]	at org.jetbrains.sbtidea.tasks.packaging.StructureBuilder$$anonfun$2.apply(StructureBuilder.scala:24)
[20:27:57]	at scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
[20:27:57]	at scala.collection.Iterator$class.foreach(Iterator.scala:727)
[20:27:57]	at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
[20:27:57]	at scala.collection.TraversableOnce$class.toMap(TraversableOnce.scala:279)
[20:27:57]	at scala.collection.AbstractIterator.toMap(Iterator.scala:1157)
[20:27:57]	at org.jetbrains.sbtidea.tasks.packaging.StructureBuilder.artifactMappings(StructureBuilder.scala:24)
[20:27:57]	at org.jetbrains.sbtidea.Keys$$anonfun$projectSettings$29$$anonfun$apply$15.apply(Keys.scala:349)
[20:27:57]	at org.jetbrains.sbtidea.Keys$$anonfun$projectSettings$29$$anonfun$apply$15.apply(Keys.scala:349)

Compile errors because package name conflicts in SDK jars

SDK jars contains libraries with package names which are conflicting.

The IntelliJ-Haskell plugin uses the CompileContextImpl of package com.intellij.compiler.impl. sbt compile gives this error:

[error] /home/rik/idea/intellij-haskell/src/main/scala/intellij/haskell/external/execution/StackCommandLine.scala:21:30: object impl is not a member of package com.intellij.compiler
[error] import com.intellij.compiler.impl._

That is because also library javac2.jar exports package com.intellij.compiler. It should use library java-impl.jar

How to prevent this compile error? Is it possible to exclude javac2.jar?

Also this error:

[error] /home/rik/idea/intellij-haskell/src/main/scala/intellij/haskell/external/execution/CommandLine.scala:28:26: object incremental is not a member of package org.jetbrains.jps
[error] import org.jetbrains.jps.incremental.messages.BuildMessage

Btw, in the past this wasn't issue.

Compiling the plugin in IntelliJ gives no errors.

Using version 2.4.1 of sbt-idea-plugin and IntelliJ version 192.6603.28

idea-runner/run return "Could not find installation home path"

[info] Done packaging.
[info] Running com.intellij.idea.Main

Start Failed: Internal error. Please report to http://jb.gg/ide/critical-startup-errors

java.lang.RuntimeException: Could not find installation home path. Please reinstall the software.
	at com.intellij.openapi.application.PathManager.getHomePath(PathManager.java:93)
	at com.intellij.openapi.application.PathManager.getHomePath(PathManager.java:72)
	at com.intellij.openapi.application.PathManager.loadProperties(PathManager.java:409)
	at com.intellij.ide.Bootstrap.main(Bootstrap.java:17)
	at com.intellij.idea.Main.main(Main.java:61)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at sbt.Run.invokeMain(Run.scala:98)
	at sbt.Run.run0(Run.scala:92)
	at sbt.Run.execute$1(Run.scala:68)
	at sbt.Run.$anonfun$run$4(Run.scala:80)
	at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:12)
	at sbt.util.InterfaceUtil$$anon$1.get(InterfaceUtil.scala:10)
	at sbt.TrapExit$App.run(TrapExit.scala:253)
	at java.lang.Thread.run(Thread.java:745)

Add blocking mode to `runIDE` task

[tobias.kahlert]
hmm, but I need it blocking. Basically I want to start the compiled plugin/intellij with some parameter, so that it generates some files, then idea will exit, and then I want to copy one of the created files to another folder (namely the created index-xml for searchable settings) (edited)

Merge strategies support

With current implementation if there are multiple files mapped to the same path, the latter would just overwrite the former.
This can be worked around by using additionalFileMappings setting, but having a more generic solution would be better.
In sbt-assembly plugin this is solved by introducing a MergeStrategy concept which takes care of resolving conflicts.

Implementing similar concept would prove useful, although coherency with IDEA readable artifacts must still be obeyed

Possible JBR issues when using runIDE?

We're developing an IntelliJ plugin using Scala which is currently using gradle-intellij-plugin, but we want to migrate it over to SBT using this plugin but I'm seeing errors like this when using the runIDE task:

java.lang.NoClassDefFoundError: com/apple/eawt/AppEvent$AboutEvent
	at com.intellij.ui.mac.MacOSApplicationProvider$Worker.initMacApplication(MacOSApplicationProvider.java:57)
	at com.intellij.ui.mac.MacOSApplicationProvider.initApplication(MacOSApplicationProvider.java:42)
	at com.intellij.idea.ApplicationLoader.startApp(ApplicationLoader.kt:159)
	at com.intellij.idea.ApplicationLoader.executeInitAppInEdt(ApplicationLoader.kt:93)
	at com.intellij.idea.ApplicationLoader.access$executeInitAppInEdt(ApplicationLoader.kt:1)
	at com.intellij.idea.ApplicationLoader$initApplication$1$1.run(ApplicationLoader.kt:355)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
	...

From what I can tell this is because JBR isn't being used. When I manually set JAVA_HOME to point to JBR before running SBT, everything works as expected:

export JAVA_HOME="/Users/reibitto/Library/Preferences/IntelliJIdea2019.3/jdks/jbrsdk-11_0_5-osx-x64-b630.1/jbrsdk/Contents/Home"

Should this be handled automatically by sbt-idea-plugin? Or maybe expose an option of some kind? For example, gradle-intellj-plugin exposes a jbrVersion setting:
https://github.com/JetBrains/gradle-intellij-plugin#configuration

Or is there a different way of resolving the issue that I'm seeing? FWIW, I tried runIDE on some other IntelliJ plugins based on sbt-idea-plugin that I found publicly on GitHub and I ran into the same NoClassDefFoundErrors for macOS. If it helps, this is what our current build.sbt looks like:
https://github.com/reibitto/zio-intellij/blob/1247caf840f4d52c6f49fc5e19b02e2eef86cd69/build.sbt

createRunnerProject does not work

Hi, I added a createRunnerProject call to my build.sbt but the idea-runner module does not get generated.

Related part looks like this:

lazy val macroPlugin = (project in file("plugin"))
.settings(commonSettings)
.settings(ideaSettings)
.settings(packagingSettings)
.settings(
name := "macroannotation-idea"
)
.enablePlugins(SbtIdeaPlugin)

lazy val ideaRunner: Project =
createRunnerProject(macroPlugin, "idea-runner")

ideaExternalPlugins should install plugins to `plugins` folder as well

While external plugins' classes must be added to compilation classpath during build, to be able to run/debug IDEA those plugins have to be excluded from initial root classpath(IDEA will load them using its own classloading mechanism from plugins folder).

This is especially important for IDEA plugins that depend on other IDEA plugins.

At the moment manual intervention is required, since necessary external plugins have to be manually copied to plugins dir.

ideaExternalPlugins doesn't work as expected

Hey!

I am not sure but seems mechanics of ideaExternalPlugins is broken. At least I can't find a proper way to compile a project that depends on external idea plugins without manual intervention.

In my project I have:

ideaExternalPlugins in ThisProject +=                                                                                       
    IdeaPlugin.Zip("scala-plugin", url("https://plugins.jetbrains.com/files/1347/65894/scala-intellij-bin-2019.2.14.zip")),

During updateIdea it downloads jar:

[info] Installed plugin 'scala-plugin to /home/unencrypted/univision/macrame-idea-scala-plugin/idea/sdk/192.5728.98/externalPlugins/scala-plugin.jar

but not unpacking it.

And then:

> show ideaExternalPluginsJars
[info] *

As a result, the sbt doesn't add external idea plugin to the classpath and I can't compile the project. From what I see in
https://github.com/JetBrains/sbt-idea-plugin/blob/master/src/main/scala/org/jetbrains/sbtidea/tasks/CreatePluginsClasspath.scala you expect external plugins to be unpacked.

If I manually unpack scala-plugin.jar to the scala-plugin folder then all start working as expected.

-XX:+UseConcMarkSweepGC is deprecated

The plugin encodes "-XX:+UseConcMarkSweepGC" as default in org.jetbrains.sbtidea.runIdea.IntellijVMOptions. When running under JDK11, this results in error messages:

[error] OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.

Can we make baseUrl for JBIdeaRepoArtifactResolver a configurable setting?

val baseUrl = s"https://www.jetbrains.com/intellij-repository/$repo/$groupId"

I'm building a plugin on CI at work and I have to go through a proxy to download the SDK zip.

i.e.

sbt-idea-plugin is hardcoded to download from https://www.jetbrains.com/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/192.7142.36/ideaIC-192.7142.36.zip

I need to change the url to this:
https://artifactory.twitter.biz/intellij-repository/releases/com/jetbrains/intellij/idea/ideaIC/192.7142.36/ideaIC-192.7142.36.zip

thanks!

idea-runner undefined setting with v3.0.0

lazy val ideaRunner: Project =
  createRunnerProject(plugin, "idea-runner")
[error] Reference to undefined setting: 
[error] 
[error]   idea-runner / ideaMainJars from idea-runner / Compile / unmanagedJars (Utils.scala:22)
[error]  
[error] Use 'last' for the full log.

Fine tune plugin dependency resolution

Plugin resolution mechanism is currently hardcoded and cannot be fine-tuned to support following scenarios:

  • disabling transitive plugin resolution
  • disabling resolution of optional plugin dependencies
  • excluding some plugin dependencies from transitive lookup

Add helper task to search for plugin id from a plugin name

Searching for a plugin id to provide as a dependency manually may be a time consuming task.
A decent alternative would be to implement a task that would search bundled and remote plugins for a plugin name(or maybe even description) and show plugin ids

Where does sbt-idea-plugin put source code for external plugins?

My build.sbt file looks like the following:

intellijPluginName in ThisBuild := "my-plugin"
intellijBuild in ThisBuild := "2019.3.3"
intellijExternalPlugins += "org.intellij.scala:2019.3.720:Nightly".toPlugin

name := "my-plugin"

version := "0.1"

scalaVersion := "2.13.1"

plugins.sbt:

resolvers += Resolver.url("jetbrains-sbt", url(s"https://dl.bintray.com/jetbrains/sbt-plugins"))(Resolver.ivyStylePatterns)

addSbtPlugin("org.jetbrains" % "sbt-idea-plugin" % "3.5.0")

sbt-idea-plugin was able to download the IntelliJ Platform SDK and Scala plugin.

Unfortunately, I was only able to find source code for the IntelliJ Platform SDK (it was downloaded to /home/my-plugin/sdk/2019.3.3/sources.zip and I had to manually set this folder as a source folder inside the IDE) but not for the Scala plugin.

Right now it looks like sbt-idea-plugin doesn't download source code for external plugins.

Ignore .DS_Store file

A .DS_store file gets created when opening a directory with Mac using the Finder app. This seems to cause some error messages until I manually delete that file. Maybe we can ignore a .DS_store file instead?

[error] Failed to build plugin index from /Users/tle/.IntelliJ-Scala-Pants-ReplPluginIC/sdk/192.7142.36/plugins/.DS_Store: Couldn't find plugin.xml in /Users/tle/.IntelliJ-Scala-Pants-ReplPluginIC/sdk/192.7142.36/plugins/.DS_Store
[info] Writing structure to /private/var/folders/9m/r6q8f2fn24xbnq5j67f9gthr0000gp/T/sbt-structure.xml...
[info] Done.
[success] Total time: 1 s, completed Nov 5, 2019 1:35:17 PM
[info] Reapplying settings...
[info] Set current project to plugin (in build file:/Users/tle/github/intellij-scala-repl/)
[error] Failed to build plugin index from /Users/tle/.IntelliJ-Scala-Pants-ReplPluginIC/sdk/192.7142.36/plugins/.DS_Store: Couldn't find plugin.xml in /Users/tle/.IntelliJ-Scala-Pants-ReplPluginIC/sdk/192.7142.36/plugins/.DS_Store
[success] Total time: 0 s, completed Nov 5, 2019 1:35:17 PM
[info] Defining Global / ideaPort
[info] The new value will be used by Compile / compile, Test / compile and 1 others.
[info] 	Run `last` for details.
[info] Reapplying settings...
[info] Set current project to plugin (in build file:/Users/tle/github/intellij-scala-repl/)
[error] Failed to build plugin index from /Users/tle/.IntelliJ-Scala-Pants-ReplPluginIC/sdk/192.7142.36/plugins/.DS_Store: Couldn't find plugin.xml in /Users/tle/.IntelliJ-Scala-Pants-ReplPluginIC/sdk/192.7142.36/plugins/.DS_Store```

NumberFormatException in updateIntellij

How to reproduce

sbt raises NumberForatException on startup after successfull intellijExternalPlugins installation.

$> sbt
(For the first time, IdeaIC and plugin are successfully downloaded)
(Then shutdown sbt and rerun)
$> sbt
[info] Loading settings for project sbt-idea-plugin-issue-build from plugins.sbt ...
[info] Loading project definition from /home/vagrant/IdeaProjects/sbt-idea-plugin-issue/project
[info] Loading settings for project myAwesomePlugin from build.sbt ...
[info] Set current project to my-awesome-plugin (in build file:/home/vagrant/IdeaProjects/sbt-idea-plugin-issue/)
[error] java.lang.NumberFormatException: For input string: "*"
[error]         at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

Configuration

  • openjdk 11.0.4 2019-07-16

project/build.properties

sbt.version=1.3.2

project/plugins.sbt

addSbtPlugin("org.jetbrains" % "sbt-idea-plugin" % "3.3.0")

build.sbt

intellijPluginName in ThisBuild := "my-awesome-plugin"
intellijBuild in ThisBuild := "192.6817.14"
intellijDownloadSources in ThisBuild := true
intellijInternalPlugins += "java"
intellijExternalPlugins += "PsiViewer".toPlugin

lazy val myAwesomePlugin = (project in file("."))
  .enablePlugins(SbtIdeaPlugin)
  .settings(
    name := "my-awesome-plugin",
    version := "0.1.0",
    scalaVersion := "2.13.1"
  )

updateIdea NullPointerException

with something like

lazy val ideaSettings = Def.settings(
  ThisBuild / ideaPluginName := "name",
  ThisBuild / ideaEdition := IdeaEdition.Community,
  ThisBuild / ideaBuild := "192.6603.28",
  ideaInternalPlugins := Seq("java"),
  ideaExternalPlugins += "org.intellij.scala::Nightly".toPlugin
)
[info] Resolving IDEA dependency for BuildInfo(192.6603.28,org.jetbrains.sbtidea.Defns$IdeaEdition$Community$@5a3428de)
[info] Downloading 2 IDEA artifacts
[error] java.lang.NullPointerException
[error]         at org.jetbrains.sbtidea.download.FileDownloader.$anonfun$getRemoteMetaData$2(FileDownloader.scala:108)
[error]         at org.jetbrains.sbtidea.download.package$.withConnection(package.scala:25)
[error]         at org.jetbrains.sbtidea.download.FileDownloader.getRemoteMetaData(FileDownloader.scala:100)
[error]         at org.jetbrains.sbtidea.download.FileDownloader.downloadNative(FileDownloader.scala:66)
[error]         at org.jetbrains.sbtidea.download.FileDownloader.download(FileDownloader.scala:21)
[error]         at org.jetbrains.sbtidea.download.IdeaUpdater.$anonfun$updateIdea$3(IdeaUpdater.scala:39)
[error]         at scala.collection.TraversableLike.$anonfun$map$1(TraversableLike.scala:237)
[error]         at scala.collection.immutable.List.foreach(List.scala:392)
[error]         at scala.collection.TraversableLike.map(TraversableLike.scala:237)
[error]         at scala.collection.TraversableLike.map$(TraversableLike.scala:230)
[error]         at scala.collection.immutable.List.map(List.scala:298)
[error]         at org.jetbrains.sbtidea.download.IdeaUpdater.updateIdea(IdeaUpdater.scala:39)
[error]         at org.jetbrains.sbtidea.download.IdeaUpdater.updateIdeaAndPlugins(IdeaUpdater.scala:27)
[error]         at org.jetbrains.sbtidea.Init.$anonfun$buildSettings$12(Init.scala:53)
[error]         at org.jetbrains.sbtidea.Init.$anonfun$buildSettings$12$adapted(Init.scala:44)
[error]         at scala.Function1.$anonfun$compose$1(Function1.scala:49)
[error]         at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:62)
[error]         at sbt.std.Transform$$anon$4.work(Transform.scala:67)
[error]         at sbt.Execute.$anonfun$submit$2(Execute.scala:280)
[error]         at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:19)
[error]         at sbt.Execute.work(Execute.scala:289)
[error]         at sbt.Execute.$anonfun$submit$1(Execute.scala:280)
[error]         at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:178)
[error]         at sbt.CompletionService$$anon$2.call(CompletionService.scala:37)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
[error]         at java.util.concurrent.FutureTask.run(FutureTask.java:266)
[error]         at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
[error]         at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
[error]         at java.lang.Thread.run(Thread.java:745)
[error] (ThisBuild / updateIdea) java.lang.NullPointerException

Add bundled plugin dependencies via plugin id instead of folder name

Bundled plugin folders are sometimes renamed in the platform which results in "cannot find bundled plugin: check plugin name" error, while the plugin itself is still there.
Since plugins tend to have stable plugin ids it would be reasonable to use them instead of relying on folder structure.

External plugins' version and compatibility isn't checked

External plugins are only downloaded from the repository once and then re-used regardless of whether there is a newer version(if installed from channel) or the plugin is no longer compatible with current IDEA version.

The plugin downloader must be able to resolve these cases and update external plugins if needed or notify the user that there is an unresolvable incompatibility with the external plugins.

External plugins not attached

trying to update an internal plugin (just support some fields generated with scala macros) for 2019.1-beta.

have tried sbt-idea-plugin 2.1.3, 2.3.0, and 2.3.1. My only external dependency is the Scala plugin. This dependency doesn't work, because:

it is extracted into the plugins directory instead of the externalPlugins directory, meaning ideaExternalPluginsJars doesn't pick up any jars
the scala plugin is extracted into a Scala directory, even though it already has a top-level Scala directory in the zip - so there's nothing in Scala/lib for ideaExternalPluginsJars to find - it's in Scala/Scala/lib

@codingismy11to7

Scala library added to classpath when not actually required

Scala library shouldn't be bundled and included in generated artifact or module structure if current IDEA plugin already depends on another one with scala-library already included in distribution.

This creates classloading conflict because scala-library classes are loaded both in parent and child plugin classloaders.

One particular example would be depending on Scala plugin, which breaks IDEA run configurations.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.