diff --git a/api/src/main/groovy/com/jessebrault/ssg/BuildScriptBasedStaticSiteGenerator.groovy b/api/src/main/groovy/com/jessebrault/ssg/BuildScriptBasedStaticSiteGenerator.groovy index 639185d..0129973 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/BuildScriptBasedStaticSiteGenerator.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/BuildScriptBasedStaticSiteGenerator.groovy @@ -2,8 +2,7 @@ package com.jessebrault.ssg import com.jessebrault.ssg.buildscript.Build import com.jessebrault.ssg.buildscript.BuildScriptConfiguratorFactory -import com.jessebrault.ssg.buildscript.BuildScriptRunner -import com.jessebrault.ssg.buildscript.BuildUtil +import com.jessebrault.ssg.buildscript.FileBuildScriptGetter import com.jessebrault.ssg.util.Diagnostic import groovy.transform.EqualsAndHashCode import groovy.transform.NullCheck @@ -50,7 +49,7 @@ final class BuildScriptBasedStaticSiteGenerator implements StaticSiteGenerator { if (this.buildScript == null) { logger.info('no specified build script; using defaults') - def result = BuildScriptRunner.runClosureScript { base -> + def result = FileBuildScriptGetter.runClosureScript { base -> configuratorFactories.each { it.get().accept(base) } @@ -58,9 +57,9 @@ final class BuildScriptBasedStaticSiteGenerator implements StaticSiteGenerator { this.builds.addAll(result) } else if (this.buildScript.exists() && this.buildScript.isFile()) { logger.info('running buildScript: {}', this.buildScript) - def buildScriptRunner = new BuildScriptRunner(this.buildScriptClassLoaderUrls) + def buildScriptRunner = new FileBuildScriptGetter(this.buildScriptClassLoaderUrls) this.buildScriptClassLoader = buildScriptRunner.getBuildScriptClassLoader() - def result = buildScriptRunner.runBuildScript( + def result = buildScriptRunner.getBuildInfo( this.buildScript.name, [args: buildScriptArgs] ) { base -> diff --git a/api/src/main/groovy/com/jessebrault/ssg/SiteSpec.groovy b/api/src/main/groovy/com/jessebrault/ssg/SiteSpec.groovy index 0e0c12b..04c068d 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/SiteSpec.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/SiteSpec.groovy @@ -27,10 +27,6 @@ final class SiteSpec { final String name final String baseUrl - SiteSpec plus(SiteSpec other) { - concat(this, other) - } - @Override String toString() { "SiteSpec(${ this.name }, ${ this.baseUrl })" diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/Build.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/Build.groovy index fbd8d2c..4029737 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/Build.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/Build.groovy @@ -1,66 +1,44 @@ package com.jessebrault.ssg.buildscript -import com.jessebrault.ssg.SiteSpec -import com.jessebrault.ssg.task.TaskFactory -import com.jessebrault.ssg.task.TaskFactorySpec +import com.jessebrault.ssg.model.Model import groovy.transform.EqualsAndHashCode import groovy.transform.NullCheck -import groovy.transform.TupleConstructor +import groowt.util.fp.property.Property +import groowt.util.fp.provider.NamedProvider +import groowt.util.fp.provider.NamedSetProvider +import groowt.util.fp.provider.Provider +import groowt.util.fp.provider.SetProvider -import java.util.function.Function +import static java.util.Objects.requireNonNull -@TupleConstructor(defaults = false) @NullCheck(includeGenerated = true) @EqualsAndHashCode final class Build { - static Build getEmpty() { - new Build( - '', - OutputDirFunctions.DEFAULT, - SiteSpec.getBlank(), - [:], - [], - [] - ) - } - - static Build get(Map args) { - new Build( - args.name as String ?: '', - args.outputDirFunction as Function ?: OutputDirFunctions.DEFAULT, - args.siteSpec as SiteSpec ?: SiteSpec.getBlank(), - args.globals as Map ?: [:], - args.taskFactorySpecs as Collection> ?: [], - args.includedBuilds as Collection ?: [] - ) - } - - static Build concat(Build b0, Build b1) { - new Build( - b0.name.blank ? b1.name : b0.name, - OutputDirFunctions.concat(b0.outputDirFunction, b1.outputDirFunction), - SiteSpec.concat(b0.siteSpec, b1.siteSpec), - b0.globals + b1.globals, - b0.taskFactorySpecs + b1.taskFactorySpecs, - b0.includedBuilds + b1.includedBuilds - ) - } - - final String name - final Function outputDirFunction - final SiteSpec siteSpec - final Map globals - final Collection> taskFactorySpecs final Collection includedBuilds + final Property name + final Property siteName + final Property baseUrl + final Provider outputDir + final Provider> globals + final Set> textsDirs + final Set> models - Build plus(Build other) { - concat(this, other) + @SuppressWarnings('GroovyAssignabilityCheck') + Build(Map args) { + this.includedBuilds = requireNonNull(args.includedBuilds) + this.name = requireNonNull(args.name) + this.siteName = requireNonNull(args.siteName) + this.baseUrl = requireNonNull(args.baseUrl) + this.outputDir = requireNonNull(args.outputDir) + this.globals = requireNonNull(args.globals) + this.textsDirs = requireNonNull(args.textsDirs) + this.models = requireNonNull(args.models) } @Override String toString() { - "Build(name: ${ this.name }, siteSpec: ${ this.siteSpec }, globals: ${ this.globals }, includedBuilds: ${ this.includedBuilds })" + "Build(name: ${ this.name })" } } diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildDelegateToBuildConverter.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildDelegateToBuildConverter.groovy new file mode 100644 index 0000000..0e4e2b8 --- /dev/null +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildDelegateToBuildConverter.groovy @@ -0,0 +1,51 @@ +package com.jessebrault.ssg.buildscript + +import com.jessebrault.ssg.buildscript.delegates.BuildDelegate +import groovy.transform.NullCheck +import groovy.transform.TupleConstructor + +@NullCheck +@TupleConstructor(includeFields = true) +class BuildDelegateToBuildConverter { + + protected Build getFromDelegate(String name, BuildDelegate delegate) { + new Build( + name: name, + siteName: delegate.siteName, + baseUrl: delegate.baseUrl, + outputDir: delegate.outputDir, + globals: delegate.globals, + models: delegate.models + ) + } + + protected void getFromBuild(Build source) { + new BuildDelegate().tap { + siteName(source.siteName) + baseUrl(source.siteName) + outputDir(source.outputDir) + globals.set(source.globals) + textsDirs(source.textsDirs) + models(source.models) + } + } + + private final FileBuildScriptGetter buildScriptGetter + private final File buildScriptsDir + + Build convert(String name, BuildScriptBase buildScript) { + final BuildDelegate delegate + if (buildScript.extending != null) { + def extendingFrom = buildScriptGetter.getBuildInfo(buildScript.extending) + def build = this.convert(buildScript.extending, extendingFrom) + delegate = this.getFromBuild(build) + } else { + delegate = new BuildDelegate() + } + def cl = buildScript.buildClosure + cl.delegate = delegate + cl() + this.getFromDelegate(name, delegate) + } + +} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraph.java b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraph.java deleted file mode 100644 index 0acf1d5..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraph.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.jessebrault.ssg.buildscript; - -import com.jessebrault.ssg.util.Monoid; -import org.jgrapht.Graph; -import org.jgrapht.graph.DefaultEdge; -import org.jgrapht.graph.DirectedAcyclicGraph; - -import java.util.Collection; -import java.util.List; -import java.util.function.BiFunction; - -public final class BuildGraph { - - private static void addAncestorEdges( - Graph graph, - BuildSpec buildSpec, - Collection allBuildSpecs - ) { - if (!graph.containsVertex(buildSpec)) { - throw new IllegalStateException("Given buildSpec " + buildSpec.getName() + " is not in the given graph."); - } - for (final var extendingName : buildSpec.getExtending()) { - final var ancestor = allBuildSpecs.stream() - .filter(bs -> extendingName.equals(bs.getName())) - .findAny() - .orElseThrow(() -> new IllegalStateException( - "Could not find ancestor " + extendingName + " for buildSpec " + buildSpec.getName() + "." - )); - graph.addEdge(ancestor, buildSpec); - addAncestorEdges(graph, ancestor, allBuildSpecs); - } - } - - private final Graph graph; - - public BuildGraph(Collection buildSpecs) { - this.graph = new DirectedAcyclicGraph<>(DefaultEdge.class); - for (final var buildSpec : buildSpecs) { - if (!this.graph.containsVertex(buildSpec)) { - this.graph.addVertex(buildSpec); - } - addAncestorEdges(this.graph, buildSpec, buildSpecs); - } - } - - public List getParents(BuildSpec start) { - return this.graph.incomingEdgesOf(start).stream() - .map(this.graph::getEdgeSource) - .toList(); - } - - @Deprecated(forRemoval = true) - public BuildIntermediate toIntermediate( - BuildSpec rootSpec, - Monoid buildIntermediateMonoid, - BiFunction parentAndSpecToIntermediate - ) { - final List parents = this.getParents(rootSpec); - if (parents.size() == 0) { - return parentAndSpecToIntermediate.apply(buildIntermediateMonoid.getZero(), rootSpec); - } else { - final List parentIntermediates = parents.stream() - .map(parent -> this.toIntermediate(parent, buildIntermediateMonoid, parentAndSpecToIntermediate)) - .toList(); - final BuildIntermediate parentsReduced = parentIntermediates.stream() - .reduce(buildIntermediateMonoid.getZero(), (bi0, bi1) -> - buildIntermediateMonoid.getConcat().apply(bi0, bi1) - ); - return parentAndSpecToIntermediate.apply(parentsReduced, rootSpec); - } - } - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildIntermediate.java b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildIntermediate.java deleted file mode 100644 index cbb1ae1..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildIntermediate.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.jessebrault.ssg.buildscript; - -import com.jessebrault.ssg.SiteSpec; -import com.jessebrault.ssg.task.TaskFactory; -import com.jessebrault.ssg.task.TaskFactorySpec; - -import java.util.Collection; -import java.util.Map; -import java.util.function.Function; - -public interface BuildIntermediate { - BuildSpec getBuildSpec(); - Function getOutputDirFunction(); - SiteSpec getSiteSpec(); - Map getGlobals(); - TypesContainer getTypes(); - SourceProviders getSources(); - Collection> getTaskFactorySpecs(); - Collection getIncludedBuilds(); -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildMonoids.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildMonoids.groovy deleted file mode 100644 index df933fe..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildMonoids.groovy +++ /dev/null @@ -1,48 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import com.jessebrault.ssg.SiteSpec -import com.jessebrault.ssg.task.TaskFactory -import com.jessebrault.ssg.task.TaskFactorySpec -import com.jessebrault.ssg.util.Monoid -import com.jessebrault.ssg.util.Monoids - -import java.util.function.Function - -final class BuildMonoids { - - static final Monoid> outputDirFunctionMonoid = OutputDirFunctions.DEFAULT_MONOID - static final Monoid siteSpecMonoid = SiteSpec.DEFAULT_MONOID - static final Monoid> globalsMonoid = Monoids.getMapMonoid() - static final Monoid typesMonoid = TypesContainer.DEFAULT_MONOID - static final Monoid sourcesMonoid = SourceProviders.DEFAULT_MONOID - - static final Monoid>> taskFactoriesMonoid = - Monoids.getMergeCollectionMonoid( - TaskFactorySpec.SAME_NAME_AND_SUPPLIER_EQ, - TaskFactorySpec.DEFAULT_SEMIGROUP - ) - - static final Monoid> includedBuildsMonoid = Monoids.getCollectionMonoid() - - static Monoid buildIntermediateMonoid = Monoids.of(SyntheticBuildIntermediate.getEmpty()) - { bi0, bi1 -> - new SyntheticBuildIntermediate( - BuildSpec.get( - name: "SyntheticBuildSpec(${ bi0.buildSpec.name }, ${ bi1.buildSpec.name })", - isAbstract: true, - extending: [], - buildClosure: { } - ), - outputDirFunctionMonoid.concat.apply(bi0.outputDirFunction, bi1.outputDirFunction), - siteSpecMonoid.concat.apply(bi0.siteSpec, bi1.siteSpec), - globalsMonoid.concat.apply(bi0.globals, bi1.globals), - typesMonoid.concat.apply(bi0.types, bi1.types), - sourcesMonoid.concat.apply(bi0.sources, bi1.sources), - taskFactoriesMonoid.concat.apply(bi0.taskFactorySpecs, bi1.taskFactorySpecs), - includedBuildsMonoid.concat.apply(bi0.includedBuilds, bi1.includedBuilds) - ) - } - - private BuildMonoids() {} - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptBase.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptBase.groovy index cee595e..e76e1e1 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptBase.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptBase.groovy @@ -1,7 +1,8 @@ package com.jessebrault.ssg.buildscript import com.jessebrault.ssg.buildscript.delegates.BuildDelegate -import groovy.transform.PackageScope +import org.jetbrains.annotations.ApiStatus +import org.jetbrains.annotations.Nullable import org.slf4j.Logger import org.slf4j.LoggerFactory import org.slf4j.Marker @@ -9,70 +10,47 @@ import org.slf4j.MarkerFactory import static java.util.Objects.requireNonNull +@SuppressWarnings('unused') abstract class BuildScriptBase extends Script { - protected static final Logger logger = LoggerFactory.getLogger(BuildScriptBase) - protected static final Marker enter = MarkerFactory.getMarker('ENTER') - protected static final Marker exit = MarkerFactory.getMarker('EXIT') + static final Logger logger = LoggerFactory.getLogger(BuildScriptBase) + static final Marker enter = MarkerFactory.getMarker('ENTER') + static final Marker exit = MarkerFactory.getMarker('EXIT') - private static Collection convertExtendingArg(Object arg) { - arg instanceof Collection ? arg as Collection - : arg instanceof String ? [arg] as Collection : [] + private String extending + private Closure buildClosure + private File projectRoot + + File getProjectRoot() { + requireNonNull(this.projectRoot) } - protected final Collection buildSpecs = [] - - /** - * args keys and values: - *
    - *
  • name: String
  • - *
  • extending?: String | Collection<String>
  • - *
- * - * @param args - * @param buildClosure - */ - void abstractBuild( - Map args, - @DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST) - Closure buildClosure - ) { - final Collection extending = convertExtendingArg(args.extending) - this.buildSpecs << BuildSpec.get( - name: requireNonNull(args.name as String), - isAbstract: true, - extending: extending, - buildClosure: buildClosure - ) + void setProjectRoot(File projectRoot) { + this.projectRoot = requireNonNull(projectRoot) } - /** - * args keys and values: - *
    - *
  • name: String
  • - *
  • extending?: String | Collection<String>
  • - *
- * - * @param args - * @param buildClosure - */ - void build( - Map args, - @DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST) - Closure buildClosure - ) { - final Collection extending = convertExtendingArg(args.extending) - this.buildSpecs << BuildSpec.get( - name: requireNonNull(args.name as String), - isAbstract: false, - extending: extending, - buildClosure: buildClosure - ) + File file(String name) { + new File(this.projectRoot, name) } - @PackageScope - Collection getBuildSpecs() { - this.buildSpecs + void build(@Nullable String extending, @DelegatesTo(value = BuildDelegate) Closure buildClosure) { + this.extending = extending + this.buildClosure = buildClosure + } + + void build(@DelegatesTo(value = BuildDelegate) Closure buildClosure) { + this.extending = null + this.buildClosure = buildClosure + } + + @ApiStatus.Internal + @Nullable String getExtending() { + this.extending + } + + @ApiStatus.Internal + Closure getBuildClosure() { + this.buildClosure } } diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptConfiguratorFactory.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptConfiguratorFactory.groovy deleted file mode 100644 index 72029d4..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptConfiguratorFactory.groovy +++ /dev/null @@ -1,7 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import java.util.function.Consumer - -interface BuildScriptConfiguratorFactory { - Consumer get() -} \ No newline at end of file diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptRunner.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptRunner.groovy deleted file mode 100644 index 0109b7d..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptRunner.groovy +++ /dev/null @@ -1,77 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import com.jessebrault.ssg.util.ExtensionUtil -import groovy.transform.NullCheck -import groovy.transform.stc.ClosureParams -import groovy.transform.stc.SimpleType -import org.codehaus.groovy.control.CompilerConfiguration -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import org.slf4j.Marker -import org.slf4j.MarkerFactory - -import java.util.function.Consumer - -@NullCheck -final class BuildScriptRunner { - - private static final Logger logger = LoggerFactory.getLogger(BuildScriptRunner) - private static final Marker enter = MarkerFactory.getMarker('ENTER') - private static final Marker exit = MarkerFactory.getMarker('EXIT') - - private static Collection runBase(BuildScriptBase base) { - base.run() - BuildSpecUtil.getBuilds(base.getBuildSpecs()) - } - - static Collection runClosureScript( - @DelegatesTo(value = BuildScriptBase, strategy = Closure.DELEGATE_FIRST) - @ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.buildscript.BuildScriptBase') - Closure scriptBody - ) { - def base = new BuildScriptBase() { - - @Override - Object run() { - scriptBody.delegate = this - scriptBody.resolveStrategy = Closure.DELEGATE_FIRST - scriptBody.call(this) - } - - } - runBase(base) - } - - private final GroovyClassLoader buildScriptClassLoader - - BuildScriptRunner(Collection classLoaderUrls) { - this.buildScriptClassLoader = new GroovyClassLoader( - Thread.currentThread().contextClassLoader, - new CompilerConfiguration().tap { - scriptBaseClass = BuildScriptBase.name - } - ) - classLoaderUrls.each(this.buildScriptClassLoader::addURL) - } - - GroovyClassLoader getBuildScriptClassLoader() { - this.buildScriptClassLoader - } - - Collection runBuildScript( - String scriptName, - Map binding, - Consumer configureBuildScript - ) { - logger.trace(enter, 'scriptName: {}, binding: {}', scriptName, binding) - Class scriptClass = this.buildScriptClassLoader.loadClass(ExtensionUtil.stripExtension(scriptName)) - def scriptObject = scriptClass.getConstructor().newInstance() - assert scriptObject instanceof BuildScriptBase - scriptObject.setBinding(new Binding(binding)) - configureBuildScript.accept(scriptObject) - def result = runBase(scriptObject) - logger.trace(exit, 'result: {}', result) - result - } - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpec.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpec.groovy deleted file mode 100644 index 94d5bb5..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpec.groovy +++ /dev/null @@ -1,57 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import com.jessebrault.ssg.buildscript.delegates.BuildDelegate -import groovy.transform.EqualsAndHashCode -import groovy.transform.NullCheck - -@NullCheck -@EqualsAndHashCode(excludes = 'buildClosure') -final class BuildSpec { - - static BuildSpec getEmpty() { - new BuildSpec('', false, [], { }) - } - - static BuildSpec get(Map args) { - new BuildSpec( - args.name as String ?: '', - args.isAbstract as boolean ?: false, - args.extending as Collection ?: [], - args.buildClosure as Closure ?: { } - ) - } - - static BuildSpec get( - String name, - boolean isAbstract, - Collection extending, - @DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST) - Closure buildClosure - ) { - new BuildSpec(name, isAbstract, extending, buildClosure) - } - - final String name - final boolean isAbstract - final Collection extending - final Closure buildClosure - - private BuildSpec( - String name, - boolean isAbstract, - Collection 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 deleted file mode 100644 index 2543a4c..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtil.groovy +++ /dev/null @@ -1,90 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import com.jessebrault.ssg.buildscript.delegates.BuildDelegate -import com.jessebrault.ssg.util.Monoid -import groovy.transform.NullCheck -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import org.slf4j.Marker -import org.slf4j.MarkerFactory - -import java.util.function.BiFunction - -@NullCheck -final class BuildSpecUtil { - - private static final Logger logger = LoggerFactory.getLogger(BuildSpecUtil) - private static final Marker enter = MarkerFactory.getMarker('ENTER') - private static final Marker exit = MarkerFactory.getMarker('EXIT') - - private static Build intermediateToBuild(BuildIntermediate intermediate) { - Build.get( - name: intermediate.buildSpec.name, - outputDirFunction: intermediate.outputDirFunction, - siteSpec: intermediate.siteSpec, - globals: intermediate.globals, - taskFactorySpecs: intermediate.taskFactorySpecs, - includedBuilds: intermediate.includedBuilds - ) - } - - private static BuildIntermediate specToIntermediate(BuildSpec buildSpec, BuildIntermediate parent) { - def d = new BuildDelegate() - buildSpec.buildClosure.delegate = d - buildSpec.buildClosure.resolveStrategy = Closure.DELEGATE_FIRST - buildSpec.buildClosure() - new BuildDelegate.BuildDelegateBuildIntermediate( - buildSpec, - d, - parent, - BuildMonoids.siteSpecMonoid, - BuildMonoids.globalsMonoid, - BuildMonoids.typesMonoid, - BuildMonoids.sourcesMonoid, - BuildMonoids.taskFactoriesMonoid, - BuildMonoids.includedBuildsMonoid - ) - } - - private static BuildIntermediate reduceWithParents( - BuildSpec rootSpec, - BuildGraph buildGraph, - Monoid buildIntermediateMonoid, - BiFunction parentAndSpecToIntermediate - ) { - final List parents = buildGraph.getParents(rootSpec) - if (parents.size() == 0) { - parentAndSpecToIntermediate.apply(buildIntermediateMonoid.zero, rootSpec) - } else { - final List parentIntermediates = parents.collect { - reduceWithParents(it, buildGraph, buildIntermediateMonoid, parentAndSpecToIntermediate) - } - final BuildIntermediate parentsReduced = parentIntermediates.inject(buildIntermediateMonoid.zero) - { acc, bi -> - buildIntermediateMonoid.concat.apply(acc, bi) - } - parentAndSpecToIntermediate.apply(parentsReduced, rootSpec) - } - } - - static Collection getBuilds(Collection buildSpecs) { - logger.trace(enter, 'buildSpecs: {}', buildSpecs) - def graph = new BuildGraph(buildSpecs) - def intermediates = buildSpecs.findResults { - if (it.isAbstract) { - null - } else { - reduceWithParents(it, graph, BuildMonoids.buildIntermediateMonoid) - { parent, spec -> - specToIntermediate(spec, parent) - } - } - } - def builds = intermediates.collect { intermediateToBuild(it) } - logger.trace(exit, 'builds: {}', builds) - builds - } - - private BuildSpecUtil() {} - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildUtil.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildUtil.groovy deleted file mode 100644 index ea026cd..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildUtil.groovy +++ /dev/null @@ -1,24 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import com.jessebrault.ssg.util.Diagnostic - -final class BuildUtil { - - static Collection diagnoseIncludedBuilds(Collection allBuilds) { - allBuilds.inject([] as Collection) { allDiagnostics, build -> - allDiagnostics + build.includedBuilds.inject([] as Collection) { buildDiagnostics, includedBuildName -> - def includedBuild = allBuilds.find { it.name == includedBuildName } - if (includedBuild == null) { - buildDiagnostics + new Diagnostic( - "The includedBuild ${ includedBuildName } is not in the collection of allBuilds" - ) - } else { - buildDiagnostics - } - } - } - } - - private BuildUtil() {} - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/DefaultBuildScriptConfiguratorFactory.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/DefaultBuildScriptConfiguratorFactory.groovy deleted file mode 100644 index 23cae26..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/DefaultBuildScriptConfiguratorFactory.groovy +++ /dev/null @@ -1,71 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import com.jessebrault.ssg.html.PageToHtmlSpecProviders -import com.jessebrault.ssg.html.PageToHtmlTaskFactory -import com.jessebrault.ssg.html.TextToHtmlSpecProviders -import com.jessebrault.ssg.html.TextToHtmlTaskFactory -import com.jessebrault.ssg.page.PageTypes -import com.jessebrault.ssg.page.PagesProviders -import com.jessebrault.ssg.part.PartTypes -import com.jessebrault.ssg.part.PartsProviders -import com.jessebrault.ssg.template.TemplateTypes -import com.jessebrault.ssg.template.TemplatesProviders -import com.jessebrault.ssg.text.TextTypes -import com.jessebrault.ssg.text.TextsProviders -import groovy.transform.EqualsAndHashCode -import groovy.transform.NullCheck -import groovy.transform.TupleConstructor - -import java.util.function.Consumer -import java.util.function.Supplier - -@TupleConstructor(includeFields = true, defaults = false) -@NullCheck(includeGenerated = true) -@EqualsAndHashCode(includeFields = true) -final class DefaultBuildScriptConfiguratorFactory implements BuildScriptConfiguratorFactory { - - private final File baseDir - private final Supplier classLoaderSupplier - - @Override - Consumer get() { - return { - it.build(name: 'default') { - outputDirFunction = { Build build -> - new OutputDir(new File(this.baseDir, build.name == 'default' ? 'build' : build.name)) - } - - types { - textTypes << TextTypes.MARKDOWN - pageTypes << PageTypes.getGsp(['.gsp', '.ssg.gst'], this.classLoaderSupplier.get()) - templateTypes << TemplateTypes.getGsp(['.gsp', '.ssg.gst'], this.classLoaderSupplier.get()) - partTypes << PartTypes.getGsp(['.gsp', '.ssg.gst'], this.classLoaderSupplier.get()) - } - - sources { base, types -> - texts TextsProviders.from(new File(this.baseDir, 'texts'), types.textTypes) - pages PagesProviders.from(new File(this.baseDir, 'pages'), types.pageTypes) - templates TemplatesProviders.from(new File(this.baseDir, 'templates'), types.templateTypes) - parts PartsProviders.from(new File(this.baseDir, 'parts'), types.partTypes) - } - - taskFactories { base, sources -> - register('textToHtml', TextToHtmlTaskFactory::new) { - it.specsProvider += TextToHtmlSpecProviders.from(sources) - it.allTextsProvider += sources.textsProvider - it.allPartsProvider += sources.partsProvider - it.allModelsProvider += sources.modelsProvider - } - - register('pageToHtml', PageToHtmlTaskFactory::new) { - it.specsProvider += PageToHtmlSpecProviders.from(sources.pagesProvider) - it.allTextsProvider += sources.textsProvider - it.allPartsProvider += sources.partsProvider - it.allModelsProvider += sources.modelsProvider - } - } - } - } - } - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/FileBuildScriptGetter.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/FileBuildScriptGetter.groovy new file mode 100644 index 0000000..bc88b4d --- /dev/null +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/FileBuildScriptGetter.groovy @@ -0,0 +1,20 @@ +package com.jessebrault.ssg.buildscript + +import groovy.transform.NullCheck +import groovy.transform.TupleConstructor + +@NullCheck +@TupleConstructor(includeFields = true) +final class FileBuildScriptGetter { + + private final File projectRoot + private final GroovyClassLoader gcl + + BuildScriptBase getBuildInfo(String name) { + Class scriptClass = this.gcl.loadClass(name, true, false) + def scriptObject = scriptClass.getConstructor().newInstance() + assert scriptObject instanceof BuildScriptBase + scriptObject + } + +} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/OutputDir.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/OutputDir.groovy deleted file mode 100644 index 40a7917..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/OutputDir.groovy +++ /dev/null @@ -1,41 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import groovy.transform.EqualsAndHashCode -import groovy.transform.NullCheck - -@NullCheck -@EqualsAndHashCode -final class OutputDir { - - private final String path - - OutputDir(String path) { - this.path = path - } - - OutputDir(File file) { - this(file.path) - } - - File asFile() { - new File(this.path) - } - - String asString() { - this.path - } - - Object asType(Class clazz) { - switch (clazz) { - case File -> this.asFile() - case String -> this.asString() - default -> throw new IllegalArgumentException('cannot cast to a class other than File or String') - } - } - - @Override - String toString() { - "OutputDir(path: ${ this.path })" - } - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/OutputDirFunctions.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/OutputDirFunctions.groovy deleted file mode 100644 index f6e33ba..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/OutputDirFunctions.groovy +++ /dev/null @@ -1,31 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import com.jessebrault.ssg.util.Monoid -import com.jessebrault.ssg.util.Monoids - -import java.util.function.Function - -final class OutputDirFunctions { - - static final Function DEFAULT = { Build build -> new OutputDir(build.name) } - - static final Monoid> DEFAULT_MONOID = Monoids.of(DEFAULT, OutputDirFunctions::concat) - - static Function concat( - Function f0, - Function f1 - ) { - f0 == OutputDirFunctions.DEFAULT ? f1 : f0 - } - - static Function of(File dir) { - return { new OutputDir(dir) } - } - - static Function of(String path) { - return { new OutputDir(path) } - } - - private OutputDirFunctions() {} - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/SourceProviders.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/SourceProviders.groovy deleted file mode 100644 index 9c85e65..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/SourceProviders.groovy +++ /dev/null @@ -1,107 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import com.jessebrault.ssg.model.Model -import com.jessebrault.ssg.page.Page -import com.jessebrault.ssg.part.Part -import com.jessebrault.ssg.provider.CollectionProvider -import com.jessebrault.ssg.provider.CollectionProviders -import com.jessebrault.ssg.template.Template -import com.jessebrault.ssg.text.Text -import com.jessebrault.ssg.util.Monoid -import com.jessebrault.ssg.util.Monoids -import groovy.transform.EqualsAndHashCode -import groovy.transform.NullCheck -import groovy.transform.TupleConstructor - -@NullCheck -@EqualsAndHashCode -final class SourceProviders { - - static final Monoid DEFAULT_MONOID = Monoids.of(getEmpty(), SourceProviders::concat) - - static SourceProviders concat(SourceProviders sp0, SourceProviders sp1) { - new SourceProviders( - sp0.textsProvider + sp1.textsProvider, - sp0.modelsProvider + sp1.modelsProvider, - sp0.pagesProvider + sp1.pagesProvider, - sp0.templatesProvider + sp1.templatesProvider, - sp0.partsProvider + sp1.partsProvider, - sp0.custom + sp1.custom - ) - } - - static SourceProviders get(Map args) { - new SourceProviders( - args.textsProvider as CollectionProvider - ?: CollectionProviders.getEmpty() as CollectionProvider, - args.modelsProvider as CollectionProvider> - ?: CollectionProviders.getEmpty() as CollectionProvider>, - args.pagesProvider as CollectionProvider - ?: CollectionProviders.getEmpty() as CollectionProvider, - args.templatesProvider as CollectionProvider