Merge pull request #7304 from eed3si9n/wip/templates

Make sbt new extensible
This commit is contained in:
eugene yokota 2023-06-25 20:07:02 -04:00 committed by GitHub
commit 4b810a63e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 29 additions and 6 deletions

View File

@ -362,6 +362,8 @@ object Defaults extends BuildCommon {
fork :== false, fork :== false,
initialize :== {}, initialize :== {},
templateResolverInfos :== Nil, templateResolverInfos :== Nil,
templateDescriptions :== TemplateCommandUtil.defaultTemplateDescriptions,
templateRunLocal := templateRunLocalInputTask(runLocalTemplate).evaluated,
forcegc :== sys.props forcegc :== sys.props
.get("sbt.task.forcegc") .get("sbt.task.forcegc")
.map(java.lang.Boolean.parseBoolean) .map(java.lang.Boolean.parseBoolean)
@ -2645,6 +2647,19 @@ object Defaults extends BuildCommon {
if (useCoursier.value) CoursierDependencyResolution(csrConfiguration.value) if (useCoursier.value) CoursierDependencyResolution(csrConfiguration.value)
else IvyDependencyResolution(ivyConfiguration.value) else IvyDependencyResolution(ivyConfiguration.value)
} }
def templateRunLocalInputTask(
runLocal: (Seq[String], Logger) => Unit
): Initialize[InputTask[Unit]] =
Def.inputTask {
import Def._
val s = streams.value
val args = spaceDelimited().parsed
runLocal(args, s.log)
}
def runLocalTemplate(arguments: Seq[String], log: Logger): Unit =
TemplateCommandUtil.defaultRunLocalTemplate(arguments.toList, log)
} }
object Classpaths { object Classpaths {

View File

@ -572,6 +572,8 @@ object Keys {
val sbtBinaryVersion = settingKey[String]("Defines the binary compatibility version substring.").withRank(BPlusSetting) val sbtBinaryVersion = settingKey[String]("Defines the binary compatibility version substring.").withRank(BPlusSetting)
val skip = taskKey[Boolean]("For tasks that support it (currently only 'compile', 'update', 'publish' and 'publishLocal'), setting skip to true will force the task to not to do its work. The exact semantics may vary depending on the task.").withRank(BSetting) val skip = taskKey[Boolean]("For tasks that support it (currently only 'compile', 'update', 'publish' and 'publishLocal'), setting skip to true will force the task to not to do its work. The exact semantics may vary depending on the task.").withRank(BSetting)
val templateResolverInfos = settingKey[Seq[TemplateResolverInfo]]("Template resolvers used for 'new'.").withRank(BSetting) val templateResolverInfos = settingKey[Seq[TemplateResolverInfo]]("Template resolvers used for 'new'.").withRank(BSetting)
val templateDescriptions = settingKey[Seq[(String, String)]]("List of templates with description used for 'new' / 'init'.")
val templateRunLocal = inputKey[Unit]("Runs a local template.").withRank(DTask)
val interactionService = taskKey[InteractionService]("Service used to ask for user input through the current user interface(s).").withRank(CTask) val interactionService = taskKey[InteractionService]("Service used to ask for user input through the current user interface(s).").withRank(CTask)
val insideCI = SettingKey[Boolean]("insideCI", "Determines if the sbt is running in a Continuous Integration environment", AMinusSetting) val insideCI = SettingKey[Boolean]("insideCI", "Determines if the sbt is running in a Continuous Integration environment", AMinusSetting)

View File

@ -42,6 +42,7 @@ private[sbt] object TemplateCommandUtil {
val extracted = (Project extract s0) val extracted = (Project extract s0)
val (s1, ivyConf) = extracted.runTask(Keys.ivyConfiguration, s0) val (s1, ivyConf) = extracted.runTask(Keys.ivyConfiguration, s0)
val scalaModuleInfo = extracted.get(Keys.updateSbtClassifiers / Keys.scalaModuleInfo) val scalaModuleInfo = extracted.get(Keys.updateSbtClassifiers / Keys.scalaModuleInfo)
val templateDescriptions = extracted.get(Keys.templateDescriptions)
val args0 = inputArg.toList ++ val args0 = inputArg.toList ++
(s0.remainingCommands match { (s0.remainingCommands match {
case exec :: Nil if exec.commandLine == "shell" => Nil case exec :: Nil if exec.commandLine == "shell" => Nil
@ -53,10 +54,10 @@ private[sbt] object TemplateCommandUtil {
run(infos, args0, s0.configuration, ivyConf, globalBase, scalaModuleInfo, log) run(infos, args0, s0.configuration, ivyConf, globalBase, scalaModuleInfo, log)
terminate terminate
} else { } else {
fortifyArgs() match { fortifyArgs(templateDescriptions.toList) match {
case Nil => terminate case Nil => terminate
case arg :: Nil if arg.endsWith(".local") => case arg :: Nil if arg.endsWith(".local") =>
localRun(arg :: Nil, log) extracted.runInputTask(Keys.templateRunLocal, " " + arg, s0)
reload reload
case args => case args =>
run(infos, args, s0.configuration, ivyConf, globalBase, scalaModuleInfo, log) run(infos, args, s0.configuration, ivyConf, globalBase, scalaModuleInfo, log)
@ -167,7 +168,7 @@ private[sbt] object TemplateCommandUtil {
private lazy val term: ITerminal = ITerminal.get private lazy val term: ITerminal = ITerminal.get
private lazy val isAnsiSupported = term.isAnsiSupported private lazy val isAnsiSupported = term.isAnsiSupported
private lazy val nonMoveLetters = ('a' to 'z').toList diff List('h', 'j', 'k', 'l', 'q') private lazy val nonMoveLetters = ('a' to 'z').toList diff List('h', 'j', 'k', 'l', 'q')
private lazy val templates = List( private[sbt] lazy val defaultTemplateDescriptions = List(
ScalaToolkitSlug -> "Scala Toolkit (beta) by Scala Center and VirtusLab", ScalaToolkitSlug -> "Scala Toolkit (beta) by Scala Center and VirtusLab",
TypelevelToolkitSlug -> "Toolkit to start building Typelevel apps", TypelevelToolkitSlug -> "Toolkit to start building Typelevel apps",
SbtCrossPlatformSlug -> "A cross-JVM/JS/Native project", SbtCrossPlatformSlug -> "A cross-JVM/JS/Native project",
@ -180,10 +181,11 @@ private[sbt] object TemplateCommandUtil {
"spotify/scio.g8" -> "A Scio project", "spotify/scio.g8" -> "A Scio project",
"disneystreaming/smithy4s.g8" -> "A Smithy4s project", "disneystreaming/smithy4s.g8" -> "A Smithy4s project",
) )
private def fortifyArgs(): List[String] = private def fortifyArgs(templates: List[(String, String)]): List[String] =
if (System.console eq null) Nil if (System.console eq null) Nil
else else
ITerminal.withStreams(true, false) { ITerminal.withStreams(true, false) {
assert(templates.size <= 20, "template list cannot have more than 20 items")
val mappingList = templates.zipWithIndex.map { val mappingList = templates.zipWithIndex.map {
case (v, idx) => toLetter(idx) -> v case (v, idx) => toLetter(idx) -> v
} }
@ -262,7 +264,9 @@ private[sbt] object TemplateCommandUtil {
else ans0 else ans0
} }
private def localRun( // This is used by Defaults.runLocalTemplate, which implements
// templateRunLocal input task.
private[sbt] def defaultRunLocalTemplate(
arguments: List[String], arguments: List[String],
log: Logger log: Logger
): Unit = ): Unit =

View File

@ -150,7 +150,9 @@ private[sbt] class TaskProgress(
"console", "console",
"consoleProject", "consoleProject",
"consoleQuick", "consoleQuick",
"state" "state",
"streams",
"streams-manager",
) )
private[this] val hiddenTasks = Set( private[this] val hiddenTasks = Set(
"compileEarly", "compileEarly",