Fixed bugs with gst; now using one GroovyScriptEngine.

This commit is contained in:
JesseBrault0709 2023-06-12 15:53:22 +02:00
parent 2208c9f4c0
commit b741765b24
25 changed files with 153 additions and 103 deletions

View File

@ -8,7 +8,7 @@ repositories {
dependencies {
// https://archiva.jessebrault.com/#artifact/com.jessebrault.gst/lib
implementation 'com.jessebrault.gst:lib:0.0.1'
implementation 'com.jessebrault.gst:lib:0.0.3'
// https://mvnrepository.com/artifact/org.apache.groovy/groovy-templates
implementation 'org.apache.groovy:groovy-templates:4.0.12'

View File

@ -18,24 +18,23 @@ final class BuildScriptBasedStaticSiteGenerator implements StaticSiteGenerator {
private static final Marker enter = MarkerFactory.getMarker('enter')
private static final Marker exit = MarkerFactory.getMarker('exit')
private final GroovyScriptEngine engine
private final Collection<BuildScriptConfiguratorFactory> configuratorFactories
@Nullable
private final File buildScript
private final Collection<File> buildSrcDirs
private final @Nullable File buildScript
private final Map<String, Object> scriptArgs
private final Collection<Build> builds = []
private boolean ranBuildScript = false
BuildScriptBasedStaticSiteGenerator(
GroovyScriptEngine engine,
Collection<BuildScriptConfiguratorFactory> configuratorFactories = [],
@Nullable File buildScript = null,
Collection<File> buildSrcDirs = [],
Map<String, Object> scriptArgs = [:]
) {
this.engine = engine
this.configuratorFactories = configuratorFactories
this.buildScript = buildScript
this.buildSrcDirs = buildSrcDirs
this.scriptArgs = scriptArgs
}
@ -54,13 +53,10 @@ final class BuildScriptBasedStaticSiteGenerator implements StaticSiteGenerator {
logger.info('running buildScript: {}', this.buildScript)
def result = BuildScripts.runBuildScript(
this.buildScript.name,
this.buildScript.parentFile.toURI().toURL(),
this.buildSrcDirs.collect { it.toURI().toURL() },
this.engine,
[args: this.scriptArgs]
) { base ->
this.configuratorFactories.each {
it.get().accept(base)
}
this.configuratorFactories.each { it.get().accept(base) }
}
this.builds.addAll(result)
} else {

View File

@ -31,6 +31,23 @@ final class BuildScripts {
runBase(base)
}
static Collection<Build> runBuildScript(
String scriptName,
GroovyScriptEngine engine,
Map<String, Object> binding = [:],
Consumer<BuildScriptBase> configureBuildScript = { }
) {
engine.config = new CompilerConfiguration().tap {
scriptBaseClass = 'com.jessebrault.ssg.buildscript.BuildScriptBase'
}
def base = engine.createScript(scriptName, new Binding(binding))
assert base instanceof BuildScriptBase
configureBuildScript.accept(base)
runBase(base)
}
@Deprecated
static Collection<Build> runBuildScript(
String scriptName,
URL scriptBaseDirUrl,
@ -50,6 +67,7 @@ final class BuildScripts {
runBase(base)
}
@Deprecated
static Collection<Build> runBuildScript(
String scriptName,
URL scriptBaseDirUrl,
@ -59,6 +77,7 @@ final class BuildScripts {
runBuildScript(scriptName, scriptBaseDirUrl, otherUrls, binding) { }
}
@Deprecated
static Collection<Build> runBuildScript(
String scriptName,
URL scriptBaseDirUrl,
@ -67,6 +86,7 @@ final class BuildScripts {
runBuildScript(scriptName, scriptBaseDirUrl, otherUrls, [:]) { }
}
@Deprecated
static Collection<Build> runBuildScript(
String scriptName,
URL scriptBaseDirUrl

View File

@ -23,8 +23,8 @@ import java.util.function.Consumer
final class DefaultBuildScriptConfiguratorFactory implements BuildScriptConfiguratorFactory {
private final File baseDir
private final ClassLoader classLoader
private final Collection<URL> scriptBaseUrls
private final File tmpDir
private final GroovyScriptEngine engine
@Override
Consumer<BuildScriptBase> get() {
@ -36,9 +36,9 @@ final class DefaultBuildScriptConfiguratorFactory implements BuildScriptConfigur
types {
textTypes << TextTypes.MARKDOWN
pageTypes << PageTypes.getGsp(['.gsp', '.ssg.gst'], this.classLoader, this.scriptBaseUrls)
templateTypes << TemplateTypes.getGsp(['.gsp', '.ssg.gst'], this.classLoader, this.scriptBaseUrls)
partTypes << PartTypes.getGsp(['.gsp', '.ssg.gst'], this.classLoader, this.scriptBaseUrls)
pageTypes << PageTypes.getGsp(['.gsp', '.ssg.gst'], this.tmpDir, this.engine)
templateTypes << TemplateTypes.getGsp(['.gsp', '.ssg.gst'], this.tmpDir, this.engine)
partTypes << PartTypes.getGsp(['.gsp', '.ssg.gst'], this.tmpDir, this.engine)
}
sources { base, types ->

View File

@ -13,8 +13,8 @@ final class GspPageRenderer implements PageRenderer {
private final StandardGspRenderer gspRenderer
GspPageRenderer(ClassLoader classLoader, Collection<URL> urls) {
this.gspRenderer = new StandardGspRenderer(classLoader, urls)
GspPageRenderer(File tmpDir, GroovyScriptEngine engine) {
this.gspRenderer = new StandardGspRenderer(tmpDir, engine)
}
@Override

View File

@ -2,11 +2,8 @@ package com.jessebrault.ssg.page
final class PageTypes {
@Deprecated
static final PageType GSP = new PageType(['.gsp'], new GspPageRenderer(PageTypes.classLoader, []))
static PageType getGsp(Collection<String> extensions, ClassLoader classLoader, Collection<URL> urls) {
new PageType(extensions, new GspPageRenderer(classLoader, urls))
static PageType getGsp(Collection<String> extensions, File tmpDir, GroovyScriptEngine engine) {
new PageType(extensions, new GspPageRenderer(tmpDir, engine))
}
private PageTypes() {}

View File

@ -15,8 +15,8 @@ final class GspPartRenderer implements PartRenderer {
private final StandardGspRenderer gspRenderer
GspPartRenderer(ClassLoader classLoader, Collection<URL> urls) {
this.gspRenderer = new StandardGspRenderer(classLoader, urls)
GspPartRenderer(File tmpDir, GroovyScriptEngine engine) {
this.gspRenderer = new StandardGspRenderer(tmpDir, engine)
}
@Override

View File

@ -2,11 +2,8 @@ package com.jessebrault.ssg.part
final class PartTypes {
@Deprecated
static final PartType GSP = new PartType(['.gsp'], new GspPartRenderer(PartTypes.classLoader, []))
static PartType getGsp(Collection<String> extensions, ClassLoader classLoader, Collection<URL> scriptBaseUrls) {
new PartType(extensions, new GspPartRenderer(classLoader, scriptBaseUrls))
static PartType getGsp(Collection<String> extensions, File tmpDir, GroovyScriptEngine engine) {
new PartType(extensions, new GspPartRenderer(tmpDir, engine))
}
private PartTypes() {}

View File

@ -13,8 +13,8 @@ final class StandardGspRenderer {
private final TemplateCreator templateCreator
StandardGspRenderer(ClassLoader parentClassLoader, Collection<URL> urls) {
this.templateCreator = new GroovyTemplateCreator(ExtendedGstParser::new, urls, parentClassLoader, true)
StandardGspRenderer(File tmpDir, GroovyScriptEngine engine) {
this.templateCreator = new GroovyTemplateCreator(ExtendedGstParser::new, tmpDir, engine, true)
}
Result<String> render(

View File

@ -14,8 +14,8 @@ final class GspTemplateRenderer implements TemplateRenderer {
private final StandardGspRenderer gspRenderer
GspTemplateRenderer(ClassLoader parentClassLoader, Collection<URL> urls) {
this.gspRenderer = new StandardGspRenderer(parentClassLoader, urls)
GspTemplateRenderer(File tmpDir, GroovyScriptEngine engine) {
this.gspRenderer = new StandardGspRenderer(tmpDir, engine)
}
@Override

View File

@ -2,15 +2,8 @@ package com.jessebrault.ssg.template
final class TemplateTypes {
@Deprecated
static final TemplateType GSP = new TemplateType(['.gsp'], new GspTemplateRenderer(TemplateTypes.classLoader, []))
static TemplateType getGsp(
Collection<String> extensions,
ClassLoader classLoader,
Collection<URL> scriptBaseUrls
) {
new TemplateType(extensions, new GspTemplateRenderer(classLoader, scriptBaseUrls))
static TemplateType getGsp(Collection<String> extensions, File tmpDir, GroovyScriptEngine engine) {
new TemplateType(extensions, new GspTemplateRenderer(tmpDir, engine))
}
private TemplateTypes() {}

View File

@ -32,19 +32,16 @@ final class BuildScriptBasedStaticSiteGeneratorTests {
}
}
def ssg = new BuildScriptBasedStaticSiteGenerator(
[new BuildScriptConfiguratorFactory() {
def tmpDir = File.createTempDir()
def engine = new GroovyScriptEngine([sourceDir.toURI().toURL(), tmpDir.toURI().toURL()] as URL[])
def ssg = new BuildScriptBasedStaticSiteGenerator(engine, [new BuildScriptConfiguratorFactory() {
@Override
Consumer<BuildScriptBase> get() {
return { }
}
@Override
Consumer<BuildScriptBase> get() {
return { }
}
}],
buildScript,
[],
[sourceDir: sourceDir]
)
}], buildScript, [sourceDir: sourceDir, tmpDir: tmpDir, engine: engine])
assertTrue(ssg.doBuild('test') {
it.each { logger.error(it.toString()) }
})

View File

@ -48,10 +48,19 @@ final class BuildScriptsTests {
tempDir
}
private static Collection<Build> getBuilds(
String scriptName,
Collection<URL> urls,
Map<String, Object> binding = [:],
Consumer<BuildScriptBase> configureBase = { }
) {
runBuildScript(scriptName, new GroovyScriptEngine(urls as URL[]), binding, configureBase)
}
@Test
void simpleScript() {
def baseDir = this.setupScripts(['simple.groovy'])
def builds = runBuildScript('simple.groovy', baseDir.toURI().toURL())
def builds = getBuilds('simple.groovy', [baseDir.toURI().toURL()])
assertEquals(1, builds.size())
assertEquals('test', builds[0].name)
}
@ -59,7 +68,7 @@ final class BuildScriptsTests {
@Test
void testImport() {
def baseDir = this.setupScripts(['testImport.groovy', 'TestHtmlTask.groovy'])
def builds = runBuildScript('testImport.groovy', baseDir.toURI().toURL())
def builds = getBuilds('testImport.groovy', [baseDir.toURI().toURL()])
assertEquals(1, builds.size())
assertEquals('test', builds[0].name)
}
@ -77,10 +86,12 @@ final class BuildScriptsTests {
}
}
}
def builds = runBuildScript(
def builds = getBuilds(
'buildSrcTest.groovy',
baseDir.toURI().toURL(),
[new File(baseDir, 'buildSrc').toURI().toURL()]
[
baseDir.toURI().toURL(),
new File(baseDir, 'buildSrc').toURI().toURL()
]
)
assertEquals(1, builds.size())
assertEquals('test', builds[0].name)
@ -89,12 +100,8 @@ final class BuildScriptsTests {
@Test
void withBinding(@Mock Consumer<String> stringConsumer) {
def baseDir = this.setupScripts(['withBinding.groovy'])
runBuildScript(
'withBinding.groovy',
baseDir.toURI().toURL(),
[],
[stringConsumer: stringConsumer]
)
def engine = new GroovyScriptEngine([baseDir.toURI().toURL()] as URL[])
runBuildScript('withBinding.groovy', engine, [stringConsumer: stringConsumer])
verify(stringConsumer).accept('test')
}

View File

@ -6,8 +6,13 @@ import com.jessebrault.ssg.util.Result
final class GspPageRendererTests implements StandardDslConsumerTests {
private static GspPageRenderer getRenderer(ClassLoader classLoader, Collection<URL> urls) {
new GspPageRenderer(classLoader, urls)
private static GspPageRenderer getRenderer(
ClassLoader classLoader,
Collection<URL> urls
) {
def tmpDir = File.createTempDir()
def engine = new GroovyScriptEngine([tmpDir.toURI().toURL(), *urls] as URL[], classLoader)
new GspPageRenderer(tmpDir, engine)
}
@Override

View File

@ -15,10 +15,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue
final class GspPartRendererTests implements StandardDslConsumerTests {
private static GspPartRenderer getRenderer(
ClassLoader classLoader = GspPartRendererTests.classLoader,
ClassLoader parentClassLoader = GspPartRendererTests.classLoader,
Collection<URL> urls = []
) {
new GspPartRenderer(classLoader, urls)
def tmpDir = File.createTempDir()
def engine = new GroovyScriptEngine([tmpDir.toURI().toURL(), *urls] as URL[], parentClassLoader)
new GspPartRenderer(tmpDir, engine)
}
private static Result<String> doRender(

View File

@ -14,10 +14,12 @@ import static org.junit.jupiter.api.Assertions.assertEquals
final class GspTemplateRendererTests implements StandardDslConsumerTests {
private static TemplateRenderer getRenderer(
ClassLoader classLoader = GspTemplateRendererTests.classLoader,
ClassLoader parentLoader = GspTemplateRendererTests.class.classLoader,
Collection<URL> urls = []
) {
new GspTemplateRenderer(classLoader, urls)
def tmpDir = File.createTempDir()
def engine = new GroovyScriptEngine([tmpDir.toURI().toURL(), *urls] as URL[], parentLoader)
new GspTemplateRenderer(tmpDir, engine)
}
private static Result<String> doRender(

View File

@ -1,3 +1,4 @@
//file:noinspection
def t = new AnotherTask()
build(name: 'test') { }

View File

@ -14,6 +14,8 @@ BuildScriptBase b
final class Args {
File sourceDir
File tmpDir
GroovyScriptEngine engine
}
def args = args as Args
@ -23,7 +25,7 @@ build(name: 'test') {
types {
textTypes << TextTypes.MARKDOWN
templateTypes << TemplateTypes.GSP
templateTypes << TemplateTypes.getGsp(['.gsp'], args.tmpDir, args.engine)
}
sources { base, types ->

View File

@ -39,17 +39,16 @@ abstract class AbstractBuildCommand extends AbstractSubCommand {
protected StaticSiteGenerator staticSiteGenerator = null
protected final Integer doSingleBuild(String requestedBuild) {
protected final Integer doSingleBuild(String requestedBuild, File tmpDir, GroovyScriptEngine engine) {
logger.traceEntry('requestedBuild: {}', requestedBuild)
if (this.staticSiteGenerator == null) {
this.staticSiteGenerator = new CliBasedStaticSiteGenerator(
new File('.'),
this.buildScript,
this.buildSrcDirs,
this.scriptArgs,
this.class.classLoader,
this.buildSrcDirs.collect { it.toURI().toURL() }
tmpDir,
engine,
this.scriptArgs
)
}

View File

@ -11,38 +11,33 @@ final class CliBasedStaticSiteGenerator implements StaticSiteGenerator {
private final File baseDir
private final File buildScript
private final Collection<File> buildSrcDirs
private final File tmpDir
private final Map<String, String> scriptArgs
private final ClassLoader classLoader
private final Collection<URL> scriptBaseUrls
private final GroovyScriptEngine engine
private StaticSiteGenerator staticSiteGenerator
CliBasedStaticSiteGenerator(
File baseDir,
File buildScript,
Collection<File> buildSrcDirs,
Map<String, String> scriptArgs,
ClassLoader classLoader,
Collection<URL> scriptBaseUrls
File tmpDir,
GroovyScriptEngine engine,
Map<String, String> scriptArgs
) {
this.baseDir = baseDir
this.buildScript = buildScript
this.buildSrcDirs = buildSrcDirs
this.tmpDir = tmpDir
this.scriptArgs = scriptArgs
this.classLoader = classLoader
this.scriptBaseUrls = scriptBaseUrls
this.engine = engine
}
@Override
boolean doBuild(String buildName, Consumer<Collection<Diagnostic>> diagnosticsConsumer) {
if (this.staticSiteGenerator == null) {
this.staticSiteGenerator = new BuildScriptBasedStaticSiteGenerator(
[new DefaultBuildScriptConfiguratorFactory(this.baseDir, this.classLoader, this.scriptBaseUrls)],
this.buildScript == new File('ssgBuilds.groovy') || this.buildScript.exists()
? new File(this.baseDir, this.buildScript.path)
: null,
this.buildSrcDirs.collect { new File(this.baseDir, it.path) },
this.engine,
[new DefaultBuildScriptConfiguratorFactory(this.baseDir, this.tmpDir, this.engine)],
this.buildScript,
this.scriptArgs
)
}

View File

@ -17,8 +17,13 @@ final class SsgBuild extends AbstractBuildCommand {
protected Integer doSubCommand() {
logger.traceEntry()
def result = 0
def tmpDir = File.createTempDir()
def urls = [tmpDir, *this.buildSrcDirs, new File('.')].collect {
it.toURI().toURL()
} as URL[]
def engine = new GroovyScriptEngine(urls)
this.requestedBuilds.each {
def buildResult = this.doSingleBuild(it)
def buildResult = this.doSingleBuild(it, tmpDir, engine)
if (buildResult == 1) {
result = 1
}

View File

@ -1,5 +1,6 @@
<html>
<%
println "delegate.text: $delegate.text"
out << parts['head.gsp'].render([
title: "${ siteSpec.name }: ${ text.frontMatter.title }"
])

View File

@ -13,5 +13,8 @@
<Root level="warn">
<AppenderRef ref="standard" />
</Root>
<Logger name="com.jessebrault.fsm" level="OFF" />
<Logger name="com.jessebrault.gst" level="OFF" />
<Logger name="com.jessebrault.gst.groovy.GroovyTemplateCreator" level="trace" />
</Loggers>
</Configuration>

View File

@ -11,22 +11,30 @@ final class CliBasedStaticSiteGeneratorTests {
@Test
void meatyInitAndBuild() {
def tempDir = File.createTempDir()
SsgInit.init(tempDir, true)
def baseDir = File.createTempDir()
SsgInit.init(baseDir, true)
def tmpDir = File.createTempDir()
def engine = new GroovyScriptEngine([
new File(baseDir, 'buildSrc').toURI().toURL(),
tmpDir.toURI().toURL()
] as URL[])
def ssg = new CliBasedStaticSiteGenerator(
tempDir,
new File('ssgBuilds.groovy'),
[new File('buildSrc')],
[:],
this.class.classLoader,
[new File(tempDir, 'buildSrc').toURI().toURL()]
baseDir,
new File(baseDir, 'ssgBuilds.groovy'),
tmpDir,
engine,
[:]
)
def diagnostics = [] as Collection<Diagnostic>
assertTrue(ssg.doBuild('production', diagnostics.&addAll))
assertTrue(ssg.doBuild('production', diagnostics.&addAll), {
diagnostics.inject('') { acc, diagnostic ->
acc + '\n' + diagnostic.message
}
})
assertTrue(diagnostics.empty)
def buildDir = new File(tempDir, 'production')
def buildDir = new File(baseDir, 'production')
assertTrue(buildDir.exists())
assertTrue(buildDir.directory)

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Configuration name="ssg" status="WARN">
<Appenders>
<Console name="standard" target="SYSTEM_OUT">
<PatternLayout>
<MarkerPatternSelector defaultPattern="%highlight{%-5level} %logger{1}: %msg%n%ex">
<PatternMatch key="FLOW" pattern="%highlight{%-5level} %logger{1}: %markerSimpleName %msg%n%ex" />
</MarkerPatternSelector>
</PatternLayout>
</Console>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="standard" />
</Root>
<Logger name="com.jessebrault.fsm" level="OFF" />
<Logger name="com.jessebrault.gst" level="OFF" />
<Logger name="com.jessebrault.gst.groovy.GroovyTemplateCreator" level="trace" />
</Loggers>
</Configuration>