Skip to content

Commit 63d1351

Browse files
committed
feat: Add command template to source generators
1 parent 9ac4586 commit 63d1351

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

frontend/src/main/scala/bloop/engine/SourceGenerator.scala

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import java.nio.file.FileSystems
44

55
import scala.collection.mutable
66
import scala.util.control.NoStackTrace
7+
import scala.util.matching.Regex
78

89
import bloop.cli.CommonOptions
910
import bloop.config.Config
@@ -21,7 +22,8 @@ final case class SourceGenerator(
2122
sourcesGlobs: List[SourcesGlobs],
2223
outputDirectory: AbsolutePath,
2324
unmangedInputs: List[AbsolutePath],
24-
command: List[String]
25+
command: List[String],
26+
commandTemplate: Option[List[String]]
2527
) {
2628

2729
/**
@@ -66,7 +68,14 @@ final case class SourceGenerator(
6668
logger: Logger,
6769
opts: CommonOptions
6870
): Task[SourceGenerator.Run] = {
69-
val cmd = (command :+ outputDirectory.syntax) ++ inputs.keys.map(_.syntax)
71+
val cmd =
72+
buildCommand(
73+
outputDirectory.syntax,
74+
inputs.keys.map(_.syntax).toSeq,
75+
unmangedInputs.keys.map(_.syntax).toSeq,
76+
logger
77+
)
78+
7079
logger.debug { () =>
7180
cmd.mkString(s"Running source generator:${System.lineSeparator()}$$ ", " ", "")
7281
}
@@ -79,6 +88,28 @@ final case class SourceGenerator(
7988
}
8089
}
8190

91+
private def buildCommand(
92+
outputDirectory: String,
93+
inputs: Seq[String],
94+
unmangedInputs: Seq[String],
95+
logger: Logger
96+
): Seq[String] =
97+
commandTemplate match {
98+
case None =>
99+
(command :+ outputDirectory) ++ inputs
100+
case Some(cmd) =>
101+
val substs = Map[String, Seq[String]](
102+
SourceGenerator.Arg.Output -> Seq(outputDirectory),
103+
SourceGenerator.Arg.Inputs -> inputs,
104+
SourceGenerator.Arg.UnmanagedInputs -> unmangedInputs
105+
).withDefault { name =>
106+
logger.warn(s"Couldn't find substitution for `$name`, consider escaping it with a $$.")
107+
Seq.empty[String]
108+
}
109+
110+
cmd.flatMap(SourceGenerator.Arg.substitute(substs)(_))
111+
}
112+
82113
private def needsUpdate(previous: SourceGenerator.Run): Task[SourceGenerator.Changes] = {
83114
previous match {
84115
case SourceGenerator.NoRun =>
@@ -141,6 +172,33 @@ object SourceGenerator {
141172
unamanagedInputs: Map[AbsolutePath, Int]
142173
) extends Changes
143174

175+
private object Arg {
176+
private val Single: Regex = """((?:\$)+)\{([a-zA-Z]+)\}""".r
177+
private val Anywhere: Regex = Single.unanchored
178+
179+
// TODO: make these configurable in some way?
180+
val Inputs = "inputs"
181+
val Output = "output"
182+
val UnmanagedInputs = "unmanaged"
183+
184+
def substitute(substs: Map[String, Seq[String]])(s: String): Seq[String] =
185+
s match {
186+
case Single("$", name) => substs(name)
187+
case _ =>
188+
Seq(Anywhere.replaceAllIn(s, m => Regex.quoteReplacement(replace(m, substs))))
189+
}
190+
191+
private def replace(mtch: Regex.Match, substs: Map[String, Seq[String]]): String = {
192+
val dollars = mtch.group(1).size
193+
val name = mtch.group(2)
194+
val value =
195+
if (dollars % 2 == 0) s"{$name}"
196+
else substs(name).mkString(" ")
197+
198+
s"${"$" * (dollars / 2)}$value"
199+
}
200+
}
201+
144202
def fromConfig(cwd: AbsolutePath, generator: Config.SourceGenerator): SourceGenerator = {
145203
val sourcesGlobs = generator.sourcesGlobs.map {
146204
case Config.SourcesGlobs(directory, depth, includes, excludes) =>
@@ -159,7 +217,9 @@ object SourceGenerator {
159217
sourcesGlobs,
160218
AbsolutePath(generator.outputDirectory),
161219
generator.unmanagedInputs.map(AbsolutePath.apply),
162-
generator.command
220+
generator.command,
221+
// TODO: change to `generator.commandTemplate` after PR to bloop-config is merged
222+
None
163223
)
164224
}
165225

frontend/src/test/scala/bloop/SourceGeneratorSpec.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import bloop.logging.RecordingLogger
99
import bloop.util.TestProject
1010
import bloop.util.TestUtil
1111

12+
// TODO: add tests after PR to bloop-config is merged
1213
object SourceGeneratorSpec extends bloop.testing.BaseSuite {
1314

1415
val generator = TestUtil.generator

project/Dependencies.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ object Dependencies {
4343
val asmVersion = "9.7.1"
4444
val ztExecVersion = "1.12"
4545
val debugAdapterVersion = "4.2.4"
46+
// TODO: update after PR to bloop-config is merged
4647
val bloopConfigVersion = "2.3.2"
4748
val semanticdbVersion = "4.9.9"
4849
val millVersion = "0.12.7"

0 commit comments

Comments
 (0)