diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpec.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpec.groovy index 670beb5..ed0d4e3 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpec.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpec.groovy @@ -1,13 +1,13 @@ package com.jessebrault.ssg.buildscript +import com.jessebrault.ssg.buildscript.delegates.BuildDelegate import groovy.transform.EqualsAndHashCode import groovy.transform.NullCheck import groovy.transform.PackageScope import groovy.transform.TupleConstructor @PackageScope -@TupleConstructor(defaults = false) -@NullCheck(includeGenerated = true) +@NullCheck() @EqualsAndHashCode(excludes = 'buildClosure') final class BuildSpec { @@ -29,6 +29,19 @@ final class BuildSpec { final BuildExtension extending final Closure buildClosure + BuildSpec( + String name, + boolean isAbstract, + BuildExtension extending, + @DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST) + Closure buildClosure + ) { + this.name = name + this.isAbstract = isAbstract + this.extending = extending + this.buildClosure = buildClosure + } + @Override String toString() { "BuildSpec(name: ${ this.name }, isAbstract: ${ this.isAbstract }, extending: ${ this.extending })" diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtil.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtil.groovy index 309a148..a246e5f 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtil.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtil.groovy @@ -57,7 +57,7 @@ final class BuildSpecUtil { } def allResults = mapBuildSpecsToResults(specs) def outputDirFunctionResult = reduceResults(allResults, OutputDirFunctions.DEFAULT_MONOID) { acc, r -> - r.getOutputDirFunctionResult(acc, { OutputDirFunctions.DEFAULT_MONOID.zero }) + r.getOutputDirFunctionResult(acc, { acc }) } def siteSpecResult = reduceResults(allResults, SiteSpec.DEFAULT_MONOID) { acc, r -> r.getSiteSpecResult(acc, true, SiteSpec.DEFAULT_MONOID) @@ -77,7 +77,7 @@ final class BuildSpecUtil { } new Build( - specs[0].name, + specs.last().name, outputDirFunctionResult, siteSpecResult, globalsResult, diff --git a/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtilTests.groovy b/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtilTests.groovy new file mode 100644 index 0000000..b870b72 --- /dev/null +++ b/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtilTests.groovy @@ -0,0 +1,49 @@ +package com.jessebrault.ssg.buildscript + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.mockito.Mock +import org.mockito.junit.jupiter.MockitoExtension + +import java.util.function.Function + +import static org.junit.jupiter.api.Assertions.assertEquals + +@ExtendWith(MockitoExtension) +final class BuildSpecUtilTests { + + @Test + void overwrittenOutputDir(@Mock Function spec1OutputDirFunction) { + def spec0 = new BuildSpec('spec0', true, BuildExtension.getEmpty(), { + outputDirFunction = { } + }) + def spec1 = new BuildSpec('spec1', false, BuildExtension.get('spec0'), { + outputDirFunction = spec1OutputDirFunction + }) + def r = BuildSpecUtil.getBuilds([spec0, spec1]) + assertEquals(1, r.size()) + def b0 = r[0] + assertEquals('spec1', b0.name) + assertEquals(spec1OutputDirFunction, b0.outputDirFunction) + } + + @Test + void outputDirManualConcat() { + def spec0 = new BuildSpec('spec0', true, BuildExtension.getEmpty(), { + outputDirFunction = OutputDirFunctions.DEFAULT + }) + def spec1 = new BuildSpec('spec1', false, BuildExtension.get('spec0'), { + outputDirFunction { + it.andThen { + new OutputDir(new File(it.asFile(), 'spec1')) + } + } + }) + def r = BuildSpecUtil.getBuilds([spec0, spec1]) + assertEquals(1, r.size()) + def b0 = r[0] + assertEquals('spec1', b0.name) + assertEquals('spec1/spec1', b0.outputDirFunction.apply(b0).asString()) + } + +} diff --git a/cli/src/main/groovy/com/jessebrault/ssg/AbstractBuildCommand.groovy b/cli/src/main/groovy/com/jessebrault/ssg/AbstractBuildCommand.groovy index 332ebc2..98bcd08 100644 --- a/cli/src/main/groovy/com/jessebrault/ssg/AbstractBuildCommand.groovy +++ b/cli/src/main/groovy/com/jessebrault/ssg/AbstractBuildCommand.groovy @@ -1,6 +1,5 @@ package com.jessebrault.ssg -import com.jessebrault.ssg.buildscript.DefaultBuildScriptConfiguratorFactory import com.jessebrault.ssg.util.Diagnostic import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.Logger @@ -10,12 +9,6 @@ abstract class AbstractBuildCommand extends AbstractSubCommand { private static final Logger logger = LogManager.getLogger(AbstractBuildCommand) - @CommandLine.Option( - names = '--baseDir', - description = 'The base directory for all components.' - ) - File baseDir = new File('.') - @CommandLine.Option( names = ['-s', '--script', '--buildScript'], description = 'The build script file to execute, relative to the baseDir.' @@ -50,12 +43,10 @@ abstract class AbstractBuildCommand extends AbstractSubCommand { logger.traceEntry('requestedBuild: {}', requestedBuild) if (this.staticSiteGenerator == null) { - this.staticSiteGenerator = new BuildScriptBasedStaticSiteGenerator( - [new DefaultBuildScriptConfiguratorFactory(this.baseDir)], - 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.staticSiteGenerator = new CliBasedStaticSiteGenerator( + new File('.'), + this.buildScript, + this.buildSrcDirs, this.scriptArgs ) } diff --git a/cli/src/main/groovy/com/jessebrault/ssg/CliBasedStaticSiteGenerator.groovy b/cli/src/main/groovy/com/jessebrault/ssg/CliBasedStaticSiteGenerator.groovy new file mode 100644 index 0000000..1395b9a --- /dev/null +++ b/cli/src/main/groovy/com/jessebrault/ssg/CliBasedStaticSiteGenerator.groovy @@ -0,0 +1,47 @@ +package com.jessebrault.ssg + +import com.jessebrault.ssg.buildscript.DefaultBuildScriptConfiguratorFactory +import com.jessebrault.ssg.util.Diagnostic +import groovy.transform.PackageScope + +import java.util.function.Consumer + +@PackageScope +final class CliBasedStaticSiteGenerator implements StaticSiteGenerator { + + private final File baseDir + private final File buildScript + private final Collection buildSrcDirs + private final Map scriptArgs + + private StaticSiteGenerator staticSiteGenerator + + CliBasedStaticSiteGenerator( + File baseDir, + File buildScript, + Collection buildSrcDirs, + Map scriptArgs + ) { + this.baseDir = baseDir + this.buildScript = buildScript + this.buildSrcDirs = buildSrcDirs + this.scriptArgs = scriptArgs + } + + @Override + boolean doBuild(String buildName, Consumer> diagnosticsConsumer) { + if (this.staticSiteGenerator == null) { + this.staticSiteGenerator = new BuildScriptBasedStaticSiteGenerator( + [new DefaultBuildScriptConfiguratorFactory(this.baseDir)], + 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.scriptArgs + ) + } + + this.staticSiteGenerator.doBuild(buildName, diagnosticsConsumer) + } + +} diff --git a/cli/src/main/resources/ssgBuilds.groovy b/cli/src/main/resources/ssgBuilds.groovy index 9221535..04592bd 100644 --- a/cli/src/main/resources/ssgBuilds.groovy +++ b/cli/src/main/resources/ssgBuilds.groovy @@ -4,26 +4,19 @@ import groovy.transform.BaseScript import com.jessebrault.ssg.buildscript.BuildScriptBase @BaseScript -BuildScriptBase base +BuildScriptBase b -allBuilds { +abstractBuild(name: 'mySiteAll', extending: 'default') { siteSpec { name = 'My Site' - } - - globals { - greeting = 'Hello from AllBuilds!' + baseUrl = 'https://mysite.com' } } -build('production') { - siteSpec { - baseUrl = 'https://example.com' - } -} +build(name: 'production', extending: 'mySiteAll') { } -build('preview') { - siteSpec { - baseUrl = 'https://example.com/preview' +build(name: 'preview', extending: 'mySiteAll') { + siteSpec { base -> + baseUrl = base.baseUrl + '/preview' // https://mysite.com/preview } } diff --git a/cli/src/test/groovy/com/jessebrault/ssg/CliBasedStaticSiteGeneratorTests.groovy b/cli/src/test/groovy/com/jessebrault/ssg/CliBasedStaticSiteGeneratorTests.groovy new file mode 100644 index 0000000..1f6d4d1 --- /dev/null +++ b/cli/src/test/groovy/com/jessebrault/ssg/CliBasedStaticSiteGeneratorTests.groovy @@ -0,0 +1,44 @@ +package com.jessebrault.ssg + +import com.jessebrault.ssg.util.Diagnostic +import com.jessebrault.ssg.util.ResourceUtil +import org.junit.jupiter.api.Test + +import static org.junit.jupiter.api.Assertions.assertEquals +import static org.junit.jupiter.api.Assertions.assertTrue + +final class CliBasedStaticSiteGeneratorTests { + + @Test + void meatyInitAndBuild() { + def tempDir = File.createTempDir() + SsgInit.init(tempDir, true) + + def ssg = new CliBasedStaticSiteGenerator( + tempDir, + new File('ssgBuilds.groovy'), + [new File('buildSrc')], + [:] + ) + def diagnostics = [] as Collection + assertTrue(ssg.doBuild('production', diagnostics.&addAll)) + assertTrue(diagnostics.empty) + + def buildDir = new File(tempDir, 'production') + assertTrue(buildDir.exists()) + assertTrue(buildDir.directory) + + def textOutputFile = new File(buildDir, 'hello.html') + assertTrue(textOutputFile.exists()) + assertTrue(textOutputFile.file) + def pageOutputFile = new File(buildDir, 'page.html') + assertTrue(pageOutputFile.exists()) + assertTrue(pageOutputFile.file) + + def expectedText = ResourceUtil.loadResourceAsString('hello.html') + def expectedPage = ResourceUtil.loadResourceAsString('page.html') + assertEquals(expectedText, textOutputFile.text) + assertEquals(expectedPage, pageOutputFile.text) + } + +} diff --git a/cli/src/test/groovy/com/jessebrault/ssg/StaticSiteGeneratorCliIntegrationTests.groovy b/cli/src/test/groovy/com/jessebrault/ssg/StaticSiteGeneratorCliIntegrationTests.groovy index 4aa0a1e..71fe827 100644 --- a/cli/src/test/groovy/com/jessebrault/ssg/StaticSiteGeneratorCliIntegrationTests.groovy +++ b/cli/src/test/groovy/com/jessebrault/ssg/StaticSiteGeneratorCliIntegrationTests.groovy @@ -1,44 +1,6 @@ package com.jessebrault.ssg -import com.jessebrault.ssg.util.ResourceUtil -import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Disabled -import static org.junit.jupiter.api.Assertions.assertEquals -import static org.junit.jupiter.api.Assertions.assertTrue - -final class StaticSiteGeneratorCliIntegrationTests { - - @Test - void meatyInitAndBuild() { - def tempDir = File.createTempDir() - SsgInit.init(tempDir, true) - - def ssgBuild = new SsgBuild().tap { - it.cli = new StaticSiteGeneratorCli().tap { - it.logLevel = new StaticSiteGeneratorCli.LogLevel().tap { - it.trace = true - } - } - it.baseDir = tempDir - it.requestedBuilds = ['production'] - } - assertEquals(0, ssgBuild.call()) - - def buildDir = new File(tempDir, 'build') - assertTrue(buildDir.exists()) - assertTrue(buildDir.directory) - - def textOutputFile = new File(buildDir, 'hello.html') - assertTrue(textOutputFile.exists()) - assertTrue(textOutputFile.file) - def pageOutputFile = new File(buildDir, 'page.html') - assertTrue(pageOutputFile.exists()) - assertTrue(pageOutputFile.file) - - def expectedText = ResourceUtil.loadResourceAsString('hello.html') - def expectedPage = ResourceUtil.loadResourceAsString('page.html') - assertEquals(expectedText, textOutputFile.text) - assertEquals(expectedPage, pageOutputFile) - } - -} +@Disabled +final class StaticSiteGeneratorCliIntegrationTests {} diff --git a/cli/src/test/resources/page.html b/cli/src/test/resources/page.html index 168e538..c7cf8c4 100644 --- a/cli/src/test/resources/page.html +++ b/cli/src/test/resources/page.html @@ -5,4 +5,4 @@

Hello, World!

- + \ No newline at end of file