mirror of https://github.com/sbt/sbt.git
65 lines
2.4 KiB
Scala
65 lines
2.4 KiB
Scala
/* sbt -- Simple Build Tool
|
|
* Copyright 2011 Mark Harrah
|
|
*/
|
|
package sbt
|
|
|
|
import java.io.File
|
|
import Keys._
|
|
import EvaluateConfigurations.{evaluateConfiguration => evaluate}
|
|
import Configurations.Compile
|
|
|
|
object Script
|
|
{
|
|
final val Name = "script"
|
|
lazy val command =
|
|
Command.command(Name) { state =>
|
|
val scriptArg = state.remainingCommands.headOption getOrElse error("No script file specified")
|
|
val script = new File(scriptArg).getAbsoluteFile
|
|
val hash = Hash.halve(Hash.toHex(Hash(script.getAbsolutePath)))
|
|
val base = new File(CommandSupport.bootDirectory(state), 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._
|
|
|
|
val embeddedSettings = blocks(script).flatMap { block =>
|
|
evaluate(eval(), script.getPath, block.lines, currentUnit.imports, block.offset+1)
|
|
}
|
|
val scriptAsSource = sources in Compile := script :: Nil
|
|
val asScript = scalacOptions ++= Seq("-Xscript", script.getName.stripSuffix(".scala"))
|
|
val scriptSettings = Seq(asScript, scriptAsSource, logLevel in Global := Level.Warn, showSuccess in Global := false)
|
|
val append = Load.transformSettings(Load.projectScope(currentRef), currentRef.build, rootProject, scriptSettings ++ embeddedSettings)
|
|
|
|
val newStructure = Load.reapply(session.original ++ append, structure)
|
|
val arguments = state.remainingCommands.drop(1)
|
|
val newState = arguments.mkString("run ", " ", "") :: state.copy(remainingCommands = Nil)
|
|
Project.setProject(session, newStructure, newState)
|
|
}
|
|
|
|
final case class Block(offset: Int, lines: Seq[String])
|
|
def blocks(file: File): Seq[Block] =
|
|
{
|
|
val lines = IO.readLines(file).toIndexedSeq
|
|
def blocks(b: Block, acc: List[Block]): List[Block] =
|
|
if(b.lines.isEmpty)
|
|
acc.reverse
|
|
else
|
|
{
|
|
val (dropped, blockToEnd) = b.lines.span { line => ! line.startsWith(BlockStart) }
|
|
val (block, remaining) = blockToEnd.span { line => ! line.startsWith(BlockEnd) }
|
|
val offset = b.offset + dropped.length
|
|
blocks(Block(offset + block.length, remaining), Block(offset, block.drop(1)) :: acc )
|
|
}
|
|
blocks(Block(0, lines), Nil)
|
|
}
|
|
val BlockStart = "/***"
|
|
val BlockEnd = "*/"
|
|
def fail(s: State, msg: String): State =
|
|
{
|
|
System.err.println(msg)
|
|
s.fail
|
|
}
|
|
}
|