Created
February 16, 2016 13:41
-
-
Save Duhemm/2748118c3f2e697b4691 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package hijack | |
import sbt._ | |
import Keys._ | |
import sbt.complete.DefaultParsers._ | |
object HijackShellPlugin extends AutoPlugin { | |
override def requires = sbt.plugins.JvmPlugin | |
override def trigger = allRequirements | |
override def buildSettings = | |
Seq( | |
commands += hijackShell, | |
onLoad in Global := { | |
val previous = (onLoad in Global).value | |
((s: State) => Hijack :: s) compose previous | |
} | |
) | |
private val Hijack = "hijack" | |
private def hijackShell = | |
Command.command(Hijack) { s => s.copy(definedCommands = s.definedCommands ++ Seq(hijackedShell)) } | |
private def getAllPluginKeys(plugins: DetectedPlugins): Seq[Def.Setting[_]] = { | |
val autoPlugins: Seq[AutoPlugin] = plugins.autoPlugins.map(_.value) | |
val nonAutoPlugins: Seq[Plugin] = plugins.plugins.values | |
val allAuto: Seq[Def.Setting[_]] = autoPlugins.flatMap { p => | |
p.buildSettings ++ p.globalSettings ++ p.projectSettings | |
} | |
val allNonAuto: Seq[Def.Setting[_]] = nonAutoPlugins.flatMap { p => | |
p.buildSettings ++ p.globalSettings ++ p.projectSettings | |
} | |
allAuto ++ allNonAuto | |
} | |
// Adapted from BasicCommands.scala | |
private def hijackedShell = Command.command(BasicCommandStrings.Shell) { s => | |
val extracted = Project.extract(s) | |
val nonPluginKeys = BuiltinCommands.allTaskAndSettingKeys(s).map((k: AttributeKey[_]) => k.label).toSet | |
val keys: Iterable[String] = | |
for { | |
unit <- extracted.structure.units.values | |
key <- getAllPluginKeys(unit.unit.plugins.detected) | |
if (!nonPluginKeys.contains(key.key.key.label)) | |
} yield key.key.key.label | |
val parser = token(OpOrID.examples(keys.toSeq: _*)) | |
import BasicKeys._ | |
val history = (s get historyPath) getOrElse Some(new File(s.baseDir, ".history")) | |
val prompt = (s get shellPrompt) match { case Some(pf) => pf(s); case None => "hijacked> " } | |
val reader = new FullReader(history, Command.combine(s.definedCommands)(s) | parser) | |
val line = reader.readLine(prompt) | |
line match { | |
case Some(line) => | |
val newState = s.copy(onFailure = Some(BasicCommandStrings.Shell), remainingCommands = line +: BasicCommandStrings.Shell +: s.remainingCommands).setInteractive(true) | |
if (line.trim.isEmpty) newState else newState.clearGlobalLog | |
case None => s.setInteractive(false) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment