mirror of https://github.com/sbt/sbt.git
Merge pull request #1426 from lpiepiora/fix-plugin-command
Fixes #1416: Plugin command doesn't work
This commit is contained in:
commit
cfe575c39e
|
|
@ -191,6 +191,11 @@ object Act {
|
||||||
def knownIDParser[T](knownKeys: Map[String, T], label: String): Parser[T] =
|
def knownIDParser[T](knownKeys: Map[String, T], label: String): Parser[T] =
|
||||||
token(examplesStrict(ID, knownKeys.keys.toSet, label)) map knownKeys
|
token(examplesStrict(ID, knownKeys.keys.toSet, label)) map knownKeys
|
||||||
|
|
||||||
|
def knownPluginParser[T](knownPlugins: Map[String, T], label: String): Parser[T] = {
|
||||||
|
val pluginLabelParser = rep1sep(ID, '.').map(_.mkString("."))
|
||||||
|
token(examplesStrict(pluginLabelParser, knownPlugins.keys.toSet, label)) map knownPlugins
|
||||||
|
}
|
||||||
|
|
||||||
def projectRef(index: KeyIndex, currentBuild: URI): Parser[ParsedAxis[ResolvedReference]] =
|
def projectRef(index: KeyIndex, currentBuild: URI): Parser[ParsedAxis[ResolvedReference]] =
|
||||||
{
|
{
|
||||||
val global = token(GlobalString ~ '/') ^^^ ParsedGlobal
|
val global = token(GlobalString ~ '/') ^^^ ParsedGlobal
|
||||||
|
|
|
||||||
|
|
@ -378,7 +378,7 @@ object BuiltinCommands {
|
||||||
}
|
}
|
||||||
val pluginParser: State => Parser[AutoPlugin] = s => {
|
val pluginParser: State => Parser[AutoPlugin] = s => {
|
||||||
val autoPlugins: Map[String, AutoPlugin] = PluginsDebug.autoPluginMap(s)
|
val autoPlugins: Map[String, AutoPlugin] = PluginsDebug.autoPluginMap(s)
|
||||||
token(Space) ~> Act.knownIDParser(autoPlugins, "plugin")
|
token(Space) ~> Act.knownPluginParser(autoPlugins, "plugin")
|
||||||
}
|
}
|
||||||
def plugin = Command(PluginCommand)(pluginParser) { (s, plugin) =>
|
def plugin = Command(PluginCommand)(pluginParser) { (s, plugin) =>
|
||||||
val helpString = PluginsDebug.help(plugin, s)
|
val helpString = PluginsDebug.help(plugin, s)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,116 @@
|
||||||
|
package sbt
|
||||||
|
|
||||||
|
import java.io._
|
||||||
|
|
||||||
|
import org.specs2.mutable.Specification
|
||||||
|
|
||||||
|
object PluginCommandTestPlugin0 extends AutoPlugin
|
||||||
|
|
||||||
|
package subpackage {
|
||||||
|
|
||||||
|
object PluginCommandTestPlugin1 extends AutoPlugin
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
object PluginCommandTest extends Specification {
|
||||||
|
sequential
|
||||||
|
|
||||||
|
import subpackage._
|
||||||
|
import FakeState._
|
||||||
|
|
||||||
|
"The `plugin` command" should {
|
||||||
|
|
||||||
|
"should work for plugins within nested in one package" in {
|
||||||
|
val output = processCommand("plugin sbt.PluginCommandTestPlugin0", PluginCommandTestPlugin0, PluginCommandTestPlugin1)
|
||||||
|
output must contain("sbt.PluginCommandTestPlugin0 is activated.")
|
||||||
|
}
|
||||||
|
|
||||||
|
"should work for plugins nested more than one package" in {
|
||||||
|
val output = processCommand("plugin sbt.subpackage.PluginCommandTestPlugin1", PluginCommandTestPlugin0, PluginCommandTestPlugin1)
|
||||||
|
output must contain("sbt.subpackage.PluginCommandTestPlugin1 is activated.")
|
||||||
|
}
|
||||||
|
|
||||||
|
"suggest a plugin when given an incorrect plugin with a similar name" in {
|
||||||
|
val output = processCommand("plugin PluginCommandTestPlugin0", PluginCommandTestPlugin0, PluginCommandTestPlugin1)
|
||||||
|
output must contain(
|
||||||
|
"Not a valid plugin: PluginCommandTestPlugin0 (similar: sbt.PluginCommandTestPlugin0, sbt.subpackage.PluginCommandTestPlugin1)"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
object FakeState {
|
||||||
|
|
||||||
|
def processCommand(input: String, enabledPlugins: AutoPlugin*): String = {
|
||||||
|
val previousOut = System.out
|
||||||
|
val outBuffer = new ByteArrayOutputStream
|
||||||
|
try {
|
||||||
|
System.setOut(new PrintStream(outBuffer, true))
|
||||||
|
val state = FakeState(enabledPlugins: _*)
|
||||||
|
Command.process(input, state)
|
||||||
|
new String(outBuffer.toByteArray)
|
||||||
|
} finally {
|
||||||
|
System.setOut(previousOut)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def apply(plugins: AutoPlugin*) = {
|
||||||
|
|
||||||
|
val base = new File("").getAbsoluteFile
|
||||||
|
val testProject = Project("test-project", base).setAutoPlugins(plugins)
|
||||||
|
|
||||||
|
val settings: Seq[Def.Setting[_]] = Nil
|
||||||
|
|
||||||
|
val currentProject = Map(testProject.base.toURI -> testProject.id)
|
||||||
|
val currentEval: () => sbt.compiler.Eval = () => Load.mkEval(Nil, base, Nil)
|
||||||
|
val sessionSettings = SessionSettings(base.toURI, currentProject, Nil, Map.empty, Nil, currentEval)
|
||||||
|
|
||||||
|
val delegates: (Scope) => Seq[Scope] = _ => Nil
|
||||||
|
val scopeLocal: Def.ScopeLocal = _ => Nil
|
||||||
|
|
||||||
|
val data: Settings[Scope] = Def.make(settings)(delegates, scopeLocal, Def.showFullKey)
|
||||||
|
val extra: KeyIndex => BuildUtil[_] = (keyIndex) => BuildUtil(base.toURI, Map.empty, keyIndex, data)
|
||||||
|
val structureIndex: StructureIndex = Load.structureIndex(data, settings, extra, Map.empty)
|
||||||
|
val streams: (State) => BuildStreams.Streams = null
|
||||||
|
|
||||||
|
val loadedDefinitions: LoadedDefinitions = new LoadedDefinitions(
|
||||||
|
base, Nil, ClassLoader.getSystemClassLoader, Nil, Seq(testProject), Nil
|
||||||
|
)
|
||||||
|
|
||||||
|
val pluginData = PluginData(Nil, Nil, None, None, Nil)
|
||||||
|
val detectedModules: DetectedModules[Plugin] = new DetectedModules(Nil)
|
||||||
|
val builds: DetectedModules[Build] = new DetectedModules[Build](Nil)
|
||||||
|
|
||||||
|
val detectedAutoPlugins: Seq[DetectedAutoPlugin] = plugins.map(p => DetectedAutoPlugin(p.label, p, hasAutoImport = false))
|
||||||
|
val detectedPlugins = new DetectedPlugins(detectedModules, detectedAutoPlugins, builds)
|
||||||
|
val loadedPlugins = new LoadedPlugins(base, pluginData, ClassLoader.getSystemClassLoader, detectedPlugins)
|
||||||
|
val buildUnit = new BuildUnit(base.toURI, base, loadedDefinitions, loadedPlugins)
|
||||||
|
|
||||||
|
val (partBuildUnit: PartBuildUnit, _) = Load.loaded(buildUnit)
|
||||||
|
val loadedBuildUnit = Load.resolveProjects(base.toURI, partBuildUnit, _ => testProject.id)
|
||||||
|
|
||||||
|
val units = Map(base.toURI -> loadedBuildUnit)
|
||||||
|
val buildStructure = new BuildStructure(units, base.toURI, settings, data, structureIndex, streams, delegates, scopeLocal)
|
||||||
|
|
||||||
|
val attributes = AttributeMap.empty ++ AttributeMap(
|
||||||
|
AttributeEntry(Keys.sessionSettings, sessionSettings),
|
||||||
|
AttributeEntry(Keys.stateBuildStructure, buildStructure)
|
||||||
|
)
|
||||||
|
|
||||||
|
State(
|
||||||
|
null,
|
||||||
|
Seq(BuiltinCommands.plugin),
|
||||||
|
Set.empty,
|
||||||
|
None,
|
||||||
|
Seq.empty,
|
||||||
|
State.newHistory,
|
||||||
|
attributes,
|
||||||
|
GlobalLogging.initial(MainLogging.globalDefault(ConsoleOut.systemOut), File.createTempFile("sbt", ".log"), ConsoleOut.systemOut),
|
||||||
|
State.Continue
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue