From 6cf6ce1129a74f50af5048cf75e1dee747d6b92e Mon Sep 17 00:00:00 2001 From: Tobias Roeser Date: Fri, 9 Aug 2024 09:01:30 +0200 Subject: [PATCH] GenIdea: unroll module dependencies (#3355) Since IDEA 2024.2, module dependencies in the `.iml` files are no longer interpreted transitively. Therefore, we need to unroll all transitive module dependencies when generating the project files. Fix https://github.com/com-lihaoyi/mill/issues/3354 Pull request: https://github.com/com-lihaoyi/mill/pull/3355 --- idea/src/mill/idea/GenIdeaImpl.scala | 22 ++++++++++++------- .../ide/gen-idea/repo/hello-idea/build.sc | 19 +++++++++++++++- .../hello-idea/idea/mill_modules/modulea.iml | 12 ++++++++++ .../hello-idea/idea/mill_modules/moduleb.iml | 13 +++++++++++ .../hello-idea/idea/mill_modules/modulec.iml | 15 +++++++++++++ .../hello-idea/idea/mill_modules/moduled.iml | 15 +++++++++++++ .../hello-idea/idea/mill_modules/modulee.iml | 12 ++++++++++ .../gen-idea/repo/hello-idea/idea/modules.xml | 6 +++++ .../mill/scalalib/api/ZincWorkerUtil.scala | 1 - .../mill/scalalib/internal/ModuleUtils.scala | 16 ++++++++++++-- .../mill/scalalib/worker/ZincWorkerImpl.scala | 3 ++- 11 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulea.iml create mode 100644 integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/moduleb.iml create mode 100644 integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulec.iml create mode 100644 integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/moduled.iml create mode 100644 integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulee.iml diff --git a/idea/src/mill/idea/GenIdeaImpl.scala b/idea/src/mill/idea/GenIdeaImpl.scala index f82e776aef7..3a53387d442 100755 --- a/idea/src/mill/idea/GenIdeaImpl.scala +++ b/idea/src/mill/idea/GenIdeaImpl.scala @@ -543,14 +543,20 @@ case class GenIdeaImpl( val libNames = Strict.Agg.from(sanizedDeps).iterator.toSeq - val depNames = Strict.Agg - .from(mod.moduleDeps.map((_, None)) ++ - mod.compileModuleDeps.map((_, Some("PROVIDED")))) - .filter(!_._1.skipIdea) - .map { case (v, s) => ScopedOrd(moduleName(moduleLabels(v)), s) } - .iterator - .toSeq - .distinct + val depNames = { + val allTransitive = mod.transitiveModuleCompileModuleDeps + val recursive = mod.recursiveModuleDeps + val provided = allTransitive.filterNot(recursive.contains) + + Strict.Agg + .from(recursive.map((_, None)) ++ + provided.map((_, Some("PROVIDED")))) + .filter(!_._1.skipIdea) + .map { case (v, s) => ScopedOrd(moduleName(moduleLabels(v)), s) } + .iterator + .toSeq + .distinct + } val isTest = mod.isInstanceOf[TestModule] diff --git a/integration/ide/gen-idea/repo/hello-idea/build.sc b/integration/ide/gen-idea/repo/hello-idea/build.sc index 7002dfc5a8f..626a2280c27 100644 --- a/integration/ide/gen-idea/repo/hello-idea/build.sc +++ b/integration/ide/gen-idea/repo/hello-idea/build.sc @@ -2,7 +2,7 @@ import mill.api.Loose.Agg import mill.define.Target import mill._ import mill.scalajslib.ScalaJSModule -import mill.scalalib.{Dep, DepSyntax, TestModule} +import mill.scalalib.{Dep, DepSyntax, JavaModule, TestModule} trait HelloIdeaModule extends scalalib.ScalaModule { def scalaVersion = "2.12.5" @@ -39,4 +39,21 @@ object HelloIdeaJs extends ScalaJSModule { ivy"com.lihaoyi::utest::0.8.4" ) } +} + +object moduleA extends JavaModule +object moduleB extends JavaModule { + override def moduleDeps = Seq(moduleA) +} +object moduleC extends JavaModule { + override def moduleDeps = Seq(moduleB) + override def compileModuleDeps = Seq(moduleE) +} +object moduleD extends JavaModule { + override def compileModuleDeps = Seq(moduleC) +} +object moduleE extends JavaModule +object moduleF extends JavaModule { + override def compileModuleDeps = Seq(moduleC) + override def moduleDeps = Seq(moduleB, moduleA) } \ No newline at end of file diff --git a/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulea.iml b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulea.iml new file mode 100644 index 00000000000..7ed61b811eb --- /dev/null +++ b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulea.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/moduleb.iml b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/moduleb.iml new file mode 100644 index 00000000000..0b3311ac04b --- /dev/null +++ b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/moduleb.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulec.iml b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulec.iml new file mode 100644 index 00000000000..0ebb17da544 --- /dev/null +++ b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulec.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/moduled.iml b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/moduled.iml new file mode 100644 index 00000000000..da9278c171b --- /dev/null +++ b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/moduled.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulee.iml b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulee.iml new file mode 100644 index 00000000000..e8fb6ec88df --- /dev/null +++ b/integration/ide/gen-idea/repo/hello-idea/idea/mill_modules/modulee.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/integration/ide/gen-idea/repo/hello-idea/idea/modules.xml b/integration/ide/gen-idea/repo/hello-idea/idea/modules.xml index dbb4e87d0ab..03f2710184e 100644 --- a/integration/ide/gen-idea/repo/hello-idea/idea/modules.xml +++ b/integration/ide/gen-idea/repo/hello-idea/idea/modules.xml @@ -8,6 +8,12 @@ + + + + + + diff --git a/scalalib/api/src/mill/scalalib/api/ZincWorkerUtil.scala b/scalalib/api/src/mill/scalalib/api/ZincWorkerUtil.scala index 21848502cc0..699506c1a39 100644 --- a/scalalib/api/src/mill/scalalib/api/ZincWorkerUtil.scala +++ b/scalalib/api/src/mill/scalalib/api/ZincWorkerUtil.scala @@ -2,7 +2,6 @@ package mill.scalalib.api import mill.api.Loose.Agg import mill.api.PathRef -import mill.scalalib.api.Versions import scala.util.matching.Regex trait ZincWorkerUtil { diff --git a/scalalib/src/mill/scalalib/internal/ModuleUtils.scala b/scalalib/src/mill/scalalib/internal/ModuleUtils.scala index dc991285ea6..54d9f82ae1c 100644 --- a/scalalib/src/mill/scalalib/internal/ModuleUtils.scala +++ b/scalalib/src/mill/scalalib/internal/ModuleUtils.scala @@ -15,7 +15,18 @@ object ModuleUtils { (module.millModuleShared.value.getOrElse(Segments()) ++ module.millModuleSegments).render } - def recursive[T <: Module](name: String, start: T, deps: T => Seq[T]): Seq[T] = { + /** + * Find all dependencies. + * The result contains `start` and all its transitive dependencies provided by `deps`, + * but does not contain duplicates. + * If it detects a cycle, it throws an exception with a meaningful message containing the cycle trace. + * @param name The nane is used in the exception message only + * @param start the start element + * @param deps A function provided the direct dependencies + * @throws BuildScriptException if there were cycles in the dependencies + */ + // FIMXE: Remove or consolidate with copy in ZincModuleImpl + def recursive[T](name: String, start: T, deps: T => Seq[T]): Seq[T] = { @tailrec def rec( seenModules: List[T], @@ -36,7 +47,8 @@ object ModuleUtils { throw new BuildScriptException(msg) } rec( - seenModules ++ Seq(cand), + if (seenModules.contains(cand)) seenModules + else { seenModules ++ Seq(cand) }, toAnalyze = ((cand :: trace, deps(cand).toList)) :: (trace, remaining) :: rest ) } diff --git a/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala b/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala index e255335fe79..9a8d730bab8 100644 --- a/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala +++ b/scalalib/worker/src/mill/scalalib/worker/ZincWorkerImpl.scala @@ -669,7 +669,8 @@ object ZincWorkerImpl { throw sys.error(msg) } rec( - seenModules ++ Seq(cand), + if (seenModules.contains(cand)) seenModules + else { seenModules ++ Seq(cand) }, toAnalyze = ((cand :: trace, deps(cand).toList)) :: (trace, remaining) :: rest ) }