sbt/main/src/test/scala/PluginCommandTest.scala

169 lines
4.9 KiB
Scala

/*
* sbt
* Copyright 2023, Scala center
* Copyright 2011 - 2022, Lightbend, Inc.
* Copyright 2008 - 2010, Mark Harrah
* Licensed under Apache License 2.0 (see LICENSE)
*/
package sbt
import java.io._
import sbt.internal._
import sbt.internal.inc.MappedFileConverter
import sbt.internal.util.{
AttributeEntry,
AttributeMap,
ConsoleOut,
GlobalLogging,
MainAppender,
Terminal,
}
import sbt.internal.inc.PlainVirtualFileConverter
object PluginCommandTestPlugin0 extends AutoPlugin { override def requires = empty }
package subpackage {
object PluginCommandTestPlugin1 extends AutoPlugin { override def requires = empty }
}
object PluginCommandTest extends verify.BasicTestSuite {
import subpackage._
import FakeState._
test("`plugin` command should work for plugins within nested in one package") {
val output = processCommand(
"plugin sbt.PluginCommandTestPlugin0",
PluginCommandTestPlugin0,
PluginCommandTestPlugin1
)
assert(output.contains("sbt.PluginCommandTestPlugin0 is activated."))
}
test("it should work for plugins nested more than one package") {
val output = processCommand(
"plugin sbt.subpackage.PluginCommandTestPlugin1",
PluginCommandTestPlugin0,
PluginCommandTestPlugin1
)
assert(output.contains("sbt.subpackage.PluginCommandTestPlugin1 is activated."))
}
test("it should suggest a plugin when given an incorrect plugin with a similar name") {
val output = processCommand(
"plugin PluginCommandTestPlugin0",
PluginCommandTestPlugin0,
PluginCommandTestPlugin1
)
assert(
output.contains(
"Not a valid plugin: PluginCommandTestPlugin0 (similar: sbt.PluginCommandTestPlugin0, sbt.subpackage.PluginCommandTestPlugin1)"
)
)
}
}
object FakeState {
def processCommand(input: String, enabledPlugins: AutoPlugin*): String = {
val outBuffer = new ByteArrayOutputStream
val logFile = File.createTempFile("sbt", ".log")
try {
val state = FakeState(logFile, enabledPlugins*)
Terminal.withOut(new PrintStream(outBuffer, true)) {
MainLoop.processCommand(Exec(input, None), state)
}
new String(outBuffer.toByteArray)
} finally {
logFile.delete()
()
}
}
def apply(logFile: File, 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: () => 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 (cMap, data: Def.Settings) =
Def.makeWithCompiledMap(settings)(using 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 converter = PlainVirtualFileConverter.converter
val pluginData = PluginData(Nil, converter)
val builds: DetectedModules[BuildDef] = new DetectedModules[BuildDef](Nil)
val detectedAutoPlugins: Seq[DetectedAutoPlugin] =
plugins.map(p => DetectedAutoPlugin(p.label, p, hasAutoImport = false))
val detectedPlugins = new DetectedPlugins(detectedAutoPlugins, builds)
val loadedPlugins =
new LoadedPlugins(base, pluginData, ClassLoader.getSystemClassLoader, detectedPlugins)
val buildUnit = new BuildUnit(base.toURI, base, loadedDefinitions, loadedPlugins, converter)
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,
cMap,
MappedFileConverter.empty,
)
val attributes = AttributeMap.empty ++ AttributeMap(
AttributeEntry(Keys.sessionSettings, sessionSettings),
AttributeEntry(Keys.stateBuildStructure, buildStructure)
)
State(
null,
Seq(BuiltinCommands.plugin),
Set.empty,
None,
List(),
State.newHistory,
attributes,
GlobalLogging.initial(
MainAppender.globalDefault(ConsoleOut.globalProxy),
logFile,
ConsoleOut.globalProxy
),
None,
State.Continue
)
}
}