Major work on buildscript dsl; new abstract build concept. N.B.: task factories not merged yet.
This commit is contained in:
parent
c74d80a69e
commit
1f8bd3270c
3
TODO.md
3
TODO.md
@ -19,10 +19,11 @@ Here will be kept all of the various todos for this project, organized by releas
|
|||||||
- [x] Remove `lib` module.
|
- [x] Remove `lib` module.
|
||||||
- [ ] Add a way for CLI to choose a build to do, or multiple builds, defaulting to 'default' if it exists.
|
- [ ] Add a way for CLI to choose a build to do, or multiple builds, defaulting to 'default' if it exists.
|
||||||
- [ ] Write lots of tests for buildscript dsl, etc.
|
- [ ] Write lots of tests for buildscript dsl, etc.
|
||||||
- [ ] Explore `base` in buildScript dsl.
|
- [x] Explore `base` in buildScript dsl.
|
||||||
- Get rid of `allBuilds` concept, and replace it with composable/concat-able builds. In the dsl we could have a notion of `abstractBuild` which can be 'extended' (i.e., on the left side of a concat operation) but not actually run (since it doesn't have a name).
|
- Get rid of `allBuilds` concept, and replace it with composable/concat-able builds. In the dsl we could have a notion of `abstractBuild` which can be 'extended' (i.e., on the left side of a concat operation) but not actually run (since it doesn't have a name).
|
||||||
- `OutputDir` should be concat-able, such that the left is the *base* for the right.
|
- `OutputDir` should be concat-able, such that the left is the *base* for the right.
|
||||||
- `OutputDirFunctions.concat` should be concat-able as well, such that both are `BiFunction<OutputDir, Build, OutputDir>`, and the output of the left is the input of the right.
|
- `OutputDirFunctions.concat` should be concat-able as well, such that both are `BiFunction<OutputDir, Build, OutputDir>`, and the output of the left is the input of the right.
|
||||||
|
- Make the delegates as dumb as possible; no more `getResult` methods; make different classes/object handle concat'ing and getting results.
|
||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
- [ ] Update CHANGELOG to reflect the gsp-dsl changes.
|
- [ ] Update CHANGELOG to reflect the gsp-dsl changes.
|
||||||
|
@ -8,7 +8,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// https://mvnrepository.com/artifact/org.apache.groovy/groovy-templates
|
// https://mvnrepository.com/artifact/org.apache.groovy/groovy-templates
|
||||||
implementation 'org.apache.groovy:groovy-templates:4.0.9'
|
implementation 'org.apache.groovy:groovy-templates:4.0.12'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
||||||
implementation 'org.commonmark:commonmark:0.21.0'
|
implementation 'org.commonmark:commonmark:0.21.0'
|
||||||
@ -18,6 +18,9 @@ dependencies {
|
|||||||
|
|
||||||
// https://mvnrepository.com/artifact/org.jsoup/jsoup
|
// https://mvnrepository.com/artifact/org.jsoup/jsoup
|
||||||
implementation 'org.jsoup:jsoup:1.16.1'
|
implementation 'org.jsoup:jsoup:1.16.1'
|
||||||
|
|
||||||
|
// https://mvnrepository.com/artifact/org.jgrapht/jgrapht-core
|
||||||
|
implementation 'org.jgrapht:jgrapht-core:1.5.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.jessebrault.ssg
|
package com.jessebrault.ssg
|
||||||
|
|
||||||
import com.jessebrault.ssg.util.Monoid
|
import com.jessebrault.ssg.util.Monoid
|
||||||
|
import com.jessebrault.ssg.util.Monoids
|
||||||
import groovy.transform.EqualsAndHashCode
|
import groovy.transform.EqualsAndHashCode
|
||||||
import groovy.transform.NullCheck
|
import groovy.transform.NullCheck
|
||||||
import groovy.transform.TupleConstructor
|
import groovy.transform.TupleConstructor
|
||||||
@ -10,10 +11,7 @@ import groovy.transform.TupleConstructor
|
|||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
final class SiteSpec {
|
final class SiteSpec {
|
||||||
|
|
||||||
static final Monoid<SiteSpec> defaultSemiGroup = new Monoid<>(
|
static final Monoid<SiteSpec> DEFAULT_MONOID = Monoids.of(getBlank(), SiteSpec::concat)
|
||||||
SiteSpec::concat,
|
|
||||||
SiteSpec::getBlank
|
|
||||||
)
|
|
||||||
|
|
||||||
static SiteSpec getBlank() {
|
static SiteSpec getBlank() {
|
||||||
new SiteSpec('', '')
|
new SiteSpec('', '')
|
||||||
|
@ -14,33 +14,6 @@ import java.util.function.Function
|
|||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
final class Build {
|
final class Build {
|
||||||
|
|
||||||
@TupleConstructor(defaults = false)
|
|
||||||
@NullCheck(includeGenerated = true)
|
|
||||||
@EqualsAndHashCode
|
|
||||||
static final class AllBuilds {
|
|
||||||
|
|
||||||
static AllBuilds concat(AllBuilds ab0, AllBuilds ab1) {
|
|
||||||
new AllBuilds(
|
|
||||||
ab0.siteSpec + ab1.siteSpec,
|
|
||||||
ab0.globals + ab1.globals,
|
|
||||||
ab0.taskFactorySpecs + ab1.taskFactorySpecs
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
static AllBuilds getEmpty() {
|
|
||||||
new AllBuilds(SiteSpec.getBlank(), [:], [])
|
|
||||||
}
|
|
||||||
|
|
||||||
final SiteSpec siteSpec
|
|
||||||
final Map<String, Object> globals
|
|
||||||
final Collection<TaskFactorySpec<TaskFactory>> taskFactorySpecs
|
|
||||||
|
|
||||||
AllBuilds plus(AllBuilds other) {
|
|
||||||
concat(this, other)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static Build getEmpty() {
|
static Build getEmpty() {
|
||||||
new Build(
|
new Build(
|
||||||
'',
|
'',
|
||||||
@ -71,16 +44,6 @@ final class Build {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Build from(AllBuilds allBuilds) {
|
|
||||||
new Build(
|
|
||||||
'',
|
|
||||||
OutputDirFunctions.DEFAULT,
|
|
||||||
allBuilds.siteSpec,
|
|
||||||
allBuilds.globals,
|
|
||||||
allBuilds.taskFactorySpecs
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
final String name
|
final String name
|
||||||
final Function<Build, OutputDir> outputDirFunction
|
final Function<Build, OutputDir> outputDirFunction
|
||||||
final SiteSpec siteSpec
|
final SiteSpec siteSpec
|
||||||
|
@ -0,0 +1,57 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
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<BuildSpec, DefaultEdge> graph,
|
||||||
|
BuildSpec spec,
|
||||||
|
Collection<BuildSpec> 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<BuildSpec, DefaultEdge> getDependencyGraph(Collection<BuildSpec> buildSpecs) {
|
||||||
|
logger.trace(enter, '')
|
||||||
|
final Graph<BuildSpec, DefaultEdge> 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<BuildSpec> getAncestors(BuildSpec child, Graph<BuildSpec, DefaultEdge> graph) {
|
||||||
|
logger.trace(enter, 'child: {}, graph: {}', child, graph)
|
||||||
|
if (child.extending.isEmpty()) {
|
||||||
|
def r = [] as Collection<BuildSpec>
|
||||||
|
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() {}
|
||||||
|
|
||||||
|
}
|
@ -1,78 +1,63 @@
|
|||||||
package com.jessebrault.ssg.buildscript
|
package com.jessebrault.ssg.buildscript
|
||||||
|
|
||||||
import com.jessebrault.ssg.buildscript.Build.AllBuilds
|
import com.jessebrault.ssg.buildscript.delegates.BuildDelegate
|
||||||
import com.jessebrault.ssg.buildscript.dsl.AllBuildsDelegate
|
import groovy.transform.PackageScope
|
||||||
import com.jessebrault.ssg.buildscript.dsl.BuildDelegate
|
|
||||||
import org.slf4j.Logger
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import org.slf4j.Marker
|
import org.slf4j.Marker
|
||||||
import org.slf4j.MarkerFactory
|
import org.slf4j.MarkerFactory
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull
|
||||||
|
|
||||||
abstract class BuildScriptBase extends Script {
|
abstract class BuildScriptBase extends Script {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(BuildScriptBase)
|
protected static final Logger logger = LoggerFactory.getLogger(BuildScriptBase)
|
||||||
private static final Marker enter = MarkerFactory.getMarker('ENTER')
|
protected static final Marker enter = MarkerFactory.getMarker('ENTER')
|
||||||
private static final Marker exit = MarkerFactory.getMarker('EXIT')
|
protected static final Marker exit = MarkerFactory.getMarker('EXIT')
|
||||||
|
|
||||||
private final Collection<AllBuildsDelegate> allBuildsDelegates = []
|
protected final Collection<BuildSpec> buildSpecs = []
|
||||||
private final Collection<BuildDelegate> buildDelegates = []
|
|
||||||
|
|
||||||
private int currentBuildNumber = 0
|
/**
|
||||||
|
* args keys: name (required), extending (optional)
|
||||||
final AllBuilds defaultAllBuilds = AllBuilds.getEmpty()
|
*
|
||||||
|
* @param args
|
||||||
void build(
|
* @param buildClosure
|
||||||
|
*/
|
||||||
|
void abstractBuild(
|
||||||
|
Map<String, Object> args,
|
||||||
@DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST)
|
@DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
Closure<?> buildClosure
|
Closure<?> buildClosure
|
||||||
) {
|
) {
|
||||||
logger.trace(enter, 'buildClosure: {}', buildClosure)
|
this.buildSpecs << new BuildSpec(
|
||||||
this.build('build' + this.currentBuildNumber, buildClosure)
|
requireNonNull(args.name as String),
|
||||||
logger.trace(exit, '')
|
true,
|
||||||
|
args.extending != null ? BuildExtension.get(args.extending as String) : BuildExtension.getEmpty(),
|
||||||
|
buildClosure
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* args keys: name (required), extending (optional)
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
* @param buildClosure
|
||||||
|
*/
|
||||||
void build(
|
void build(
|
||||||
String name,
|
Map<String, Object> args,
|
||||||
@DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST)
|
@DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
Closure<?> buildClosure
|
Closure<?> buildClosure
|
||||||
) {
|
) {
|
||||||
logger.trace(enter, 'name: {}, buildClosure: {}', name, buildClosure)
|
this.buildSpecs << new BuildSpec(
|
||||||
def d = new BuildDelegate().tap {
|
requireNonNull(args.name as String),
|
||||||
it.name = name
|
false,
|
||||||
}
|
args.extending != null ? BuildExtension.get(args.extending as String) : BuildExtension.getEmpty(),
|
||||||
buildClosure.setDelegate(d)
|
buildClosure
|
||||||
buildClosure.setResolveStrategy(Closure.DELEGATE_FIRST)
|
)
|
||||||
buildClosure()
|
|
||||||
this.buildDelegates << d
|
|
||||||
this.currentBuildNumber++
|
|
||||||
logger.trace(exit, '')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void allBuilds(
|
@PackageScope
|
||||||
@DelegatesTo(value = AllBuildsDelegate, strategy = Closure.DELEGATE_FIRST)
|
Collection<BuildSpec> getBuildSpecs() {
|
||||||
Closure<?> allBuildsClosure
|
this.buildSpecs
|
||||||
) {
|
|
||||||
logger.trace(enter, 'allBuildsClosure: {}', allBuildsClosure)
|
|
||||||
def d = new AllBuildsDelegate()
|
|
||||||
allBuildsClosure.setDelegate(d)
|
|
||||||
allBuildsClosure.setResolveStrategy(Closure.DELEGATE_FIRST)
|
|
||||||
allBuildsClosure()
|
|
||||||
this.allBuildsDelegates << d
|
|
||||||
logger.trace(exit, '')
|
|
||||||
}
|
|
||||||
|
|
||||||
Collection<Build> getBuilds() {
|
|
||||||
logger.trace(enter, '')
|
|
||||||
def allBuilds = this.defaultAllBuilds
|
|
||||||
this.allBuildsDelegates.each {
|
|
||||||
allBuilds += it.getResult()
|
|
||||||
}
|
|
||||||
|
|
||||||
def baseBuild = Build.from(allBuilds)
|
|
||||||
def result = this.buildDelegates.collect {
|
|
||||||
baseBuild + it.getResult()
|
|
||||||
}
|
|
||||||
logger.trace(exit, 'result: {}', result)
|
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
package com.jessebrault.ssg.buildscript
|
||||||
|
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.NullCheck
|
||||||
|
import groovy.transform.PackageScope
|
||||||
|
import groovy.transform.TupleConstructor
|
||||||
|
|
||||||
|
@PackageScope
|
||||||
|
@TupleConstructor(defaults = false)
|
||||||
|
@NullCheck(includeGenerated = true)
|
||||||
|
@EqualsAndHashCode(excludes = 'buildClosure')
|
||||||
|
final class BuildSpec {
|
||||||
|
|
||||||
|
static BuildSpec getEmpty() {
|
||||||
|
new BuildSpec('', false, BuildExtension.getEmpty(), { })
|
||||||
|
}
|
||||||
|
|
||||||
|
static BuildSpec get(Map<String, Object> args) {
|
||||||
|
new BuildSpec(
|
||||||
|
args.name as String ?: '',
|
||||||
|
args.isAbstract as boolean ?: false,
|
||||||
|
args.extending as BuildExtension ?: BuildExtension.getEmpty(),
|
||||||
|
args.buildClosure as Closure<?> ?: { }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
final String name
|
||||||
|
final boolean isAbstract
|
||||||
|
final BuildExtension extending
|
||||||
|
final Closure<?> buildClosure
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String toString() {
|
||||||
|
"BuildSpec(name: ${ this.name }, isAbstract: ${ this.isAbstract }, extending: ${ this.extending })"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package com.jessebrault.ssg.buildscript
|
||||||
|
|
||||||
|
import com.jessebrault.ssg.SiteSpec
|
||||||
|
import com.jessebrault.ssg.buildscript.delegates.BuildDelegate
|
||||||
|
import com.jessebrault.ssg.util.Monoid
|
||||||
|
import com.jessebrault.ssg.util.Monoids
|
||||||
|
import com.jessebrault.ssg.util.Zero
|
||||||
|
import org.jgrapht.traverse.DepthFirstIterator
|
||||||
|
import org.slf4j.Logger
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
import org.slf4j.Marker
|
||||||
|
import org.slf4j.MarkerFactory
|
||||||
|
|
||||||
|
import java.util.function.BiFunction
|
||||||
|
|
||||||
|
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 <T> T reduceResults(
|
||||||
|
Collection<BuildDelegate.Results> resultsCollection,
|
||||||
|
Zero<T> tZero,
|
||||||
|
BiFunction<T, BuildDelegate.Results, T> resultsToT
|
||||||
|
) {
|
||||||
|
resultsCollection.inject(tZero.zero) { acc, r ->
|
||||||
|
resultsToT.apply(acc, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Collection<BuildDelegate.Results> mapBuildSpecsToResults(Collection<BuildSpec> 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 Monoid<Map<String, Object>> getGlobalsMonoid() {
|
||||||
|
Monoids.of([:]) { m0, m1 ->
|
||||||
|
m0 + m1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Build toBuild(
|
||||||
|
Collection<BuildSpec> 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, { OutputDirFunctions.DEFAULT_MONOID.zero })
|
||||||
|
}
|
||||||
|
def siteSpecResult = reduceResults(allResults, SiteSpec.DEFAULT_MONOID) { acc, r ->
|
||||||
|
r.getSiteSpecResult(acc, true, SiteSpec.DEFAULT_MONOID)
|
||||||
|
}
|
||||||
|
def globalsResult = reduceResults(allResults, getGlobalsMonoid()) { acc, r ->
|
||||||
|
r.getGlobalsResult(acc, true, getGlobalsMonoid())
|
||||||
|
}
|
||||||
|
new Build(
|
||||||
|
specs[0].name,
|
||||||
|
outputDirFunctionResult,
|
||||||
|
siteSpecResult,
|
||||||
|
globalsResult,
|
||||||
|
[] // TODO
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
static Collection<Build> getBuilds(Collection<BuildSpec> buildSpecs) {
|
||||||
|
logger.trace(enter, '')
|
||||||
|
def graph = BuildGraphUtil.getDependencyGraph(buildSpecs)
|
||||||
|
def r = new DepthFirstIterator<>(graph).findResults {
|
||||||
|
if (it.isAbstract) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
def ancestors = BuildGraphUtil.getAncestors(it, graph)
|
||||||
|
logger.debug('ancestors of {}: {}', it, ancestors)
|
||||||
|
toBuild([*ancestors, it])
|
||||||
|
}
|
||||||
|
logger.trace(exit, 'r: {}', r)
|
||||||
|
r
|
||||||
|
}
|
||||||
|
|
||||||
|
private BuildSpecUtil() {}
|
||||||
|
|
||||||
|
}
|
@ -1,11 +1,16 @@
|
|||||||
package com.jessebrault.ssg.buildscript
|
package com.jessebrault.ssg.buildscript
|
||||||
|
|
||||||
|
import com.jessebrault.ssg.util.Monoid
|
||||||
|
import com.jessebrault.ssg.util.Monoids
|
||||||
|
|
||||||
import java.util.function.Function
|
import java.util.function.Function
|
||||||
|
|
||||||
final class OutputDirFunctions {
|
final class OutputDirFunctions {
|
||||||
|
|
||||||
static final Function<Build, OutputDir> DEFAULT = { Build build -> new OutputDir(build.name) }
|
static final Function<Build, OutputDir> DEFAULT = { Build build -> new OutputDir(build.name) }
|
||||||
|
|
||||||
|
static final Monoid<Function<Build, OutputDir>> DEFAULT_MONOID = Monoids.of(DEFAULT, OutputDirFunctions::concat)
|
||||||
|
|
||||||
static Function<Build, OutputDir> concat(
|
static Function<Build, OutputDir> concat(
|
||||||
Function<Build, OutputDir> f0,
|
Function<Build, OutputDir> f0,
|
||||||
Function<Build, OutputDir> f1
|
Function<Build, OutputDir> f1
|
||||||
|
@ -4,6 +4,7 @@ import groovy.transform.NullCheck
|
|||||||
import groovy.transform.stc.ClosureParams
|
import groovy.transform.stc.ClosureParams
|
||||||
import groovy.transform.stc.SimpleType
|
import groovy.transform.stc.SimpleType
|
||||||
import org.codehaus.groovy.control.CompilerConfiguration
|
import org.codehaus.groovy.control.CompilerConfiguration
|
||||||
|
import org.jgrapht.traverse.DepthFirstIterator
|
||||||
|
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ final class SimpleBuildScriptRunner implements BuildScriptRunner {
|
|||||||
assert buildScript instanceof BuildScriptBase
|
assert buildScript instanceof BuildScriptBase
|
||||||
configureBuildScript.accept(buildScript)
|
configureBuildScript.accept(buildScript)
|
||||||
buildScript.run()
|
buildScript.run()
|
||||||
buildScript.getBuilds()
|
BuildSpecUtil.getBuilds(buildScript.buildSpecs)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -48,7 +49,7 @@ final class SimpleBuildScriptRunner implements BuildScriptRunner {
|
|||||||
|
|
||||||
}
|
}
|
||||||
base.run()
|
base.run()
|
||||||
base.getBuilds()
|
BuildSpecUtil.getBuilds(base.buildSpecs)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ import com.jessebrault.ssg.provider.CollectionProvider
|
|||||||
import com.jessebrault.ssg.provider.CollectionProviders
|
import com.jessebrault.ssg.provider.CollectionProviders
|
||||||
import com.jessebrault.ssg.template.Template
|
import com.jessebrault.ssg.template.Template
|
||||||
import com.jessebrault.ssg.text.Text
|
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.EqualsAndHashCode
|
||||||
import groovy.transform.NullCheck
|
import groovy.transform.NullCheck
|
||||||
import groovy.transform.TupleConstructor
|
import groovy.transform.TupleConstructor
|
||||||
@ -16,6 +18,8 @@ import groovy.transform.TupleConstructor
|
|||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
final class SourceProviders {
|
final class SourceProviders {
|
||||||
|
|
||||||
|
static final Monoid<SourceProviders> DEFAULT_MONOID = Monoids.of(getEmpty(), SourceProviders::concat)
|
||||||
|
|
||||||
static SourceProviders concat(SourceProviders sp0, SourceProviders sp1) {
|
static SourceProviders concat(SourceProviders sp0, SourceProviders sp1) {
|
||||||
new SourceProviders(
|
new SourceProviders(
|
||||||
sp0.textsProvider + sp1.textsProvider,
|
sp0.textsProvider + sp1.textsProvider,
|
||||||
@ -61,4 +65,11 @@ final class SourceProviders {
|
|||||||
concat(this, other)
|
concat(this, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String toString() {
|
||||||
|
"SourceProviders(textsProvider: ${ this.textsProvider }, modelsProvider: ${ this.modelsProvider }, " +
|
||||||
|
"pagesProvider: ${ this.pagesProvider }, templatesProvider: ${ this.templatesProvider }, " +
|
||||||
|
"partsProvider: ${ this.partsProvider })"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,8 @@ import com.jessebrault.ssg.page.PageType
|
|||||||
import com.jessebrault.ssg.part.PartType
|
import com.jessebrault.ssg.part.PartType
|
||||||
import com.jessebrault.ssg.template.TemplateType
|
import com.jessebrault.ssg.template.TemplateType
|
||||||
import com.jessebrault.ssg.text.TextType
|
import com.jessebrault.ssg.text.TextType
|
||||||
|
import com.jessebrault.ssg.util.Monoid
|
||||||
|
import com.jessebrault.ssg.util.Monoids
|
||||||
import groovy.transform.EqualsAndHashCode
|
import groovy.transform.EqualsAndHashCode
|
||||||
import groovy.transform.NullCheck
|
import groovy.transform.NullCheck
|
||||||
import groovy.transform.TupleConstructor
|
import groovy.transform.TupleConstructor
|
||||||
@ -13,10 +15,21 @@ import groovy.transform.TupleConstructor
|
|||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
final class TypesContainer {
|
final class TypesContainer {
|
||||||
|
|
||||||
|
static final Monoid<TypesContainer> DEFAULT_MONOID = Monoids.of(getEmpty(), TypesContainer::concat)
|
||||||
|
|
||||||
static TypesContainer getEmpty() {
|
static TypesContainer getEmpty() {
|
||||||
new TypesContainer([], [], [], [])
|
new TypesContainer([], [], [], [])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TypesContainer get(Map<String, Object> args) {
|
||||||
|
new TypesContainer(
|
||||||
|
args.textTypes ? args.textTypes as Collection<TextType> : [],
|
||||||
|
args.pageTypes ? args.pageTypes as Collection<PageType> : [],
|
||||||
|
args.templateTypes ? args.templateTypes as Collection<TemplateType> : [],
|
||||||
|
args.partTypes ? args.partTypes as Collection<PartType> : []
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
static TypesContainer concat(TypesContainer tc0, TypesContainer tc1) {
|
static TypesContainer concat(TypesContainer tc0, TypesContainer tc1) {
|
||||||
new TypesContainer(
|
new TypesContainer(
|
||||||
tc0.textTypes + tc1.textTypes,
|
tc0.textTypes + tc1.textTypes,
|
||||||
@ -26,13 +39,19 @@ final class TypesContainer {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Collection<TextType> textTypes
|
final Collection<TextType> textTypes
|
||||||
Collection<PageType> pageTypes
|
final Collection<PageType> pageTypes
|
||||||
Collection<TemplateType> templateTypes
|
final Collection<TemplateType> templateTypes
|
||||||
Collection<PartType> partTypes
|
final Collection<PartType> partTypes
|
||||||
|
|
||||||
TypesContainer plus(TypesContainer other) {
|
TypesContainer plus(TypesContainer other) {
|
||||||
concat(this, other)
|
concat(this, other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String toString() {
|
||||||
|
"TypesContainer(textTypes: ${ this.textTypes }, pageTypes: ${ this.pageTypes }, " +
|
||||||
|
"templateTypes: ${ this.templateTypes }, partTypes: ${ this.partTypes })"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,287 @@
|
|||||||
|
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.mutable.Mutable
|
||||||
|
import com.jessebrault.ssg.mutable.Mutables
|
||||||
|
import com.jessebrault.ssg.task.TaskFactory
|
||||||
|
import com.jessebrault.ssg.task.TaskFactorySpec
|
||||||
|
import com.jessebrault.ssg.util.Monoid
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.NullCheck
|
||||||
|
import groovy.transform.TupleConstructor
|
||||||
|
import groovy.transform.stc.ClosureParams
|
||||||
|
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)
|
||||||
|
@EqualsAndHashCode(includeFields = true)
|
||||||
|
final class BuildDelegate {
|
||||||
|
|
||||||
|
@TupleConstructor(includeFields = true, defaults = false)
|
||||||
|
@NullCheck(includeGenerated = true)
|
||||||
|
@EqualsAndHashCode(includeFields = true)
|
||||||
|
static final class Results {
|
||||||
|
|
||||||
|
private final BuildDelegate delegate
|
||||||
|
|
||||||
|
Function<Build, OutputDir> getOutputDirFunctionResult(
|
||||||
|
Function<Build, OutputDir> base,
|
||||||
|
Supplier<Function<Build, OutputDir>> onEmpty
|
||||||
|
) {
|
||||||
|
this.delegate.outputDirFunction.getOrElse {
|
||||||
|
this.delegate.outputDirFunctionMapper.match(onEmpty) {
|
||||||
|
it.apply(base)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SiteSpec getSiteSpecResult(
|
||||||
|
SiteSpec base,
|
||||||
|
boolean onConcatWithBaseEmpty,
|
||||||
|
Monoid<SiteSpec> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> getGlobalsResult(
|
||||||
|
Map<String, Object> base,
|
||||||
|
boolean onConcatWithBaseEmpty,
|
||||||
|
Monoid<Map<String, Object>> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TypesContainer getTypesResult(
|
||||||
|
TypesContainer base,
|
||||||
|
boolean onConcatWithBaseEmpty,
|
||||||
|
Monoid<TypesContainer> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceProviders getSourcesResult(
|
||||||
|
SourceProviders base,
|
||||||
|
boolean onConcatWithBaseEmpty,
|
||||||
|
Monoid<SourceProviders> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<TaskFactorySpec<TaskFactory>> getTaskFactoriesResult(
|
||||||
|
Collection<TaskFactorySpec<TaskFactory>> base,
|
||||||
|
boolean onConcatWithBaseEmpty,
|
||||||
|
Monoid<Collection<TaskFactorySpec<TaskFactory>>> 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Mutable<Function<Build, OutputDir>> outputDirFunction = Mutables.getEmpty()
|
||||||
|
private final Mutable<UnaryOperator<Function<Build, OutputDir>>> outputDirFunctionMapper = Mutables.getEmpty()
|
||||||
|
|
||||||
|
private final Mutable<Boolean> siteSpecConcatBase = Mutables.getEmpty()
|
||||||
|
private final Mutable<Closure<?>> siteSpecClosure = Mutables.getEmpty()
|
||||||
|
|
||||||
|
private final Mutable<Boolean> globalsConcatBase = Mutables.getEmpty()
|
||||||
|
private final Mutable<Closure<?>> globalsClosure = Mutables.getEmpty()
|
||||||
|
|
||||||
|
private final Mutable<Boolean> typesConcatBase = Mutables.getEmpty()
|
||||||
|
private final Mutable<Closure<?>> typesClosure = Mutables.getEmpty()
|
||||||
|
|
||||||
|
private final Mutable<Boolean> sourcesConcatBase = Mutables.getEmpty()
|
||||||
|
private final Mutable<Closure<?>> sourcesClosure = Mutables.getEmpty()
|
||||||
|
|
||||||
|
private final Mutable<Boolean> taskFactoriesConcatBase = Mutables.getEmpty()
|
||||||
|
private final Mutable<Closure<?>> taskFactoriesClosure = Mutables.getEmpty()
|
||||||
|
|
||||||
|
void setOutputDirFunction(Function<Build, OutputDir> outputDirFunction) {
|
||||||
|
this.outputDirFunction.set(outputDirFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOutputDir(File file) {
|
||||||
|
this.outputDirFunction.set { new OutputDir(file) }
|
||||||
|
}
|
||||||
|
|
||||||
|
void setOutputDir(String path) {
|
||||||
|
this.outputDirFunction.set { new OutputDir(path) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maps the *base*
|
||||||
|
void outputDirFunction(UnaryOperator<Function<Build, OutputDir>> mapper) {
|
||||||
|
this.outputDirFunctionMapper.set(mapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
void siteSpec(
|
||||||
|
@DelegatesTo(value = SiteSpecDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.SiteSpec')
|
||||||
|
Closure<?> siteSpecClosure
|
||||||
|
) {
|
||||||
|
this.siteSpec(true, siteSpecClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
void siteSpec(
|
||||||
|
boolean concatWithBase,
|
||||||
|
@DelegatesTo(value = SiteSpecDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.SiteSpec')
|
||||||
|
Closure<?> siteSpecClosure
|
||||||
|
) {
|
||||||
|
this.siteSpecConcatBase.set(concatWithBase)
|
||||||
|
this.siteSpecClosure.set(siteSpecClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
void globals(
|
||||||
|
@DelegatesTo(value = GlobalsDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(value = FromString, options = 'Map<String, Object>')
|
||||||
|
Closure<?> globalsClosure
|
||||||
|
) {
|
||||||
|
this.globals(true, globalsClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
void globals(
|
||||||
|
boolean concatWithBase,
|
||||||
|
@DelegatesTo(value = GlobalsDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(value = FromString, options = 'Map<String, Object>')
|
||||||
|
Closure<?> globalsClosure
|
||||||
|
) {
|
||||||
|
this.globalsConcatBase.set(concatWithBase)
|
||||||
|
this.globalsClosure.set(globalsClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
void types(
|
||||||
|
@DelegatesTo(value = TypesDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.buildscript.TypesContainer')
|
||||||
|
Closure<?> typesClosure
|
||||||
|
) {
|
||||||
|
this.types(true, typesClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
void types(
|
||||||
|
boolean concatWithBase,
|
||||||
|
@DelegatesTo(value = TypesDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.buildscript.TypesContainer')
|
||||||
|
Closure<?> typesClosure
|
||||||
|
) {
|
||||||
|
this.typesConcatBase.set(concatWithBase)
|
||||||
|
this.typesClosure.set(typesClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
void sources(
|
||||||
|
@DelegatesTo(value = SourceProvidersDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(
|
||||||
|
value = FromString,
|
||||||
|
options = 'com.jessebrault.ssg.buildscript.SourceProviders, com.jessebrault.ssg.buildscript.TypesContainer'
|
||||||
|
)
|
||||||
|
Closure<?> sourcesClosure
|
||||||
|
) {
|
||||||
|
this.sources(true, sourcesClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
void sources(
|
||||||
|
boolean concatWithBase,
|
||||||
|
@DelegatesTo(value = SourceProvidersDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(
|
||||||
|
value = FromString,
|
||||||
|
options = 'com.jessebrault.ssg.buildscript.SourceProviders, com.jessebrault.ssg.buildscript.TypesContainer'
|
||||||
|
)
|
||||||
|
Closure<?> sourcesClosure
|
||||||
|
) {
|
||||||
|
this.sourcesConcatBase.set(concatWithBase)
|
||||||
|
this.sourcesClosure.set(sourcesClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
void taskFactories(
|
||||||
|
@DelegatesTo(value = TaskFactoriesDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(
|
||||||
|
value = FromString,
|
||||||
|
options = 'java.util.Collection<com.jessebrault.ssg.task.TaskFactorySpec<com.jessebrault.ssg.task.TaskFactory>>, com.jessebrault.ssg.buildscript.SourceProviders'
|
||||||
|
)
|
||||||
|
Closure<?> taskFactoriesClosure
|
||||||
|
) {
|
||||||
|
this.taskFactories(true, taskFactoriesClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
void taskFactories(
|
||||||
|
boolean concatWithBase,
|
||||||
|
@DelegatesTo(value = TaskFactoriesDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
@ClosureParams(
|
||||||
|
value = FromString,
|
||||||
|
options = 'java.util.Collection<com.jessebrault.ssg.task.TaskFactorySpec<com.jessebrault.ssg.task.TaskFactory>>, com.jessebrault.ssg.buildscript.SourceProviders'
|
||||||
|
)
|
||||||
|
Closure<?> taskFactoriesClosure
|
||||||
|
) {
|
||||||
|
this.taskFactoriesConcatBase.set(concatWithBase)
|
||||||
|
this.taskFactoriesClosure.set(taskFactoriesClosure)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
package com.jessebrault.ssg.buildscript.delegates
|
||||||
|
|
||||||
final class GlobalsDelegate {
|
final class GlobalsDelegate {
|
||||||
|
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.jessebrault.ssg.buildscript.delegates
|
||||||
|
|
||||||
|
import com.jessebrault.ssg.SiteSpec
|
||||||
|
import com.jessebrault.ssg.util.Zero
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull
|
||||||
|
|
||||||
|
final class SiteSpecDelegate {
|
||||||
|
|
||||||
|
private String name
|
||||||
|
private String baseUrl
|
||||||
|
|
||||||
|
SiteSpecDelegate(Zero<SiteSpec> siteSpecZero) {
|
||||||
|
this.name = siteSpecZero.zero.name
|
||||||
|
this.baseUrl = siteSpecZero.zero.baseUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
String getName() {
|
||||||
|
return this.name
|
||||||
|
}
|
||||||
|
|
||||||
|
void setName(String name) {
|
||||||
|
this.name = requireNonNull(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
String getBaseUrl() {
|
||||||
|
return this.baseUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
void setBaseUrl(String baseUrl) {
|
||||||
|
this.baseUrl = requireNonNull(baseUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
SiteSpec getResult() {
|
||||||
|
new SiteSpec(this.name, this.baseUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
package com.jessebrault.ssg.buildscript.delegates
|
||||||
|
|
||||||
import com.jessebrault.ssg.buildscript.SourceProviders
|
import com.jessebrault.ssg.buildscript.SourceProviders
|
||||||
import com.jessebrault.ssg.model.Model
|
import com.jessebrault.ssg.model.Model
|
||||||
@ -8,7 +8,11 @@ import com.jessebrault.ssg.provider.CollectionProvider
|
|||||||
import com.jessebrault.ssg.provider.CollectionProviders
|
import com.jessebrault.ssg.provider.CollectionProviders
|
||||||
import com.jessebrault.ssg.template.Template
|
import com.jessebrault.ssg.template.Template
|
||||||
import com.jessebrault.ssg.text.Text
|
import com.jessebrault.ssg.text.Text
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.NullCheck
|
||||||
|
|
||||||
|
@NullCheck
|
||||||
|
@EqualsAndHashCode
|
||||||
final class SourceProvidersDelegate {
|
final class SourceProvidersDelegate {
|
||||||
|
|
||||||
private CollectionProvider<Text> textsProvider = CollectionProviders.getEmpty()
|
private CollectionProvider<Text> textsProvider = CollectionProviders.getEmpty()
|
@ -1,24 +1,32 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
package com.jessebrault.ssg.buildscript.delegates
|
||||||
|
|
||||||
import com.jessebrault.ssg.task.TaskFactory
|
import com.jessebrault.ssg.task.TaskFactory
|
||||||
import com.jessebrault.ssg.task.TaskFactorySpec
|
import com.jessebrault.ssg.task.TaskFactorySpec
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.NullCheck
|
||||||
|
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
@NullCheck
|
||||||
|
@EqualsAndHashCode(includeFields = true)
|
||||||
final class TaskFactoriesDelegate {
|
final class TaskFactoriesDelegate {
|
||||||
|
|
||||||
private final Map<String, TaskFactorySpec<TaskFactory>> specs = [:]
|
private final Collection<TaskFactorySpec<TaskFactory>> specs = []
|
||||||
|
|
||||||
|
private boolean isRegistered(String name) {
|
||||||
|
this.specs.find { it.name == name } != null
|
||||||
|
}
|
||||||
|
|
||||||
private void checkNotRegistered(String name) {
|
private void checkNotRegistered(String name) {
|
||||||
if (this.specs.containsKey(name)) {
|
if (this.isRegistered(name)) {
|
||||||
throw new IllegalArgumentException("a TaskFactory is already registered by the name ${ name }")
|
throw new IllegalArgumentException("a TaskFactory is already registered by the name ${ name }")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void register(String name, Supplier<? extends TaskFactory> factorySupplier) {
|
void register(String name, Supplier<? extends TaskFactory> factorySupplier) {
|
||||||
this.checkNotRegistered(name)
|
this.checkNotRegistered(name)
|
||||||
this.specs[name] = new TaskFactorySpec<>(factorySupplier, [])
|
this.specs << new TaskFactorySpec<>(name, factorySupplier, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
def <T extends TaskFactory> void register(
|
def <T extends TaskFactory> void register(
|
||||||
@ -27,22 +35,31 @@ final class TaskFactoriesDelegate {
|
|||||||
Consumer<T> factoryConfigurator
|
Consumer<T> factoryConfigurator
|
||||||
) {
|
) {
|
||||||
this.checkNotRegistered(name)
|
this.checkNotRegistered(name)
|
||||||
this.specs[name] = new TaskFactorySpec<>(factorySupplier, [factoryConfigurator])
|
this.specs << new TaskFactorySpec<>(name, factorySupplier, [factoryConfigurator])
|
||||||
|
}
|
||||||
|
|
||||||
|
void register(TaskFactorySpec<TaskFactory> spec) {
|
||||||
|
this.specs << spec
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerAll(Collection<TaskFactorySpec<TaskFactory>> specs) {
|
||||||
|
this.specs.addAll(specs)
|
||||||
}
|
}
|
||||||
|
|
||||||
def <T extends TaskFactory> void configure(
|
def <T extends TaskFactory> void configure(
|
||||||
String name,
|
String name,
|
||||||
Class<T> factoryClass, // Dummy so we get better auto-complete
|
Class<T> factoryClass, // Dummy so we get better auto-complete
|
||||||
Consumer<T> factoryConfigureClosure
|
Consumer<T> factoryConfigurator
|
||||||
) {
|
) {
|
||||||
if (!this.specs.containsKey(name)) {
|
if (!this.isRegistered(name)) {
|
||||||
throw new IllegalArgumentException("there is no TaskFactory registered by name ${ name }")
|
throw new IllegalArgumentException("there is no TaskFactory registered by name ${ name }")
|
||||||
}
|
}
|
||||||
|
def spec = this.specs.find { it.name == name }
|
||||||
// Potentially dangerous, but the configurators Collection *should* only contain the correct types.
|
// Potentially dangerous, but the configurators Collection *should* only contain the correct types.
|
||||||
this.specs[name].configurators << (factoryConfigureClosure as Consumer<TaskFactory>)
|
spec.configurators << (factoryConfigurator as Consumer<TaskFactory>)
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, TaskFactorySpec> getResult() {
|
Collection<TaskFactorySpec<TaskFactory>> getResult() {
|
||||||
this.specs
|
this.specs
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
package com.jessebrault.ssg.buildscript.delegates
|
||||||
|
|
||||||
import com.jessebrault.ssg.buildscript.TypesContainer
|
import com.jessebrault.ssg.buildscript.TypesContainer
|
||||||
import com.jessebrault.ssg.page.PageType
|
import com.jessebrault.ssg.page.PageType
|
@ -1,29 +0,0 @@
|
|||||||
package com.jessebrault.ssg.buildscript.domain
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.property.Properties
|
|
||||||
import com.jessebrault.ssg.property.Property
|
|
||||||
import com.jessebrault.ssg.util.Monoid
|
|
||||||
|
|
||||||
final class MutableSiteSpec {
|
|
||||||
|
|
||||||
private static final Monoid<String> nameAndBaseUrlMonoid = new Monoid<>(
|
|
||||||
{ s0, s1 -> s1 },
|
|
||||||
{ '' }
|
|
||||||
)
|
|
||||||
|
|
||||||
static final Monoid<MutableSiteSpec> MONOID = new Monoid<>(
|
|
||||||
MutableSiteSpec::concat,
|
|
||||||
MutableSiteSpec::new
|
|
||||||
)
|
|
||||||
|
|
||||||
private static MutableSiteSpec concat(MutableSiteSpec ms0, MutableSiteSpec ms1) {
|
|
||||||
new MutableSiteSpec().tap {
|
|
||||||
name.set(ms1.name.get())
|
|
||||||
baseUrl.set(ms1.baseUrl.get())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final Property<String> name = Properties.get(nameAndBaseUrlMonoid)
|
|
||||||
final Property<String> baseUrl = Properties.get(nameAndBaseUrlMonoid)
|
|
||||||
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.SiteSpec
|
|
||||||
import com.jessebrault.ssg.buildscript.SourceProviders
|
|
||||||
import com.jessebrault.ssg.buildscript.TypesContainer
|
|
||||||
import com.jessebrault.ssg.task.TaskFactory
|
|
||||||
import com.jessebrault.ssg.task.TaskFactorySpec
|
|
||||||
import groovy.transform.stc.ClosureParams
|
|
||||||
import groovy.transform.stc.SimpleType
|
|
||||||
|
|
||||||
abstract class AbstractBuildDelegate<T> {
|
|
||||||
|
|
||||||
private final Collection<Closure<?>> siteSpecClosures = []
|
|
||||||
private final Collection<Closure<?>> globalsClosures = []
|
|
||||||
private final Collection<Closure<?>> typesClosures = []
|
|
||||||
private final Collection<Closure<?>> sourcesClosures = []
|
|
||||||
private final Collection<Closure<?>> taskFactoriesClosures = []
|
|
||||||
|
|
||||||
abstract T getResult()
|
|
||||||
|
|
||||||
protected final SiteSpec getSiteSpecResult() {
|
|
||||||
this.siteSpecClosures.inject(SiteSpec.getBlank()) { acc, closure ->
|
|
||||||
def d = new SiteSpecDelegate()
|
|
||||||
closure.delegate = d
|
|
||||||
//noinspection UnnecessaryQualifiedReference
|
|
||||||
closure.resolveStrategy = Closure.DELEGATE_FIRST
|
|
||||||
closure()
|
|
||||||
acc + d.getResult()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final Map<String, Object> getGlobalsResult() {
|
|
||||||
this.globalsClosures.inject([:] as Map<String, Object>) { acc, closure ->
|
|
||||||
def d = new GlobalsDelegate()
|
|
||||||
closure.delegate = d
|
|
||||||
//noinspection UnnecessaryQualifiedReference
|
|
||||||
closure.resolveStrategy = Closure.DELEGATE_FIRST
|
|
||||||
closure()
|
|
||||||
acc + d.getResult()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final TypesContainer getTypesResult() {
|
|
||||||
this.typesClosures.inject(TypesContainer.getEmpty()) { acc, closure ->
|
|
||||||
def d = new TypesDelegate()
|
|
||||||
closure.delegate = d
|
|
||||||
//noinspection UnnecessaryQualifiedReference
|
|
||||||
closure.resolveStrategy = Closure.DELEGATE_FIRST
|
|
||||||
closure()
|
|
||||||
acc + d.getResult()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final SourceProviders getSourcesResult(TypesContainer typesContainer) {
|
|
||||||
this.sourcesClosures.inject(SourceProviders.getEmpty()) { acc, closure ->
|
|
||||||
def d = new SourceProvidersDelegate()
|
|
||||||
closure.delegate = d
|
|
||||||
//noinspection UnnecessaryQualifiedReference
|
|
||||||
closure.resolveStrategy = Closure.DELEGATE_FIRST
|
|
||||||
closure(typesContainer)
|
|
||||||
acc + d.getResult()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final Collection<TaskFactorySpec<TaskFactory>> getTaskFactoriesResult(SourceProviders sourceProviders) {
|
|
||||||
this.taskFactoriesClosures.inject([:] as Map<String, TaskFactorySpec>) { acc, closure ->
|
|
||||||
def d = new TaskFactoriesDelegate()
|
|
||||||
closure.delegate = d
|
|
||||||
//noinspection UnnecessaryQualifiedReference
|
|
||||||
closure.resolveStrategy = Closure.DELEGATE_FIRST
|
|
||||||
closure(sourceProviders)
|
|
||||||
def specs = d.getResult()
|
|
||||||
specs.forEach { name, spec ->
|
|
||||||
acc.merge(name, spec) { spec0, spec1 -> spec0 + spec1 }
|
|
||||||
}
|
|
||||||
acc
|
|
||||||
}.values()
|
|
||||||
}
|
|
||||||
|
|
||||||
void siteSpec(
|
|
||||||
@DelegatesTo(value = SiteSpecDelegate, strategy = Closure.DELEGATE_FIRST)
|
|
||||||
Closure<?> siteSpecClosure
|
|
||||||
) {
|
|
||||||
this.siteSpecClosures << siteSpecClosure
|
|
||||||
}
|
|
||||||
|
|
||||||
void globals(
|
|
||||||
@DelegatesTo(value = GlobalsDelegate, strategy = Closure.DELEGATE_FIRST)
|
|
||||||
Closure<?> globalsClosure
|
|
||||||
) {
|
|
||||||
this.globalsClosures << globalsClosure
|
|
||||||
}
|
|
||||||
|
|
||||||
void types(
|
|
||||||
@DelegatesTo(value = TypesDelegate, strategy = Closure.DELEGATE_FIRST)
|
|
||||||
Closure<?> typesClosure
|
|
||||||
) {
|
|
||||||
this.typesClosures << typesClosure
|
|
||||||
}
|
|
||||||
|
|
||||||
void providers(
|
|
||||||
@DelegatesTo(value = SourceProvidersDelegate, strategy = Closure.DELEGATE_FIRST)
|
|
||||||
@ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.buildscript.TypesContainer')
|
|
||||||
Closure<?> providersClosure
|
|
||||||
) {
|
|
||||||
this.sourcesClosures << providersClosure
|
|
||||||
}
|
|
||||||
|
|
||||||
void taskFactories(
|
|
||||||
@DelegatesTo(value = TaskFactoriesDelegate, strategy = Closure.DELEGATE_FIRST)
|
|
||||||
@ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.buildscript.SourceProviders')
|
|
||||||
Closure<?> taskFactoriesClosure
|
|
||||||
) {
|
|
||||||
this.taskFactoriesClosures << taskFactoriesClosure
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.buildscript.Build
|
|
||||||
|
|
||||||
final class AllBuildsDelegate extends AbstractBuildDelegate<Build.AllBuilds> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Build.AllBuilds getResult() {
|
|
||||||
new Build.AllBuilds(
|
|
||||||
this.getSiteSpecResult(),
|
|
||||||
this.getGlobalsResult(),
|
|
||||||
this.getTaskFactoriesResult(this.getSourcesResult(this.getTypesResult()))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.buildscript.Build
|
|
||||||
import com.jessebrault.ssg.buildscript.OutputDir
|
|
||||||
import com.jessebrault.ssg.buildscript.OutputDirFunctions
|
|
||||||
|
|
||||||
import java.util.function.Function
|
|
||||||
|
|
||||||
final class BuildDelegate extends AbstractBuildDelegate<Build> {
|
|
||||||
|
|
||||||
String name = ''
|
|
||||||
private Function<Build, OutputDir> outputDirFunction = OutputDirFunctions.DEFAULT
|
|
||||||
|
|
||||||
@Override
|
|
||||||
Build getResult() {
|
|
||||||
new Build(
|
|
||||||
this.name,
|
|
||||||
this.outputDirFunction,
|
|
||||||
this.getSiteSpecResult(),
|
|
||||||
this.getGlobalsResult(),
|
|
||||||
this.getTaskFactoriesResult(this.getSourcesResult(this.getTypesResult()))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOutputDirFunction(Function<Build, OutputDir> outputDirFunction) {
|
|
||||||
this.outputDirFunction = outputDirFunction
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOutputDir(File file) {
|
|
||||||
this.outputDirFunction = OutputDirFunctions.of(file)
|
|
||||||
}
|
|
||||||
|
|
||||||
void setOutputDir(String path) {
|
|
||||||
this.outputDirFunction = OutputDirFunctions.of(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.SiteSpec
|
|
||||||
|
|
||||||
final class SiteSpecDelegate {
|
|
||||||
|
|
||||||
String name
|
|
||||||
String baseUrl
|
|
||||||
|
|
||||||
SiteSpecDelegate() {
|
|
||||||
def blank = SiteSpec.getBlank()
|
|
||||||
this.name = blank.name
|
|
||||||
this.baseUrl = blank.baseUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
SiteSpec getResult() {
|
|
||||||
new SiteSpec(this.name, this.baseUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
33
api/src/main/groovy/com/jessebrault/ssg/mutable/Mutable.java
Normal file
33
api/src/main/groovy/com/jessebrault/ssg/mutable/Mutable.java
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package com.jessebrault.ssg.mutable;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.*;
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public interface Mutable<T> {
|
||||||
|
T get();
|
||||||
|
void set(T t);
|
||||||
|
void unset();
|
||||||
|
|
||||||
|
boolean isPresent();
|
||||||
|
|
||||||
|
default boolean isEmpty() {
|
||||||
|
return !this.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void filterInPlace(Predicate<T> filter);
|
||||||
|
void mapInPlace(UnaryOperator<T> mapper);
|
||||||
|
<U> void zipInPlace(Mutable<U> other, Supplier<T> onEmpty, Supplier<U> onOtherEmpty, BiFunction<T, U, T> zipper);
|
||||||
|
|
||||||
|
<U> U match(Supplier<U> onEmpty, Function<T, U> onPresentMapper);
|
||||||
|
T getOrElse(Supplier<T> onEmpty);
|
||||||
|
|
||||||
|
<U> Mutable<U> chain(Function<T, Mutable<U>> mapper);
|
||||||
|
<U> Mutable<U> map(Function<T, U> mapper);
|
||||||
|
|
||||||
|
<U, R> Mutable<R> zip(Mutable<U> other, BiFunction<T, U, R> zipper);
|
||||||
|
|
||||||
|
Optional<T> asOptional();
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.jessebrault.ssg.mutable;
|
||||||
|
|
||||||
|
import com.jessebrault.ssg.util.Monoid;
|
||||||
|
import com.jessebrault.ssg.util.Monoids;
|
||||||
|
import com.jessebrault.ssg.util.Semigroup;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public final class Mutables {
|
||||||
|
|
||||||
|
public static <T> Monoid<Mutable<T>> getMonoid(final Semigroup<T> tSemigroup) {
|
||||||
|
return Monoids.of(Mutables.getEmpty(), (m0, m1) -> {
|
||||||
|
if (m0.isPresent() && m1.isPresent()) {
|
||||||
|
return get(tSemigroup.getConcat().apply(m0.get(), m1.get()));
|
||||||
|
} else if (m0.isPresent()) {
|
||||||
|
return m0;
|
||||||
|
} else if (m1.isPresent()) {
|
||||||
|
return m1;
|
||||||
|
} else {
|
||||||
|
return getEmpty();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> @NotNull Mutable<T> getEmpty() {
|
||||||
|
return new SimpleMutable<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Mutable<T> get(T initialValue) {
|
||||||
|
return new SimpleMutable<>(initialValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Mutables() {}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
package com.jessebrault.ssg.mutable;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.*;
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
final class SimpleMutable<T> implements Mutable<T> {
|
||||||
|
|
||||||
|
private T t;
|
||||||
|
|
||||||
|
public SimpleMutable(T initialValue) {
|
||||||
|
this.t = initialValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleMutable() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T get() {
|
||||||
|
if (this.t == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
return this.t;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(T t) {
|
||||||
|
this.t = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unset() {
|
||||||
|
this.t = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPresent() {
|
||||||
|
return this.t != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void filterInPlace(Predicate<T> filter) {
|
||||||
|
if (this.t != null && !filter.test(this.t)) {
|
||||||
|
this.unset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mapInPlace(UnaryOperator<T> mapper) {
|
||||||
|
this.t = mapper.apply(this.t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <U> void zipInPlace(Mutable<U> other, Supplier<T> onEmpty, Supplier<U> onOtherEmpty, BiFunction<T, U, T> zipper) {
|
||||||
|
this.t = zipper.apply(
|
||||||
|
this.isPresent() ? this.t : onEmpty.get(),
|
||||||
|
other.isPresent() ? other.get() : onOtherEmpty.get()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <U> U match(Supplier<U> onEmpty, Function<T, U> onPresentMapper) {
|
||||||
|
return this.t != null ? onPresentMapper.apply(this.t) : onEmpty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getOrElse(Supplier<T> other) {
|
||||||
|
return this.t != null ? this.t : other.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <U> Mutable<U> chain(Function<T, Mutable<U>> mapper) {
|
||||||
|
return this.map(mapper).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <U> Mutable<U> map(Function<T, U> mapper) {
|
||||||
|
return this.t != null ? Mutables.get(mapper.apply(this.t)) : Mutables.getEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <U, R> Mutable<R> zip(Mutable<U> other, BiFunction<T, U, R> zipper) {
|
||||||
|
return this.isPresent() && other.isPresent()
|
||||||
|
? Mutables.get(zipper.apply(this.get(), other.get()))
|
||||||
|
: Mutables.getEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<T> asOptional() {
|
||||||
|
return Optional.ofNullable(this.t);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,21 +0,0 @@
|
|||||||
package com.jessebrault.ssg.property
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.util.Monoid
|
|
||||||
|
|
||||||
final class Properties {
|
|
||||||
|
|
||||||
static <T> Property<T> get(Monoid<T> semiGroup) {
|
|
||||||
new SimpleProperty<>(semiGroup)
|
|
||||||
}
|
|
||||||
|
|
||||||
static <T> Property<T> get(Monoid<T> semiGroup, T convention) {
|
|
||||||
new SimpleProperty<>(semiGroup, convention)
|
|
||||||
}
|
|
||||||
|
|
||||||
static <T> Property<T> get(Monoid<T> semiGroup, T convention, T t) {
|
|
||||||
new SimpleProperty<>(semiGroup, convention, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
private Properties() {}
|
|
||||||
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
package com.jessebrault.ssg.property
|
|
||||||
|
|
||||||
import java.util.function.UnaryOperator
|
|
||||||
|
|
||||||
interface Property<T> {
|
|
||||||
T get()
|
|
||||||
void set(T t)
|
|
||||||
void unset()
|
|
||||||
|
|
||||||
T getConvention()
|
|
||||||
void setConvention(T t)
|
|
||||||
void unsetConvention()
|
|
||||||
|
|
||||||
void map(UnaryOperator<T> mapper)
|
|
||||||
void merge(
|
|
||||||
@DelegatesTo(type = 'T', strategy = Closure.DELEGATE_FIRST)
|
|
||||||
Closure<?> configurator
|
|
||||||
)
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
package com.jessebrault.ssg.property
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.util.Monoid
|
|
||||||
import groovy.transform.EqualsAndHashCode
|
|
||||||
import groovy.transform.NullCheck
|
|
||||||
import groovy.transform.PackageScope
|
|
||||||
|
|
||||||
import java.util.function.UnaryOperator
|
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull
|
|
||||||
|
|
||||||
@PackageScope
|
|
||||||
@NullCheck(includeGenerated = true)
|
|
||||||
@EqualsAndHashCode(includeFields = true)
|
|
||||||
final class SimpleProperty<T> implements Property<T> {
|
|
||||||
|
|
||||||
private final Monoid<T> monoid
|
|
||||||
|
|
||||||
private T t
|
|
||||||
private T convention
|
|
||||||
|
|
||||||
SimpleProperty(Monoid<T> monoid) {
|
|
||||||
this.monoid = monoid
|
|
||||||
this.convention = this.monoid.empty.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleProperty(Monoid<T> monoid, T convention) {
|
|
||||||
this.monoid = monoid
|
|
||||||
this.convention = convention
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleProperty(Monoid<T> monoid, T convention, T t) {
|
|
||||||
this.monoid = monoid
|
|
||||||
this.t = t
|
|
||||||
this.convention = convention
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
T get() {
|
|
||||||
this.t != null ? this.t : requireNonNull(this.convention)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void set(T t) {
|
|
||||||
this.t = t
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void unset() {
|
|
||||||
this.t = null
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
T getConvention() {
|
|
||||||
requireNonNull(this.convention)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void setConvention(T t) {
|
|
||||||
this.convention = t
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void unsetConvention() {
|
|
||||||
this.t = null
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void map(UnaryOperator<T> mapper) {
|
|
||||||
this.t = requireNonNull(mapper.apply(this.t))
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void merge(
|
|
||||||
@DelegatesTo(type = 'T', strategy = Closure.DELEGATE_FIRST)
|
|
||||||
Closure<?> configurator
|
|
||||||
) {
|
|
||||||
def d = requireNonNull(this.monoid.empty.get())
|
|
||||||
configurator.delegate = d
|
|
||||||
configurator.resolveStrategy = Closure.DELEGATE_FIRST
|
|
||||||
configurator()
|
|
||||||
this.t = requireNonNull(this.monoid.concat.apply(this.t != null ? this.t : this.monoid.empty.get(), d))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,25 +1,35 @@
|
|||||||
package com.jessebrault.ssg.task
|
package com.jessebrault.ssg.task
|
||||||
|
|
||||||
|
import com.jessebrault.ssg.util.Semigroup
|
||||||
|
import com.jessebrault.ssg.util.Semigroups
|
||||||
import groovy.transform.EqualsAndHashCode
|
import groovy.transform.EqualsAndHashCode
|
||||||
import groovy.transform.NullCheck
|
import groovy.transform.NullCheck
|
||||||
import groovy.transform.TupleConstructor
|
import groovy.transform.TupleConstructor
|
||||||
|
|
||||||
import java.util.function.BiFunction
|
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Make this deeply immutable
|
||||||
|
*/
|
||||||
@TupleConstructor(defaults = false)
|
@TupleConstructor(defaults = false)
|
||||||
@NullCheck(includeGenerated = true)
|
@NullCheck(includeGenerated = true)
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
final class TaskFactorySpec<T extends TaskFactory> {
|
final class TaskFactorySpec<T extends TaskFactory> {
|
||||||
|
|
||||||
|
static Semigroup<TaskFactorySpec<TaskFactory>> DEFAULT_SEMIGROUP = Semigroups.of(TaskFactorySpec::concat)
|
||||||
|
|
||||||
static <T extends TaskFactory> TaskFactorySpec<T> concat(TaskFactorySpec<T> spec0, TaskFactorySpec<T> spec1) {
|
static <T extends TaskFactory> TaskFactorySpec<T> concat(TaskFactorySpec<T> spec0, TaskFactorySpec<T> spec1) {
|
||||||
|
if (spec0.name != spec1.name) {
|
||||||
|
throw new IllegalArgumentException('names must be equal!')
|
||||||
|
}
|
||||||
if (spec0.supplier != spec1.supplier) {
|
if (spec0.supplier != spec1.supplier) {
|
||||||
throw new IllegalArgumentException("suppliers must be equal!")
|
throw new IllegalArgumentException("suppliers must be equal!")
|
||||||
}
|
}
|
||||||
new TaskFactorySpec(spec0.supplier, spec0.configurators + spec1.configurators)
|
new TaskFactorySpec(spec0.name, spec0.supplier, spec0.configurators + spec1.configurators)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final String name
|
||||||
final Supplier<T> supplier
|
final Supplier<T> supplier
|
||||||
final Collection<Consumer<T>> configurators
|
final Collection<Consumer<T>> configurators
|
||||||
|
|
||||||
|
@ -1,16 +1,6 @@
|
|||||||
package com.jessebrault.ssg.util
|
package com.jessebrault.ssg.util
|
||||||
|
|
||||||
import groovy.transform.EqualsAndHashCode
|
import org.jetbrains.annotations.ApiStatus
|
||||||
import groovy.transform.NullCheck
|
|
||||||
import groovy.transform.TupleConstructor
|
|
||||||
|
|
||||||
import java.util.function.BinaryOperator
|
@ApiStatus.Experimental
|
||||||
import java.util.function.Supplier
|
interface Monoid<T> extends Semigroup<T>, Zero<T> {}
|
||||||
|
|
||||||
@TupleConstructor(defaults = false)
|
|
||||||
@NullCheck(includeGenerated = true)
|
|
||||||
@EqualsAndHashCode
|
|
||||||
final class Monoid<T> {
|
|
||||||
final BinaryOperator<T> concat
|
|
||||||
final Supplier<T> empty
|
|
||||||
}
|
|
||||||
|
16
api/src/main/groovy/com/jessebrault/ssg/util/Monoids.groovy
Normal file
16
api/src/main/groovy/com/jessebrault/ssg/util/Monoids.groovy
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package com.jessebrault.ssg.util
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus
|
||||||
|
|
||||||
|
import java.util.function.BinaryOperator
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
final class Monoids {
|
||||||
|
|
||||||
|
static <T> Monoid<T> of(T zero, BinaryOperator<T> concat) {
|
||||||
|
new SimpleMonoid<>(zero, concat)
|
||||||
|
}
|
||||||
|
|
||||||
|
private Monoids() {}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.jessebrault.ssg.util
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus
|
||||||
|
|
||||||
|
import java.util.function.BinaryOperator
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
interface Semigroup<T> {
|
||||||
|
BinaryOperator<T> getConcat()
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.jessebrault.ssg.util
|
||||||
|
|
||||||
|
import java.util.function.BinaryOperator
|
||||||
|
|
||||||
|
final class Semigroups {
|
||||||
|
|
||||||
|
static <T> Semigroup<T> of(BinaryOperator<T> concat) {
|
||||||
|
new SimpleSemigroup<>(concat)
|
||||||
|
}
|
||||||
|
|
||||||
|
private Semigroups() {}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.jessebrault.ssg.util
|
||||||
|
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.NullCheck
|
||||||
|
import groovy.transform.PackageScope
|
||||||
|
import groovy.transform.TupleConstructor
|
||||||
|
import org.jetbrains.annotations.ApiStatus
|
||||||
|
|
||||||
|
import java.util.function.BinaryOperator
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@PackageScope
|
||||||
|
@TupleConstructor(defaults = false)
|
||||||
|
@NullCheck(includeGenerated = true)
|
||||||
|
@EqualsAndHashCode
|
||||||
|
final class SimpleMonoid<T> implements Monoid<T> {
|
||||||
|
final T zero
|
||||||
|
final BinaryOperator<T> concat
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.jessebrault.ssg.util
|
||||||
|
|
||||||
|
import groovy.transform.EqualsAndHashCode
|
||||||
|
import groovy.transform.NullCheck
|
||||||
|
import groovy.transform.PackageScope
|
||||||
|
import groovy.transform.TupleConstructor
|
||||||
|
import org.jetbrains.annotations.ApiStatus
|
||||||
|
|
||||||
|
import java.util.function.BinaryOperator
|
||||||
|
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@PackageScope
|
||||||
|
@TupleConstructor(defaults = false)
|
||||||
|
@NullCheck(includeGenerated = true)
|
||||||
|
@EqualsAndHashCode
|
||||||
|
final class SimpleSemigroup<T> implements Semigroup<T> {
|
||||||
|
final BinaryOperator<T> concat
|
||||||
|
}
|
5
api/src/main/groovy/com/jessebrault/ssg/util/Zero.groovy
Normal file
5
api/src/main/groovy/com/jessebrault/ssg/util/Zero.groovy
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package com.jessebrault.ssg.util
|
||||||
|
|
||||||
|
interface Zero<T> {
|
||||||
|
T getZero()
|
||||||
|
}
|
@ -0,0 +1,98 @@
|
|||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,11 +13,11 @@ import static org.junit.jupiter.api.Assertions.assertEquals
|
|||||||
@ExtendWith(MockitoExtension)
|
@ExtendWith(MockitoExtension)
|
||||||
final class BuildScriptBaseTests {
|
final class BuildScriptBaseTests {
|
||||||
|
|
||||||
private static Collection<Build> scriptToBuilds(
|
private static Collection<BuildSpec> scriptToBuildSpecs(
|
||||||
@DelegatesTo(value = BuildScriptBase, strategy = Closure.DELEGATE_FIRST)
|
@DelegatesTo(value = BuildScriptBase, strategy = Closure.DELEGATE_FIRST)
|
||||||
Closure<?> script
|
Closure<?> script
|
||||||
) {
|
) {
|
||||||
def s = new BuildScriptBase() {
|
def base = new BuildScriptBase() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Object run() {
|
Object run() {
|
||||||
@ -27,14 +27,22 @@ final class BuildScriptBaseTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
s.run()
|
base.run()
|
||||||
s.getBuilds()
|
base.buildSpecs
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
private static Collection<Build> scriptToBuilds(
|
||||||
|
@DelegatesTo(value = BuildScriptBase, strategy = Closure.DELEGATE_FIRST)
|
||||||
|
Closure<?> script
|
||||||
|
) {
|
||||||
|
BuildSpecUtil.getBuilds(scriptToBuildSpecs(script))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void oneBuildWithName0() {
|
void oneBuildWithName0() {
|
||||||
def r = scriptToBuilds {
|
def r = scriptToBuildSpecs {
|
||||||
build('test') { }
|
build(name: 'test') { }
|
||||||
}
|
}
|
||||||
assertEquals(1, r.size())
|
assertEquals(1, r.size())
|
||||||
def b0 = r[0]
|
def b0 = r[0]
|
||||||
@ -43,10 +51,8 @@ final class BuildScriptBaseTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void oneBuildWithName1() {
|
void oneBuildWithName1() {
|
||||||
def r = scriptToBuilds {
|
def r = scriptToBuildSpecs {
|
||||||
build {
|
build(name: 'test') { }
|
||||||
name = 'test'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
assertEquals(1, r.size())
|
assertEquals(1, r.size())
|
||||||
def b0 = r[0]
|
def b0 = r[0]
|
||||||
@ -54,90 +60,64 @@ final class BuildScriptBaseTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void oneBuildOutputDirWithFunction(@Mock Function<Build, OutputDir> mockOutputDirFunction) {
|
void twoBuildsNotRelated() {
|
||||||
def r = scriptToBuilds {
|
def r = scriptToBuildSpecs {
|
||||||
build {
|
build(name: 'b0') { }
|
||||||
outputDirFunction = mockOutputDirFunction
|
build(name: 'b1') { }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
assertEquals(1, r.size())
|
assertEquals(2, r.size())
|
||||||
def b0 = r[0]
|
|
||||||
assertEquals(mockOutputDirFunction, b0.outputDirFunction)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void oneBuildOutputDirWithFile() {
|
void childParentBuild() {
|
||||||
def f = new File('test')
|
def r = scriptToBuildSpecs {
|
||||||
def r = scriptToBuilds {
|
build(name: 'child', extending: 'parent') { }
|
||||||
build {
|
build(name: 'parent') { }
|
||||||
outputDir = f
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
assertEquals(1, r.size())
|
assertEquals(2, r.size())
|
||||||
def b0 = r[0]
|
assertEquals(
|
||||||
assertEquals(f, b0.outputDirFunction.apply(b0) as File)
|
[
|
||||||
|
BuildSpec.get(name: 'child', extending: BuildExtension.get('parent')),
|
||||||
|
BuildSpec.get(name: 'parent')
|
||||||
|
],
|
||||||
|
r
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void oneBuildOutputDirWithString() {
|
void threeGenerations() {
|
||||||
def r = scriptToBuilds {
|
def r = scriptToBuildSpecs {
|
||||||
build {
|
build(name: 'child', extending: 'parent') { }
|
||||||
outputDir = 'test'
|
build(name: 'parent', extending: 'grandparent') { }
|
||||||
}
|
build(name: 'grandparent') { }
|
||||||
}
|
}
|
||||||
assertEquals(1, r.size())
|
assertEquals(3, r.size())
|
||||||
def b0 = r[0]
|
assertEquals(
|
||||||
assertEquals('test', b0.outputDirFunction.apply(b0) as String)
|
[
|
||||||
|
BuildSpec.get(name: 'child', extending: BuildExtension.get('parent')),
|
||||||
|
BuildSpec.get(name: 'parent', extending: BuildExtension.get('grandparent')),
|
||||||
|
BuildSpec.get(name: 'grandparent')
|
||||||
|
],
|
||||||
|
r
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void oneBuildSiteSpec() {
|
void siblingsAndParent() {
|
||||||
def r = scriptToBuilds {
|
def r = scriptToBuildSpecs {
|
||||||
build {
|
build(name: 'child0', extending: 'parent') { }
|
||||||
siteSpec {
|
build(name: 'child1', extending: 'parent') { }
|
||||||
name = 'testSite'
|
build(name: 'parent') { }
|
||||||
baseUrl = 'https://testsite.com'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
assertEquals(1, r.size())
|
assertEquals(3, r.size())
|
||||||
def b0 = r[0]
|
assertEquals(
|
||||||
assertEquals(new SiteSpec('testSite', 'https://testsite.com'), b0.siteSpec)
|
[
|
||||||
}
|
BuildSpec.get(name: 'child0', extending: BuildExtension.get('parent')),
|
||||||
|
BuildSpec.get(name: 'child1', extending: BuildExtension.get('parent')),
|
||||||
@Test
|
BuildSpec.get(name: 'parent')
|
||||||
void allBuildsProvidesSiteSpec() {
|
],
|
||||||
def r = scriptToBuilds {
|
r
|
||||||
allBuilds {
|
)
|
||||||
siteSpec {
|
|
||||||
name = 'testSite'
|
|
||||||
baseUrl = 'https://testsite.com'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build('test') { }
|
|
||||||
}
|
|
||||||
assertEquals(1, r.size())
|
|
||||||
def b0 = r[0]
|
|
||||||
assertEquals(new SiteSpec('testSite', 'https://testsite.com'), b0.siteSpec)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void allBuildsSiteSpecOverwritten() {
|
|
||||||
def r = scriptToBuilds {
|
|
||||||
allBuilds {
|
|
||||||
siteSpec {
|
|
||||||
name = 'no'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
build {
|
|
||||||
siteSpec {
|
|
||||||
name = 'yes'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assertEquals(1, r.size())
|
|
||||||
def b0 = r[0]
|
|
||||||
assertEquals(new SiteSpec('yes', ''), b0.siteSpec)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,68 +16,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals
|
|||||||
@ExtendWith(MockitoExtension)
|
@ExtendWith(MockitoExtension)
|
||||||
final class BuildTests {
|
final class BuildTests {
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension)
|
|
||||||
static final class AllBuildsTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void twoEmptiesEqual() {
|
|
||||||
def ab0 = Build.AllBuilds.getEmpty()
|
|
||||||
def ab1 = Build.AllBuilds.getEmpty()
|
|
||||||
assertEquals(ab0, ab1)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void siteSpecsAdded() {
|
|
||||||
def ab0 = new Build.AllBuilds(
|
|
||||||
new SiteSpec('test', ''),
|
|
||||||
[:],
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
def ab1 = new Build.AllBuilds(
|
|
||||||
new SiteSpec('', 'test'),
|
|
||||||
[:],
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
def sum = ab0 + ab1
|
|
||||||
assertEquals(new SiteSpec('test', 'test'), sum.siteSpec)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void globalsAdded() {
|
|
||||||
def ab0 = new Build.AllBuilds(
|
|
||||||
SiteSpec.getBlank(),
|
|
||||||
[a: 0],
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
def ab1 = new Build.AllBuilds(
|
|
||||||
SiteSpec.getBlank(),
|
|
||||||
[b: 1],
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
def sum = ab0 + ab1
|
|
||||||
assertEquals([a: 0, b: 1], sum.globals)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void taskFactorySpecsAdded(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
|
||||||
def spec0 = new TaskFactorySpec<>(taskFactorySupplier, [])
|
|
||||||
def spec1 = new TaskFactorySpec<>(taskFactorySupplier, [])
|
|
||||||
def ab0 = new Build.AllBuilds(
|
|
||||||
SiteSpec.getBlank(),
|
|
||||||
[:],
|
|
||||||
[spec0]
|
|
||||||
)
|
|
||||||
def ab1 = new Build.AllBuilds(
|
|
||||||
SiteSpec.getBlank(),
|
|
||||||
[:],
|
|
||||||
[spec1]
|
|
||||||
)
|
|
||||||
def sum = ab0 + ab1
|
|
||||||
assertEquals([spec0, spec1], sum.taskFactorySpecs)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void twoEmptiesEqual() {
|
void twoEmptiesEqual() {
|
||||||
def b0 = Build.getEmpty()
|
def b0 = Build.getEmpty()
|
||||||
@ -131,8 +69,8 @@ final class BuildTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void taskFactorySpecsAdded(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
void taskFactorySpecsAdded(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
||||||
def spec0 = new TaskFactorySpec<>(taskFactorySupplier, [])
|
def spec0 = new TaskFactorySpec<>('spec0', taskFactorySupplier, [])
|
||||||
def spec1 = new TaskFactorySpec<>(taskFactorySupplier, [])
|
def spec1 = new TaskFactorySpec<>('spec1', taskFactorySupplier, [])
|
||||||
def b0 = Build.get(taskFactorySpecs: [spec0])
|
def b0 = Build.get(taskFactorySpecs: [spec0])
|
||||||
def b1 = Build.get(taskFactorySpecs: [spec1])
|
def b1 = Build.get(taskFactorySpecs: [spec1])
|
||||||
def sum = b0 + b1
|
def sum = b0 + b1
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.jessebrault.ssg.buildscript
|
package com.jessebrault.ssg.buildscript
|
||||||
|
|
||||||
|
import com.jessebrault.ssg.SiteSpec
|
||||||
import groovy.transform.NullCheck
|
import groovy.transform.NullCheck
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.extension.ExtendWith
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
@ -7,6 +8,7 @@ import org.mockito.Mock
|
|||||||
import org.mockito.junit.jupiter.MockitoExtension
|
import org.mockito.junit.jupiter.MockitoExtension
|
||||||
|
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
import java.util.function.Function
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||||
import static org.mockito.Mockito.verify
|
import static org.mockito.Mockito.verify
|
||||||
@ -15,6 +17,8 @@ import static org.mockito.Mockito.verify
|
|||||||
@ExtendWith(MockitoExtension)
|
@ExtendWith(MockitoExtension)
|
||||||
final class SimpleBuildScriptRunnerTests {
|
final class SimpleBuildScriptRunnerTests {
|
||||||
|
|
||||||
|
private final BuildScriptRunner runner = new SimpleBuildScriptRunner()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be non-static, otherwise Groovy gets confused inside the Closures.
|
* Must be non-static, otherwise Groovy gets confused inside the Closures.
|
||||||
*
|
*
|
||||||
@ -46,8 +50,7 @@ final class SimpleBuildScriptRunnerTests {
|
|||||||
@Test
|
@Test
|
||||||
void simpleScript() {
|
void simpleScript() {
|
||||||
def baseDir = this.setupScripts(['simple.groovy'])
|
def baseDir = this.setupScripts(['simple.groovy'])
|
||||||
def runner = new SimpleBuildScriptRunner()
|
def builds = this.runner.runBuildScript('simple.groovy', baseDir.toURI().toURL())
|
||||||
def builds = runner.runBuildScript('simple.groovy', baseDir.toURI().toURL())
|
|
||||||
assertEquals(1, builds.size())
|
assertEquals(1, builds.size())
|
||||||
assertEquals('test', builds[0].name)
|
assertEquals('test', builds[0].name)
|
||||||
}
|
}
|
||||||
@ -55,8 +58,7 @@ final class SimpleBuildScriptRunnerTests {
|
|||||||
@Test
|
@Test
|
||||||
void testImport() {
|
void testImport() {
|
||||||
def baseDir = this.setupScripts(['testImport.groovy', 'TestHtmlTask.groovy'])
|
def baseDir = this.setupScripts(['testImport.groovy', 'TestHtmlTask.groovy'])
|
||||||
def runner = new SimpleBuildScriptRunner()
|
def builds = this.runner.runBuildScript('testImport.groovy', baseDir.toURI().toURL())
|
||||||
def builds = runner.runBuildScript('testImport.groovy', baseDir.toURI().toURL())
|
|
||||||
assertEquals(1, builds.size())
|
assertEquals(1, builds.size())
|
||||||
assertEquals('test', builds[0].name)
|
assertEquals('test', builds[0].name)
|
||||||
}
|
}
|
||||||
@ -74,8 +76,7 @@ final class SimpleBuildScriptRunnerTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
def runner = new SimpleBuildScriptRunner()
|
def builds = this.runner.runBuildScript(
|
||||||
def builds = runner.runBuildScript(
|
|
||||||
'buildSrcTest.groovy',
|
'buildSrcTest.groovy',
|
||||||
baseDir.toURI().toURL(),
|
baseDir.toURI().toURL(),
|
||||||
[new File(baseDir, 'buildSrc').toURI().toURL()]
|
[new File(baseDir, 'buildSrc').toURI().toURL()]
|
||||||
@ -87,8 +88,7 @@ final class SimpleBuildScriptRunnerTests {
|
|||||||
@Test
|
@Test
|
||||||
void withBinding(@Mock Consumer<String> stringConsumer) {
|
void withBinding(@Mock Consumer<String> stringConsumer) {
|
||||||
def baseDir = this.setupScripts(['withBinding.groovy'])
|
def baseDir = this.setupScripts(['withBinding.groovy'])
|
||||||
def runner = new SimpleBuildScriptRunner()
|
this.runner.runBuildScript(
|
||||||
runner.runBuildScript(
|
|
||||||
'withBinding.groovy',
|
'withBinding.groovy',
|
||||||
baseDir.toURI().toURL(),
|
baseDir.toURI().toURL(),
|
||||||
[],
|
[],
|
||||||
@ -99,12 +99,85 @@ final class SimpleBuildScriptRunnerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void customScript() {
|
void customScript() {
|
||||||
def runner = new SimpleBuildScriptRunner()
|
def result = this.runner.runBuildScript {
|
||||||
def result = runner.runBuildScript {
|
build(name: 'test') { }
|
||||||
build('test') { }
|
|
||||||
}
|
}
|
||||||
assertEquals(1, result.size())
|
assertEquals(1, result.size())
|
||||||
assertEquals('test', result[0].name)
|
assertEquals('test', result[0].name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void oneBuildOutputDirWithFunction(@Mock Function<Build, OutputDir> mockOutputDirFunction) {
|
||||||
|
def r = this.runner.runBuildScript {
|
||||||
|
build(name: 'test') {
|
||||||
|
outputDirFunction = mockOutputDirFunction
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(1, r.size())
|
||||||
|
def b0 = r[0]
|
||||||
|
assertEquals(mockOutputDirFunction, b0.outputDirFunction)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void oneBuildOutputDirWithFile() {
|
||||||
|
def f = new File('test')
|
||||||
|
def r = this.runner.runBuildScript {
|
||||||
|
build(name: 'test') {
|
||||||
|
outputDir = f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(1, r.size())
|
||||||
|
def b0 = r[0]
|
||||||
|
assertEquals(f, b0.outputDirFunction.apply(b0) as File)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void oneBuildOutputDirWithString() {
|
||||||
|
def r = this.runner.runBuildScript {
|
||||||
|
build(name: 'test') {
|
||||||
|
outputDir = 'test'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(1, r.size())
|
||||||
|
def b0 = r[0]
|
||||||
|
assertEquals('test', b0.outputDirFunction.apply(b0) as String)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void oneBuildSiteSpec() {
|
||||||
|
def r = this.runner.runBuildScript {
|
||||||
|
build(name: 'test') {
|
||||||
|
siteSpec {
|
||||||
|
name = 'testSite'
|
||||||
|
baseUrl = 'https://testsite.com'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(1, r.size())
|
||||||
|
def b0 = r[0]
|
||||||
|
assertEquals(new SiteSpec('testSite', 'https://testsite.com'), b0.siteSpec)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void oneBuildWithAbstractParent() {
|
||||||
|
def r = this.runner.runBuildScript {
|
||||||
|
abstractBuild(name: 'parent') {
|
||||||
|
siteSpec {
|
||||||
|
name = 'Test Site'
|
||||||
|
baseUrl = 'https://test.com'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build(name: 'child', extending: 'parent') {
|
||||||
|
siteSpec { base ->
|
||||||
|
baseUrl = base.baseUrl + '/child'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(1, r.size())
|
||||||
|
def b0 = r[0]
|
||||||
|
assertEquals(new SiteSpec('Test Site', 'https://test.com/child'), b0.siteSpec)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,297 @@
|
|||||||
|
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.provider.CollectionProvider
|
||||||
|
import com.jessebrault.ssg.provider.CollectionProviders
|
||||||
|
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
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension
|
||||||
|
|
||||||
|
import java.util.function.Function
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension)
|
||||||
|
final class BuildDelegateTests {
|
||||||
|
|
||||||
|
private final BuildDelegate d = new BuildDelegate()
|
||||||
|
|
||||||
|
private BuildDelegate.Results getResults() {
|
||||||
|
new BuildDelegate.Results(this.d)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void simpleOutputDirFunction(
|
||||||
|
@Mock Function<Build, OutputDir> expected,
|
||||||
|
@Mock Function<Build, OutputDir> base,
|
||||||
|
@Mock Supplier<Function<Build, OutputDir>> onEmpty
|
||||||
|
) {
|
||||||
|
this.d.outputDirFunction = expected
|
||||||
|
def r = this.results.getOutputDirFunctionResult(base, onEmpty)
|
||||||
|
assertEquals(expected, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mappedOutputDirFunction(
|
||||||
|
@Mock Supplier<Function<Build, OutputDir>> onEmpty
|
||||||
|
) {
|
||||||
|
final Function<Build, OutputDir> base = { Build b ->
|
||||||
|
new OutputDir('test')
|
||||||
|
}
|
||||||
|
this.d.outputDirFunction {
|
||||||
|
it.andThen { new OutputDir(it.asString() + '/nested') }
|
||||||
|
}
|
||||||
|
def r = this.results.getOutputDirFunctionResult(base, onEmpty)
|
||||||
|
def outputDir = r.apply(Build.getEmpty())
|
||||||
|
assertEquals('test/nested', outputDir.asString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void emptyOutputDirFunction(
|
||||||
|
@Mock Function<Build, OutputDir> base,
|
||||||
|
@Mock Function<Build, OutputDir> 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
|
||||||
|
)
|
||||||
|
assertEquals('test', r.name)
|
||||||
|
assertEquals('testUrl', r.baseUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mappedSiteSpec() {
|
||||||
|
this.d.siteSpec { base ->
|
||||||
|
name = base.name + 'Preview'
|
||||||
|
baseUrl = base.baseUrl + '/preview'
|
||||||
|
}
|
||||||
|
def r = this.results.getSiteSpecResult(
|
||||||
|
new SiteSpec('mySite', 'https://mysite.com'),
|
||||||
|
true,
|
||||||
|
SiteSpec.DEFAULT_MONOID
|
||||||
|
)
|
||||||
|
assertEquals('mySitePreview', r.name)
|
||||||
|
assertEquals('https://mysite.com/preview', r.baseUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void siteSpecBaseConcat() {
|
||||||
|
this.d.siteSpec {
|
||||||
|
name = '123'
|
||||||
|
}
|
||||||
|
def r = this.results.getSiteSpecResult(
|
||||||
|
new SiteSpec('', '456'),
|
||||||
|
true,
|
||||||
|
SiteSpec.DEFAULT_MONOID
|
||||||
|
)
|
||||||
|
assertEquals('123', r.name)
|
||||||
|
assertEquals('456', r.baseUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void siteSpecBaseNoConcat() {
|
||||||
|
this.d.siteSpec(false) {
|
||||||
|
name = '123'
|
||||||
|
}
|
||||||
|
def r = this.results.getSiteSpecResult(
|
||||||
|
new SiteSpec('', '456'),
|
||||||
|
true,
|
||||||
|
SiteSpec.DEFAULT_MONOID
|
||||||
|
)
|
||||||
|
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<Map<String, Object>> getGlobalsMonoid() {
|
||||||
|
Monoids.of([:]) { m0, m1 -> m0 + m1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void globalsNoBase() {
|
||||||
|
this.d.globals {
|
||||||
|
test = 'abc'
|
||||||
|
}
|
||||||
|
def r = this.results.getGlobalsResult([:], true, getGlobalsMonoid())
|
||||||
|
assertEquals([test: 'abc'], r)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void globalsWithBase() {
|
||||||
|
this.d.globals { base ->
|
||||||
|
test = base.test
|
||||||
|
}
|
||||||
|
def r = this.results.getGlobalsResult(
|
||||||
|
[test: 'abc'],
|
||||||
|
true,
|
||||||
|
getGlobalsMonoid()
|
||||||
|
)
|
||||||
|
assertEquals([test: 'abc'], r)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void globalsEmpty() {
|
||||||
|
assertEquals([:], this.results.getGlobalsResult([:], true, getGlobalsMonoid()))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void typesNoBase() {
|
||||||
|
this.d.types {
|
||||||
|
textTypes << TextTypes.MARKDOWN
|
||||||
|
}
|
||||||
|
def r = this.results.getTypesResult(
|
||||||
|
TypesContainer.getEmpty(),
|
||||||
|
true,
|
||||||
|
TypesContainer.DEFAULT_MONOID
|
||||||
|
)
|
||||||
|
assertEquals(TypesContainer.get(textTypes: [TextTypes.MARKDOWN]), r)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void typesWithBaseNoConcat() {
|
||||||
|
this.d.types(false) { base ->
|
||||||
|
textTypes.addAll(base.textTypes)
|
||||||
|
}
|
||||||
|
def r = this.results.getTypesResult(
|
||||||
|
TypesContainer.get(textTypes: [TextTypes.MARKDOWN]),
|
||||||
|
true,
|
||||||
|
TypesContainer.DEFAULT_MONOID
|
||||||
|
)
|
||||||
|
assertEquals(TypesContainer.get(textTypes: [TextTypes.MARKDOWN]), r)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sourceProvidersNoBase(@Mock CollectionProvider<Text> textsProvider) {
|
||||||
|
this.d.sources { base, types ->
|
||||||
|
texts textsProvider
|
||||||
|
}
|
||||||
|
def r = this.results.getSourcesResult(
|
||||||
|
SourceProviders.getEmpty(),
|
||||||
|
true,
|
||||||
|
SourceProviders.DEFAULT_MONOID,
|
||||||
|
TypesContainer.getEmpty()
|
||||||
|
)
|
||||||
|
assertTrue(textsProvider in r.textsProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cannot use Mockito for not yet understood reasons;
|
||||||
|
// it seems that the mock is a part of an addition somewhere on the left side,
|
||||||
|
// and because it doesn't have the method stubbed/mocked it
|
||||||
|
// returns null. Why this confuses Groovy much later with
|
||||||
|
// SourceProviders is not clear; perhaps because the mock
|
||||||
|
// returns null, it throws an exception somewhere that is
|
||||||
|
// swallowed?
|
||||||
|
@Test
|
||||||
|
void sourceProvidersWithBase(/* @Mock CollectionProvider<Text> textsProvider */) {
|
||||||
|
def textsProvider = CollectionProviders.fromCollection([] as Collection<Text>)
|
||||||
|
this.d.sources { base, types ->
|
||||||
|
texts base.textsProvider
|
||||||
|
}
|
||||||
|
def r = this.results.getSourcesResult(
|
||||||
|
SourceProviders.get(textsProvider: textsProvider),
|
||||||
|
true,
|
||||||
|
SourceProviders.DEFAULT_MONOID,
|
||||||
|
TypesContainer.getEmpty()
|
||||||
|
)
|
||||||
|
assertTrue(textsProvider in r.textsProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sourceProvidersMergeBase() {
|
||||||
|
def textsProvider = CollectionProviders.fromCollection([] as Collection<Text>)
|
||||||
|
def r = this.results.getSourcesResult(
|
||||||
|
SourceProviders.get(textsProvider: textsProvider),
|
||||||
|
true,
|
||||||
|
SourceProviders.DEFAULT_MONOID,
|
||||||
|
TypesContainer.getEmpty()
|
||||||
|
)
|
||||||
|
assertTrue(textsProvider in r.textsProvider)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Monoid<Collection<TaskFactorySpec<TaskFactory>>> getTaskFactoriesMonoid() {
|
||||||
|
Monoids.of([] as Collection<TaskFactorySpec<TaskFactory>>) { c0, c1 ->
|
||||||
|
c0 + c1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void taskFactoriesNoBase(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
||||||
|
this.d.taskFactories { base, sources ->
|
||||||
|
register('f0', taskFactorySupplier)
|
||||||
|
}
|
||||||
|
def r = this.results.getTaskFactoriesResult(
|
||||||
|
[],
|
||||||
|
true,
|
||||||
|
getTaskFactoriesMonoid(),
|
||||||
|
SourceProviders.getEmpty()
|
||||||
|
)
|
||||||
|
assertEquals(1, r.size())
|
||||||
|
def spec0 = r[0]
|
||||||
|
assertEquals('f0', spec0.name)
|
||||||
|
assertEquals(taskFactorySupplier, spec0.supplier)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void taskFactoriesWithBase(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
||||||
|
this.d.taskFactories(false) { base, sources ->
|
||||||
|
registerAll(base)
|
||||||
|
}
|
||||||
|
def r = this.results.getTaskFactoriesResult(
|
||||||
|
[new TaskFactorySpec<TaskFactory>('spec0', taskFactorySupplier, [])],
|
||||||
|
true,
|
||||||
|
getTaskFactoriesMonoid(),
|
||||||
|
SourceProviders.getEmpty()
|
||||||
|
)
|
||||||
|
assertEquals(1, r.size())
|
||||||
|
def spec0 = r[0]
|
||||||
|
assertEquals('spec0', spec0.name)
|
||||||
|
assertEquals(taskFactorySupplier, spec0.supplier)
|
||||||
|
assertEquals([], spec0.configurators)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void taskFactoriesMergeBase(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
||||||
|
def r = this.results.getTaskFactoriesResult(
|
||||||
|
[new TaskFactorySpec<TaskFactory>('spec0', taskFactorySupplier, [])],
|
||||||
|
true,
|
||||||
|
getTaskFactoriesMonoid(),
|
||||||
|
SourceProviders.getEmpty()
|
||||||
|
)
|
||||||
|
assertEquals(1, r.size())
|
||||||
|
def spec0 = r[0]
|
||||||
|
assertEquals('spec0', spec0.name)
|
||||||
|
assertEquals(taskFactorySupplier, spec0.supplier)
|
||||||
|
assertEquals([], spec0.configurators)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.jessebrault.ssg.buildscript.delegates
|
||||||
|
|
||||||
|
import com.jessebrault.ssg.SiteSpec
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows
|
||||||
|
|
||||||
|
final class SiteSpecDelegateTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void nullNotAllowed() {
|
||||||
|
def d = new SiteSpecDelegate(SiteSpec.DEFAULT_MONOID)
|
||||||
|
assertThrows(NullPointerException, {
|
||||||
|
d.name = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
package com.jessebrault.ssg.buildscript.delegates
|
||||||
|
|
||||||
import com.jessebrault.ssg.task.TaskFactory
|
import com.jessebrault.ssg.task.TaskFactory
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@ -10,9 +10,7 @@ import org.mockito.junit.jupiter.MockitoExtension
|
|||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow
|
import static org.junit.jupiter.api.Assertions.*
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension)
|
@ExtendWith(MockitoExtension)
|
||||||
final class TaskFactoriesDelegateTests {
|
final class TaskFactoriesDelegateTests {
|
||||||
@ -28,9 +26,10 @@ final class TaskFactoriesDelegateTests {
|
|||||||
d.configure('test', TaskFactory, taskFactoryConsumer)
|
d.configure('test', TaskFactory, taskFactoryConsumer)
|
||||||
} as Executable)
|
} as Executable)
|
||||||
def result = d.getResult()
|
def result = d.getResult()
|
||||||
assertTrue(result.containsKey('test'))
|
def testSpec = result.find { it.name == 'test' }
|
||||||
assertEquals(taskFactorySupplier, result['test'].supplier)
|
assertNotNull(testSpec)
|
||||||
assertTrue(result['test'].configurators.contains(taskFactoryConsumer))
|
assertEquals(taskFactorySupplier, testSpec.supplier)
|
||||||
|
assertTrue(testSpec.configurators.contains(taskFactoryConsumer))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -41,9 +40,10 @@ final class TaskFactoriesDelegateTests {
|
|||||||
def d = new TaskFactoriesDelegate()
|
def d = new TaskFactoriesDelegate()
|
||||||
d.register('test', taskFactorySupplier, taskFactoryConsumer)
|
d.register('test', taskFactorySupplier, taskFactoryConsumer)
|
||||||
def result = d.getResult()
|
def result = d.getResult()
|
||||||
assertTrue(result.containsKey('test'))
|
def testSpec = result.find { it.name == 'test' }
|
||||||
assertEquals(taskFactorySupplier, result['test'].supplier)
|
assertNotNull(testSpec)
|
||||||
assertTrue(result['test'].configurators.contains(taskFactoryConsumer))
|
assertEquals(taskFactorySupplier, testSpec.supplier)
|
||||||
|
assertTrue(testSpec.configurators.contains(taskFactoryConsumer))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,97 +0,0 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.SiteSpec
|
|
||||||
import com.jessebrault.ssg.buildscript.SourceProviders
|
|
||||||
import com.jessebrault.ssg.buildscript.TypesContainer
|
|
||||||
import com.jessebrault.ssg.page.Page
|
|
||||||
import com.jessebrault.ssg.page.PageTypes
|
|
||||||
import com.jessebrault.ssg.provider.CollectionProvider
|
|
||||||
import com.jessebrault.ssg.task.TaskFactory
|
|
||||||
import com.jessebrault.ssg.text.Text
|
|
||||||
import com.jessebrault.ssg.text.TextTypes
|
|
||||||
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.Supplier
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue
|
|
||||||
|
|
||||||
@ExtendWith(MockitoExtension)
|
|
||||||
abstract class AbstractBuildDelegateTests<T> {
|
|
||||||
|
|
||||||
protected abstract AbstractBuildDelegate<T> getDelegate()
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void siteSpecsAdded() {
|
|
||||||
def d = this.getDelegate()
|
|
||||||
d.siteSpec {
|
|
||||||
name = 'test'
|
|
||||||
}
|
|
||||||
d.siteSpec {
|
|
||||||
baseUrl = 'test'
|
|
||||||
}
|
|
||||||
def sum = d.getSiteSpecResult()
|
|
||||||
assertEquals(new SiteSpec('test', 'test'), sum)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void globalsAdded() {
|
|
||||||
def d = this.getDelegate()
|
|
||||||
d.globals {
|
|
||||||
a = 0
|
|
||||||
}
|
|
||||||
d.globals {
|
|
||||||
b = 1
|
|
||||||
}
|
|
||||||
def sum = d.getGlobalsResult()
|
|
||||||
assertEquals([a: 0, b: 1], sum)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void typesAdded() {
|
|
||||||
def d = this.getDelegate()
|
|
||||||
d.types {
|
|
||||||
textTypes << TextTypes.MARKDOWN
|
|
||||||
}
|
|
||||||
d.types {
|
|
||||||
pageTypes << PageTypes.GSP
|
|
||||||
}
|
|
||||||
def sum = d.getTypesResult()
|
|
||||||
assertTrue(TextTypes.MARKDOWN in sum.textTypes)
|
|
||||||
assertTrue(PageTypes.GSP in sum.pageTypes)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void sourcesAdded(@Mock CollectionProvider<Text> textsProvider, @Mock CollectionProvider<Page> pagesProvider) {
|
|
||||||
def d = this.getDelegate()
|
|
||||||
d.providers {
|
|
||||||
texts(textsProvider)
|
|
||||||
}
|
|
||||||
d.providers {
|
|
||||||
pages(pagesProvider)
|
|
||||||
}
|
|
||||||
def sum = d.getSourcesResult(TypesContainer.getEmpty())
|
|
||||||
assertTrue(textsProvider in sum.textsProvider)
|
|
||||||
assertTrue(pagesProvider in sum.pagesProvider)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void taskFactoriesAdded(@Mock Supplier<TaskFactory> taskFactorySupplier) {
|
|
||||||
def d = this.getDelegate()
|
|
||||||
d.taskFactories {
|
|
||||||
register('tf0', taskFactorySupplier)
|
|
||||||
}
|
|
||||||
d.taskFactories {
|
|
||||||
register('tf1', taskFactorySupplier)
|
|
||||||
}
|
|
||||||
def sum = d.getTaskFactoriesResult(SourceProviders.getEmpty())
|
|
||||||
assertEquals(2, sum.size())
|
|
||||||
assertTrue(sum.inject(true) { acc, spec ->
|
|
||||||
acc && spec.supplier == taskFactorySupplier
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.buildscript.Build
|
|
||||||
|
|
||||||
final class AllBuildsDelegateTests extends AbstractBuildDelegateTests<Build.AllBuilds> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected AbstractBuildDelegate<Build.AllBuilds> getDelegate() {
|
|
||||||
new AllBuildsDelegate()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
package com.jessebrault.ssg.buildscript.dsl
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.buildscript.Build
|
|
||||||
|
|
||||||
final class BuildDelegateTests extends AbstractBuildDelegateTests<Build> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected AbstractBuildDelegate<Build> getDelegate() {
|
|
||||||
new BuildDelegate()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.jessebrault.ssg.mutable
|
||||||
|
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue
|
||||||
|
|
||||||
|
final class SimpleMutableTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void set() {
|
||||||
|
final Mutable<String> p = Mutables.getEmpty()
|
||||||
|
p.set('test')
|
||||||
|
assertEquals('test', p.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void unset() {
|
||||||
|
final Mutable<String> p = Mutables.getEmpty()
|
||||||
|
p.set('test')
|
||||||
|
p.unset()
|
||||||
|
assertThrows(NullPointerException, p.&get)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mapInPlace() {
|
||||||
|
final Mutable<String> p = Mutables.getEmpty()
|
||||||
|
p.set('abc')
|
||||||
|
p.mapInPlace { it + 'def' }
|
||||||
|
assertEquals('abcdef', p.get())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void filterInPlace() {
|
||||||
|
final Mutable<String> p = Mutables.getEmpty()
|
||||||
|
p.set('abc')
|
||||||
|
p.filterInPlace { it.startsWith('z') }
|
||||||
|
assertTrue(p.isEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void matchEmpty() {
|
||||||
|
final Mutable<String> p = Mutables.getEmpty()
|
||||||
|
def matched = p.match(
|
||||||
|
() -> 'a',
|
||||||
|
{ it + 'z' }
|
||||||
|
)
|
||||||
|
assertEquals('a', matched)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void matchPresent() {
|
||||||
|
final Mutable<String> p = Mutables.getEmpty()
|
||||||
|
p.set('a')
|
||||||
|
def matched = p.match(
|
||||||
|
() -> 'a',
|
||||||
|
{it + 'z' }
|
||||||
|
)
|
||||||
|
assertEquals('az', matched)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,24 +0,0 @@
|
|||||||
package com.jessebrault.ssg.property
|
|
||||||
|
|
||||||
import com.jessebrault.ssg.buildscript.domain.MutableSiteSpec
|
|
||||||
import org.junit.jupiter.api.Test
|
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
|
||||||
|
|
||||||
final class SimplePropertyTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void merge() {
|
|
||||||
def p = Properties.get(MutableSiteSpec.MONOID)
|
|
||||||
p.merge {
|
|
||||||
name.set('Hello')
|
|
||||||
}
|
|
||||||
p.map {
|
|
||||||
it.name.map { it + ', World!' }
|
|
||||||
it
|
|
||||||
}
|
|
||||||
def ms = p.get()
|
|
||||||
assertEquals('Hello, World!', ms.name.get())
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,3 +1,3 @@
|
|||||||
def t = new AnotherTask()
|
def t = new AnotherTask()
|
||||||
|
|
||||||
build('test') { }
|
build(name: 'test') { }
|
||||||
|
@ -11,7 +11,5 @@ final Logger logger = LoggerFactory.getLogger('simple.groovy')
|
|||||||
|
|
||||||
logger.debug('executing simple buildScript')
|
logger.debug('executing simple buildScript')
|
||||||
|
|
||||||
build {
|
build(name: 'test') { }
|
||||||
name = 'test'
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
def t = new TestHtmlTask()
|
def t = new TestHtmlTask()
|
||||||
|
|
||||||
build {
|
build(name: 'test') { }
|
||||||
name = 'test'
|
|
||||||
}
|
|
||||||
|
@ -13,20 +13,20 @@ import com.jessebrault.ssg.util.Result
|
|||||||
import groovy.transform.BaseScript
|
import groovy.transform.BaseScript
|
||||||
|
|
||||||
@BaseScript
|
@BaseScript
|
||||||
BuildScriptBase base
|
BuildScriptBase b
|
||||||
|
|
||||||
build('test') {
|
build(name: 'test') {
|
||||||
outputDirFunction = { Build b -> new OutputDir(new File(args.sourceDir, 'build')) }
|
outputDirFunction = { Build build -> new OutputDir(new File(args.sourceDir, 'build')) }
|
||||||
|
|
||||||
types {
|
types {
|
||||||
textTypes << TextTypes.MARKDOWN
|
textTypes << TextTypes.MARKDOWN
|
||||||
templateTypes << TemplateTypes.GSP
|
templateTypes << TemplateTypes.GSP
|
||||||
}
|
}
|
||||||
providers { types ->
|
sources { base, types ->
|
||||||
texts TextsProviders.from(new File(args.sourceDir, 'texts'), types.textTypes)
|
texts TextsProviders.from(new File(args.sourceDir, 'texts'), types.textTypes)
|
||||||
templates TemplatesProviders.from(new File(args.sourceDir, 'templates'), types.templateTypes)
|
templates TemplatesProviders.from(new File(args.sourceDir, 'templates'), types.templateTypes)
|
||||||
}
|
}
|
||||||
taskFactories { sources ->
|
taskFactories { base, sources ->
|
||||||
register('textToHtml', TextToHtmlTaskFactory::new) {
|
register('textToHtml', TextToHtmlTaskFactory::new) {
|
||||||
it.specProvider += CollectionProviders.fromSupplier {
|
it.specProvider += CollectionProviders.fromSupplier {
|
||||||
def templates = sources.templatesProvider.provide()
|
def templates = sources.templatesProvider.provide()
|
||||||
|
@ -13,7 +13,7 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// https://mvnrepository.com/artifact/org.apache.groovy/groovy
|
// https://mvnrepository.com/artifact/org.apache.groovy/groovy
|
||||||
api 'org.apache.groovy:groovy:4.0.9'
|
api 'org.apache.groovy:groovy:4.0.12'
|
||||||
|
|
||||||
// https://mvnrepository.com/artifact/org.jetbrains/annotations
|
// https://mvnrepository.com/artifact/org.jetbrains/annotations
|
||||||
api 'org.jetbrains:annotations:24.0.0'
|
api 'org.jetbrains:annotations:24.0.0'
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
abstractBuild(name: 'redDogAll', extends: 'default') {
|
abstractBuild(name: 'redDogAll', extends: 'default') {
|
||||||
// siteSpec(Closure) is short for siteSpec.merge(Closure)
|
|
||||||
siteSpec {
|
siteSpec {
|
||||||
name = 'Red Dog Ensemble'
|
name = 'Red Dog Ensemble'
|
||||||
baseUrl = 'https://reddogensemble.com'
|
baseUrl = 'https://reddogensemble.com'
|
||||||
@ -8,30 +7,14 @@ abstractBuild(name: 'redDogAll', extends: 'default') {
|
|||||||
globals {
|
globals {
|
||||||
greeting = 'Say hello to good music!'
|
greeting = 'Say hello to good music!'
|
||||||
}
|
}
|
||||||
|
|
||||||
sources { types ->
|
|
||||||
models.map { acc ->
|
|
||||||
acc + someMethodThatGetsEventModels()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
taskFactories { sources ->
|
|
||||||
register(name: 'eventToHtml', supplier: ModelToHtmlFactory::new) {
|
|
||||||
modelsProvider.map { acc ->
|
|
||||||
acc + CollectionProviders.fromSupplier {
|
|
||||||
sources.models.provide().findAll { it.name.startsWith('event/') }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
build(name: 'preview', extends: 'redDogAll') {
|
build(name: 'preview', extends: 'redDogAll') {
|
||||||
siteSpec { base ->
|
siteSpec { base ->
|
||||||
baseUrl = base.baseUrl + '/preview' // if possible
|
baseUrl = base.baseUrl + '/preview'
|
||||||
}
|
}
|
||||||
|
|
||||||
globals {
|
globals {
|
||||||
greeting = 'Hello from preview!'
|
greeting = 'Hello from preview!' // overwrite
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user