From 2663a983891f759d25bd384f4d324f440cd21b59 Mon Sep 17 00:00:00 2001 From: Tomasz Godzik Date: Fri, 6 Sep 2024 12:33:07 +0200 Subject: [PATCH] bugfix: Also deduplicate if options split by space --- .../test/scala/scala/build/tests/BuildTests.scala | 3 ++- .../src/main/scala/scala/build/Positioned.scala | 2 +- .../src/main/scala/scala/build/options/JavaOpt.scala | 3 ++- .../main/scala/scala/build/options/ScalacOpt.scala | 12 +++++++----- .../scala/scala/build/options/ShadowingSeq.scala | 7 +++---- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/modules/build/src/test/scala/scala/build/tests/BuildTests.scala b/modules/build/src/test/scala/scala/build/tests/BuildTests.scala index b940c103ae..4ecd34013f 100644 --- a/modules/build/src/test/scala/scala/build/tests/BuildTests.scala +++ b/modules/build/src/test/scala/scala/build/tests/BuildTests.scala @@ -625,7 +625,8 @@ abstract class BuildTests(server: Boolean) extends TestUtil.ScalaCliBuildSuite { } test("cli scalac options shadowing using directives") { - val cliScalacOptions = Seq("-Xmaxwarns", "4", "-g:source", "-language:no2AutoTupling") + val cliScalacOptions = + Seq("-Xmaxwarns", "4", "-g:source", "-language:no2AutoTupling", "-language", "no2AutoTupling") val usingDirectiveScalacOptions = Seq( "-nobootcp", "-Xmaxwarns", diff --git a/modules/options/src/main/scala/scala/build/Positioned.scala b/modules/options/src/main/scala/scala/build/Positioned.scala index 5e86961525..a0672245e6 100644 --- a/modules/options/src/main/scala/scala/build/Positioned.scala +++ b/modules/options/src/main/scala/scala/build/Positioned.scala @@ -61,7 +61,7 @@ object Positioned { underlying: ShadowingSeq.KeyOf[T] ): ShadowingSeq.KeyOf[Positioned[T]] = ShadowingSeq.KeyOf( - p => underlying.get(p.value), + pSeq => underlying.makeKey(pSeq.map(_.value)), seq => underlying.groups(seq.map(_.value)) ) } diff --git a/modules/options/src/main/scala/scala/build/options/JavaOpt.scala b/modules/options/src/main/scala/scala/build/options/JavaOpt.scala index 56b1bf18b1..530a342fe2 100644 --- a/modules/options/src/main/scala/scala/build/options/JavaOpt.scala +++ b/modules/options/src/main/scala/scala/build/options/JavaOpt.scala @@ -10,6 +10,7 @@ final case class JavaOpt(value: String) { else if (value.startsWith("@")) Some("@") else None } + } object JavaOpt { @@ -29,7 +30,7 @@ object JavaOpt { } implicit val keyOf: ShadowingSeq.KeyOf[JavaOpt] = ShadowingSeq.KeyOf( - _.key, + opts => opts.headOption.flatMap(_.key).orElse(Some(opts.map(_.value).mkString(":"))), seq => ScalacOpt.groupCliOptions(seq.map(_.value)) ) } diff --git a/modules/options/src/main/scala/scala/build/options/ScalacOpt.scala b/modules/options/src/main/scala/scala/build/options/ScalacOpt.scala index e1d7b0611f..6fbcb86a84 100644 --- a/modules/options/src/main/scala/scala/build/options/ScalacOpt.scala +++ b/modules/options/src/main/scala/scala/build/options/ScalacOpt.scala @@ -9,15 +9,16 @@ final case class ScalacOpt(value: String) { /** @return raw key for the option (only if the key can be shadowed from the CLI) */ private[options] def shadowableKey: Option[String] = key match - case Some(key) if ScalacOpt.repeatingKeys.exists(_.startsWith(key)) => Some(value) - case otherwise => otherwise + case Some(key) + if ScalacOpt.repeatingKeys.exists(rKey => rKey.startsWith(key + ":") || rKey == key) => None + case otherwise => otherwise } object ScalacOpt { private val repeatingKeys = Set( - "-Xplugin:", + "-Xplugin", "-P", // plugin options - "-language:" + "-language" ) implicit val hashedType: HashedType[ScalacOpt] = { @@ -25,7 +26,8 @@ object ScalacOpt { } implicit val keyOf: ShadowingSeq.KeyOf[ScalacOpt] = ShadowingSeq.KeyOf( - _.shadowableKey, + opts => + opts.headOption.flatMap(_.shadowableKey).orElse(Some(opts.map(_.value).mkString(":"))), seq => groupCliOptions(seq.map(_.value)) ) diff --git a/modules/options/src/main/scala/scala/build/options/ShadowingSeq.scala b/modules/options/src/main/scala/scala/build/options/ShadowingSeq.scala index 35a3f14f16..1ff88b5daf 100644 --- a/modules/options/src/main/scala/scala/build/options/ShadowingSeq.scala +++ b/modules/options/src/main/scala/scala/build/options/ShadowingSeq.scala @@ -28,10 +28,9 @@ final case class ShadowingSeq[T] private (values: Seq[Seq[T]]) { else { val l = new mutable.ListBuffer[Seq[T]] val seen = new mutable.HashSet[String] - for (group <- values.iterator ++ other.iterator) { assert(group.nonEmpty) - val keyOpt = key.get(group.head) + val keyOpt = key.makeKey(group) if (!keyOpt.exists(seen.contains)) { l += group for (key <- keyOpt) @@ -58,13 +57,13 @@ final case class ShadowingSeq[T] private (values: Seq[Seq[T]]) { object ShadowingSeq { final case class KeyOf[T]( - get: T => Option[String], + makeKey: Seq[T] => Option[String], /** The indices at which sub-groups of values start */ groups: Seq[T] => Seq[Int] ) object KeyOf { implicit val keyOfAnyDependency: KeyOf[AnyDependency] = - KeyOf(dep => Some(dep.module.render), _.indices) + KeyOf(deps => deps.headOption.map(_.module.render), _.indices) } implicit def monoid[T](implicit key: KeyOf[T]): ConfigMonoid[ShadowingSeq[T]] =