bloop
bloop copied to clipboard
feat: Add command template to source generators
This PR is an attempt to provide a more flexible configuration for source generator commands through templating.
It should be fully backward compatible with existing source generator configurations.
Implementation Details
- Support for the following template variables:
${inputs},${output}, and${unmanaged} - Variables as standalone arguments expand into multiple arguments (e.g.
${inputs}->"test1.in""test2.in") - Variables within arguments are joined (e.g.
prefix${inputs}suffix->"prefixtest1.in test2.insuffix") - Unknown variables expand to empty strings with a warning message, this behaviour allows for future extension of the variable set
- Double dollar signs escape template variables (e.g.
$${inputs}->"${inputs}")
This should come in handy for https://github.com/VirtusLab/scala-cli/pull/3583 to eliminate the need for "wrappers" that only reorder the arguments.
Thanks for the contribution! Do you have an example of how would a template look like?
Thanks for the contribution! Do you have an example of how would a template look like?
Hi! For example, if we have a Config.SourceGenerator like this (some types are simplified for the sake of readability):
Configuration
SourceGenerator(
sourcesGlobs = SourcesGlobs(
directory = "/path/to/input",
walkDepth = None,
includes = "glob:*.in",
excludes = Nil
),
outputDirectory = "/path/to/output",
command = Nil,
commandTemplate = List(
"python3",
"-c",
"import sys; print(*sys.argv[1:], sep=\"\\n\")",
"${inputs}",
"$${inputs}",
"pref${inputs}suf",
"smth",
"${unmanaged}",
"pref${unmanaged}suf",
"${nonexistent}",
"$$${output}"
)
)
The command would be expanded into:
Command
Seq(
"python3",
"-c",
"import sys; print(*sys.argv[1:], sep=\"\\n\")",
"/path/to/input/test1.in",
"/path/to/input/test2.in",
"${inputs}",
"pref/path/to/input/test1.in /path/to/input/test2.insuf",
"smth",
"prefsuf",
"$/path/to/output"
)
Which, when run, would output (line numbers added for reference):
Output
1 | Warning: Couldn't find substitution for `nonexistent`, consider escaping it with a $.
2 | /path/to/input/test1.in
3 | /path/to/input/test2.in
4 | ${inputs}
5 | pref/path/to/input/test1.in /path/to/input/test2.insuf
6 | smth
7 | prefsuf
8 | $/path/to/output
Let's go through each line:
-
${inputs}expands to three separate arguments (lines 2-3) -
$${inputs}expands to${inputs}(line 4) -
pref${inputs}sufexpands to one argument (line 5) -
smthis not interpreted in any way and is passed as is (line 6) -
${unmanaged}expands to an empty list of arguments because it'sNil -
pref${unmanaged}sufexpands to one argumentprefsuf(line 7) -
${nonexistent}expands to an empty list of arguments too, but also prints a warning because there's no such variable (line 1) -
$$${output}expands to one argument containing$at the beginning (line 8)
Please let me know if you have any further questions.