顿搜
SBT 命令执行过程
06/17
在sbt--and-plugins包下,有一个command jar包(如command_2.12-1.1.4.jar), 该jar包下有一个sbt package,包含一个MainLoop的Scala文件,定义了一个MainLoop的object,包含一个processCommand方法。
def processCommand(exec: Exec, state: State): State
- exec就是要执行的命令
state记录了执行的状态,如currentCommand表示当前执行的命令, next表示下一个状态 - 调用Command的combine方法,得到parser
def combine(cmds: Seq[Command]): State => Parser[() => State]
- cmds:state中预定义的命令
- 调用separateCommand方法, 将state中预定义的命令分成SimpleCommand和ArbitraryCommand
private[this] def separateCommands(
cmds: Seq[Command]): (Seq[SimpleCommand], Seq[ArbitraryCommand])- 调用simpleParser方法,对SimpleCommand进行解析,得到解析器
- def simpleParser(cmds: Seq[SimpleCommand]): State => Parser[() => State]
- 使用得到的parser,调用parse对命令进行解析
- def parseT: Either[String, T]
- 将解析的结果赋给newState,返回newState
MainLoop中的next方法
def next(state: State): State
调用State的process方法,使用processCommand执行state中的currentCommand
def process(f: (Exec, State) => State): State = {
def runCmd(cmd: Exec, remainingCommands: List[Exec]) = { log.debug(s"> $cmd") f(cmd, s.copy(remainingCommands = remainingCommands, currentCommand = Some(cmd), history = cmd :: s.history)) } s.remainingCommands match { case List() => exit(true) case List(x, xs @ _*) => runCmd(x, xs.toList) } }- f指代processCommand函数
MainLoop中的run方法
@tailrec def run(state: State): RunNext
递归所有命令的执行,如果State.next 是State.Continue,表示可以继续,调用next(state)执行下一条命令
reload命令
loadp: loadProject
- [info] Loading settings from idea.sbt,plugins.sbt ...
- [info] Loading global plugins from /Users/dary/.sbt/1.0/plugins
- [info] Loading settings from plugins.sbt ...
- [info] Loading project definition from /Users/dary/code/custom-conversion-web/project
- [info] Loading settings from build.sbt ...
- [info] Set current project to custom-conversion-web (in build file:/Users/dary/code/custom-conversion-web/)