From ad90590bc6f2fd2d7668d1a94e31a3d31d93eccb Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 1 Oct 2022 16:17:44 -0400 Subject: [PATCH] Fix project loading Problem ------- Given val root, currently both `root` and synthetic root gets loaded. This might be caused by build.sbt being virtualized, and no longer matching the build root directory. Solution -------- For now, comparing the canonical paths seems to fix the issue. --- main/src/main/scala/sbt/internal/Load.scala | 58 +++++++++++---------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index 2c8a6c945..69badea0f 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -557,7 +557,7 @@ private[sbt] object Load { // since base directories are resolved at this point (after 'projects'), // we can compare Files instead of converting to URIs - def isRoot(p: Project) = p.base == unit.localBase + def isRoot(p: Project) = p.base.getCanonicalFile() == unit.localBase.getCanonicalFile() val externals = referenced(defined).toList val explicitRoots = unit.definitions.builds.flatMap(_.rootProject) @@ -784,7 +784,9 @@ private[sbt] object Load { // TODO - As of sbt 0.13.6 we should always have a default root project from // here on, so the autogenerated build aggregated can be removed from this code. ( I think) // We may actually want to move it back here and have different flags in loadTransitive... - val hasRoot = loadedProjectsRaw.projects.exists(_.base == normBase) || defsScala.exists( + val hasRoot = loadedProjectsRaw.projects.exists( + _.base.getCanonicalFile() == normBase.getCanonicalFile() + ) || defsScala.exists( _.rootProject.isDefined ) val (loadedProjects, defaultBuildIfNone, keepClassFiles) = @@ -913,7 +915,7 @@ private[sbt] object Load { ): LoadedProjects = /*timed(s"Load.loadTransitive(${ newProjects.map(_.id) })", log)*/ { - def load(newProjects: Seq[Project], acc: Seq[Project], generated: Seq[Path]) = { + def load(newProjects: Seq[Project], acc: Seq[Project], generated: Seq[Path]) = loadTransitive( newProjects, buildBase, @@ -923,23 +925,23 @@ private[sbt] object Load { acc, memoSettings, log, - false, + makeOrDiscoverRoot = false, buildUri, context, generated, Nil, converter, ) - } // load all relevant configuration files (.sbt, as .scala already exists at this point) def discover(base: File): DiscoveredProjects = { val auto = - if (base == buildBase) AddSettings.allDefaults + if (base.getCanonicalFile() == buildBase.getCanonicalFile()) AddSettings.allDefaults else AddSettings.defaultSbtFiles val extraFiles = - if (base == buildBase && isMetaBuildContext(context)) extraSbtFiles + if base.getCanonicalFile() == buildBase.getCanonicalFile() && isMetaBuildContext(context) + then extraSbtFiles else Nil discoverProjects(auto, base, extraFiles, plugins, eval, memoSettings, converter) } @@ -1008,24 +1010,24 @@ private[sbt] object Load { buildBase ) val discoveredIdsStr = discovered.map(_.id).mkString(",") - val (root, expand, moreProjects, otherProjects) = rootOpt match { - case Some(root) => - log.debug(s"[Loading] Found root project ${root.id} w/ remaining $discoveredIdsStr") - (root, true, discovered, LoadedProjects(Nil, Nil)) - case None => - log.debug(s"[Loading] Found non-root projects $discoveredIdsStr") - // Here we do something interesting... We need to create an aggregate root project - val otherProjects = load(discovered, acc, Nil) - val root = { - val existingIds = otherProjects.projects.map(_.id) - val defaultID = autoID(buildBase, context, existingIds) - val refs = existingIds.map(id => ProjectRef(buildUri, id)) - if (discovered.isEmpty || java.lang.Boolean.getBoolean("sbt.root.ivyplugin")) - BuildDef.defaultAggregatedProject(defaultID, buildBase, refs) - else BuildDef.generatedRootWithoutIvyPlugin(defaultID, buildBase, refs) - } - (root, false, Nil, otherProjects) - } + val (root, expand, moreProjects, otherProjects) = + rootOpt match + case Some(root) => + log.debug(s"[Loading] Found root project ${root.id} w/ remaining $discoveredIdsStr") + (root, true, discovered, LoadedProjects(Nil, Nil)) + case None => + log.debug(s"[Loading] Found non-root projects $discoveredIdsStr") + // Here we do something interesting... We need to create an aggregate root project + val otherProjects = load(discovered, acc, Nil) + val root = { + val existingIds = otherProjects.projects.map(_.id) + val defaultID = autoID(buildBase, context, existingIds) + val refs = existingIds.map(id => ProjectRef(buildUri, id)) + if (discovered.isEmpty || java.lang.Boolean.getBoolean("sbt.root.ivyplugin")) + BuildDef.defaultAggregatedProject(defaultID, buildBase, refs) + else BuildDef.generatedRootWithoutIvyPlugin(defaultID, buildBase, refs) + } + (root, false, Nil, otherProjects) val (finalRoot, projectLevelExtra) = timed(s"Load.loadTransitive: finalizeProject($root)", log) { finalizeProject(root, files, extraFiles, expand) @@ -1207,8 +1209,7 @@ private[sbt] object Load { // .filterNot(_.isHidden) // .map(_.toPath) case sf: DefaultSbtFiles => - sbtFiles - // .filter(sf.include) + sbtFiles.filter(sf.include) // .filterNot(_.isHidden) // .map(_.toPath) case q: Sequence => @@ -1219,7 +1220,8 @@ private[sbt] object Load { val rawFiles = associatedFiles(auto) val loadedFiles = loadFiles(rawFiles) val rawProjects = loadedFiles.projects - val (root, nonRoot) = rawProjects.partition(_.base == projectBase) + val (root, nonRoot) = + rawProjects.partition(_.base.getCanonicalFile() == projectBase.getCanonicalFile()) // TODO - good error message if more than one root project DiscoveredProjects( root.headOption,