<commit_before>/* sbt -- Simple Build Tool
 * Copyright 2011 <NAME>
 */
package sbt
package internal

import sbt.librarymanagement.{ Configuration, Configurations, Resolver, UpdateOptions }
import sbt.internal.librarymanagement.{ DefaultFileToStore, InlineIvyConfiguration, IvyPaths }

import java.io.File
import java.net.{ URI, URL }
import compiler.Eval
import scala.annotation.tailrec
import collection.mutable
import sbt.internal.inc.{ Analysis, ClasspathOptionsUtil, ModuleUtilities }
import sbt.internal.inc.classpath.ClasspathUtilities
import Project.inScope
import Def.{ isDummy, ScopedKey, ScopeLocal, Setting }
import Keys.{
  appConfiguration,
  baseDirectory,
  configuration,
  exportedProducts,
  fullClasspath,
  fullResolvers,
  loadedBuild,
  onLoadMessage,
  pluginData,
  resolvedScoped,
  sbtPlugin,
  scalacOptions,
  streams,
  thisProject,
  thisProjectRef,
  update
}
import tools.nsc.reporters.ConsoleReporter
import sbt.internal.util.{ Attributed, Settings, Show, ~> }
import sbt.util.{ Eval => Ev }
import sbt.internal.util.Attributed.data
import Scope.GlobalScope
import sbt.internal.util.Types.const
import BuildPaths._
import BuildStreams._
import sbt.io.{ GlobFilter, IO, Path }
import sbt.util.Logger
import xsbti.compile.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) =
    {
      val (base, config) = timed("Load.defaultLoad until apply", log) {
        val globalBase = getGlobalBase(state)
        val base = baseDirectory.getCanonicalFile
        val rawConfig = defaultPreGlobal(state, base, globalBase, log)
        val config0 = defaultWithGlobal(state, base, rawConfig, globalBase, log)
        val config = if (isPlugin) enableSbtPlugin(config0) else config0.copy(extraBuilds = topLevelExtras)
        (base, config)
      }
      val result = apply(base, state, config)
      result
    }

  def defaultPreGlobal(state: State, baseDirectory: File, globalBase: File, log: Logger): LoadBuildConfiguration =
    {
      val provider = state.configuration.provider
      val scalaProvider = provider.scalaProvider
      val stagingDirectory = getStagingDirectory(state, globalBase).getCanonicalFile
      val loader = getClass.getClassLoader
      val classpath = Attributed.blankSeq(provider.mainClasspath ++ scalaProvider.jars)
      val localOnly = false
      val lock = None
      val checksums = Vector.empty
      val ivyPaths = IvyPaths(baseDirectory, bootIvyHome(state.configuration))
      val ivyConfiguration = new InlineIvyConfiguration(ivyPaths, Resolver.withDefaultResolvers(Nil).toVector,
        Vector.empty, Vector.empty, localOnly, lock, checksums, None, UpdateOptions(), log)
      val compilers = Compiler.compilers(ClasspathOptionsUtil.boot, ivyConfiguration, DefaultFileToStore)(state.configuration, log)
      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)
    }
  private def bootIvyHome(app: xsbti.AppConfiguration): Option[File] =
    try { Option(app.provider.scalaProvider.launcher.ivyHome) }
    catch { case _: NoSuchMethodError => None }
  def injectGlobal(state: State): Seq[Setting[_]] =
    (appConfiguration in GlobalScope :== state.configuration) +:
      LogManager.settingsLogger(state) +:
      EvaluateTask.injectSettings
  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 =
    {
      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[_]] =
    {
      val eval = mkEval(data(config.globalPluginClasspath), base, defaultEvalOptions)

      val imports = BuildUtil.baseImports ++
        config.detectedGlobalPlugins.imports

      loader => {
        val loaded = EvaluateConfigurations(eval, files, imports)(loader)
        // TODO - We have a potential leak of config-classes in the global directory right now.
        // We need to find a way to clean these safely, or at least warn users about
        // unused class files that could be cleaned when multiple sbt instances are not running.
        loaded.settings
      }
    }
  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))
    } else
      config

  def defaultDelegates: LoadedBuild => Scope => Seq[Scope] = (lb: LoadedBuild) => {
    val rootProject = getRootProject(lb.units)
    def resolveRef(project: Reference): ResolvedReference = Scope.resolveReference(lb.root, rootProject, project)
    Scope.delegates(
      lb.allProjectRefs,
      (_: ResolvedProject).configurations.map(c => ConfigKey(c.name)),
      resolveRef,
      rootProject,
      project => projectInherit(lb, project),
      (project, config) => configInherit(lb, project, config, rootProject),
      task => task.extend,
      (project, extra) => Nil
    )
  }
  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)
    }
  def configInheritRef(lb: LoadedBuild, ref: ProjectRef, config: ConfigKey): Seq[ConfigKey] =
    configurationOpt(lb.units, ref.build, ref.project, config).toList.flatMap(_.extendsConfigs).map(c => ConfigKey(c.name))

  def projectInherit(lb: LoadedBuild, ref: ProjectRef): Seq[ProjectRef] =
    getProject(lb.units, ref.build, ref.project).delegates

  // build, load, and evaluate all units.
  //  1) Compile all plugin definitions
  //  2) Evaluate plugin definitions to obtain and compile plugins and get the resulting classpath for the build definition
  //  3) Instantiate Plugins on that classpath
  //  4) Compile all build definitions using plugin classpath
  //  5) Load build definitions.
  //  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) =
    {
      val log = config.log

      // load, which includes some resolution, but can't fill in project IDs yet, so follow with full resolution
      val partBuild = timed("Load.apply: load", log) { load(rootBase, s, config) }
      val loaded = timed("Load.apply: resolveProjects", log) {
        resolveProjects(partBuild)
      }
      val projects = loaded.units
      lazy val rootEval = lazyEval(loaded.units(loaded.root).unit)
      val settings = timed("Load.apply: finalTransforms", log) {
        finalTransforms(buildConfigurations(loaded, getRootProject(projects), config.injectSettings))
      }
      val delegates = timed("Load.apply: config.delegates", log) { config.delegates(loaded) }
      val data = timed("Load.apply: Def.make(settings)...", log) {
        Def.make(settings)(delegates, config.scopeLocal, Project.showLoadingKey(loaded))
      }
      Project.checkTargets(data) foreach sys.error
      val index = timed("Load.apply: structureIndex", log) {
        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))
    }

  // 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
  // 3. resolvedScoped is replaced with the defining key as a value
  // Note: this must be idempotent.
  def finalTransforms(ss: Seq[Setting[_]]): Seq[Setting[_]] =<commit_msg>Display log when sbt loading is going to pause<commit_after>/* sbt -- Simple Build Tool
 * Copyright 2011 <NAME>
 */
