build.sbt (952 lines of code) (raw):

import Common.* import CompilationCache.compilationCacheSettings import Dependencies.provided import DynamicDependenciesFetcher.* import LocalRepoPackager.{localRepoDependencies, localRepoUpdate, relativeJarPath, sbtDep} import org.jetbrains.sbtidea.Keys.* import org.jetbrains.sbtidea.PluginJars import java.nio.file.Path // Global build settings (ThisBuild / intellijPluginName) := "Scala" (ThisBuild / intellijBuild) := Versions.intellijVersion (ThisBuild / intellijPlatform) := (Global / intellijPlatform).??(IntelliJPlatform.IdeaCommunity).value (ThisBuild / autoRemoveOldCachedIntelliJSDK) := true (ThisBuild / autoRemoveOldCachedDownloads) := true ThisBuild / resolvers := { // not exactly sure why "releases" and "staging" would ever need to be enabled // Resolver.sonatypeOssRepos("releases") ++ // Resolver.sonatypeOssRepos("staging") ++ // enable if you need to resolve SNAPSHOT versions of open source libraries // Resolver.sonatypeOssRepos("snapshots") ++ // enable if you need to resolve Scala 2.12, 2.13 RC versions // Seq( // "scala-integration" at "https://scala-ci.typesafe.com/artifactory/scala-integration/" // ) ++ Seq( "JetBrains Maven Central" at "https://cache-redirector.jetbrains.com/maven-central" ) } ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-xml" % VersionScheme.Always (Global / javacOptions) := globalJavacOptions (Global / scalacOptions) := globalScalacOptions Global / intellijAttachSources := true // Muted lint warnings for keys used by the IDE, but not by sbt (coming from sbt-ide-settings) Global / excludeLintKeys ++= Set(idePackagePrefix, ideSkipProject, ideExcludedDirectories, ideaConfigOptions, intellijPlugins) val definedTestsScopeFilter: ScopeFilter = ScopeFilter(inDependencies(scalaCommunity, includeRoot = false), inConfigurations(Test)) // Main projects lazy val scalaCommunity: sbt.Project = newProject("scalaCommunity", file(".")) .dependsOn( bsp % "test->test;compile->compile", bspJUnit % "test->test;compile->compile", bspTerminal % "test->test;compile->compile", codeInsight % "test->test;compile->compile", conversion % "test->test;compile->compile", uast % "test->test;compile->compile", worksheet % "test->test;compile->compile", scalaImpl % "test->test;compile->compile", scalaMetaImpl % "test->test;compile->compile", structureView % "test->test;compile->compile", sbtImpl % "test->test;compile->compile", sbtProjectImportingTests % "test->test", bspIntegrationTests % "test->test", compilerIntegration % "test->test;compile->compile", compilerIntegrationServerManagement % "test->test;compile->compile", scalaCompilerPluginTests % "test->test;compile->compile", debugger % "test->test;compile->compile", testingSupport % "test->test;compile->compile", gradleIntegration % "test->test;compile->compile", i18nIntegration % "test->test;compile->compile", intelliLangIntegration % "test->test;compile->compile", markdownIntegration % "test->test;compile->compile", mavenIntegration % "test->test;compile->compile", propertiesIntegration % "test->test;compile->compile", mlCompletionIntegration % "test->test;compile->compile", textAnalysis % "test->test;compile->compile", kotlinUtils % "test->test;compile->compile", structuralSearch % "test->test;compile->compile", scalaLanguageUtils % "test->test;compile->compile", scalaLanguageUtilsRt % "test->test;compile->compile", pluginXml, scalaCli % "test->test;compile->compile", javaDecompilerIntegration % "test->test;compile->compile", scalastyleIntegration, intellijBazelIntegration, ) .settings(MainProjectSettings) .settings( packageAdditionalProjects := Seq( jps, compilerJps, repackagedZinc, worksheetReplInterfaceImpls, compileServer, scalaCompilerPlugin_2_12, scalaCompilerPlugin_2_13, scalaCompilerPlugin_3_3, nailgunRunners, copyrightIntegration, devKitIntegration, featuresTrainerIntegration, junitIntegration, mlCompletionPropertiesIntegration, runtimeDependencies, ), // all sub-project tests need to be run within main project's classpath Test / definedTests := definedTests.all(definedTestsScopeFilter).value.flatten, cleanAll := Common.cleanAllTask(None).value ) lazy val pluginXml = newProject("pluginXml", file("pluginXml")) .settings(NoSourceDirectories) .settings( packageMethod := PackagingMethod.Standalone(), packageFileMappings += { val patchedVersionFile: File = Common.patchPluginXML(baseDirectory.value / "resources" / "META-INF" / "plugin.xml") streams.value.log.info(s"patched version in file: ${patchedVersionFile.getPath}") patchedVersionFile -> "lib/pluginXml.jar!/META-INF/plugin.xml" }, ) lazy val scalaApi = newProject("scala-api", file("scala/scala-api")) .settings( idePackagePrefix := Some("org.jetbrains.plugins.scala") ) lazy val workspaceEntities = newProjectWithKotlin("workspace-entities", file("sbt/sbt-impl/workspace-entities")) .settings( Compile / unmanagedSourceDirectories ++= Seq(sourceDirectory.value / "gen"), scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions ) lazy val sbtKotlinUtils = newProjectWithKotlin("sbt-kotlin-utils", file("sbt/sbt-kotlin-utils")) .settings( crossPaths := false, autoScalaLibrary := false ) lazy val sbtApi = newProject("sbt-api", file("sbt/sbt-api")) .dependsOn( scalaApi, compilerShared, workspaceEntities, testUtilsCommon % "test->test" ) .enablePlugins(BuildInfoPlugin) .settings( buildInfoPackage := "org.jetbrains.sbt.buildinfo", buildInfoKeys := Seq( "sbtStructureVersion" -> Versions.sbtStructureVersion, "sbtIdeaShellVersion" -> Versions.sbtIdeaShellVersion, "sbtIdeaCompilerIndicesVersion" -> Versions.compilerIndicesVersion, "sbtStructurePath_0_13" -> relativeJarPath(Dependencies.structureExtractor_0_13), "sbtStructurePath_1_0" -> relativeJarPath(Dependencies.structureExtractor_1_0), "sbtStructurePath_1_3" -> relativeJarPath(Dependencies.structureExtractor_1_3), "sbtStructurePath_2" -> relativeJarPath(Dependencies.structureExtractor_2), ), buildInfoOptions += BuildInfoOption.ConstantValue ) lazy val codeInsight = newProject( "codeInsight", file("scala/codeInsight") ).dependsOn( scalaImpl % "test->test;compile->compile" ) lazy val conversion = newProject( "conversion", file("scala/conversion") ).dependsOn( codeInsight % "test->test;compile->compile" ) lazy val uast = newProject( "uast", file("scala/uast") ).dependsOn( scalaImpl % "test->test;compile->compile", ).settings( intellijPlugins += "JUnit".toPlugin ) lazy val worksheet = newProject("worksheet", file("scala/worksheet")) .dependsOn( bsp, compilerIntegration % "test->test;compile->compile", worksheetReplInterface, repl % "test->test;compile->compile", //do we indeed need this dependency on Scala REPL? can we get rid of it? ).settings( packageMethod := PackagingMethod.PluginModule("scalaCommunity.worksheet") ) // A subproject which exists only to hold a precompiled jar in its `lib` directory. lazy val worksheetReplInterface = Project("worksheet-repl-interface", file("scala/worksheet/repl-interface")) .settings(NoSourceDirectories) .settings( organization := JetBrains, crossPaths := false, autoScalaLibrary := false, ideSkipProject := true, intellijMainJars := Seq.empty, intellijTestJars := Seq.empty, intellijPlugins := Seq.empty, // Settings for packaging unmanaged jar dependencies in the plugin (jar files in the `lib` project directory). // Without this definition of `packageFileMappings`, the unmanaged jar dependencies are ignored. packageMethod := PackagingMethod.DepsOnly(), packageFileMappings := { val unmanagedJars = ((Compile / unmanagedBase).value ** "*.jar").get() unmanagedJars.map(f => (f, s"lib/${f.getName}")) } ) // A subproject which exists only to hold a precompiled jar in its `lib` directory. lazy val worksheetReplInterfaceImpls = Project("worksheet-repl-interface-impls", file("scala/worksheet/repl-interface/impls")) .settings(NoSourceDirectories) .settings( organization := JetBrains, crossPaths := false, autoScalaLibrary := false, ideSkipProject := true, intellijMainJars := Seq.empty, intellijTestJars := Seq.empty, intellijPlugins := Seq.empty, // Settings for packaging unmanaged jar dependencies in the plugin (jar files in the `lib` project directory). // Without this definition of `packageFileMappings`, the unmanaged jar dependencies are ignored. packageMethod := PackagingMethod.DepsOnly(), packageFileMappings := { val unmanagedJars = ((Compile / unmanagedBase).value ** "*.jar").get() unmanagedJars.map(f => (f, s"worksheet-repl-interface/${f.getName}")) } ) lazy val structureView = newProject("structure-view", file("scala/structure-view")) .dependsOn(scalaImpl % "test->test;compile->compile") .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, ) lazy val repl = newProject("repl", file("scala/repl")) .dependsOn( scalaImpl % "test->test;compile->compile", structureView % "test->test;compile->compile", ) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, packageMethod := PackagingMethod.MergeIntoOther(scalaCommunity) ) lazy val tastyReader = Project("tasty-reader", file("scala/tasty-reader")) .dependsOn(scalaLanguageUtils) .dependsOn(scalaLanguageUtilsRt) .settings(projectDirectoriesSettings) .settings( name := "tasty-reader", organization := JetBrains, idePackagePrefix := Some("org.jetbrains.plugins.scala.tasty.reader"), intellijMainJars := Seq.empty, intellijTestJars := Seq.empty, scalaVersion := Versions.scala3Version, libraryDependencies += Dependencies.tastyCore, (Compile / scalacOptions) := Seq("-deprecation"), (Test / unmanagedResourceDirectories) += baseDirectory.value / "testdata", libraryDependencies ++= Seq( Dependencies.junit % Test, Dependencies.junitInterface % Test, ) ) .settings(compilationCacheSettings) lazy val scalaImpl: sbt.Project = newProject("scala-impl", file("scala/scala-impl")) .dependsOn( compilerShared, scalaApi, scalaLanguageUtils, sbtApi, decompiler % "test->test;compile->compile", tastyReader % "test->test;compile->compile", scalatestFinders, runners, testRunners, testUtilsCommon % "test->test" ) .settings( ideExcludedDirectories := Seq( baseDirectory.value / "target", baseDirectory.value / "testdata" / "projectsForHighlightingTests" / ".ivy_cache", baseDirectory.value / "testdata" / "projectsForHighlightingTests" / ".coursier_cache", //NOTE: when updating, please also update `org.jetbrains.scalateamcity.common.Caching.highlightingPatterns` baseDirectory.value / "testdata" / "projectsForHighlightingTests" / "downloaded", ), //scalacOptions in Global += "-Xmacro-settings:analyze-caches", libraryDependencies ++= DependencyGroups.scalaCommunity, libraryDependencies ++= Seq( //for ExternalSystemTestCase and ExternalSystemImportingTestCase Dependencies.intellijExternalSystemTestFramework % Test, Dependencies.slf4jApi % Test, //for PlatformTestUtil.newPerformanceTest Dependencies.intellijIdeMetricsBenchmark % Test, Dependencies.intellijIdeMetricsCollector % Test, Dependencies.intellijIdeUtilCommon % Test, ), // for dependency version completion/inspections libraryDependencies += Dependencies.coursierApi, resolvers += Versions.intellijRepository_ForManagedIntellijDependencies, intellijPlugins += "JUnit".toPlugin, intellijPluginJars := intellijPluginJars.value.map { case PluginJars(descriptor, root, cp) => PluginJars(descriptor, root, cp.filterNot(_.getName.contains("junit-jupiter-api"))) }, packageLibraryMappings := Seq( // "com.thesamet.scalapb" %% "scalapb-runtime" % ".*" -> None, // "com.thesamet.scalapb" %% "lenses" % ".*" -> None, Dependencies.scalaXml -> Some("lib/scala-xml.jar"), Dependencies.scalaReflect -> Some("lib/scala-reflect.jar"), Dependencies.scalaParserCombinators -> Some("lib/scala-parser-combinators.jar"), Dependencies.scalaLibrary -> None, Dependencies.scala3Library -> None ) ) /** * Encapsulates scala.meta, so that we don't have to depend on in directly in scala-impl */ lazy val scalaMetaImpl: sbt.Project = newProject("scala-meta-impl", file("scala/scala-meta-impl")) .dependsOn(scalaImpl % "test->test;compile->compile") .settings( scalaVersion := Versions.scalaVersion, libraryDependencies ++= Seq( Dependencies.scalaMetaCore, Dependencies.scalapbRuntime ), ) /** * Utilities for Kotlin-Scala interop written in Kotlin */ lazy val kotlinUtils: sbt.Project = newProjectWithKotlin("kotlin-utils", file("scala/kotlin-utils")) .dependsOn(scalaLanguageUtils) .settings( idePackagePrefix := Some("org.jetbrains.plugins.scala.kotlin.util"), packageMethod := PackagingMethod.MergeIntoOther(scalaCommunity), ) /** * Utilities which only depend on the Scala standard library and do not depend on other libraries or IntelliJ SDK */ lazy val scalaLanguageUtils: sbt.Project = newPlainScalaProject("scala-utils-language", file("scala/scala-utils-language")) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, packageMethod := PackagingMethod.MergeIntoOther(scalaCommunity) ) /** * Same as [[scalaLanguageUtils]], but utilities from this module can be used form both IntelliJ IDEA process and JPS process. * Keep this module as small as possible with no other dependencies */ lazy val scalaLanguageUtilsRt: sbt.Project = newPlainScalaProject("scala-utils-language-rt", file("scala/scala-utils-language-rt")) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := outOfIDEAProcessScala3ScalacOptions, Compile / javacOptions := outOfIDEAProcessJavacOptions, packageMethod := PackagingMethod.Standalone("lib/utils_rt.jar", static = true), ) /** * The modules contain common test utilities that can be used from any other module. * It only has dependency on the plain Scala and on the JUnit test framework. * It doesn't have any dependencies on IntelliJ SDK entities or test framework. */ lazy val testUtilsCommon: sbt.Project = newPlainScalaProject("test-utils-common", file("scala/test-utils-common")) .projectWithTestsOnly lazy val sbtImpl = newProject("sbt-impl", file("sbt/sbt-impl")) .dependsOn( sbtApi, sbtKotlinUtils, scalaImpl % "test->test;compile->compile", ) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, // libraryDependencies += Dependencies.sbtStructureCore.exclude("org.scala-lang.modules", "scala-xml_3") ) lazy val sbtProjectImportingTests = newProject("sbt-project-importing-tests", file("sbt/sbt-project-importing-tests")) .projectWithTestsOnly .dependsOn( sbtImpl % "compile->compile;test->test", // this dependency is added primarily use CompileServerLauncher from sbt importing test (to shut it down) compilerIntegrationServerManagement % "compile->compile;test->test", ) lazy val compilerIntegration = newProject("compiler-integration", file("scala/compiler-integration")) .dependsOn( compilerIntegrationServerManagement % "test->test;compile->compile", scalaImpl % "test->test;compile->compile", codeInsight % "test->test;compile->compile", sbtImpl % "test->test;compile->compile", scalaMetaImpl % "test->test;compile->compile", jps, bsp ) .settings( packageMethod := PackagingMethod.PluginModule("scalaCommunity.compiler-integration") ) lazy val compilerIntegrationServerManagement = newProject("compiler-integration-server-management", file("scala/compiler-integration-server-management")) .dependsOn( scalaImpl % "test->test;compile->compile", ) .settings( // It's fine to merge it into the same module packageMethod := PackagingMethod.PluginModule("scalaCommunity.compiler-integration") ) lazy val debugger = newProject("debugger", file("scala/debugger")) .dependsOn( scalaImpl % "test->test;compile->compile", compilerIntegration % "test->test;compile->compile" ).settings( packageMethod := PackagingMethod.PluginModule("scalaCommunity.debugger") ) lazy val compileServer = newPlainScalaProject("compile-server", file("scala/compile-server")) .dependsOn(compilerShared, repackagedZinc, worksheetReplInterface) .withJpsClasspath .settings( Compile / javacOptions := outOfIDEAProcessJavacOptions, Compile / scalacOptions := outOfIDEAProcessScalacOptions, packageMethod := PackagingMethod.Standalone("lib/jps/compile-server.jar", static = true), libraryDependencies += Dependencies.nailgun, packageLibraryMappings += Dependencies.nailgun -> Some("lib/jps/nailgun.jar") ) // Compiler plugins def compilerPluginProject( projectName: String, projectPath: File, scalaCompilerVersion: String, extraScalacOptions: Seq[String], packagingOutputPath: String ): sbt.Project = Project(projectName, projectPath) .disablePlugins(SbtIdeaPluginExtension) .settings( name := projectName, organization := JetBrains, intellijPlugins := Seq.empty, scalaVersion := scalaCompilerVersion, libraryDependencies += { val artifact = scalaCompilerVersion match { case scala3 if scala3.startsWith("3.") => "org.scala-lang" %% "scala3-compiler" % scala3 case scala2 => "org.scala-lang" % "scala-compiler" % scala2 } artifact % Provided }, libraryDependencies ++= Seq( Dependencies.jetbrainsAnnotations % Provided, Dependencies.junit % Test, Dependencies.junitInterface % Test, Dependencies.opentest4j % Test ), Compile / scalacOptions := Seq("--release", "8") ++ extraScalacOptions, packageMethod := PackagingMethod.Standalone(packagingOutputPath), Test / fork := true ) .settings(projectDirectoriesSettings) .settings(compilationCacheSettings) lazy val scalaCompilerPlugin_2_12: sbt.Project = compilerPluginProject( projectName = "compiler-plugin-2_12", projectPath = file("scala/compiler-plugin/scala-2.12"), scalaCompilerVersion = "2.12.20", extraScalacOptions = Seq("-deprecation"), packagingOutputPath = "lib/jps/compiler-plugin-2.12.jar" ) lazy val scalaCompilerPlugin_2_13: sbt.Project = compilerPluginProject( projectName = "compiler-plugin-2_13", projectPath = file("scala/compiler-plugin/scala-2.13"), scalaCompilerVersion = "2.13.15", extraScalacOptions = Seq("-deprecation"), packagingOutputPath = "lib/jps/compiler-plugin-2.13.jar" ) lazy val scalaCompilerPlugin_3_3: sbt.Project = compilerPluginProject( projectName = "compiler-plugin-3_3", projectPath = file("scala/compiler-plugin/scala-3.3"), scalaCompilerVersion = "3.3.6", extraScalacOptions = Seq.empty, packagingOutputPath = "lib/jps/compiler-plugin-3.3.jar" ) lazy val scalaCompilerPluginTests: sbt.Project = newProject("compiler-plugin-tests", file("scala/compiler-plugin/tests")) .dependsOn(scalaImpl) lazy val compilerJps = newPlainScalaProject("compiler-jps", file("scala/compiler-jps")) .dependsOn(jps, compileServer) .withJpsClasspath .settings( (Compile / javacOptions) := outOfIDEAProcessJavacOptions, (Compile / scalacOptions) := outOfIDEAProcessScalacOptions, packageMethod := PackagingMethod.Standalone("lib/jps/compiler-jps.jar", static = true), libraryDependencies ++= Seq(Dependencies.scalaParallelCollections), packageLibraryMappings ++= Seq( Dependencies.scalaParallelCollections -> Some("lib/jps/scala-parallel-collections.jar") ), ) lazy val repackagedZinc = newProject("repackagedZinc", file("target/tools/zinc")) .settings(NoSourceDirectories) .settings( packageOutputDir := baseDirectory.value / "plugin", packageAssembleLibraries := true, shadePatterns += ShadePattern("com.google.protobuf.**", "zinc.protobuf.@1"), packageMethod := PackagingMethod.DepsOnly("lib/jps/incremental-compiler.jar"), libraryDependencies ++= Seq(Dependencies.zinc, Dependencies.compilerInterface, Dependencies.sbtInterface), // We package and ship these jars separately. They are also transitive dependencies of `zinc`. // These mappings ensure that the transitive dependencies are not packaged into the assembled // `incremental-compiler.jar`, which leads to a bloated classpath with repeated classes. packageLibraryMappings ++= Seq( Dependencies.compilerInterface -> None, Dependencies.sbtInterface -> None ) ) lazy val compilerShared = newPlainScalaProject("compiler-shared", file("scala/compiler-shared")) .dependsOn(scalaLanguageUtilsRt) .withJpsSharedClasspath .settings( scalaVersion := Versions.scala3Version, (Compile / javacOptions) := outOfIDEAProcessJavacOptions, (Compile / scalacOptions) := outOfIDEAProcessScala3ScalacOptions, packageMethod := PackagingMethod.Standalone("lib/compiler-shared.jar", static = true) ) lazy val jps = newPlainScalaProject("jps", file("scala/jps")) .withJpsClasspath .settings( Compile / javacOptions := outOfIDEAProcessJavacOptions, Compile / scalacOptions := outOfIDEAProcessScalacOptions, packageMethod := PackagingMethod.Standalone("lib/scala-jps.jar", static = true), libraryDependencies += Dependencies.compilerIndicesProtocol, packageLibraryMappings += Dependencies.compilerIndicesProtocol -> Some(s"lib/scala-compiler-indices-protocol_2.13-${Versions.compilerIndicesVersion}.jar") ) lazy val runners: Project = newProject("runners", file("scala/runners")) .settings( (Compile / javacOptions) := outOfIDEAProcessJavacOptions, (Compile / scalacOptions) := outOfIDEAProcessScalacOptions, packageMethod := PackagingMethod.Standalone(static = true), packageAdditionalProjects ++= Seq(testRunners, testRunners_spec2_2x) ) lazy val structuralSearch = newProject("structural-search", file("scala/structural-search")) .dependsOn( scalaImpl % "test->test;compile->compile", codeInsight % "test->test;compile->compile" ) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "JUnit".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.structural-search") ) lazy val testingSupport = newProject("testing-support", file("scala/test-integration/testing-support")) .dependsOn( scalaImpl % "test->test;compile->compile", sbtImpl % "test->test;compile->compile", bsp, structureView % "test->test;compile->compile", compilerIntegration % "test->test;compile->compile" ) .settings( intellijPlugins += "JUnit".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.testing-support") ) lazy val testRunners: Project = newProject("test-runners", file("scala/test-integration/test-runners")) .settings( (Compile / javacOptions) := outOfIDEAProcessJavacOptions, (Compile / scalacOptions) := outOfIDEAProcessScalacOptions, packageMethod := PackagingMethod.MergeIntoOther(runners), libraryDependencies ++= DependencyGroups.testRunners ) lazy val testRunners_spec2_2x: Project = newProject("test-runners-spec2_2x", file("scala/test-integration/test-runners-spec2_2x")) .dependsOn(testRunners) .settings( (Compile / javacOptions) := outOfIDEAProcessJavacOptions, (Compile / scalacOptions) := outOfIDEAProcessScalacOptions, packageMethod := PackagingMethod.MergeIntoOther(runners), libraryDependencies ++= Seq(provided.specs2_2x) ) lazy val scalatestFindersRootDir = file("scala/test-integration/scalatest-finders") lazy val scalatestFinders = Project("scalatest-finders", scalatestFindersRootDir) .settings( name := "scalatest-finders", organization := JetBrains, scalaVersion := Versions.scalaVersion, // NOTE: we might continue NOT using Scala in scalatestFinders just in case // in some future we will decide again to extract the library, so as it can be used even without scala jar crossPaths := false, // disable using the Scala version in output paths and artifacts autoScalaLibrary := false, // removes Scala dependency, scalacOptions := Seq(), // scala is disabled anyway, set empty options to move to a separate compiler profile (in IntelliJ model) javacOptions := globalJavacOptions, // finders are run in IDEA process, so using JDK 17 packageMethod := PackagingMethod.Standalone("lib/scalatest-finders-patched.jar"), intellijMainJars := Nil, intellijTestJars := Nil, ) .settings(compilationCacheSettings) lazy val scalatestFindersTestSettings = Seq( scalacOptions := Seq("-deprecation") ) val scalatestLatest_2 = "2.2.6" val scalatestLatest_3_0 = "3.0.9" val scalatestLatest_3_2 = "3.2.16" lazy val scalatestFindersTests_2 = Project("scalatest-finders-tests-2", scalatestFindersRootDir / "tests-2") .dependsOn(scalatestFinders) .settings( name := "scalatest-finders-tests-2", organization := JetBrains, scalatestFindersTestSettings, scalaVersion := "2.11.12", libraryDependencies := Seq("org.scalatest" %% "scalatest" % scalatestLatest_2 % Test), intellijMainJars := Nil, intellijTestJars := Nil ) .settings(compilationCacheSettings) lazy val scalatestFindersTests_3_0 = Project("scalatest-finders-tests-3_0", scalatestFindersRootDir / "tests-3_0") .dependsOn(scalatestFinders) .settings( name := "scalatest-finders-tests-3_0", organization := JetBrains, scalatestFindersTestSettings, scalaVersion := "2.12.20", libraryDependencies := Seq("org.scalatest" %% "scalatest" % scalatestLatest_3_0 % Test), intellijMainJars := Nil, intellijTestJars := Nil, ) .settings(compilationCacheSettings) lazy val scalatestFindersTests_3_2 = Project("scalatest-finders-tests-3_2", scalatestFindersRootDir / "tests-3_2") .dependsOn(scalatestFinders) .settings( name := "scalatest-finders-tests-3_2", organization := JetBrains, scalatestFindersTestSettings, scalaVersion := Versions.scalaVersion, libraryDependencies := Seq("org.scalatest" %% "scalatest" % scalatestLatest_3_2 % Test), intellijMainJars := Nil, intellijTestJars := Nil, ) .settings(compilationCacheSettings) lazy val nailgunRunners = newProject("nailgun", file("scala/nailgun")) .settings( (Compile / javacOptions) := outOfIDEAProcessJavacOptions, (Compile / scalacOptions) := outOfIDEAProcessScalacOptions, libraryDependencies += Dependencies.nailgun, packageLibraryMappings += Dependencies.nailgun -> Some("lib/jps/nailgun.jar"), packageMethod := PackagingMethod.Standalone("lib/scala-nailgun-runner.jar", static = true) ) lazy val decompiler = newProject("decompiler", file("scala/decompiler")) .dependsOn(scalaLanguageUtils) .settings( libraryDependencies ++= DependencyGroups.decompiler, packageMethod := PackagingMethod.Standalone("lib/scalap.jar") ) lazy val bspJUnit = newProject("bsp-junit", file("bsp-builtin/bsp-junit")) .dependsOn( bsp % "test->test;compile->compile", ) .settings( intellijPlugins += "JUnit".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.bsp-junit") ) lazy val bspTerminal = newProject("bsp-terminal", file("bsp-builtin/bsp-terminal")) .dependsOn( bsp % "test->test;compile->compile", ) .settings( intellijPlugins += "org.jetbrains.plugins.terminal".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.bsp-terminal") ) lazy val bsp = newProject("bsp", file("bsp-builtin/bsp")) .enablePlugins(BuildInfoPlugin) .dependsOn( scalaImpl % "test->test;compile->compile", sbtImpl % "test->test;compile->compile", compilerIntegrationServerManagement % "test->test;compile->compile", ) .settings( libraryDependencies ++= DependencyGroups.bsp, buildInfoPackage := "org.jetbrains.bsp.buildinfo", buildInfoKeys := Seq("bloopVersion" -> Versions.bloopVersion), buildInfoOptions += BuildInfoOption.ConstantValue, packageMethod := PackagingMethod.PluginModule("scalaCommunity.bsp"), ) lazy val bspIntegrationTests = newProject("bsp-integration-tests", file("bsp-builtin/bsp-integration-tests")) .projectWithTestsOnly .dependsOn( bsp % "compile->compile;test->test", compilerIntegration % "compile->compile;test->test", ) lazy val scalaCli = newProject("scala-cli", file("scala-cli")) .dependsOn( scalaImpl % "test->test;compile->compile", bsp % "test->test;compile->compile", ).settings( packageMethod := PackagingMethod.PluginModule("scalaCommunity.scala-cli") ) // Integration with other IDEA plugins //TODO: rename the module module and maybe base packages (check external usages) // it actually doesn't have anything related to actual devkit integration, it doesn't depend on anything from it // it's similar to DevKit plugin in it's purpose, but it's different. // It just contains some internal actions required for Scala Plugin development (or other Scala-based plugins using sbt-idea-plugin) lazy val devKitIntegration = newProject("devKit", file("scala/integration/devKit")) .dependsOn(scalaImpl, sbtImpl) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, packageMethod := PackagingMethod.PluginModule("scalaCommunity.devkit") ) lazy val copyrightIntegration = newProject("copyright", file("scala/integration/copyright")) .dependsOn(scalaImpl) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "com.intellij.copyright".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.copyright") ) lazy val gradleIntegration = newProject("gradle", file("scala/integration/gradle")) .dependsOn( scalaImpl % "test->test;compile->compile", sbtImpl % "test->test;compile->compile", compilerIntegration % "test->test;compile->compile" ) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins ++= Seq( "com.intellij.gradle", // required by Android "org.intellij.groovy", // required by Gradle "com.intellij.properties" // required by Gradle ).map(_.toPlugin), packageMethod := PackagingMethod.PluginModule("scalaCommunity.gradle") ) lazy val intellijBazelIntegration = newProject("intellij-bazel", file("scala/integration/intellij-bazel")) .dependsOn(scalaImpl, sbtImpl, testingSupport) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "org.jetbrains.bazel::stable".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.intellij-bazel") ) lazy val intelliLangIntegration = newProject( "intelliLang", file("scala/integration/intellilang") ).dependsOn( scalaImpl % "test->test;compile->compile" ).settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "com.intellij.modules.json".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.intelliLang") ) lazy val markdownIntegration = newProject("markdown", file("scala/integration/markdown")) .dependsOn(scalaApi) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, idePackagePrefix := Some("org.jetbrains.plugins.scala.markdown"), intellijPlugins += "org.intellij.plugins.markdown".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.markdown"), ) lazy val mavenIntegration = newProject("maven", file("scala/integration/maven")) .dependsOn( scalaImpl % "test->test;compile->compile", testingSupport, sbtImpl % "test->test;compile->compile", compilerIntegration % "test->test;compile->compile" ) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins ++= Seq( "org.jetbrains.idea.maven", "org.jetbrains.idea.reposearch" // required for Maven (IJPL-35276) ).map(_.toPlugin), libraryDependencies ++= Seq( Dependencies.intellijMavenTestFramework % Test, Dependencies.intellijEelJavaTestFramework % Test ), resolvers += Versions.intellijRepository_ForManagedIntellijDependencies, packageMethod := PackagingMethod.PluginModule("scalaCommunity.maven") ) lazy val junitIntegration = newProject("junit", file("scala/integration/junit")) .dependsOn(sbtImpl) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "JUnit".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.junit") ) lazy val i18nIntegration = newProject("i18n", file("scala/integration/i18n")) .dependsOn(scalaImpl % "test->test;compile->compile") .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "com.intellij.java-i18n".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.i18n") ) lazy val propertiesIntegration = newProject("properties", file("scala/integration/properties")) .dependsOn( scalaImpl % "test->test;compile->compile", sbtImpl ).settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "com.intellij.properties".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.properties") ) lazy val javaDecompilerIntegration = newProject("java-decompiler", file("scala/integration/java-decompiler")) .dependsOn(scalaImpl % "test->test;compile->compile") .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "org.jetbrains.java.decompiler".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.javaDecompiler") ) lazy val mlCompletionIntegration = newProject("ml-completion", file("scala/integration/ml-completion")) .dependsOn(scalaImpl, sbtImpl) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "com.intellij.completion.ml.ranking".toPlugin, resolvers += DependencyResolvers.IntelliJDependencies, libraryDependencies += "org.jetbrains.intellij.deps.completion" % "completion-ranking-scala" % "0.4.1", packageMethod := PackagingMethod.PluginModule("scalaCommunity.mlCompletion") ) lazy val mlCompletionPropertiesIntegration = newProject("ml-completion-properties", file("scala/integration/ml-completion-properties")) .dependsOn( mlCompletionIntegration, propertiesIntegration ) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins ++= Seq( "com.intellij.completion.ml.ranking", "com.intellij.properties" ).map(_.toPlugin), packageMethod := PackagingMethod.PluginModule("scalaCommunity.mlCompletion.properties") ) lazy val scalastyleIntegration = newProject("scalastyle", file("scala/integration/scalastyle")) .dependsOn(scalaImpl) .settings( libraryDependencies += Dependencies.scalastyle, packageLibraryMappings += (Dependencies.scalaCollectionCompat -> Some("lib/scala-collection-compat.jar")) ) //Integration with: // - Build-in spellchecker (see com.intellij.spellchecker package) // - Grazie plugin (more advanced spell + grammar checker) lazy val textAnalysis = newProject("textAnalysis", file("scala/integration/textAnalysis")) .dependsOn( scalaImpl % "test->test;compile->compile", intelliLangIntegration //uses logic related to parsing interpolated strings ) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins ++= Seq( "tanvd.grazi".toPlugin ), //Language packs needed at runtime to run tests resolvers ++= Seq( DependencyResolvers.IntelliJDependencies, DependencyResolvers.Grazie ), libraryDependencies ++= Seq( //languagetool-core is available in the platform, exclude it to avoid some strange runtime errors in tests ("org.jetbrains.intellij.deps.languagetool" % "language-ru" % Versions.LanguageToolVersion % Test).exclude("org.jetbrains.intellij.deps.languagetool", "languagetool-core"), ("org.jetbrains.intellij.deps.languagetool" % "language-de" % Versions.LanguageToolVersion % Test).exclude("org.jetbrains.intellij.deps.languagetool", "languagetool-core"), ("org.jetbrains.intellij.deps.languagetool" % "language-it" % Versions.LanguageToolVersion % Test).exclude("org.jetbrains.intellij.deps.languagetool", "languagetool-core"), // notTransitive is very important, otherwise the libraries bring in an old version of kotlin-stdlib which results in missing methods at runtime ("ai.grazie.spell" % "hunspell-ru" % Versions.HunspellDictionaryVersion % Test).notTransitive(), ("ai.grazie.spell" % "hunspell-de" % Versions.HunspellDictionaryVersion % Test).notTransitive() ), packageMethod := PackagingMethod.PluginModule("scalaCommunity.textAnalysis"), ) lazy val featuresTrainerIntegration = newProject("features-trainer", file("scala/integration/features-trainer")) .dependsOn( scalaImpl % "test->test;compile->compile", ) .settings( scalaVersion := Versions.scala3Version, Compile / scalacOptions := globalScala3ScalacOptions, intellijPlugins += "training".toPlugin, packageMethod := PackagingMethod.PluginModule("scalaCommunity.featuresTrainer") ) // SCL-20376 - The package search plugin will be replaced by a new one, requiring a rewrite of the integration code. //lazy val packageSearchIntegration = // newProject("packagesearch", file("scala/integration/packagesearch")) // .dependsOn(scalaImpl, sbtImpl) // .settings( // // The packageSearch plugin is no longer distributed with IDEA. It will soon be available on the plugin // // marketplace once more and this workaround will be unnecessary. // // TODO: use `intellijVersion_ForManagedIntellijDependencies` as version once the plugin is published properly // libraryDependencies += "com.jetbrains.intellij.packageSearch" % "package-search" % "232.6095-EAP-CANDIDATE-SNAPSHOT" % Provided notTransitive(), // resolvers += MavenRepository("intellij-repository-snapshots", "https://www.jetbrains.com/intellij-repository/snapshots"), // packageMethod := PackagingMethod.MergeIntoOther(scalaCommunity) // ) // Utility projects lazy val runtimeDependencies = project.in(file("target/tools/runtime-dependencies")) .enablePlugins(DynamicDependenciesFetcher, LocalRepoPackager) .settings(NoSourceDirectories) .settings( name := "runtimeDependencies", organization := JetBrains, crossPaths := false, autoScalaLibrary := false, resolvers += Classpaths.sbtPluginReleases, ideSkipProject := true, packageMethod := PackagingMethod.DepsOnly(), dynamicDependencies := Seq( binaryDep("org.scala-sbt", "sbt-launch", "1.11.5") -> "launcher/sbt-launch.jar", binaryDep("org.scala-sbt", "util-interface", Versions.sbtVersion) -> "lib/jps/sbt-interface.jar", binaryDep("org.scala-sbt", "compiler-interface", Versions.zincVersion) -> "lib/jps/compiler-interface.jar", sourceDep("org.scala-sbt", "compiler-bridge", "2.10", Versions.zincVersion) -> "lib/jps/compiler-bridge-sources_2.10.jar", sourceDep("org.scala-sbt", "compiler-bridge", "2.11", Versions.zincVersion) -> "lib/jps/compiler-bridge-sources_2.11.jar", sourceDep("org.scala-sbt", "compiler-bridge", "2.13", Versions.zincVersion) -> "lib/jps/compiler-bridge-sources_2.13.jar", binaryDep("org.scala-lang", "scala3-sbt-bridge", "3.0.2") -> "lib/jps/scala3-sbt-bridge_3.0.jar", binaryDep("org.scala-lang", "scala3-sbt-bridge", "3.1.3") -> "lib/jps/scala3-sbt-bridge_3.1.jar", binaryDep("org.scala-lang", "scala3-sbt-bridge", "3.2.2") -> "lib/jps/scala3-sbt-bridge_3.2.jar", binaryDep("org.scala-lang", "scala3-sbt-bridge", "3.3.1") -> "lib/jps/scala3-sbt-bridge_3.3.1.jar", binaryDep("org.scala-lang", "scala3-sbt-bridge", "3.3.3") -> "lib/jps/scala3-sbt-bridge_3.3.jar", binaryDep("org.scala-lang", "scala3-sbt-bridge", "3.4.0") -> "lib/jps/scala3-sbt-bridge_3.4.jar", binaryDep("org.scala-sbt.rt", "java9-rt-export", Versions.java9rtExportVersion) -> "java9-rt-export/java9-rt-export.jar", ), localRepoDependencies := List( Dependencies.structureExtractor_0_13, Dependencies.structureExtractor_1_0, Dependencies.structureExtractor_1_3, Dependencies.structureExtractor_2, sbtDep("org.jetbrains.scala", "sbt-idea-shell", Versions.sbtIdeaShellVersion, Versions.Sbt.binary_0_13), sbtDep("org.jetbrains.scala", "sbt-idea-shell", Versions.sbtIdeaShellVersion, Versions.Sbt.binary_1_0), sbtDep("org.jetbrains.scala", "sbt-idea-shell", Versions.sbtIdeaShellVersion, Versions.Sbt.binary_2), // SCL-22858 compiler bytecode indices are disabled in sbt shell // sbtDep("org.jetbrains.scala", "sbt-idea-compiler-indices", Versions.compilerIndicesVersion, Versions.Sbt.binary_0_13), // sbtDep("org.jetbrains.scala", "sbt-idea-compiler-indices", Versions.compilerIndicesVersion, Versions.Sbt.binary_1_0) ), update := { dynamicDependenciesUpdate.value localRepoUpdate.value update.value }, packageFileMappings ++= { localRepoUpdate.value.map { case (src, trg) => val targetPath = Path.of("repo").resolve(trg) src.toFile -> targetPath.toString } ++ dynamicDependenciesUpdate.value.map { case (src, trg) => src.toFile -> trg.toString } } ) .settings(compilationCacheSettings) //lazy val jmhBenchmarks = // newProject("benchmarks", file("scala/benchmarks")) // .dependsOn(scalaImpl % "test->test") // .enablePlugins(JmhPlugin) //////////////////////////////////////////// // // Testing keys and settings // //////////////////////////////////////////// import Common.TestCategory.* def runInputTask(key: InputKey[?], input: String, inState: State, resultState: State): State = { val extracted = Project.extract(inState) try { extracted.runInputTask(key, input, inState) resultState } catch { case _: Exception => resultState.fail } } def runTestsInTC(category: String): String = s"testOnly -- -v -s -a +c +q --include-categories=$category --exclude-categories=$flakyTests" addCommandAlias("runFileSetTests", runTestsInTC(fileSetTests)) addCommandAlias("runCompilationTestsZinc", runTestsInTC(compilationTestsZinc)) addCommandAlias("runCompilationTestsIDEA", runTestsInTC(compilationTestsIDEA)) addCommandAlias("runCompilerHighlightingTests", runTestsInTC(compilerHighlightingTests)) addCommandAlias("runCompletionTests", runTestsInTC(completionTests)) addCommandAlias("runEditorTests", runTestsInTC(editorTests)) addCommandAlias("runSlowTests", runTestsInTC(slowTests)) addCommandAlias("runSlowTests2", runTestsInTC(slowTests2)) addCommandAlias("runDebuggerTests", runTestsInTC(debuggerTests)) addCommandAlias("runDebuggerEvaluationTests", runTestsInTC(debuggerEvaluationTests)) addCommandAlias("runScalacTests", runTestsInTC(scalacTests)) addCommandAlias("runTypeInferenceTests", runTestsInTC(typecheckerTests)) addCommandAlias("runTestingSupportTests", runTestsInTC(testingSupportTests)) addCommandAlias("runTextToTextTests", runTestsInTC(textToTextTests)) addCommandAlias("runWorksheetEvaluationTests", runTestsInTC(worksheetEvaluationTests)) addCommandAlias("runHighlightingTests", runTestsInTC(highlightingTests)) addCommandAlias("runNightlyTests", runTestsInTC(randomTypingTests)) addCommandAlias("runFlakyTests", s"testOnly -- -v -s -a +c +q --include-categories=$flakyTests") //it's run during "Package" step on TC addCommandAlias("runBundleSortingTests", runTestsInTC(bundleSortingTests)) lazy val categoriesToExclude = List( fileSetTests, compilationTestsZinc, compilationTestsIDEA, compilerHighlightingTests, completionTests, editorTests, slowTests, slowTests2, debuggerTests, debuggerEvaluationTests, scalacTests, typecheckerTests, testingSupportTests, textToTextTests, highlightingTests, worksheetEvaluationTests, randomTypingTests, flakyTests ) def runFastTestsInTC(glob: String): String = s"testOnly $glob -- -v -s -a +c +q --exclude-categories=${categoriesToExclude.mkString(",")}" addCommandAlias("runFastTests", runFastTestsInTC("*")) // subsets of tests to split the complete test run into smaller chunks addCommandAlias("runFastTestsComIntelliJ", runFastTestsInTC("com.intellij.*")) addCommandAlias("runFastTestsOrgJetbrains", runFastTestsInTC("org.jetbrains.*")) addCommandAlias("runFastTestsScala", runFastTestsInTC("scala.*")) // Compiler plugin tests command definitions. addCommandAlias("runCompilerPluginTests-2_12", "compiler-plugin-2_12/testOnly -- -v -s -a +c +q") addCommandAlias("runCompilerPluginTests-2_13", "compiler-plugin-2_13/testOnly -- -v -s -a +c +q") addCommandAlias("runCompilerPluginTests-3_3", "compiler-plugin-3_3/testOnly -- -v -s -a +c +q") addCommandAlias("runCompilerPluginTests", "runCompilerPluginTests-2_12; runCompilerPluginTests-2_13; runCompilerPluginTests-3_3")