From c7ba01380ed28f8e758cc830d510224b36fb7eb8 Mon Sep 17 00:00:00 2001 From: JesseBrault0709 <62299747+JesseBrault0709@users.noreply.github.com> Date: Fri, 16 Jun 2023 14:02:54 +0200 Subject: [PATCH] Added multiple inheritance for builds. --- .../ssg/buildscript/BuildExtension.groovy | 57 ------ .../ssg/buildscript/BuildGraph.java | 73 +++++++ .../ssg/buildscript/BuildGraphUtil.groovy | 79 -------- .../ssg/buildscript/BuildIntermediate.java | 20 ++ .../ssg/buildscript/BuildMonoids.groovy | 48 +++++ .../ssg/buildscript/BuildScriptBase.groovy | 39 ++-- .../ssg/buildscript/BuildSpec.groovy | 33 +-- .../ssg/buildscript/BuildSpecUtil.groovy | 148 ++++++-------- .../SyntheticBuildIntermediate.groovy | 74 +++++++ .../delegates/BuildDelegate.groovy | 188 ++++++++---------- .../com/jessebrault/ssg/util/Monoids.groovy | 8 + .../buildscript/BuildGraphUtilTests.groovy | 98 --------- .../buildscript/BuildScriptBaseTests.groovy | 10 +- .../ssg/buildscript/BuildSpecUtilTests.groovy | 16 +- .../delegates/BuildDelegateTests.groovy | 182 ++++++----------- 15 files changed, 487 insertions(+), 586 deletions(-) delete mode 100644 api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildExtension.groovy create mode 100644 api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraph.java delete mode 100644 api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraphUtil.groovy create mode 100644 api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildIntermediate.java create mode 100644 api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildMonoids.groovy create mode 100644 api/src/main/groovy/com/jessebrault/ssg/buildscript/SyntheticBuildIntermediate.groovy delete mode 100644 api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildGraphUtilTests.groovy diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildExtension.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildExtension.groovy deleted file mode 100644 index 1290c3d..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildExtension.groovy +++ /dev/null @@ -1,57 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import groovy.transform.NullCheck -import groovy.transform.PackageScope - -@PackageScope -@NullCheck -final class BuildExtension { - - static BuildExtension getEmpty() { - new BuildExtension() - } - - static BuildExtension get(String buildName) { - new BuildExtension(buildName) - } - - private final String buildName - - private BuildExtension(String buildName) { - this.buildName = buildName - } - - private BuildExtension() { - this.buildName = null - } - - boolean isPresent() { - this.buildName != null - } - - boolean isEmpty() { - !this.present - } - - String getBuildName() { - Objects.requireNonNull(this.buildName) - } - - @Override - String toString() { - this.present ? "BuildExtension(extending: ${ this.buildName })" : "BuildExtension(empty)" - } - - @Override - int hashCode() { - Objects.hash(this.buildName) - } - - @Override - boolean equals(Object obj) { - obj.is(this) - || (obj instanceof BuildExtension && obj.present && obj.buildName == this.buildName) - || (obj instanceof BuildExtension && !obj.present && !this.present) - } - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraph.java b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraph.java new file mode 100644 index 0000000..0acf1d5 --- /dev/null +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraph.java @@ -0,0 +1,73 @@ +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/BuildGraphUtil.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraphUtil.groovy deleted file mode 100644 index dacaf39..0000000 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildGraphUtil.groovy +++ /dev/null @@ -1,79 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import groovy.transform.PackageScope -import org.jgrapht.Graph -import org.jgrapht.graph.DefaultEdge -import org.jgrapht.graph.DirectedAcyclicGraph -import org.slf4j.Logger -import org.slf4j.LoggerFactory -import org.slf4j.Marker -import org.slf4j.MarkerFactory - -@PackageScope -final class BuildGraphUtil { - - private static final Logger logger = LoggerFactory.getLogger(BuildGraphUtil) - private static final Marker enter = MarkerFactory.getMarker('ENTER') - private static final Marker exit = MarkerFactory.getMarker('EXIT') - - private static void addParentEdges( - Graph graph, - BuildSpec spec, - Collection allBuildSpecs - ) { - logger.trace(enter, 'graph: {}, spec: {}', graph, spec) - if (!graph.containsVertex(spec)) { - throw new IllegalStateException("given spec is not in the graph") - } - if (spec.extending.present) { - def parent = allBuildSpecs.find { it.name == spec.extending.buildName } - if (parent == null) { - throw new IllegalStateException("no such parent/extends from build: ${ spec.extending.buildName }") - } - if (!graph.containsVertex(parent)) { - graph.addVertex(parent) - } - graph.addEdge(parent, spec) - addParentEdges(graph, parent, allBuildSpecs) - } - logger.trace(exit, '') - } - - static Graph getDependencyGraph(Collection buildSpecs) { - logger.trace(enter, '') - final Graph graph = new DirectedAcyclicGraph<>(DefaultEdge) - buildSpecs.each { - if (!graph.containsVertex(it)) { - graph.addVertex(it) - } - addParentEdges(graph, it, buildSpecs) - } - logger.trace(exit, 'graph: {}', graph) - graph - } - - static Collection getAncestors(BuildSpec child, Graph graph) { - logger.trace(enter, 'child: {}, graph: {}', child, graph) - if (child.extending.isEmpty()) { - def r = [] as Collection - logger.trace(exit, 'r: {}', r) - r - } else { - // use incoming to get edges pointing to child - def incomingEdges = graph.incomingEdgesOf(child) - if (incomingEdges.size() == 0) { - throw new IllegalArgumentException("child does not have an edge to its parent") - } - if (incomingEdges.size() > 1) { - throw new IllegalArgumentException("child has more than one parent") - } - def parent = graph.getEdgeSource(incomingEdges[0]) - def r = getAncestors(parent, graph) + [parent] // needs to be 'oldest' -> 'youngest' - logger.trace(exit, 'r: {}', r) - r - } - } - - private BuildGraphUtil() {} - -} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildIntermediate.java b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildIntermediate.java new file mode 100644 index 0000000..cbb1ae1 --- /dev/null +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildIntermediate.java @@ -0,0 +1,20 @@ +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 new file mode 100644 index 0000000..df933fe --- /dev/null +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildMonoids.groovy @@ -0,0 +1,48 @@ +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 f1e4808..cee595e 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptBase.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildScriptBase.groovy @@ -15,10 +15,19 @@ abstract class BuildScriptBase extends Script { protected static final Marker enter = MarkerFactory.getMarker('ENTER') protected 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 : [] + } + protected final Collection buildSpecs = [] /** - * args keys: name (required), extending (optional) + * args keys and values: + *
    + *
  • name: String
  • + *
  • extending?: String | Collection<String>
  • + *
* * @param args * @param buildClosure @@ -28,16 +37,21 @@ abstract class BuildScriptBase extends Script { @DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST) Closure buildClosure ) { - this.buildSpecs << new BuildSpec( - requireNonNull(args.name as String), - true, - args.extending != null ? BuildExtension.get(args.extending as String) : BuildExtension.getEmpty(), - buildClosure + final Collection extending = convertExtendingArg(args.extending) + this.buildSpecs << BuildSpec.get( + name: requireNonNull(args.name as String), + isAbstract: true, + extending: extending, + buildClosure: buildClosure ) } /** - * args keys: name (required), extending (optional) + * args keys and values: + *
    + *
  • name: String
  • + *
  • extending?: String | Collection<String>
  • + *
* * @param args * @param buildClosure @@ -47,11 +61,12 @@ abstract class BuildScriptBase extends Script { @DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST) Closure buildClosure ) { - this.buildSpecs << new BuildSpec( - requireNonNull(args.name as String), - false, - args.extending != null ? BuildExtension.get(args.extending as String) : BuildExtension.getEmpty(), - buildClosure + final Collection extending = convertExtendingArg(args.extending) + this.buildSpecs << BuildSpec.get( + name: requireNonNull(args.name as String), + isAbstract: false, + extending: extending, + buildClosure: buildClosure ) } 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 ed0d4e3..94d5bb5 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpec.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpec.groovy @@ -3,36 +3,43 @@ 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 -@NullCheck() +@NullCheck @EqualsAndHashCode(excludes = 'buildClosure') final class BuildSpec { static BuildSpec getEmpty() { - new BuildSpec('', false, BuildExtension.getEmpty(), { }) + new BuildSpec('', false, [], { }) } static BuildSpec get(Map args) { new BuildSpec( args.name as String ?: '', args.isAbstract as boolean ?: false, - args.extending as BuildExtension ?: BuildExtension.getEmpty(), + args.extending as Collection ?: [], args.buildClosure as Closure ?: { } ) } - final String name - final boolean isAbstract - final BuildExtension extending - final Closure buildClosure - - BuildSpec( + static BuildSpec get( String name, boolean isAbstract, - BuildExtension extending, + 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 ) { 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 3a0d07c..2543a4c 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtil.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtil.groovy @@ -1,13 +1,8 @@ package com.jessebrault.ssg.buildscript -import com.jessebrault.ssg.SiteSpec import com.jessebrault.ssg.buildscript.delegates.BuildDelegate -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 com.jessebrault.ssg.util.Zero -import org.jgrapht.traverse.DepthFirstIterator +import groovy.transform.NullCheck import org.slf4j.Logger import org.slf4j.LoggerFactory import org.slf4j.Marker @@ -15,98 +10,79 @@ 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 final Monoid> globalsMonoid = Monoids.of([:]) { m0, m1 -> - m0 + m1 - } - - private static final Monoid> includedBuildsMonoid = Monoids.of([]) { c0, c1 -> - c0 + c1 - } - - private static final Monoid>> taskFactoriesMonoid = - Monoids.getMergeCollectionMonoid(TaskFactorySpec.SAME_NAME_AND_SUPPLIER_EQ, TaskFactorySpec.DEFAULT_SEMIGROUP) - - private static T reduceResults( - Collection resultsCollection, - Zero tZero, - BiFunction resultsToT - ) { - resultsCollection.inject(tZero.zero) { acc, r -> - resultsToT.apply(acc, r) - } - } - - private static Collection mapBuildSpecsToResults(Collection buildSpecs) { - buildSpecs.collect { - def delegate = new BuildDelegate() - it.buildClosure.delegate = delegate - //noinspection UnnecessaryQualifiedReference - it.buildClosure.resolveStrategy = Closure.DELEGATE_FIRST - it.buildClosure() - new BuildDelegate.Results(delegate) - } - } - - private static Build toBuild( - Collection specs - ) { - if (specs.empty) { - throw new IllegalArgumentException('specs must contain at least one BuildSpec') - } - def allResults = mapBuildSpecsToResults(specs) - def outputDirFunctionResult = reduceResults(allResults, OutputDirFunctions.DEFAULT_MONOID) { acc, r -> - r.getOutputDirFunctionResult(acc, { acc }) - } - def siteSpecResult = reduceResults(allResults, SiteSpec.DEFAULT_MONOID) { acc, r -> - r.getSiteSpecResult(acc, true, SiteSpec.DEFAULT_MONOID) - } - def globalsResult = reduceResults(allResults, globalsMonoid) { acc, r -> - r.getGlobalsResult(acc, true, globalsMonoid) - } - - def typesResult = reduceResults(allResults, TypesContainer.DEFAULT_MONOID) { acc, r -> - r.getTypesResult(acc, true, TypesContainer.DEFAULT_MONOID) - } - def sourcesResult = reduceResults(allResults, SourceProviders.DEFAULT_MONOID) { acc, r -> - r.getSourcesResult(acc, true, SourceProviders.DEFAULT_MONOID, typesResult) - } - def taskFactoriesResult = reduceResults(allResults, taskFactoriesMonoid) { acc, r -> - r.getTaskFactoriesResult(acc, true, taskFactoriesMonoid, sourcesResult) - } - - def includedBuildsResult = reduceResults(allResults, includedBuildsMonoid) { acc, r -> - r.getIncludedBuildsResult(acc, true, includedBuildsMonoid) - } - + private static Build intermediateToBuild(BuildIntermediate intermediate) { Build.get( - name: specs.last().name, - outputDirFunction: outputDirFunctionResult, - siteSpec: siteSpecResult, - globals: globalsResult, - taskFactorySpecs: taskFactoriesResult, - includedBuilds: includedBuildsResult + name: intermediate.buildSpec.name, + outputDirFunction: intermediate.outputDirFunction, + siteSpec: intermediate.siteSpec, + globals: intermediate.globals, + taskFactorySpecs: intermediate.taskFactorySpecs, + includedBuilds: intermediate.includedBuilds ) } - static Collection getBuilds(Collection buildSpecs) { - logger.trace(enter, '') - def graph = BuildGraphUtil.getDependencyGraph(buildSpecs) - def r = new DepthFirstIterator<>(graph).findResults { - if (it.isAbstract) { - return null + 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) } - def ancestors = BuildGraphUtil.getAncestors(it, graph) - logger.debug('ancestors of {}: {}', it, ancestors) - toBuild([*ancestors, it]) + final BuildIntermediate parentsReduced = parentIntermediates.inject(buildIntermediateMonoid.zero) + { acc, bi -> + buildIntermediateMonoid.concat.apply(acc, bi) + } + parentAndSpecToIntermediate.apply(parentsReduced, rootSpec) } - logger.trace(exit, 'r: {}', r) - r + } + + 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/SyntheticBuildIntermediate.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/SyntheticBuildIntermediate.groovy new file mode 100644 index 0000000..ed77a60 --- /dev/null +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/SyntheticBuildIntermediate.groovy @@ -0,0 +1,74 @@ +package com.jessebrault.ssg.buildscript + +import com.jessebrault.ssg.SiteSpec +import com.jessebrault.ssg.task.TaskFactory +import com.jessebrault.ssg.task.TaskFactorySpec +import groovy.transform.EqualsAndHashCode +import groovy.transform.NullCheck +import groovy.transform.TupleConstructor + +import java.util.function.Function + +@TupleConstructor(defaults = false) +@NullCheck(includeGenerated = true) +@EqualsAndHashCode +final class SyntheticBuildIntermediate implements BuildIntermediate { + + static BuildIntermediate getEmpty() { + new SyntheticBuildIntermediate( + BuildSpec.getEmpty(), + OutputDirFunctions.DEFAULT, + SiteSpec.getBlank(), + [:], + TypesContainer.getEmpty(), + SourceProviders.getEmpty(), + [], + [] + ) + } + + static BuildIntermediate get(Map args) { + new SyntheticBuildIntermediate( + args.buildSpec as BuildSpec ?: BuildSpec.getEmpty(), + args.outputDirFunction as Function ?: OutputDirFunctions.DEFAULT, + args.siteSpec as SiteSpec ?: SiteSpec.getBlank(), + args.globals as Map ?: [:], + args.types as TypesContainer ?: TypesContainer.getEmpty(), + args.sources as SourceProviders ?: SourceProviders.getEmpty(), + args.taskFactorySpecs as Collection> ?: [], + args.includedBuilds as Collection ?: [] + ) + } + + static BuildIntermediate get( + BuildSpec buildSpec, + Function outputDirFunction, + SiteSpec siteSpec, + Map globals, + TypesContainer types, + SourceProviders sources, + Collection> taskFactorySpecs, + Collection includedBuilds + ) { + new SyntheticBuildIntermediate( + buildSpec, + outputDirFunction, + siteSpec, + globals, + types, + sources, + taskFactorySpecs, + includedBuilds + ) + } + + final BuildSpec buildSpec + final Function outputDirFunction + final SiteSpec siteSpec + final Map globals + final TypesContainer types + final SourceProviders sources + final Collection> taskFactorySpecs + final Collection includedBuilds + +} diff --git a/api/src/main/groovy/com/jessebrault/ssg/buildscript/delegates/BuildDelegate.groovy b/api/src/main/groovy/com/jessebrault/ssg/buildscript/delegates/BuildDelegate.groovy index 69655e0..d375364 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/buildscript/delegates/BuildDelegate.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/buildscript/delegates/BuildDelegate.groovy @@ -1,10 +1,7 @@ package com.jessebrault.ssg.buildscript.delegates import com.jessebrault.ssg.SiteSpec -import com.jessebrault.ssg.buildscript.Build -import com.jessebrault.ssg.buildscript.OutputDir -import com.jessebrault.ssg.buildscript.SourceProviders -import com.jessebrault.ssg.buildscript.TypesContainer +import com.jessebrault.ssg.buildscript.* import com.jessebrault.ssg.mutable.Mutable import com.jessebrault.ssg.mutable.Mutables import com.jessebrault.ssg.task.TaskFactory @@ -18,7 +15,6 @@ import groovy.transform.stc.FromString import groovy.transform.stc.SimpleType import java.util.function.Function -import java.util.function.Supplier import java.util.function.UnaryOperator @NullCheck(includeGenerated = true) @@ -28,133 +24,107 @@ final class BuildDelegate { @TupleConstructor(includeFields = true, defaults = false) @NullCheck(includeGenerated = true) @EqualsAndHashCode(includeFields = true) - static final class Results { + static final class BuildDelegateBuildIntermediate implements BuildIntermediate { + private final BuildSpec buildSpec private final BuildDelegate delegate + private final BuildIntermediate parent - Function getOutputDirFunctionResult( - Function base, - Supplier> onEmpty - ) { + private final Monoid siteSpecMonoid + private final Monoid> globalsMonoid + private final Monoid typesMonoid + private final Monoid sourcesMonoid + private final Monoid>> taskFactoriesMonoid + private final Monoid> includedBuildsMonoid + + @Override + BuildSpec getBuildSpec() { + this.buildSpec + } + + @Override + Function getOutputDirFunction() { this.delegate.outputDirFunction.getOrElse { - this.delegate.outputDirFunctionMapper.match(onEmpty) { - it.apply(base) + this.delegate.outputDirFunctionMapper.match({ parent.outputDirFunction }) { + it.apply(this.parent.outputDirFunction) } } } - SiteSpec getSiteSpecResult( - SiteSpec base, - boolean onConcatWithBaseEmpty, - Monoid siteSpecMonoid - ) { - def concatWithBase = this.delegate.siteSpecConcatBase.isPresent() - ? this.delegate.siteSpecConcatBase.get() - : onConcatWithBaseEmpty - def onEmpty = { concatWithBase ? base : siteSpecMonoid.zero } - this.delegate.siteSpecClosure.match(onEmpty) { - def d = new SiteSpecDelegate(siteSpecMonoid) - it.delegate = d - //noinspection UnnecessaryQualifiedReference - it.resolveStrategy = Closure.DELEGATE_FIRST - it(base) - def r = d.getResult() - concatWithBase ? siteSpecMonoid.concat.apply(base, r) : r + @Override + SiteSpec getSiteSpec() { + def siteSpecClosure = this.delegate.siteSpecClosure.getOrElse { return { } } + def d = new SiteSpecDelegate(this.siteSpecMonoid) + siteSpecClosure.delegate = d + siteSpecClosure.resolveStrategy = Closure.DELEGATE_FIRST + siteSpecClosure(this.parent.siteSpec) + if (this.delegate.siteSpecConcatBase.getOrElse { true }) { + this.siteSpecMonoid.concat.apply(this.parent.siteSpec, d.result) + } else { + d.result } } - Map getGlobalsResult( - Map base, - boolean onConcatWithBaseEmpty, - Monoid> globalsMonoid - ) { - def concatWithBase = this.delegate.globalsConcatBase.isPresent() - ? this.delegate.globalsConcatBase.get() - : onConcatWithBaseEmpty - def onEmpty = { concatWithBase ? base : globalsMonoid.zero } - this.delegate.globalsClosure.match(onEmpty) { - def d = new GlobalsDelegate() - it.delegate = d - //noinspection UnnecessaryQualifiedReference - it.resolveStrategy = Closure.DELEGATE_FIRST - it(base) - def r = d.getResult() - concatWithBase ? globalsMonoid.concat.apply(base, r) : r + @Override + Map getGlobals() { + def globalsClosure = this.delegate.globalsClosure.getOrElse { return { } } + def d = new GlobalsDelegate() + globalsClosure.delegate = d + globalsClosure.resolveStrategy = Closure.DELEGATE_FIRST + globalsClosure(this.parent.globals) + if (this.delegate.globalsConcatBase.getOrElse { true }) { + this.globalsMonoid.concat.apply(this.parent.globals, d.getResult()) + } else { + d.getResult() } } - TypesContainer getTypesResult( - TypesContainer base, - boolean onConcatWithBaseEmpty, - Monoid typesContainerMonoid - ) { - def concatWithBase = this.delegate.typesConcatBase.isPresent() - ? this.delegate.typesConcatBase.get() - : onConcatWithBaseEmpty - def onEmpty = { concatWithBase ? base : typesContainerMonoid.zero } - this.delegate.typesClosure.match(onEmpty) { - def d = new TypesDelegate() - it.delegate = d - //noinspection UnnecessaryQualifiedReference - it.resolveStrategy = Closure.DELEGATE_FIRST - it(base) - def r = d.getResult() - concatWithBase ? typesContainerMonoid.concat.apply(base, r) : r + @Override + TypesContainer getTypes() { + def typesClosure = this.delegate.typesClosure.getOrElse { return { } } + def d = new TypesDelegate() + typesClosure.delegate = d + typesClosure.resolveStrategy = Closure.DELEGATE_FIRST + typesClosure(this.parent.types) + if (this.delegate.typesConcatBase.getOrElse { true }) { + this.typesMonoid.concat.apply(this.parent.types, d.result) + } else { + d.result } } - SourceProviders getSourcesResult( - SourceProviders base, - boolean onConcatWithBaseEmpty, - Monoid sourceProvidersMonoid, - TypesContainer types - ) { - def concatWithBase = this.delegate.sourcesConcatBase.isPresent() - ? this.delegate.sourcesConcatBase.get() - : onConcatWithBaseEmpty - def onEmpty = { concatWithBase ? base : sourceProvidersMonoid.zero } - this.delegate.sourcesClosure.match(onEmpty) { - def d = new SourceProvidersDelegate() - it.delegate = d - //noinspection UnnecessaryQualifiedReference - it.resolveStrategy = Closure.DELEGATE_FIRST - it(base, types) - def r = d.getResult() - concatWithBase ? sourceProvidersMonoid.concat.apply(base, r) : r + @Override + SourceProviders getSources() { + def sourcesClosure = this.delegate.sourcesClosure.getOrElse { return { base, types -> } } + def d = new SourceProvidersDelegate() + sourcesClosure.delegate = d + sourcesClosure.resolveStrategy = Closure.DELEGATE_FIRST + sourcesClosure(this.parent.sources, this.types) + if (this.delegate.sourcesConcatBase.getOrElse { true }) { + this.sourcesMonoid.concat.apply(this.parent.sources, d.result) + } else { + d.result } } - Collection> getTaskFactoriesResult( - Collection> base, - boolean onConcatWithBaseEmpty, - Monoid>> taskFactorySpecsMonoid, - SourceProviders sources - ) { - def concatWithBase = this.delegate.taskFactoriesConcatBase.isPresent() - ? this.delegate.taskFactoriesConcatBase.get() - : onConcatWithBaseEmpty - def onEmpty = { concatWithBase ? base : taskFactorySpecsMonoid.zero } - this.delegate.taskFactoriesClosure.match(onEmpty) { - def d = new TaskFactoriesDelegate() - it.delegate = d - //noinspection UnnecessaryQualifiedReference - it.resolveStrategy = Closure.DELEGATE_FIRST - it(base, sources) - def r = d.getResult() - concatWithBase ? taskFactorySpecsMonoid.concat.apply(base, r) : r + @Override + Collection> getTaskFactorySpecs() { + def taskFactoriesClosure = this.delegate.taskFactoriesClosure.getOrElse { return { base, sources -> } } + def d = new TaskFactoriesDelegate() + taskFactoriesClosure.delegate = d + taskFactoriesClosure.resolveStrategy = Closure.DELEGATE_FIRST + taskFactoriesClosure(this.parent.taskFactorySpecs, this.sources) + if (this.delegate.taskFactoriesConcatBase.getOrElse { true }) { + this.taskFactoriesMonoid.concat.apply(this.parent.taskFactorySpecs, d.result) + } else { + d.result } } - Collection getIncludedBuildsResult( - Collection base, - boolean onConcatWithBaseEmpty, - Monoid> includedBuildsMonoid - ) { - def concatWithBase = this.delegate.includedBuildsConcatBase.isPresent() - ? this.delegate.includedBuildsConcatBase.get() - : onConcatWithBaseEmpty - if (concatWithBase) { - includedBuildsMonoid.concat.apply(base, this.delegate.includedBuilds) + @Override + Collection getIncludedBuilds() { + if (this.delegate.includedBuildsConcatBase.getOrElse { true }) { + this.includedBuildsMonoid.concat.apply(this.parent.includedBuilds, this.delegate.includedBuilds) } else { this.delegate.includedBuilds } diff --git a/api/src/main/groovy/com/jessebrault/ssg/util/Monoids.groovy b/api/src/main/groovy/com/jessebrault/ssg/util/Monoids.groovy index 8185fc7..6694d60 100644 --- a/api/src/main/groovy/com/jessebrault/ssg/util/Monoids.groovy +++ b/api/src/main/groovy/com/jessebrault/ssg/util/Monoids.groovy @@ -28,6 +28,14 @@ final class Monoids { }) } + static Monoid> getCollectionMonoid() { + of([], { c0, c1 -> c0 + c1 }) + } + + static Monoid> getMapMonoid() { + of([:], { m0, m1 -> m0 + m1 }) + } + private Monoids() {} } diff --git a/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildGraphUtilTests.groovy b/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildGraphUtilTests.groovy deleted file mode 100644 index 2edb4e2..0000000 --- a/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildGraphUtilTests.groovy +++ /dev/null @@ -1,98 +0,0 @@ -package com.jessebrault.ssg.buildscript - -import groovy.transform.PackageScope -import org.junit.jupiter.api.Test - -import static com.jessebrault.ssg.buildscript.BuildGraphUtil.getAncestors -import static com.jessebrault.ssg.buildscript.BuildGraphUtil.getDependencyGraph -import static org.junit.jupiter.api.Assertions.* - -@PackageScope -final class BuildGraphUtilTests { - - @Test - void oneBuildGraph() { - def spec = BuildSpec.getEmpty() - def graph = getDependencyGraph([spec]) - assertTrue(graph.containsVertex(spec)) - assertEquals(0, graph.edgesOf(spec).size()) - } - - @Test - void twoBuildsNotConnectedGraph() { - def spec0 = BuildSpec.getEmpty() - def spec1 = BuildSpec.getEmpty() - def graph = getDependencyGraph([spec0, spec1]) - [spec0, spec1].each { - assertTrue(graph.containsVertex(it)) - assertEquals(0, graph.edgesOf(it).size()) - } - } - - @Test - void twoBuildsParentAndChildGraph() { - def child = BuildSpec.get(name: 'child', extending: BuildExtension.get('parent')) - def parent = BuildSpec.get(name: 'parent') - def graph = getDependencyGraph([child, parent]) - [child, parent].each { - assertTrue(graph.containsVertex(it)) - } - assertEquals(1, graph.edgeSet().size()) - assertTrue(graph.containsEdge(parent, child)) - } - - @Test - void threeBuildPyramidGraph() { - def left = BuildSpec.get(name: 'left', extending: BuildExtension.get('parent')) - def right = BuildSpec.get(name: 'right', extending: BuildExtension.get('parent')) - def parent = BuildSpec.get(name: 'parent') - def graph = getDependencyGraph([left, right, parent]) - [left, right, parent].each { - assertTrue(graph.containsVertex(it)) - } - assertEquals(2, graph.edgeSet().size()) - assertTrue(graph.containsEdge(parent, left)) - assertTrue(graph.containsEdge(parent, right)) - } - - @Test - void noAncestors() { - def spec = BuildSpec.getEmpty() - def graph = getDependencyGraph([spec]) - def ancestors = getAncestors(spec, graph) - assertEquals(0, ancestors.size()) - } - - @Test - void oneAncestor() { - def child = BuildSpec.get(name: 'child', extending: BuildExtension.get('parent')) - def parent = BuildSpec.get(name: 'parent') - def graph = getDependencyGraph([child, parent]) - def ancestors = getAncestors(child, graph) - assertEquals(1, ancestors.size()) - assertIterableEquals([parent], ancestors) - } - - @Test - void pyramidNotConfusedBySibling() { - def child = BuildSpec.get(name: 'child', extending: BuildExtension.get('parent')) - def sibling = BuildSpec.get(name: 'sibling', extending: BuildExtension.get('parent')) - def parent = BuildSpec.get(name: 'parent') - def graph = getDependencyGraph([child, sibling, parent]) - def ancestorsOfChild = getAncestors(child, graph) - assertEquals(1, ancestorsOfChild.size()) - assertIterableEquals([parent], ancestorsOfChild) - } - - @Test - void threeGenerationAncestors() { - def child = BuildSpec.get(name: 'child', extending: BuildExtension.get('parent')) - def parent = BuildSpec.get(name: 'parent', extending: BuildExtension.get('grandparent')) - def grandparent = BuildSpec.get(name: 'grandparent') - def graph = getDependencyGraph([child, parent, grandparent]) - def ancestorsOfChild = getAncestors(child, graph) - assertEquals(2, ancestorsOfChild.size()) - assertIterableEquals([grandparent, parent], ancestorsOfChild) - } - -} diff --git a/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildScriptBaseTests.groovy b/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildScriptBaseTests.groovy index 50e5d88..de6ab9f 100644 --- a/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildScriptBaseTests.groovy +++ b/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildScriptBaseTests.groovy @@ -77,7 +77,7 @@ final class BuildScriptBaseTests { assertEquals(2, r.size()) assertEquals( [ - BuildSpec.get(name: 'child', extending: BuildExtension.get('parent')), + BuildSpec.get(name: 'child', extending: ['parent']), BuildSpec.get(name: 'parent') ], r @@ -94,8 +94,8 @@ final class BuildScriptBaseTests { assertEquals(3, r.size()) assertEquals( [ - BuildSpec.get(name: 'child', extending: BuildExtension.get('parent')), - BuildSpec.get(name: 'parent', extending: BuildExtension.get('grandparent')), + BuildSpec.get(name: 'child', extending: ['parent']), + BuildSpec.get(name: 'parent', extending: ['grandparent']), BuildSpec.get(name: 'grandparent') ], r @@ -112,8 +112,8 @@ final class BuildScriptBaseTests { assertEquals(3, r.size()) assertEquals( [ - BuildSpec.get(name: 'child0', extending: BuildExtension.get('parent')), - BuildSpec.get(name: 'child1', extending: BuildExtension.get('parent')), + BuildSpec.get(name: 'child0', extending: ['parent']), + BuildSpec.get(name: 'child1', extending: ['parent']), BuildSpec.get(name: 'parent') ], r diff --git a/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtilTests.groovy b/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtilTests.groovy index b870b72..9cdc150 100644 --- a/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtilTests.groovy +++ b/api/src/test/groovy/com/jessebrault/ssg/buildscript/BuildSpecUtilTests.groovy @@ -14,12 +14,12 @@ final class BuildSpecUtilTests { @Test void overwrittenOutputDir(@Mock Function spec1OutputDirFunction) { - def spec0 = new BuildSpec('spec0', true, BuildExtension.getEmpty(), { + def spec0 = BuildSpec.get('spec0', true, []) { outputDirFunction = { } - }) - def spec1 = new BuildSpec('spec1', false, BuildExtension.get('spec0'), { + } + def spec1 = BuildSpec.get('spec1', false, ['spec0']) { outputDirFunction = spec1OutputDirFunction - }) + } def r = BuildSpecUtil.getBuilds([spec0, spec1]) assertEquals(1, r.size()) def b0 = r[0] @@ -29,16 +29,16 @@ final class BuildSpecUtilTests { @Test void outputDirManualConcat() { - def spec0 = new BuildSpec('spec0', true, BuildExtension.getEmpty(), { + def spec0 = BuildSpec.get('spec0', true, []) { outputDirFunction = OutputDirFunctions.DEFAULT - }) - def spec1 = new BuildSpec('spec1', false, BuildExtension.get('spec0'), { + } + def spec1 = BuildSpec.get('spec1', false, ['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] diff --git a/api/src/test/groovy/com/jessebrault/ssg/buildscript/delegates/BuildDelegateTests.groovy b/api/src/test/groovy/com/jessebrault/ssg/buildscript/delegates/BuildDelegateTests.groovy index 7612fe2..d04e17f 100644 --- a/api/src/test/groovy/com/jessebrault/ssg/buildscript/delegates/BuildDelegateTests.groovy +++ b/api/src/test/groovy/com/jessebrault/ssg/buildscript/delegates/BuildDelegateTests.groovy @@ -2,8 +2,12 @@ package com.jessebrault.ssg.buildscript.delegates import com.jessebrault.ssg.SiteSpec import com.jessebrault.ssg.buildscript.Build +import com.jessebrault.ssg.buildscript.BuildIntermediate +import com.jessebrault.ssg.buildscript.BuildMonoids +import com.jessebrault.ssg.buildscript.BuildSpec import com.jessebrault.ssg.buildscript.OutputDir import com.jessebrault.ssg.buildscript.SourceProviders +import com.jessebrault.ssg.buildscript.SyntheticBuildIntermediate import com.jessebrault.ssg.buildscript.TypesContainer import com.jessebrault.ssg.provider.CollectionProvider import com.jessebrault.ssg.provider.CollectionProviders @@ -11,8 +15,6 @@ import com.jessebrault.ssg.task.TaskFactory import com.jessebrault.ssg.task.TaskFactorySpec import com.jessebrault.ssg.text.Text import com.jessebrault.ssg.text.TextTypes -import com.jessebrault.ssg.util.Monoid -import com.jessebrault.ssg.util.Monoids import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.mockito.Mock @@ -29,55 +31,48 @@ final class BuildDelegateTests { private final BuildDelegate d = new BuildDelegate() - private BuildDelegate.Results getResults() { - new BuildDelegate.Results(this.d) + private BuildIntermediate getResults(BuildIntermediate parent = SyntheticBuildIntermediate.getEmpty()) { + new BuildDelegate.BuildDelegateBuildIntermediate( + BuildSpec.getEmpty(), + this.d, + parent, + BuildMonoids.siteSpecMonoid, + BuildMonoids.globalsMonoid, + BuildMonoids.typesMonoid, + BuildMonoids.sourcesMonoid, + BuildMonoids.taskFactoriesMonoid, + BuildMonoids.includedBuildsMonoid + ) } @Test - void simpleOutputDirFunction( - @Mock Function expected, - @Mock Function base, - @Mock Supplier> onEmpty - ) { + void simpleOutputDirFunction(@Mock Function expected) { this.d.outputDirFunction = expected - def r = this.results.getOutputDirFunctionResult(base, onEmpty) + def r = this.getResults().outputDirFunction assertEquals(expected, r) } @Test - void mappedOutputDirFunction( - @Mock Supplier> onEmpty - ) { + void mappedOutputDirFunction() { final Function base = { Build b -> new OutputDir('test') } this.d.outputDirFunction { it.andThen { new OutputDir(it.asString() + '/nested') } } - def r = this.results.getOutputDirFunctionResult(base, onEmpty) + def r = this.getResults(SyntheticBuildIntermediate.get(outputDirFunction: base)) + .outputDirFunction def outputDir = r.apply(Build.getEmpty()) assertEquals('test/nested', outputDir.asString()) } - @Test - void emptyOutputDirFunction( - @Mock Function base, - @Mock Function empty - ) { - assertEquals(empty, this.results.getOutputDirFunctionResult(base, { empty })) - } - @Test void siteSpecNoBase() { this.d.siteSpec { name = 'test' baseUrl = 'testUrl' } - def r = this.results.getSiteSpecResult( - SiteSpec.getBlank(), - true, - SiteSpec.DEFAULT_MONOID - ) + def r = this.getResults().siteSpec assertEquals('test', r.name) assertEquals('testUrl', r.baseUrl) } @@ -88,11 +83,9 @@ final class BuildDelegateTests { name = base.name + 'Preview' baseUrl = base.baseUrl + '/preview' } - def r = this.results.getSiteSpecResult( - new SiteSpec('mySite', 'https://mysite.com'), - true, - SiteSpec.DEFAULT_MONOID - ) + def r = this.getResults( + SyntheticBuildIntermediate.get(siteSpec: new SiteSpec('mySite', 'https://mysite.com')) + ).siteSpec assertEquals('mySitePreview', r.name) assertEquals('https://mysite.com/preview', r.baseUrl) } @@ -102,11 +95,9 @@ final class BuildDelegateTests { this.d.siteSpec { name = '123' } - def r = this.results.getSiteSpecResult( - new SiteSpec('', '456'), - true, - SiteSpec.DEFAULT_MONOID - ) + def r = this.getResults( + SyntheticBuildIntermediate.get(siteSpec: new SiteSpec('', '456')) + ).siteSpec assertEquals('123', r.name) assertEquals('456', r.baseUrl) } @@ -116,25 +107,16 @@ final class BuildDelegateTests { this.d.siteSpec(false) { name = '123' } - def r = this.results.getSiteSpecResult( - new SiteSpec('', '456'), - true, - SiteSpec.DEFAULT_MONOID - ) + def r = this.getResults( + SyntheticBuildIntermediate.get(siteSpec: new SiteSpec('', '456')) + ).siteSpec assertEquals('123', r.name) assertEquals(SiteSpec.DEFAULT_MONOID.zero.baseUrl, r.baseUrl) } @Test void emptySiteSpec() { - assertEquals( - SiteSpec.getBlank(), - this.results.getSiteSpecResult(SiteSpec.getBlank(), true, SiteSpec.DEFAULT_MONOID) - ) - } - - private static Monoid> getGlobalsMonoid() { - Monoids.of([:]) { m0, m1 -> m0 + m1 } + assertEquals(SiteSpec.getBlank(), this.getResults().siteSpec) } @Test @@ -142,7 +124,7 @@ final class BuildDelegateTests { this.d.globals { test = 'abc' } - def r = this.results.getGlobalsResult([:], true, getGlobalsMonoid()) + def r = this.getResults().globals assertEquals([test: 'abc'], r) } @@ -151,17 +133,13 @@ final class BuildDelegateTests { this.d.globals { base -> test = base.test } - def r = this.results.getGlobalsResult( - [test: 'abc'], - true, - getGlobalsMonoid() - ) + def r = this.getResults(SyntheticBuildIntermediate.get(globals: [test: 'abc'])).globals assertEquals([test: 'abc'], r) } @Test void globalsEmpty() { - assertEquals([:], this.results.getGlobalsResult([:], true, getGlobalsMonoid())) + assertEquals([:], this.getResults().globals) } @Test @@ -169,11 +147,7 @@ final class BuildDelegateTests { this.d.types { textTypes << TextTypes.MARKDOWN } - def r = this.results.getTypesResult( - TypesContainer.getEmpty(), - true, - TypesContainer.DEFAULT_MONOID - ) + def r = this.getResults().types assertEquals(TypesContainer.get(textTypes: [TextTypes.MARKDOWN]), r) } @@ -182,11 +156,9 @@ final class BuildDelegateTests { this.d.types(false) { base -> textTypes.addAll(base.textTypes) } - def r = this.results.getTypesResult( - TypesContainer.get(textTypes: [TextTypes.MARKDOWN]), - true, - TypesContainer.DEFAULT_MONOID - ) + def r = this.getResults( + SyntheticBuildIntermediate.get(types: TypesContainer.get(textTypes: [TextTypes.MARKDOWN])) + ).types assertEquals(TypesContainer.get(textTypes: [TextTypes.MARKDOWN]), r) } @@ -195,12 +167,7 @@ final class BuildDelegateTests { this.d.sources { base, types -> texts textsProvider } - def r = this.results.getSourcesResult( - SourceProviders.getEmpty(), - true, - SourceProviders.DEFAULT_MONOID, - TypesContainer.getEmpty() - ) + def r = this.getResults().sources assertTrue(textsProvider in r.textsProvider) } @@ -217,44 +184,27 @@ final class BuildDelegateTests { this.d.sources { base, types -> texts base.textsProvider } - def r = this.results.getSourcesResult( - SourceProviders.get(textsProvider: textsProvider), - true, - SourceProviders.DEFAULT_MONOID, - TypesContainer.getEmpty() - ) + def r = this.getResults( + SyntheticBuildIntermediate.get(sources: SourceProviders.get(textsProvider: textsProvider)) + ).sources assertTrue(textsProvider in r.textsProvider) } @Test void sourceProvidersMergeBase() { def textsProvider = CollectionProviders.fromCollection([] as Collection) - def r = this.results.getSourcesResult( - SourceProviders.get(textsProvider: textsProvider), - true, - SourceProviders.DEFAULT_MONOID, - TypesContainer.getEmpty() - ) + def r = this.getResults( + SyntheticBuildIntermediate.get(sources: SourceProviders.get(textsProvider: textsProvider)) + ).sources assertTrue(textsProvider in r.textsProvider) } - private static Monoid>> getTaskFactoriesMonoid() { - Monoids.of([] as Collection>) { c0, c1 -> - c0 + c1 - } - } - @Test void taskFactoriesNoBase(@Mock Supplier taskFactorySupplier) { this.d.taskFactories { base, sources -> register('f0', taskFactorySupplier) } - def r = this.results.getTaskFactoriesResult( - [], - true, - getTaskFactoriesMonoid(), - SourceProviders.getEmpty() - ) + def r = this.getResults().taskFactorySpecs assertEquals(1, r.size()) def spec0 = r[0] assertEquals('f0', spec0.name) @@ -266,12 +216,11 @@ final class BuildDelegateTests { this.d.taskFactories(false) { base, sources -> registerAll(base) } - def r = this.results.getTaskFactoriesResult( - [new TaskFactorySpec('spec0', taskFactorySupplier, [])], - true, - getTaskFactoriesMonoid(), - SourceProviders.getEmpty() - ) + def r = this.getResults( + SyntheticBuildIntermediate.get( + taskFactorySpecs: [new TaskFactorySpec('spec0', taskFactorySupplier, [])] + ) + ).taskFactorySpecs assertEquals(1, r.size()) def spec0 = r[0] assertEquals('spec0', spec0.name) @@ -281,12 +230,11 @@ final class BuildDelegateTests { @Test void taskFactoriesMergeBase(@Mock Supplier taskFactorySupplier) { - def r = this.results.getTaskFactoriesResult( - [new TaskFactorySpec('spec0', taskFactorySupplier, [])], - true, - getTaskFactoriesMonoid(), - SourceProviders.getEmpty() - ) + def r = this.getResults( + SyntheticBuildIntermediate.get( + taskFactorySpecs: [new TaskFactorySpec('spec0', taskFactorySupplier, [])] + ) + ).taskFactorySpecs assertEquals(1, r.size()) def spec0 = r[0] assertEquals('spec0', spec0.name) @@ -294,17 +242,13 @@ final class BuildDelegateTests { assertEquals([], spec0.configurators) } - private static Monoid> getIncludedBuildsMonoid() { - Monoids.of([]) { c0, c1 -> c0 + c1 } - } - @Test void includedBuildsNoBase() { this.d.concatIncludedBuildsWithBase = false this.d.includeBuild('included') - def r = this.results.getIncludedBuildsResult( - ['notIncluded'], true, getIncludedBuildsMonoid() - ) + def r = this.getResults( + SyntheticBuildIntermediate.get(includedBuilds: ['notIncluded']) + ).includedBuilds assertEquals(1, r.size()) def includedBuild0 = r[0] assertEquals('included', includedBuild0) @@ -313,9 +257,9 @@ final class BuildDelegateTests { @Test void includedBuildsWithBase() { this.d.concatIncludedBuildsWithBase = true - def r = this.results.getIncludedBuildsResult( - ['baseIncluded'], true, getIncludedBuildsMonoid() - ) + def r = this.getResults( + SyntheticBuildIntermediate.get(includedBuilds: ['baseIncluded']) + ).includedBuilds assertEquals(1, r.size()) def includedBuild0 = r[0] assertEquals('baseIncluded', includedBuild0)