diff --git a/main/src/main/scala/sbt/ProjectExtra.scala b/main/src/main/scala/sbt/ProjectExtra.scala index f1f7e0f04c..b7c956adc2 100755 --- a/main/src/main/scala/sbt/ProjectExtra.scala +++ b/main/src/main/scala/sbt/ProjectExtra.scala @@ -357,31 +357,6 @@ trait ProjectExtra extends Scoped.Syntax: def setCond[T](key: AttributeKey[T], vopt: Option[T], attributes: AttributeMap): AttributeMap = attributes.setCond(key, vopt) - private[sbt] def checkTargets(data: Settings[Scope]): Option[String] = - val dups = overlappingTargets(allTargets(data)) - if (dups.isEmpty) None - else { - val dupStrs = dups map { case (dir, scopes) => - s"${dir.getAbsolutePath}:\n\t${scopes.mkString("\n\t")}" - } - Some(s"Overlapping output directories:${dupStrs.mkString}") - } - - private[this] def overlappingTargets( - targets: Seq[(ProjectRef, File)] - ): Map[File, Seq[ProjectRef]] = - targets.groupBy(_._2).view.filter(_._2.size > 1).mapValues(_.map(_._1)).toMap - - private[this] def allTargets(data: Settings[Scope]): Seq[(ProjectRef, File)] = { - import ScopeFilter._ - val allProjects = ScopeFilter(Make.inAnyProject) - val targetAndRef = Def.setting { (Keys.thisProjectRef.value, Keys.target.value) } - new SettingKeyAll(Def.optional(targetAndRef)(identity)) - .all(allProjects) - .evaluate(data) - .flatMap(x => x) - } - private[sbt] def equalKeys(a: ScopedKey[_], b: ScopedKey[_], mask: ScopeMask): Boolean = a.key == b.key && Scope.equal(a.scope, b.scope, mask) diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 74a012b69b..2efafdfbd0 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -283,8 +283,7 @@ private[sbt] object Load { ) } - // todo: fix this - // Project.checkTargets(data) foreach sys.error + checkTargets(data).foreach(sys.error) val index = timed("Load.apply: structureIndex", log) { structureIndex(data, settings, loaded.extra(data), projects) } @@ -304,6 +303,29 @@ private[sbt] object Load { (rootEval, bs) } + private def checkTargets(data: Settings[Scope]): Option[String] = + val dups = overlappingTargets(allTargets(data)) + if (dups.isEmpty) None + else { + val dupStr = dups.map { case (dir, scopes) => + s"${dir.getAbsolutePath}:\n\t${scopes.mkString("\n\t")}" + }.mkString + Some(s"Overlapping output directories:$dupStr") + } + + private def overlappingTargets(targets: Seq[(ProjectRef, File)]): Map[File, Seq[ProjectRef]] = + targets.groupBy(_._2).view.filter(_._2.size > 1).mapValues(_.map(_._1)).toMap + + private def allTargets(data: Settings[Scope]): Seq[(ProjectRef, File)] = { + import ScopeFilter._ + val allProjects = ScopeFilter(Make.inAnyProject) + val targetAndRef = Def.setting { (Keys.thisProjectRef.value, Keys.target.value) } + new SettingKeyAll(Def.optional(targetAndRef)(identity)) + .all(allProjects) + .evaluate(data) + .flatMap(x => x) + } + // map dependencies on the special tasks: // 1. the scope of 'streams' is the same as the defining key and has the task axis set to the defining key // 2. the defining key is stored on constructed tasks: used for error reporting among other things