diff --git a/main/src/main/scala/sbt/Project.scala b/main/src/main/scala/sbt/Project.scala index c1b1bc4c1..dcf4ae8ed 100755 --- a/main/src/main/scala/sbt/Project.scala +++ b/main/src/main/scala/sbt/Project.scala @@ -317,13 +317,16 @@ sealed trait ResolvedProject extends ProjectDefinition[ProjectRef] { /** The [[AutoPlugin]]s enabled for this project as computed from [[plugins]].*/ def autoPlugins: Seq[AutoPlugin] + } sealed trait ClasspathDep[PR <: ProjectReference] { def project: PR; def configuration: Option[String] } + final case class ResolvedClasspathDependency(project: ProjectRef, configuration: Option[String]) extends ClasspathDep[ProjectRef] + final case class ClasspathDependency(project: ProjectReference, configuration: Option[String]) extends ClasspathDep[ProjectReference] @@ -350,6 +353,7 @@ object Project extends ProjectExtra { } private def evalNil[A]: Eval[Seq[A]] = Eval.now(Vector()) + // hardcoded version of sequence for flipping Eval and Seq def sequenceEval[A](es: Seq[Eval[A]]): Eval[Seq[A]] = (evalNil[A] /: es) { (acc0, x0) => @@ -361,16 +365,18 @@ object Project extends ProjectExtra { } def apply(id: String, base: File): Project = - unresolved(id, - base, - evalNil, - evalNil, - evalNil, - evalNil, - Nil, - Plugins.empty, - Nil, - ProjectOrigin.Organic) + unresolved( + id, + base, + evalNil, + evalNil, + evalNil, + evalNil, + Nil, + Plugins.empty, + Nil, + ProjectOrigin.Organic + ) // TODO: add parameter for plugins and projectOrigin in 1.0 // TODO: Modify default settings to be the core settings, and automatically add the IvyModule + JvmPlugins. @@ -385,38 +391,48 @@ object Project extends ProjectExtra { if (isProjectLoaded(state)) showContextKey(session(state), structure(state), keyNameColor) else Def.showFullKey - def showContextKey(session: SessionSettings, - structure: BuildStructure, - keyNameColor: Option[String] = None): Show[ScopedKey[_]] = + def showContextKey( + session: SessionSettings, + structure: BuildStructure, + keyNameColor: Option[String] = None + ): Show[ScopedKey[_]] = Def.showRelativeKey(session.current, structure.allProjects.size > 1, keyNameColor) - def showLoadingKey(loaded: LoadedBuild, - keyNameColor: Option[String] = None): Show[ScopedKey[_]] = - Def.showRelativeKey(ProjectRef(loaded.root, loaded.units(loaded.root).rootProjects.head), - loaded.allProjectRefs.size > 1, - keyNameColor) + def showLoadingKey( + loaded: LoadedBuild, + keyNameColor: Option[String] = None + ): Show[ScopedKey[_]] = + Def.showRelativeKey( + ProjectRef(loaded.root, loaded.units(loaded.root).rootProjects.head), + loaded.allProjectRefs.size > 1, + keyNameColor + ) /** This is a variation of def apply that mixes in GeneratedRootProject. */ - private[sbt] def mkGeneratedRoot(id: String, - base: File, - aggregate: Eval[Seq[ProjectReference]]): Project = { - validProjectID(id).foreach(errMsg => sys.error("Invalid project ID: " + errMsg)) - new ProjectDef[ProjectReference](id, - base, - aggregate, - evalNil, - evalNil, - evalNil, - Nil, - Plugins.empty, - Nil, - ProjectOrigin.GenericRoot) with Project - with GeneratedRootProject + private[sbt] def mkGeneratedRoot( + id: String, + base: File, + aggregate: Eval[Seq[ProjectReference]] + ): Project = { + validProjectID(id).foreach(errMsg => sys.error(s"Invalid project ID: $errMsg")) + new ProjectDef[ProjectReference]( + id, + base, + aggregate, + evalNil, + evalNil, + evalNil, + Nil, + Plugins.empty, + Nil, + ProjectOrigin.GenericRoot + ) with Project with GeneratedRootProject } /** Returns None if `id` is a valid Project ID or Some containing the parser error message if it is not.*/ def validProjectID(id: String): Option[String] = DefaultParsers.parse(id, DefaultParsers.ID).left.toOption + private[this] def validProjectIDStart(id: String): Boolean = DefaultParsers.parse(id, DefaultParsers.IDStart).isRight @@ -438,66 +454,78 @@ object Project extends ProjectExtra { */ def normalizeModuleID(id: String): String = normalizeBase(id) - private def resolved(id: String, - base: File, - aggregateEval: Eval[Seq[ProjectRef]], - dependenciesEval: Eval[Seq[ClasspathDep[ProjectRef]]], - delegatesEval: Eval[Seq[ProjectRef]], - settingsEval: Eval[Seq[Def.Setting[_]]], - configurations: Seq[Configuration], - plugins: Plugins, - autoPlugins: Seq[AutoPlugin], - origin: ProjectOrigin): ResolvedProject = - new ProjectDef[ProjectRef](id, - base, - aggregateEval, - dependenciesEval, - delegatesEval, - settingsEval, - configurations, - plugins, - autoPlugins, - origin) with ResolvedProject + private def resolved( + id: String, + base: File, + aggregateEval: Eval[Seq[ProjectRef]], + dependenciesEval: Eval[Seq[ClasspathDep[ProjectRef]]], + delegatesEval: Eval[Seq[ProjectRef]], + settingsEval: Eval[Seq[Def.Setting[_]]], + configurations: Seq[Configuration], + plugins: Plugins, + autoPlugins: Seq[AutoPlugin], + origin: ProjectOrigin + ): ResolvedProject = + new ProjectDef[ProjectRef]( + id, + base, + aggregateEval, + dependenciesEval, + delegatesEval, + settingsEval, + configurations, + plugins, + autoPlugins, + origin + ) with ResolvedProject - private def unresolved(id: String, - base: File, - aggregateEval: Eval[Seq[ProjectReference]], - dependenciesEval: Eval[Seq[ClasspathDep[ProjectReference]]], - delegatesEval: Eval[Seq[ProjectReference]], - settingsEval: Eval[Seq[Def.Setting[_]]], - configurations: Seq[Configuration], - plugins: Plugins, - autoPlugins: Seq[AutoPlugin], - origin: ProjectOrigin): Project = { + private def unresolved( + id: String, + base: File, + aggregateEval: Eval[Seq[ProjectReference]], + dependenciesEval: Eval[Seq[ClasspathDep[ProjectReference]]], + delegatesEval: Eval[Seq[ProjectReference]], + settingsEval: Eval[Seq[Def.Setting[_]]], + configurations: Seq[Configuration], + plugins: Plugins, + autoPlugins: Seq[AutoPlugin], + origin: ProjectOrigin + ): Project = { validProjectID(id).foreach(errMsg => sys.error("Invalid project ID: " + errMsg)) - new ProjectDef[ProjectReference](id, - base, - aggregateEval, - dependenciesEval, - delegatesEval, - settingsEval, - configurations, - plugins, - autoPlugins, - origin) with Project + new ProjectDef[ProjectReference]( + id, + base, + aggregateEval, + dependenciesEval, + delegatesEval, + settingsEval, + configurations, + plugins, + autoPlugins, + origin + ) with Project } final class Constructor(p: ProjectReference) { def %(conf: Configuration): ClasspathDependency = %(conf.name) - def %(conf: String): ClasspathDependency = new ClasspathDependency(p, Some(conf)) + def %(conf: String): ClasspathDependency = ClasspathDependency(p, Some(conf)) } def getOrError[T](state: State, key: AttributeKey[T], msg: String): T = state get key getOrElse sys.error(msg) + def structure(state: State): BuildStructure = getOrError(state, stateBuildStructure, "No build loaded.") + def session(state: State): SessionSettings = getOrError(state, sessionSettings, "Session not initialized.") + def isProjectLoaded(state: State): Boolean = (state has sessionSettings) && (state has stateBuildStructure) def extract(state: State): Extracted = extract(session(state), structure(state)) + private[sbt] def extract(se: SessionSettings, st: BuildStructure): Extracted = Extracted(st, se, se.current)(showContextKey(se, st)) @@ -506,6 +534,7 @@ object Project extends ProjectExtra { def getProject(ref: ProjectRef, structure: BuildStructure): Option[ResolvedProject] = getProject(ref, structure.units) + def getProject(ref: ProjectRef, structure: LoadedBuild): Option[ResolvedProject] = getProject(ref, structure.units) @@ -531,8 +560,10 @@ object Project extends ProjectExtra { } def orIdentity[T](opt: Option[T => T]): T => T = opt getOrElse idFun + def getHook[T](key: SettingKey[T => T], data: Settings[Scope]): T => T = orIdentity(key in Global get data) + def getHooks(data: Settings[Scope]): (State => State, State => State) = (getHook(Keys.onLoad, data), getHook(Keys.onUnload, data)) @@ -561,8 +592,10 @@ object Project extends ProjectExtra { val newAttrs = setCond(serverPort.key, port, newAttrs0) .put(historyPath.key, history) .put(templateResolverInfos.key, trs) - s.copy(attributes = setCond(shellPrompt.key, prompt, newAttrs), - definedCommands = newDefinedCommands) + s.copy( + attributes = setCond(shellPrompt.key, prompt, newAttrs), + definedCommands = newDefinedCommands + ) } def setCond[T](key: AttributeKey[T], vopt: Option[T], attributes: AttributeMap): AttributeMap = @@ -792,7 +825,7 @@ object Project extends ProjectExtra { case Current => val base = s.configuration.baseDirectory projectReturn(s) match { - case Nil => (setProjectReturn(s, base :: Nil), base); case x :: xs => (s, x) + case Nil => (setProjectReturn(s, base :: Nil), base); case x :: _ => (s, x) } case Plugins => @@ -805,9 +838,11 @@ object Project extends ProjectExtra { (newS, newBase) } - def runTask[T](taskKey: ScopedKey[Task[T]], - state: State, - checkCycles: Boolean = false): Option[(State, Result[T])] = { + def runTask[T]( + taskKey: ScopedKey[Task[T]], + state: State, + checkCycles: Boolean = false + ): Option[(State, Result[T])] = { val extracted = Project.extract(state) val ch = EvaluateTask.cancelStrategy(extracted, extracted.structure, state) val p = EvaluateTask.executeProgress(extracted, extracted.structure, state) @@ -817,9 +852,11 @@ object Project extends ProjectExtra { runTask(taskKey, state, EvaluateTaskConfig(r, checkCycles, p, ch, fgc, mfi)) } - def runTask[T](taskKey: ScopedKey[Task[T]], - state: State, - config: EvaluateTaskConfig): Option[(State, Result[T])] = { + def runTask[T]( + taskKey: ScopedKey[Task[T]], + state: State, + config: EvaluateTaskConfig + ): Option[(State, Result[T])] = { val extracted = Project.extract(state) EvaluateTask(extracted.structure, taskKey, state, extracted.currentRef, config) } @@ -884,8 +921,9 @@ trait ProjectExtra extends ProjectExtra0 { implicit ev: T => ProjectReference): Constructor = new Constructor(p) - implicit def classpathDependency[T](p: T)( - implicit ev: T => ProjectReference): ClasspathDep[ProjectReference] = + implicit def classpathDependency[T]( + p: T + )(implicit ev: T => ProjectReference): ClasspathDep[ProjectReference] = ClasspathDependency(p, None) // These used to be in Project so that they didn't need to get imported (due to Initialize being nested in Project). diff --git a/main/src/main/scala/sbt/internal/BuildDef.scala b/main/src/main/scala/sbt/internal/BuildDef.scala index af8482797..4578413b0 100644 --- a/main/src/main/scala/sbt/internal/BuildDef.scala +++ b/main/src/main/scala/sbt/internal/BuildDef.scala @@ -29,9 +29,11 @@ trait BuildDef { private[sbt] object BuildDef { val defaultEmpty: BuildDef = new BuildDef { override def projects = Nil } + val default: BuildDef = new BuildDef { override def projectDefinitions(base: File) = defaultProject(defaultID(base), base) :: Nil } + def defaultAggregated(id: String, aggregate: Seq[ProjectRef]): BuildDef = new BuildDef { override def projectDefinitions(base: File) = defaultAggregatedProject(id, base, aggregate) :: Nil @@ -42,13 +44,17 @@ private[sbt] object BuildDef { def defaultProject(id: String, base: File): Project = Project(id, base).settings(defaultProjectSettings) + def defaultAggregatedProject(id: String, base: File, agg: Seq[ProjectRef]): Project = defaultProject(id, base).aggregate(agg: _*) - private[sbt] def generatedRootWithoutIvyPlugin(id: String, - base: File, - agg: Seq[ProjectRef]): Project = + private[sbt] def generatedRootWithoutIvyPlugin( + id: String, + base: File, + agg: Seq[ProjectRef] + ): Project = Project.mkGeneratedRoot(id, base, Eval.later(agg)).settings(defaultProjectSettings) + private[sbt] def defaultProjectSettings: Seq[Setting[_]] = Seq( // TODO - Can we move this somewhere else? ordering of settings is causing this to get borked. // if the user has overridden the name, use the normal organization that is derived from the name. @@ -61,7 +67,8 @@ private[sbt] object BuildDef { }, autoGeneratedProject := true ) - def analyzed(in: Seq[Attributed[_]]): Seq[xsbti.compile.CompileAnalysis] = in.flatMap { - _.metadata.get(Keys.analysis) - } + + def analyzed(in: Seq[Attributed[_]]): Seq[xsbti.compile.CompileAnalysis] = + in.flatMap { _.metadata.get(Keys.analysis) } + } diff --git a/main/src/main/scala/sbt/internal/Load.scala b/main/src/main/scala/sbt/internal/Load.scala index b30946aca..77c6582fe 100755 --- a/main/src/main/scala/sbt/internal/Load.scala +++ b/main/src/main/scala/sbt/internal/Load.scala @@ -46,11 +46,13 @@ import xsbti.compile.{ ClasspathOptionsUtil, Compilers } private[sbt] object Load { // note that there is State passed in but not pulled out - def defaultLoad(state: State, - baseDirectory: File, - log: Logger, - isPlugin: Boolean = false, - topLevelExtras: List[URI] = Nil): (() => Eval, BuildStructure) = { + def defaultLoad( + state: State, + baseDirectory: File, + log: Logger, + isPlugin: Boolean = false, + topLevelExtras: List[URI] = Nil + ): (() => Eval, BuildStructure) = { val (base, config) = timed("Load.defaultLoad until apply", log) { val globalBase = getGlobalBase(state) val base = baseDirectory.getCanonicalFile @@ -64,10 +66,12 @@ private[sbt] object Load { result } - def defaultPreGlobal(state: State, - baseDirectory: File, - globalBase: File, - log: Logger): LoadBuildConfiguration = { + def defaultPreGlobal( + state: State, + baseDirectory: File, + globalBase: File, + log: Logger + ): LoadBuildConfiguration = { val app = state.configuration val provider = app.provider val scalaProvider = app.provider.scalaProvider @@ -101,26 +105,30 @@ private[sbt] object Load { scalaJarsTarget = zincDir, log = log ) - val compilers = ZincUtil.compilers(instance = si, - classpathOptions = classpathOptions, - javaHome = None, - scalac) + val compilers = ZincUtil.compilers( + instance = si, + classpathOptions = classpathOptions, + javaHome = None, + scalac + ) val evalPluginDef = EvaluateTask.evalPluginDef(log) _ val delegates = defaultDelegates val pluginMgmt = PluginManagement(loader) val inject = InjectSettings(injectGlobal(state), Nil, const(Nil)) - LoadBuildConfiguration(stagingDirectory, - classpath, - loader, - compilers, - evalPluginDef, - delegates, - EvaluateTask.injectStreams, - pluginMgmt, - inject, - None, - Nil, - log) + LoadBuildConfiguration( + stagingDirectory, + classpath, + loader, + compilers, + evalPluginDef, + delegates, + EvaluateTask.injectStreams, + pluginMgmt, + inject, + None, + Nil, + log + ) } private def bootIvyHome(app: xsbti.AppConfiguration): Option[File] = @@ -134,34 +142,40 @@ private[sbt] object Load { DefaultBackgroundJobService.backgroundJobServiceSetting +: EvaluateTask.injectSettings - def defaultWithGlobal(state: State, - base: File, - rawConfig: LoadBuildConfiguration, - globalBase: File, - log: Logger): LoadBuildConfiguration = { + def defaultWithGlobal( + state: State, + base: File, + rawConfig: LoadBuildConfiguration, + globalBase: File, + log: Logger + ): LoadBuildConfiguration = { val globalPluginsDir = getGlobalPluginsDirectory(state, globalBase) val withGlobal = loadGlobal(state, base, globalPluginsDir, rawConfig) val globalSettings = configurationSources(getGlobalSettingsDirectory(state, globalBase)) loadGlobalSettings(base, globalBase, globalSettings, withGlobal) } - def loadGlobalSettings(base: File, - globalBase: File, - files: Seq[File], - config: LoadBuildConfiguration): LoadBuildConfiguration = { + def loadGlobalSettings( + base: File, + globalBase: File, + files: Seq[File], + config: LoadBuildConfiguration + ): LoadBuildConfiguration = { val compiled: ClassLoader => Seq[Setting[_]] = if (files.isEmpty || base == globalBase) const(Nil) else buildGlobalSettings(globalBase, files, config) config.copy(injectSettings = config.injectSettings.copy(projectLoaded = compiled)) } - def buildGlobalSettings(base: File, - files: Seq[File], - config: LoadBuildConfiguration): ClassLoader => Seq[Setting[_]] = { + def buildGlobalSettings( + base: File, + files: Seq[File], + config: LoadBuildConfiguration + ): ClassLoader => Seq[Setting[_]] = { val eval = mkEval(data(config.globalPluginClasspath), base, defaultEvalOptions) - val imports = BuildUtil.baseImports ++ - config.detectedGlobalPlugins.imports + val imports = + BuildUtil.baseImports ++ config.detectedGlobalPlugins.imports loader => { @@ -172,10 +186,12 @@ private[sbt] object Load { loaded.settings } } - def loadGlobal(state: State, - base: File, - global: File, - config: LoadBuildConfiguration): LoadBuildConfiguration = + def loadGlobal( + state: State, + base: File, + global: File, + config: LoadBuildConfiguration + ): LoadBuildConfiguration = if (base != global && global.exists) { val gp = GlobalPlugin.load(global, state, config) config.copy(globalPlugin = Some(gp)) @@ -198,10 +214,12 @@ private[sbt] object Load { ) } - def configInherit(lb: LoadedBuild, - ref: ResolvedReference, - config: ConfigKey, - rootProject: URI => String): Seq[ConfigKey] = + def configInherit( + lb: LoadedBuild, + ref: ResolvedReference, + config: ConfigKey, + rootProject: URI => String + ): Seq[ConfigKey] = ref match { case pr: ProjectRef => configInheritRef(lb, pr, config) case BuildRef(uri) => configInheritRef(lb, ProjectRef(uri, rootProject(uri)), config) @@ -226,9 +244,11 @@ private[sbt] object Load { // 6) Load all configurations using build definitions and plugins (their classpaths and loaded instances). // 7) Combine settings from projects, plugins, and configurations // 8) Evaluate settings - def apply(rootBase: File, - s: State, - config: LoadBuildConfiguration): (() => Eval, BuildStructure) = { + def apply( + rootBase: File, + s: State, + config: LoadBuildConfiguration + ): (() => Eval, BuildStructure) = { val log = config.log // load, which includes some resolution, but can't fill in project IDs yet, so follow with full resolution @@ -254,15 +274,17 @@ private[sbt] object Load { structureIndex(data, settings, loaded.extra(data), projects) } val streams = timed("Load.apply: mkStreams", log) { mkStreams(projects, loaded.root, data) } - (rootEval, - new BuildStructure(projects, - loaded.root, - settings, - data, - index, - streams, - delegates, - config.scopeLocal)) + val bs = new BuildStructure( + projects, + loaded.root, + settings, + data, + index, + streams, + delegates, + config.scopeLocal + ) + (rootEval, bs) } // map dependencies on the special tasks: @@ -298,21 +320,25 @@ private[sbt] object Load { def setDefinitionKey[T](tk: Task[T], key: ScopedKey[_]): Task[T] = if (isDummy(tk)) tk else Task(tk.info.set(Keys.taskDefinitionKey, key), tk.work) - def structureIndex(data: Settings[Scope], - settings: Seq[Setting[_]], - extra: KeyIndex => BuildUtil[_], - projects: Map[URI, LoadedBuildUnit]): StructureIndex = { + def structureIndex( + data: Settings[Scope], + settings: Seq[Setting[_]], + extra: KeyIndex => BuildUtil[_], + projects: Map[URI, LoadedBuildUnit] + ): StructureIndex = { val keys = Index.allKeys(settings) val attributeKeys = Index.attributeKeys(data) ++ keys.map(_.key) val scopedKeys = keys ++ data.allKeys((s, k) => ScopedKey(s, k)).toVector val projectsMap = projects.mapValues(_.defined.keySet) val keyIndex = KeyIndex(scopedKeys.toVector, projectsMap) val aggIndex = KeyIndex.aggregate(scopedKeys.toVector, extra(keyIndex), projectsMap) - new StructureIndex(Index.stringToKeyMap(attributeKeys), - Index.taskToKeyMap(data), - Index.triggers(data), - keyIndex, - aggIndex) + new StructureIndex( + Index.stringToKeyMap(attributeKeys), + Index.taskToKeyMap(data), + Index.triggers(data), + keyIndex, + aggIndex + ) } // Reevaluates settings after modifying them. Does not recompile or reload any build components. @@ -343,9 +369,11 @@ private[sbt] object Load { case _ => false } - def buildConfigurations(loaded: LoadedBuild, - rootProject: URI => String, - injectSettings: InjectSettings): Seq[Setting[_]] = { + def buildConfigurations( + loaded: LoadedBuild, + rootProject: URI => String, + injectSettings: InjectSettings + ): Seq[Setting[_]] = { ((loadedBuild in GlobalScope :== loaded) +: transformProjectOnly(loaded.root, rootProject, injectSettings.global)) ++ inScope(GlobalScope)(loaded.autos.globalSettings) ++ @@ -357,32 +385,33 @@ private[sbt] object Load { val ref = ProjectRef(uri, id) val defineConfig: Seq[Setting[_]] = for (c <- project.configurations) yield ((configuration in (ref, ConfigKey(c.name))) :== c) - val builtin - : Seq[Setting[_]] = (thisProject :== project) +: (thisProjectRef :== ref) +: defineConfig + val builtin: Seq[Setting[_]] = + (thisProject :== project) +: (thisProjectRef :== ref) +: defineConfig val settings = builtin ++ project.settings ++ injectSettings.project // map This to thisScope, Select(p) to mapRef(uri, rootProject, p) transformSettings(projectScope(ref), uri, rootProject, settings) } val buildScope = Scope(Select(BuildRef(uri)), Zero, Zero, Zero) val buildBase = baseDirectory :== build.localBase - val buildSettings = - transformSettings(buildScope, - uri, - rootProject, - pluginBuildSettings ++ (buildBase +: build.buildSettings)) + val settings3 = pluginBuildSettings ++ (buildBase +: build.buildSettings) + val buildSettings = transformSettings(buildScope, uri, rootProject, settings3) buildSettings ++ projectSettings } } - def transformProjectOnly(uri: URI, - rootProject: URI => String, - settings: Seq[Setting[_]]): Seq[Setting[_]] = + def transformProjectOnly( + uri: URI, + rootProject: URI => String, + settings: Seq[Setting[_]] + ): Seq[Setting[_]] = Project.transform(Scope.resolveProject(uri, rootProject), settings) - def transformSettings(thisScope: Scope, - uri: URI, - rootProject: URI => String, - settings: Seq[Setting[_]]): Seq[Setting[_]] = + def transformSettings( + thisScope: Scope, + uri: URI, + rootProject: URI => String, + settings: Seq[Setting[_]] + ): Seq[Setting[_]] = Project.transform(Scope.resolveScope(thisScope, uri, rootProject), settings) def projectScope(project: Reference): Scope = Scope(Select(project), Zero, Zero, Zero) @@ -491,11 +520,13 @@ private[sbt] object Load { val explicitRoots = unit.definitions.builds.flatMap(_.rootProject) val projectsInRoot = if (explicitRoots.isEmpty) defined.filter(isRoot) else explicitRoots val rootProjects = if (projectsInRoot.isEmpty) firstDefined :: Nil else projectsInRoot - (new PartBuildUnit(unit, - defined.map(d => (d.id, d)).toMap, - rootProjects.map(_.id), - buildSettings(unit)), - externals) + val partBuildUnit = new PartBuildUnit( + unit, + defined.map(d => (d.id, d)).toMap, + rootProjects.map(_.id), + buildSettings(unit) + ) + (partBuildUnit, externals) } def buildSettings(unit: BuildUnit): Seq[Setting[_]] = { @@ -537,7 +568,7 @@ private[sbt] object Load { def checkProjectBase(buildBase: File, projectBase: File): Unit = { checkDirectory(projectBase) assert(buildBase == projectBase || IO.relativize(buildBase, projectBase).isDefined, - "Directory " + projectBase + " is not contained in build root " + buildBase) + s"Directory $projectBase is not contained in build root $buildBase") } def checkBuildBase(base: File) = checkDirectory(base) @@ -566,9 +597,8 @@ private[sbt] object Load { val loadedUnit = builds(refURI) if (!(loadedUnit.defined contains refID)) { val projectIDs = loadedUnit.defined.keys.toSeq.sorted - sys.error( - "No project '" + refID + "' in '" + refURI + "'.\nValid project IDs: " + projectIDs - .mkString(", ")) + sys.error(s"""No project '$refID' in '$refURI'. + |Valid project IDs: ${projectIDs.mkString(", ")}""".stripMargin) } } } @@ -596,10 +626,12 @@ private[sbt] object Load { def resolveProjects(uri: URI, unit: PartBuildUnit, rootProject: URI => String): LoadedBuildUnit = { IO.assertAbsolute(uri) val resolve = (_: Project).resolve(ref => Scope.resolveProjectRef(uri, rootProject, ref)) - new LoadedBuildUnit(unit.unit, - unit.defined mapValues resolve, - unit.rootProjects, - unit.buildSettings) + new LoadedBuildUnit( + unit.unit, + unit.defined mapValues resolve, + unit.rootProjects, + unit.buildSettings + ) } def projects(unit: BuildUnit): Seq[Project] = { @@ -613,16 +645,20 @@ private[sbt] object Load { def getRootProject(map: Map[URI, BuildUnitBase]): URI => String = uri => getBuild(map, uri).rootProjects.headOption getOrElse emptyBuild(uri) - def getConfiguration(map: Map[URI, LoadedBuildUnit], - uri: URI, - id: String, - conf: ConfigKey): Configuration = + def getConfiguration( + map: Map[URI, LoadedBuildUnit], + uri: URI, + id: String, + conf: ConfigKey + ): Configuration = configurationOpt(map, uri, id, conf) getOrElse noConfiguration(uri, id, conf.name) - def configurationOpt(map: Map[URI, LoadedBuildUnit], - uri: URI, - id: String, - conf: ConfigKey): Option[Configuration] = + def configurationOpt( + map: Map[URI, LoadedBuildUnit], + uri: URI, + id: String, + conf: ConfigKey + ): Option[Configuration] = getProject(map, uri, id).configurations.find(_.name == conf.name) def getProject(map: Map[URI, LoadedBuildUnit], uri: URI, id: String): ResolvedProject = @@ -664,21 +700,21 @@ private[sbt] object Load { val hasRootAlreadyDefined = defsScala.exists(_.rootProject.isDefined) val memoSettings = new mutable.HashMap[File, LoadedSbtFile] - def loadProjects(ps: Seq[Project], createRoot: Boolean) = { - val result = loadTransitive(ps, - normBase, - plugs, - () => eval, - config.injectSettings, - Nil, - memoSettings, - config.log, - createRoot, - uri, - config.pluginManagement.context, - Nil) - result - } + def loadProjects(ps: Seq[Project], createRoot: Boolean) = + loadTransitive( + ps, + normBase, + plugs, + () => eval, + config.injectSettings, + Nil, + memoSettings, + config.log, + createRoot, + uri, + config.pluginManagement.context, + Nil + ) val loadedProjectsRaw = timed("Load.loadUnit: loadedProjectsRaw", log) { loadProjects(initialProjects, !hasRootAlreadyDefined) } @@ -716,19 +752,23 @@ private[sbt] object Load { (prev, sbtFile) => prev.zip(sbtFile.definitions) } - val loadedDefs = new LoadedDefinitions(defDir, - Nil, - plugs.loader, - defs, - loadedProjects, - plugs.detected.builds.names, - valDefinitions) + val loadedDefs = new LoadedDefinitions( + defDir, + Nil, + plugs.loader, + defs, + loadedProjects, + plugs.detected.builds.names, + valDefinitions + ) new BuildUnit(uri, normBase, loadedDefs, plugs) } - private[this] def autoID(localBase: File, - context: PluginManagement.Context, - existingIDs: Seq[String]): String = { + private[this] def autoID( + localBase: File, + context: PluginManagement.Context, + existingIDs: Seq[String] + ): String = { def normalizeID(f: File) = Project.normalizeProjectID(f.getName) match { case Right(id) => id case Left(msg) => sys.error(autoIDError(f, msg)) @@ -753,8 +793,10 @@ private[sbt] object Load { b.projectDefinitions(base).map(resolveBase(base)) // Lame hackery to keep track of our state. - private[this] case class LoadedProjects(projects: Seq[Project], - generatedConfigClassFiles: Seq[File]) + private[this] case class LoadedProjects( + projects: Seq[Project], + generatedConfigClassFiles: Seq[File] + ) /** * Loads a new set of projects, including any transitively defined projects underneath this one. @@ -847,18 +889,20 @@ private[sbt] object Load { case Seq(next, rest @ _*) => log.debug(s"[Loading] Loading project ${next.id} @ ${next.base}") val (finished, discovered, generated) = discoverAndLoad(next) - loadTransitive(rest ++ discovered, - buildBase, - plugins, - eval, - injectSettings, - acc :+ finished, - memoSettings, - log, - false, - buildUri, - context, - generated ++ generatedConfigClassFiles) + loadTransitive( + rest ++ discovered, + buildBase, + plugins, + eval, + injectSettings, + acc :+ finished, + memoSettings, + log, + false, + buildUri, + context, + generated ++ generatedConfigClassFiles + ) case Nil if makeOrDiscoverRoot => log.debug(s"[Loading] Scanning directory ${buildBase}") discover(AddSettings.defaultSbtFiles, buildBase) match { @@ -887,18 +931,20 @@ private[sbt] object Load { case DiscoveredProjects(None, discovered, files, generated) => log.debug(s"[Loading] Found non-root projects ${discovered.map(_.id).mkString(",")}") // Here we do something interesting... We need to create an aggregate root project - val otherProjects = loadTransitive(discovered, - buildBase, - plugins, - eval, - injectSettings, - acc, - memoSettings, - log, - false, - buildUri, - context, - Nil) + val otherProjects = loadTransitive( + discovered, + buildBase, + plugins, + eval, + injectSettings, + acc, + memoSettings, + log, + false, + buildUri, + context, + Nil + ) val otherGenerated = otherProjects.generatedConfigClassFiles val existingIds = otherProjects.projects map (_.id) val refs = existingIds map (id => ProjectRef(buildUri, id)) @@ -1032,11 +1078,13 @@ private[sbt] object Load { // TODO - We should import vals defined in other sbt files here, if we wish to // share. For now, build.sbt files have their own unique namespace. def loadSettingsFile(src: File): LoadedSbtFile = - EvaluateConfigurations.evaluateSbtFile(eval(), - src, - IO.readLines(src), - loadedPlugins.detected.imports, - 0)(loader) + EvaluateConfigurations.evaluateSbtFile( + eval(), + src, + IO.readLines(src), + loadedPlugins.detected.imports, + 0 + )(loader) // How to merge SbtFiles we read into one thing def merge(ls: Seq[LoadedSbtFile]): LoadedSbtFile = (LoadedSbtFile.empty /: ls) { _ merge _ } // Loads a given file, or pulls from the cache. @@ -1085,17 +1133,21 @@ private[sbt] object Load { val prod = (exportedProducts in Configurations.Runtime).value val cp = (fullClasspath in Configurations.Runtime).value val opts = (scalacOptions in Configurations.Compile).value - PluginData(removeEntries(cp, prod), - prod, - Some(fullResolvers.value), - Some(update.value), - opts) + PluginData( + removeEntries(cp, prod), + prod, + Some(fullResolvers.value), + Some(update.value), + opts + ) }, onLoadMessage := ("Loading project definition from " + baseDirectory.value) )) - private[this] def removeEntries(cp: Seq[Attributed[File]], - remove: Seq[Attributed[File]]): Seq[Attributed[File]] = { + private[this] def removeEntries( + cp: Seq[Attributed[File]], + remove: Seq[Attributed[File]] + ): Seq[Attributed[File]] = { val files = data(remove).toSet cp filter { f => !files.contains(f.data) @@ -1122,15 +1174,17 @@ private[sbt] object Load { else noPlugins(dir, config) - def hasDefinition(dir: File) = { + def hasDefinition(dir: File): Boolean = { import sbt.io.syntax._ (dir * -GlobFilter(DefaultTargetName)).get.nonEmpty } def noPlugins(dir: File, config: LoadBuildConfiguration): LoadedPlugins = - loadPluginDefinition(dir, - config, - PluginData(config.globalPluginClasspath, Nil, None, None, Nil)) + loadPluginDefinition( + dir, + config, + PluginData(config.globalPluginClasspath, Nil, None, None, Nil) + ) def buildPlugins(dir: File, s: State, config: LoadBuildConfiguration): LoadedPlugins = loadPluginDefinition(dir, config, buildPluginDefinition(dir, s, config)) @@ -1142,9 +1196,11 @@ private[sbt] object Load { * @param pluginData The data required to load plugins. * @return An instance of the loaded build with plugin information. */ - def loadPluginDefinition(dir: File, - config: LoadBuildConfiguration, - pluginData: PluginData): LoadedPlugins = { + def loadPluginDefinition( + dir: File, + config: LoadBuildConfiguration, + pluginData: PluginData + ): LoadedPlugins = { val definitionClasspath = pluginData.definitionClasspath val dependencyClasspath = pluginData.dependencyClasspath val pluginLoader: ClassLoader = @@ -1162,8 +1218,10 @@ private[sbt] object Load { * @param depcp The user-defined dependency classpath. * @return A classpath aggregating both without repeated entries. */ - def buildPluginClasspath(config: LoadBuildConfiguration, - depcp: Seq[Attributed[File]]): Def.Classpath = { + def buildPluginClasspath( + config: LoadBuildConfiguration, + depcp: Seq[Attributed[File]] + ): Def.Classpath = { if (depcp.isEmpty) config.classpath else (depcp ++ config.classpath).distinct } @@ -1177,9 +1235,11 @@ private[sbt] object Load { * @param definitionClasspath The definition classpath for build definitions. * @return A classloader ready to class load plugins. */ - def pluginDefinitionLoader(config: LoadBuildConfiguration, - dependencyClasspath: Def.Classpath, - definitionClasspath: Def.Classpath): ClassLoader = { + def pluginDefinitionLoader( + config: LoadBuildConfiguration, + dependencyClasspath: Def.Classpath, + definitionClasspath: Def.Classpath + ): ClassLoader = { val manager = config.pluginManagement val parentLoader: ClassLoader = { if (dependencyClasspath.isEmpty) manager.initialLoader @@ -1210,21 +1270,25 @@ private[sbt] object Load { val currentProject = session map (_.currentProject) getOrElse Map.empty val currentBuild = session map (_.currentBuild) filter (uri => structure.units.keys exists (uri ==)) getOrElse structure.root - new SessionSettings(currentBuild, - projectMap(structure, currentProject), - structure.settings, - Map.empty, - Nil, - rootEval) + new SessionSettings( + currentBuild, + projectMap(structure, currentProject), + structure.settings, + Map.empty, + Nil, + rootEval + ) } def initialSession(structure: BuildStructure, rootEval: () => Eval): SessionSettings = - new SessionSettings(structure.root, - projectMap(structure, Map.empty), - structure.settings, - Map.empty, - Nil, - rootEval) + new SessionSettings( + structure.root, + projectMap(structure, Map.empty), + structure.settings, + Map.empty, + Nil, + rootEval + ) def projectMap(structure: BuildStructure, current: Map[URI, String]): Map[URI, String] = { val units = structure.units @@ -1244,9 +1308,11 @@ private[sbt] object Load { final class EvaluatedConfigurations(val eval: Eval, val settings: Seq[Setting[_]]) - final case class InjectSettings(global: Seq[Setting[_]], - project: Seq[Setting[_]], - projectLoaded: ClassLoader => Seq[Setting[_]]) { + final case class InjectSettings( + global: Seq[Setting[_]], + project: Seq[Setting[_]], + projectLoaded: ClassLoader => Seq[Setting[_]] + ) { import java.net.URLClassLoader private val cache: mutable.Map[String, Seq[Setting[_]]] = mutable.Map.empty // Cache based on the underlying URL values of the classloader @@ -1303,11 +1369,13 @@ final case class LoadBuildConfiguration( val pluginData = globalPlugin match { case Some(info) => val data = info.data - PluginData(data.fullClasspath, - data.internalClasspath, - Some(data.resolvers), - Some(data.updateReport), - Nil) + PluginData( + data.fullClasspath, + data.internalClasspath, + Some(data.resolvers), + Some(data.updateReport), + Nil + ) case None => PluginData(globalPluginClasspath) } val baseDir = globalPlugin match {