mirror of https://github.com/sbt/sbt.git
scripts: change base directory
This commit is contained in:
parent
b56701f37e
commit
dc6584ff68
|
|
@ -180,7 +180,7 @@ final class Eval(optionsNoncp: Seq[String], classpath: Seq[File], mkReporter: Se
|
||||||
|
|
||||||
val DefaultStartLine = 0
|
val DefaultStartLine = 0
|
||||||
private[this] def makeModuleName(hash: String): String = "$" + halve(hash)
|
private[this] def makeModuleName(hash: String): String = "$" + halve(hash)
|
||||||
private[this] def halve(s: String) = if(s.length > 2) s.substring(0, s.length / 2)
|
private[this] def halve(s: String): String = if(s.length > 2) s.substring(0, s.length / 2) else s
|
||||||
private[this] def noImports = new EvalImports(Nil, "")
|
private[this] def noImports = new EvalImports(Nil, "")
|
||||||
private[this] def mkUnit(srcName: String, firstLine: Int, s: String) = new CompilationUnit(new EvalSourceFile(srcName, firstLine, s))
|
private[this] def mkUnit(srcName: String, firstLine: Int, s: String) = new CompilationUnit(new EvalSourceFile(srcName, firstLine, s))
|
||||||
private[this] def checkError(label: String) = if(reporter.hasErrors) throw new EvalException(label)
|
private[this] def checkError(label: String) = if(reporter.hasErrors) throw new EvalException(label)
|
||||||
|
|
|
||||||
|
|
@ -20,19 +20,30 @@ package sbt
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
/** This class is the entry point for sbt.*/
|
/** This class is the entry point for sbt.*/
|
||||||
class xMain extends xsbti.AppMain
|
final class xMain extends xsbti.AppMain
|
||||||
{
|
{
|
||||||
final def run(configuration: xsbti.AppConfiguration): xsbti.MainResult =
|
def run(configuration: xsbti.AppConfiguration): xsbti.MainResult =
|
||||||
{
|
{
|
||||||
import BuiltinCommands.{initialize, defaults, DefaultBootCommands}
|
import BuiltinCommands.{initialAttributes, initialize, defaults, DefaultBootCommands}
|
||||||
import CommandSupport.{DefaultsCommand, InitCommand}
|
import CommandSupport.{DefaultsCommand, InitCommand}
|
||||||
val initialCommandDefs = Seq(initialize, defaults)
|
val initialCommandDefs = Seq(initialize, defaults)
|
||||||
val commands = DefaultsCommand +: InitCommand +: (DefaultBootCommands ++ configuration.arguments.map(_.trim))
|
val commands = DefaultsCommand +: InitCommand +: (DefaultBootCommands ++ configuration.arguments.map(_.trim))
|
||||||
val state = State( configuration, initialCommandDefs, Set.empty, None, commands, initialAttributes, Next.Continue )
|
val state = State( configuration, initialCommandDefs, Set.empty, None, commands, initialAttributes, Next.Continue )
|
||||||
run(state)
|
MainLoop.run(state)
|
||||||
}
|
}
|
||||||
def initialAttributes = AttributeMap.empty.put(logged, ConsoleLogger())
|
}
|
||||||
|
final class ScriptMain extends xsbti.AppMain
|
||||||
|
{
|
||||||
|
def run(configuration: xsbti.AppConfiguration): xsbti.MainResult =
|
||||||
|
{
|
||||||
|
import BuiltinCommands.{initialAttributes, ScriptCommands}
|
||||||
|
val commands = Script.Name +: configuration.arguments.map(_.trim)
|
||||||
|
val state = State( configuration, ScriptCommands, Set.empty, None, commands, initialAttributes, Next.Continue )
|
||||||
|
MainLoop.run(state)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
object MainLoop
|
||||||
|
{
|
||||||
@tailrec final def run(state: State): xsbti.MainResult =
|
@tailrec final def run(state: State): xsbti.MainResult =
|
||||||
{
|
{
|
||||||
import Next._
|
import Next._
|
||||||
|
|
@ -59,7 +70,10 @@ class xMain extends xsbti.AppMain
|
||||||
import CommandSupport._
|
import CommandSupport._
|
||||||
object BuiltinCommands
|
object BuiltinCommands
|
||||||
{
|
{
|
||||||
def DefaultCommands: Seq[Command] = Seq(ignore, help, reboot, read, history, continuous, exit, loadProject, loadProjectImpl, loadFailed, Script.command, Cross.crossBuild, Cross.switchVersion,
|
def initialAttributes = AttributeMap.empty.put(logged, ConsoleLogger())
|
||||||
|
|
||||||
|
def ScriptCommands: Seq[Command] = Seq(ignore, exit, Script.command, act, nop)
|
||||||
|
def DefaultCommands: Seq[Command] = Seq(ignore, help, reboot, read, history, continuous, exit, loadProject, loadProjectImpl, loadFailed, Cross.crossBuild, Cross.switchVersion,
|
||||||
projects, project, setOnFailure, clearOnFailure, ifLast, multi, shell, set, inspect, eval, alias, append, last, lastGrep, nop, sessionCommand, act)
|
projects, project, setOnFailure, clearOnFailure, ifLast, multi, shell, set, inspect, eval, alias, append, last, lastGrep, nop, sessionCommand, act)
|
||||||
def DefaultBootCommands: Seq[String] = LoadProject :: (IfLast + " " + Shell) :: Nil
|
def DefaultBootCommands: Seq[String] = LoadProject :: (IfLast + " " + Shell) :: Nil
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ package sbt
|
||||||
import Project._
|
import Project._
|
||||||
import Keys.{appConfiguration, stateBuildStructure, commands, configuration, historyPath, logged, projectCommand, sessionSettings, shellPrompt, streams, thisProject, thisProjectRef, watch}
|
import Keys.{appConfiguration, stateBuildStructure, commands, configuration, historyPath, logged, projectCommand, sessionSettings, shellPrompt, streams, thisProject, thisProjectRef, watch}
|
||||||
import Scope.{GlobalScope,ThisScope}
|
import Scope.{GlobalScope,ThisScope}
|
||||||
|
import Load.BuildStructure
|
||||||
import CommandSupport.logger
|
import CommandSupport.logger
|
||||||
import Types.idFun
|
import Types.idFun
|
||||||
|
|
||||||
|
|
@ -58,7 +59,7 @@ sealed trait Project extends ProjectDefinition[ProjectReference]
|
||||||
}
|
}
|
||||||
sealed trait ResolvedProject extends ProjectDefinition[ProjectRef]
|
sealed trait ResolvedProject extends ProjectDefinition[ProjectRef]
|
||||||
|
|
||||||
final case class Extracted(structure: Load.BuildStructure, session: SessionSettings, currentRef: ProjectRef, rootProject: URI => String)
|
final case class Extracted(structure: BuildStructure, session: SessionSettings, currentRef: ProjectRef, rootProject: URI => String)
|
||||||
{
|
{
|
||||||
lazy val currentUnit = structure units currentRef.build
|
lazy val currentUnit = structure units currentRef.build
|
||||||
lazy val currentProject = currentUnit defined currentRef.project
|
lazy val currentProject = currentUnit defined currentRef.project
|
||||||
|
|
@ -93,22 +94,18 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
}
|
}
|
||||||
|
|
||||||
def getOrError[T](state: State, key: AttributeKey[T], msg: String): T = state get key getOrElse error(msg)
|
def getOrError[T](state: State, key: AttributeKey[T], msg: String): T = state get key getOrElse error(msg)
|
||||||
def structure(state: State): Load.BuildStructure = getOrError(state, stateBuildStructure, "No build loaded.")
|
def structure(state: State): BuildStructure = getOrError(state, stateBuildStructure, "No build loaded.")
|
||||||
def session(state: State): SessionSettings = getOrError(state, sessionSettings, "Session not initialized.")
|
def session(state: State): SessionSettings = getOrError(state, sessionSettings, "Session not initialized.")
|
||||||
|
|
||||||
def extract(state: State): Extracted =
|
def extract(state: State): Extracted = extract( session(state), structure(state) )
|
||||||
{
|
def extract(se: SessionSettings, st: BuildStructure): Extracted = Extracted(st, se, se.current, Load.getRootProject(st.units))
|
||||||
val se = session(state)
|
|
||||||
val st = structure(state)
|
|
||||||
Extracted(st, se, se.current, Load.getRootProject(st.units))
|
|
||||||
}
|
|
||||||
|
|
||||||
def getProjectForReference(ref: Reference, structure: Load.BuildStructure): Option[ResolvedProject] =
|
def getProjectForReference(ref: Reference, structure: BuildStructure): Option[ResolvedProject] =
|
||||||
ref match { case pr: ProjectRef => getProject(pr, structure); case _ => None }
|
ref match { case pr: ProjectRef => getProject(pr, structure); case _ => None }
|
||||||
def getProject(ref: ProjectRef, structure: Load.BuildStructure): Option[ResolvedProject] =
|
def getProject(ref: ProjectRef, structure: BuildStructure): Option[ResolvedProject] =
|
||||||
(structure.units get ref.build).flatMap(_.defined get ref.project)
|
(structure.units get ref.build).flatMap(_.defined get ref.project)
|
||||||
|
|
||||||
def setProject(session: SessionSettings, structure: Load.BuildStructure, s: State): State =
|
def setProject(session: SessionSettings, structure: BuildStructure, s: State): State =
|
||||||
{
|
{
|
||||||
val newAttrs = s.attributes.put(stateBuildStructure, structure).put(sessionSettings, session)
|
val newAttrs = s.attributes.put(stateBuildStructure, structure).put(sessionSettings, session)
|
||||||
val newState = s.copy(attributes = newAttrs)
|
val newState = s.copy(attributes = newAttrs)
|
||||||
|
|
@ -185,10 +182,10 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
throw new MessageOnlyException(c.getMessage)
|
throw new MessageOnlyException(c.getMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
def delegates(structure: Load.BuildStructure, scope: Scope, key: AttributeKey[_]): Seq[ScopedKey[_]] =
|
def delegates(structure: BuildStructure, scope: Scope, key: AttributeKey[_]): Seq[ScopedKey[_]] =
|
||||||
structure.delegates(scope).map(d => ScopedKey(d, key))
|
structure.delegates(scope).map(d => ScopedKey(d, key))
|
||||||
|
|
||||||
def details(structure: Load.BuildStructure, actual: Boolean, scope: Scope, key: AttributeKey[_]): String =
|
def details(structure: BuildStructure, actual: Boolean, scope: Scope, key: AttributeKey[_]): String =
|
||||||
{
|
{
|
||||||
val scoped = ScopedKey(scope,key)
|
val scoped = ScopedKey(scope,key)
|
||||||
val value =
|
val value =
|
||||||
|
|
@ -213,13 +210,13 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
printScopes("Delegates", delegates(structure, scope, key)) +
|
printScopes("Delegates", delegates(structure, scope, key)) +
|
||||||
printScopes("Related", related)
|
printScopes("Related", related)
|
||||||
}
|
}
|
||||||
def graphSettings(structure: Load.BuildStructure, basedir: File)
|
def graphSettings(structure: BuildStructure, basedir: File)
|
||||||
{
|
{
|
||||||
def graph(actual: Boolean, name: String) = graphSettings(structure, actual, name, new File(basedir, name + ".dot"))
|
def graph(actual: Boolean, name: String) = graphSettings(structure, actual, name, new File(basedir, name + ".dot"))
|
||||||
graph(true, "actual_dependencies")
|
graph(true, "actual_dependencies")
|
||||||
graph(false, "declared_dependencies")
|
graph(false, "declared_dependencies")
|
||||||
}
|
}
|
||||||
def graphSettings(structure: Load.BuildStructure, actual: Boolean, graphName: String, file: File)
|
def graphSettings(structure: BuildStructure, actual: Boolean, graphName: String, file: File)
|
||||||
{
|
{
|
||||||
type Rel = Relation[ScopedKey[_], ScopedKey[_]]
|
type Rel = Relation[ScopedKey[_], ScopedKey[_]]
|
||||||
val cMap = compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal)
|
val cMap = compiled(structure.settings, actual)(structure.delegates, structure.scopeLocal)
|
||||||
|
|
@ -267,7 +264,7 @@ object Project extends Init[Scope] with ProjectExtra
|
||||||
EvaluateTask.evaluateTask(extracted.structure, taskKey, state, extracted.currentRef, checkCycles, maxWorkers)
|
EvaluateTask.evaluateTask(extracted.structure, taskKey, state, extracted.currentRef, checkCycles, maxWorkers)
|
||||||
}
|
}
|
||||||
def globalLoggerKey = fillTaskAxis(ScopedKey(GlobalScope, streams.key))
|
def globalLoggerKey = fillTaskAxis(ScopedKey(GlobalScope, streams.key))
|
||||||
def installGlobalLogger(s: State, structure: Load.BuildStructure): State =
|
def installGlobalLogger(s: State, structure: BuildStructure): State =
|
||||||
{
|
{
|
||||||
val str = structure.streams(globalLoggerKey)
|
val str = structure.streams(globalLoggerKey)
|
||||||
str.open()
|
str.open()
|
||||||
|
|
|
||||||
|
|
@ -10,25 +10,33 @@ package sbt
|
||||||
|
|
||||||
object Script
|
object Script
|
||||||
{
|
{
|
||||||
|
final val Name = "script"
|
||||||
lazy val command =
|
lazy val command =
|
||||||
Command.command("script") { state =>
|
Command.command(Name) { state =>
|
||||||
val scriptArg = state.remainingCommands.headOption getOrElse error("No script file specified")
|
val scriptArg = state.remainingCommands.headOption getOrElse error("No script file specified")
|
||||||
val script = new File(scriptArg).getAbsoluteFile
|
val script = new File(scriptArg).getAbsoluteFile
|
||||||
val extracted = Project.extract(state)
|
val hash = halve(Hash.toHex(Hash(script.getAbsolutePath)))
|
||||||
|
val base = new File(state.configuration.provider.scalaProvider.launcher.bootDirectory, hash)
|
||||||
|
IO.createDirectory(base)
|
||||||
|
|
||||||
|
val (eval, structure) = Load.defaultLoad(state, base, CommandSupport.logger(state))
|
||||||
|
val session = Load.initialSession(structure, eval)
|
||||||
|
val extracted = Project.extract(session, structure)
|
||||||
import extracted._
|
import extracted._
|
||||||
|
|
||||||
val eval = session.currentEval()
|
val embeddedSettings = blocks(script).flatMap { block =>
|
||||||
val settings = blocks(script).flatMap { block =>
|
evaluate(eval(), script.getPath, block.lines, currentUnit.imports, block.offset+1)
|
||||||
evaluate(eval, script.getPath, block.lines, currentUnit.imports, block.offset+1)
|
|
||||||
}
|
}
|
||||||
val scriptAsSource = sources in Compile := script :: Nil
|
val scriptAsSource = sources in Compile := script :: Nil
|
||||||
val asScript = scalacOptions ++= Seq("-Xscript", script.getName.stripSuffix(".scala"))
|
val asScript = scalacOptions ++= Seq("-Xscript", script.getName.stripSuffix(".scala"))
|
||||||
val logQuiet = (logLevel in Global := Level.Warn) :: (showSuccess in Global := false) :: Nil
|
val scriptSettings = Seq(asScript, scriptAsSource, logLevel in Global := Level.Warn, showSuccess in Global := false)
|
||||||
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, asScript +: (logQuiet ++ settings))
|
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, scriptSettings ++ embeddedSettings)
|
||||||
|
|
||||||
val newStructure = Load.reapply(session.original ++ append, structure)
|
val newStructure = Load.reapply(session.original ++ append, structure)
|
||||||
val newState = "run" :: state.copy(remainingCommands = state.remainingCommands.drop(1))
|
val newState = "run" :: state.copy(remainingCommands = state.remainingCommands.drop(1))
|
||||||
Project.setProject(session, newStructure, newState)
|
Project.setProject(session, newStructure, newState)
|
||||||
}
|
}
|
||||||
|
def halve(s: String): String = if(s.length > 3) s.substring(0, s.length / 2) else s
|
||||||
|
|
||||||
final case class Block(offset: Int, lines: Seq[String])
|
final case class Block(offset: Int, lines: Seq[String])
|
||||||
def blocks(file: File): Seq[Block] =
|
def blocks(file: File): Seq[Block] =
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue