diff --git a/.github/workflows/scala.yml b/.github/workflows/scala.yml index 0ffbec41..d4a99ca9 100644 --- a/.github/workflows/scala.yml +++ b/.github/workflows/scala.yml @@ -11,13 +11,13 @@ jobs: name: sbt-idea-plugin plugin Build & Test runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-java@v4 + - uses: actions/checkout@v6 + - uses: actions/setup-java@v5 with: distribution: temurin java-version: 17 cache: sbt - uses: sbt/setup-sbt@v1 - - uses: coursier/cache-action@v6 + - uses: coursier/cache-action@v8 - name: Compile & Test run: sbt test diff --git a/ideaSupport/src/main/scala/org/jetbrains/sbtidea/Init.scala b/ideaSupport/src/main/scala/org/jetbrains/sbtidea/Init.scala index 4757861c..0220a8c1 100644 --- a/ideaSupport/src/main/scala/org/jetbrains/sbtidea/Init.scala +++ b/ideaSupport/src/main/scala/org/jetbrains/sbtidea/Init.scala @@ -124,6 +124,11 @@ trait Init { this: Keys.type => intellijPlugins := Seq.empty, intellijExtraRuntimePluginsInTests := Seq.empty, + intellijExtraJUnitTemplateLibraryDependencies := Seq.empty, + + ivyConfigurations += intellijJUnitTemplateConfig, + libraryDependencies ++= intellijExtraJUnitTemplateLibraryDependencies.value + .map(_ % intellijJUnitTemplateConfig), intellijMainJarsClasspath := AttributedClasspathTasks.main.value, intellijTestJarsClasspath := AttributedClasspathTasks.test.value, diff --git a/ideaSupport/src/main/scala/org/jetbrains/sbtidea/Keys.scala b/ideaSupport/src/main/scala/org/jetbrains/sbtidea/Keys.scala index 28070458..93049935 100644 --- a/ideaSupport/src/main/scala/org/jetbrains/sbtidea/Keys.scala +++ b/ideaSupport/src/main/scala/org/jetbrains/sbtidea/Keys.scala @@ -27,6 +27,14 @@ object Keys extends Defns with Init with Utils with Quirks { lazy val intellijExtraRuntimePluginsInTests = settingKey[Seq[IntellijPlugin]]( "List of IntelliJ platform plugins to include in tests at runtime") + lazy val intellijExtraJUnitTemplateLibraryDependencies = settingKey[Seq[ModuleID]]( + "Extra library dependencies provided only on the JUnit test Run Configuration template classpath " + + "(generated during IDEA project import). These do not affect the sbt Test classpath." + ).withRank(sbt.KeyRanks.Invisible) + + private[sbtidea] lazy val intellijJUnitTemplateConfig: Configuration = + Configuration.of("IntellijJUnitTemplate", "intellij-junit-template").hide + @Deprecated(forRemoval = true) @deprecated("The setting is ignored and will be removed in future versions. The sources are always downloaded") lazy val intellijDownloadSources = settingKey[Boolean]( diff --git a/ideaSupport/src/main/scala/org/jetbrains/sbtidea/tasks/classpath/TestClasspathTasks.scala b/ideaSupport/src/main/scala/org/jetbrains/sbtidea/tasks/classpath/TestClasspathTasks.scala index b3d73a4b..687d7435 100644 --- a/ideaSupport/src/main/scala/org/jetbrains/sbtidea/tasks/classpath/TestClasspathTasks.scala +++ b/ideaSupport/src/main/scala/org/jetbrains/sbtidea/tasks/classpath/TestClasspathTasks.scala @@ -1,9 +1,10 @@ package org.jetbrains.sbtidea.tasks.classpath +import org.jetbrains.sbtidea.Keys.intellijJUnitTemplateConfig import org.jetbrains.sbtidea.packaging.PackagingKeys.packageOutputDir import sbt.* import sbt.Def.Classpath -import sbt.Keys.{exportedProductsNoTracking, externalDependencyClasspath} +import sbt.Keys.{classpathTypes, exportedProductsNoTracking, externalDependencyClasspath, update} import scala.collection.mutable @@ -36,7 +37,14 @@ object TestClasspathTasks { val outputDir = packageOutputDir.value val pluginPlaceholderPatterns = PluginClasspathUtils.pluginClasspathPattern(outputDir) val commonClasspath = commonTestClasspath.value - pluginPlaceholderPatterns ++ commonClasspath.map(_.data.getAbsolutePath) + val extraTemplateJars = Classpaths.managedJars( + intellijJUnitTemplateConfig, + classpathTypes.value, + update.value + ) + pluginPlaceholderPatterns ++ + commonClasspath.map(_.data.getAbsolutePath) ++ + extraTemplateJars.map(_.data.getAbsolutePath) } /** diff --git a/ideaSupport/src/test/scala/org/jetbrains/sbtidea/integrationTests/SbtIdeaPluginIntegrationTest.scala b/ideaSupport/src/test/scala/org/jetbrains/sbtidea/integrationTests/SbtIdeaPluginIntegrationTest.scala index a06f73b3..bfc32161 100644 --- a/ideaSupport/src/test/scala/org/jetbrains/sbtidea/integrationTests/SbtIdeaPluginIntegrationTest.scala +++ b/ideaSupport/src/test/scala/org/jetbrains/sbtidea/integrationTests/SbtIdeaPluginIntegrationTest.scala @@ -1,6 +1,7 @@ package org.jetbrains.sbtidea.integrationTests import org.jetbrains.sbtidea.download.api.IdeInstallationContext +import org.jetbrains.sbtidea.testUtils.SbtProjectFilesUtils import org.jetbrains.sbtidea.testUtils.SbtProjectFilesUtils.runSbtProcess import org.jetbrains.sbtidea.testUtils.IoUtils import org.scalatest.matchers.should.Matchers @@ -123,6 +124,47 @@ class SbtIdeaPluginIntegrationTest junitTemplateText should include("junit_template_argfile.txt") } + test("intellijExtraJUnitTemplateLibraryDependencies appears only on the JUnit template classpath") { + val projectDir = testProjectsDir / "simple-with-plugin" + + // Inject SDK paths/settings into the fixture; this rewrites extra.sbt from a clean state + // (runUpdateIntellijCommand calls cleanUntrackedVcsFiles -> git clean -fdx first). + runUpdateIntellijCommand(projectDir) + + // Configure one extra dep that should appear ONLY on the generated JUnit template classpath. + appendExtraJUnitTemplateLibDepToExtraSbt(projectDir) + + // 1) Generate the JUnit template — the jar must end up in the argfile. + runSbtProcess(Seq("createIDEARunConfiguration"), projectDir) + + val argFile = projectDir / ".idea" / "runConfigurations" / "junit_template_argfile.txt" + assertFileExists(argFile) + val argFileText = IoUtils.readLines(argFile).mkString(System.lineSeparator()) + argFileText should include("commons-io-2.16.1.jar") + + // 2) The same jar must NOT appear on the sbt Test / fullClasspath. + val result = runSbtProcess( + Seq("show Test/fullClasspath"), + projectDir, + ioMode = SbtProjectFilesUtils.IoMode.PrintAndCollectOutput, + ) + val fullClasspathOutput = result.outputLines.getOrElse(Seq.empty).mkString("\n") + fullClasspathOutput should not include "commons-io-2.16.1.jar" + } + + private def appendExtraJUnitTemplateLibDepToExtraSbt(projectDir: File): Unit = { + val extraSbt = projectDir / "extra.sbt" + assertFileExists(extraSbt) + val current = IoUtils.readLines(extraSbt).mkString(System.lineSeparator()) + //language=SBT + val additional = + """ + | + |intellijExtraJUnitTemplateLibraryDependencies += "commons-io" % "commons-io" % "2.16.1" + |""".stripMargin + IoUtils.writeStringToFile(extraSbt, current + additional) + } + private def dumpFileStructure(directory: File): String = { val IndentIncrement = " " diff --git a/project/build.properties b/project/build.properties index e480c675..6edd024b 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.11.5 +sbt.version=1.12.10 diff --git a/project/plugins.sbt b/project/plugins.sbt index 8439a1af..494a1b96 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,2 +1,2 @@ -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.11.1") -addSbtPlugin("org.jetbrains.scala" % "sbt-ide-settings" % "1.1.2") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.11.2") +addSbtPlugin("org.jetbrains.scala" % "sbt-ide-settings" % "1.1.4")