package sbt
package internal

import sbt.librarymanagement.{ Configuration, Configurations, Resolver, UpdateOptions }
import sbt.internal.librarymanagement.{ DefaultFileToStore, InlineIvyConfiguration, IvyPaths }

import java.io.File
import java.net.{ URI, URL }
import compiler.Eval
import scala.annotation.tailrec
import collection.mutable
import sbt.internal.inc.{ Analysis, ClasspathOptionsUtil, ModuleUtilities }
import sbt.internal.inc.classpath.ClasspathUtilities
import Project.inScope
import Def.{ isDummy, ScopedKey, ScopeLocal, Setting }
import Keys.{
  appConfiguration,
  baseDirectory,
  configuration,
  exportedProducts,
  fullClasspath,
  fullResolvers,
  loadedBuild,
  onLoadMessage,
  pluginData,
  resolvedScoped,
  sbtPlugin,
  scalacOptions,
  streams,
  thisProject,
  thisProjectRef,
  update
}
import tools.nsc.reporters.ConsoleReporter
import sbt.internal.util.{ Attributed, Settings, Show, ~> }
import sbt.util.{ Eval => Ev }
import sbt.internal.util.Attributed.data
import Scope.GlobalScope
import sbt.internal.util.Types.const
import BuildPaths._
import BuildStreams._
import sbt.io.{ GlobFilter, IO, Path }
import sbt.util.Logger
import xsbti.compile.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) =
    {
      val (base, config) = timed("Load.defaultLoad until apply", log) {
        val globalBase = getGlobalBase(state)
        val base = baseDirectory.getCanonicalFile
        val rawConfig = defaultPreGlobal(state, base, globalBase, log)
        val config0 = defaultWithGlobal(state, base, rawConfig, globalBase, log)
        val config = if (isPlugin) enableSbtPlugin(config0) else config0.copy(extraBuilds = topLevelExtras)
        (base, config)
      }
      val result = apply(base, state, config)
      result
    }

  def defaultPreGlobal(state: State, baseDirectory: File, globalBase: File, log: Logger): LoadBuildConfiguration =
    {
      val provider = state.configuration.provider
      val scalaProvider = provider.scalaProvider
      val stagingDirectory = getStagingDirectory(state, globalBase).getCanonicalFile
      val loader = getClass.getClassLoader
      val classpath = Attributed.blankSeq(provider.mainClasspath ++ scalaProvider.jars)
      val localOnly = false
      val lock = None
      val checksums = Vector.empty
      val ivyPaths = IvyPaths(baseDirectory, bootIvyHome(state.configuration))
      val ivyConfiguration = new InlineIvyConfiguration(ivyPaths, Resolver.withDefaultResolvers(Nil).toVector,
        Vector.empty, Vector.empty, localOnly, lock, checksums, None, UpdateOptions(), log)
      val compilers = Compiler.compilers(ClasspathOptionsUtil.boot, ivyConfiguration, DefaultFileToStore)(state.configuration, log)
      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)
    }
  private def bootIvyHome(app: xsbti.AppConfiguration): Option[File] =
    try { Option(app.provider.scalaProvider.launcher.ivyHome) }
    catch { case _: NoSuchMethodError => None }
  def injectGlobal(state: State): Seq[Setting[_]] =
    (appConfiguration in GlobalScope :== state.configuration) +:
      LogManager.settingsLogger(state) +:
      EvaluateTask.injectSettings
  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 =
    {
      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[_]] =
    {
      val eval = mkEval(data(config.globalPluginClasspath), base, defaultEvalOptions)

      val imports = BuildUtil.baseImports ++
        config.detectedGlobalPlugins.imports

      loader => {
        val loaded = EvaluateConfigurations(eval, files, imports)(loader)
        // TODO - We have a potential leak of config-classes in the global directory right now.
        // We need to find a way to clean these safely, or at least warn users about
        // unused class files that could be cleaned when multiple sbt instances are not running.
        loaded.settings
      }
    }
  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))
    } else
      config

  def defaultDelegates: LoadedBuild => Scope => Seq[Scope] = (lb: LoadedBuild) => {
    val rootProject = getRootProject(lb.units)
    def resolveRef(project: Reference): ResolvedReference = Scope.resolveReference(lb.root, rootProject, project)
    Scope.delegates(
      lb.allProjectRefs,
      (_: ResolvedProject).configurations.map(c => ConfigKey(c.name)),
      resolveRef,
      rootProject,
      project => projectInherit(lb, project),
      (project, config) => configInherit(lb, project, config, rootProject),
      task => task.extend,
      (project, extra) => Nil
    )
  }
  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)
    }
  def configInheritRef(lb: LoadedBuild, ref: ProjectRef, config: ConfigKey): Seq[ConfigKey] =
    configurationOpt(lb.units, ref.build, ref.project, config).toList.flatMap(_.extendsConfigs).map(c => ConfigKey(c.name))

  def projectInherit(lb: LoadedBuild, ref: ProjectRef): Seq[ProjectRef] =
    getProject(lb.units, ref.build, ref.project).delegates

  // build, load, and evaluate all units.
  //  1) Compile all plugin definitions
  //  2) Evaluate plugin definitions to obtain and compile plugins and get the resulting classpath for the build definition
  //  3) Instantiate Plugins on that classpath
  //  4) Compile all build definitions using plugin classpath
  //  5) Load build definitions.
  //  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) =
    {
      val log = config.log

      // load, which includes some resolution, but can't fill in project IDs yet, so follow with full resolution
      val partBuild = timed("Load.apply: load", log) { load(rootBase, s, config) }
      val loaded = timed("Load.apply: resolveProjects", log) {
        resolveProjects(partBuild)
      }
      val projects = loaded.units
      lazy val rootEval = lazyEval(loaded.units(loaded.root).unit)
      val settings = timed("Load.apply: finalTransforms", log) {
        finalTransforms(buildConfigurations(loaded, getRootProject(projects), config.injectSettings))
      }
      val delegates = timed("Load.apply: config.delegates", log) { config.delegates(loaded) }
      val data = timed("Load.apply: Def.make(settings)...", log) {
        // When settings.size is 100000, Def.make takes around 10s.
        if (settings.size > 10000) {
          log.info(s"Resolving key references (${settings.size} settings) ...")
        }
        Def.make(settings)(delegates, config.scopeLocal, Project.showLoadingKey(loaded))
      }
      Project.checkTargets(data) foreach sys.error
      val index = timed("Load.apply: structureIndex", log) {
        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))
    }

  // 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
  // 3. resolvedScoped is replaced with the defining key as a value
  // Note: this must be idempotent.
  def finalTransforms(ss: Seq[Setting[_]]): Seq[Setting[_]] =
{'fraction_non_alphanumeric': 0.09896223387183053, 'fraction_numerical': 0.0026211618701187547, 'mean_word_length': 3.9654714475431607, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4616045', 'n_tokens_mistral': 5344, 'n_tokens_neox': 5229, 'n_words': 1514}