Worked on buildscript.
This commit is contained in:
parent
f11334c74b
commit
c502727243
@ -2,8 +2,7 @@ package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.buildscript.Build
|
||||
import com.jessebrault.ssg.buildscript.BuildScriptConfiguratorFactory
|
||||
import com.jessebrault.ssg.buildscript.BuildScriptRunner
|
||||
import com.jessebrault.ssg.buildscript.BuildUtil
|
||||
import com.jessebrault.ssg.buildscript.FileBuildScriptGetter
|
||||
import com.jessebrault.ssg.util.Diagnostic
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
@ -50,7 +49,7 @@ final class BuildScriptBasedStaticSiteGenerator implements StaticSiteGenerator {
|
||||
|
||||
if (this.buildScript == null) {
|
||||
logger.info('no specified build script; using defaults')
|
||||
def result = BuildScriptRunner.runClosureScript { base ->
|
||||
def result = FileBuildScriptGetter.runClosureScript { base ->
|
||||
configuratorFactories.each {
|
||||
it.get().accept(base)
|
||||
}
|
||||
@ -58,9 +57,9 @@ final class BuildScriptBasedStaticSiteGenerator implements StaticSiteGenerator {
|
||||
this.builds.addAll(result)
|
||||
} else if (this.buildScript.exists() && this.buildScript.isFile()) {
|
||||
logger.info('running buildScript: {}', this.buildScript)
|
||||
def buildScriptRunner = new BuildScriptRunner(this.buildScriptClassLoaderUrls)
|
||||
def buildScriptRunner = new FileBuildScriptGetter(this.buildScriptClassLoaderUrls)
|
||||
this.buildScriptClassLoader = buildScriptRunner.getBuildScriptClassLoader()
|
||||
def result = buildScriptRunner.runBuildScript(
|
||||
def result = buildScriptRunner.getBuildInfo(
|
||||
this.buildScript.name,
|
||||
[args: buildScriptArgs]
|
||||
) { base ->
|
||||
|
@ -27,10 +27,6 @@ final class SiteSpec {
|
||||
final String name
|
||||
final String baseUrl
|
||||
|
||||
SiteSpec plus(SiteSpec other) {
|
||||
concat(this, other)
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"SiteSpec(${ this.name }, ${ this.baseUrl })"
|
||||
|
@ -1,66 +1,44 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
import com.jessebrault.ssg.task.TaskFactory
|
||||
import com.jessebrault.ssg.task.TaskFactorySpec
|
||||
import com.jessebrault.ssg.model.Model
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
import groowt.util.fp.property.Property
|
||||
import groowt.util.fp.provider.NamedProvider
|
||||
import groowt.util.fp.provider.NamedSetProvider
|
||||
import groowt.util.fp.provider.Provider
|
||||
import groowt.util.fp.provider.SetProvider
|
||||
|
||||
import java.util.function.Function
|
||||
import static java.util.Objects.requireNonNull
|
||||
|
||||
@TupleConstructor(defaults = false)
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode
|
||||
final class Build {
|
||||
|
||||
static Build getEmpty() {
|
||||
new Build(
|
||||
'',
|
||||
OutputDirFunctions.DEFAULT,
|
||||
SiteSpec.getBlank(),
|
||||
[:],
|
||||
[],
|
||||
[]
|
||||
)
|
||||
}
|
||||
|
||||
static Build get(Map<String, Object> args) {
|
||||
new Build(
|
||||
args.name as String ?: '',
|
||||
args.outputDirFunction as Function<Build, OutputDir> ?: OutputDirFunctions.DEFAULT,
|
||||
args.siteSpec as SiteSpec ?: SiteSpec.getBlank(),
|
||||
args.globals as Map<String, Object> ?: [:],
|
||||
args.taskFactorySpecs as Collection<TaskFactorySpec<TaskFactory>> ?: [],
|
||||
args.includedBuilds as Collection<String> ?: []
|
||||
)
|
||||
}
|
||||
|
||||
static Build concat(Build b0, Build b1) {
|
||||
new Build(
|
||||
b0.name.blank ? b1.name : b0.name,
|
||||
OutputDirFunctions.concat(b0.outputDirFunction, b1.outputDirFunction),
|
||||
SiteSpec.concat(b0.siteSpec, b1.siteSpec),
|
||||
b0.globals + b1.globals,
|
||||
b0.taskFactorySpecs + b1.taskFactorySpecs,
|
||||
b0.includedBuilds + b1.includedBuilds
|
||||
)
|
||||
}
|
||||
|
||||
final String name
|
||||
final Function<Build, OutputDir> outputDirFunction
|
||||
final SiteSpec siteSpec
|
||||
final Map<String, Object> globals
|
||||
final Collection<TaskFactorySpec<TaskFactory>> taskFactorySpecs
|
||||
final Collection<String> includedBuilds
|
||||
final Property<String> name
|
||||
final Property<String> siteName
|
||||
final Property<String> baseUrl
|
||||
final Provider<File> outputDir
|
||||
final Provider<Map<String, Object>> globals
|
||||
final Set<Provider<File>> textsDirs
|
||||
final Set<NamedProvider<Model>> models
|
||||
|
||||
Build plus(Build other) {
|
||||
concat(this, other)
|
||||
@SuppressWarnings('GroovyAssignabilityCheck')
|
||||
Build(Map args) {
|
||||
this.includedBuilds = requireNonNull(args.includedBuilds)
|
||||
this.name = requireNonNull(args.name)
|
||||
this.siteName = requireNonNull(args.siteName)
|
||||
this.baseUrl = requireNonNull(args.baseUrl)
|
||||
this.outputDir = requireNonNull(args.outputDir)
|
||||
this.globals = requireNonNull(args.globals)
|
||||
this.textsDirs = requireNonNull(args.textsDirs)
|
||||
this.models = requireNonNull(args.models)
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"Build(name: ${ this.name }, siteSpec: ${ this.siteSpec }, globals: ${ this.globals }, includedBuilds: ${ this.includedBuilds })"
|
||||
"Build(name: ${ this.name })"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.buildscript.delegates.BuildDelegate
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@NullCheck
|
||||
@TupleConstructor(includeFields = true)
|
||||
class BuildDelegateToBuildConverter {
|
||||
|
||||
protected Build getFromDelegate(String name, BuildDelegate delegate) {
|
||||
new Build(
|
||||
name: name,
|
||||
siteName: delegate.siteName,
|
||||
baseUrl: delegate.baseUrl,
|
||||
outputDir: delegate.outputDir,
|
||||
globals: delegate.globals,
|
||||
models: delegate.models
|
||||
)
|
||||
}
|
||||
|
||||
protected void getFromBuild(Build source) {
|
||||
new BuildDelegate().tap {
|
||||
siteName(source.siteName)
|
||||
baseUrl(source.siteName)
|
||||
outputDir(source.outputDir)
|
||||
globals.set(source.globals)
|
||||
textsDirs(source.textsDirs)
|
||||
models(source.models)
|
||||
}
|
||||
}
|
||||
|
||||
private final FileBuildScriptGetter buildScriptGetter
|
||||
private final File buildScriptsDir
|
||||
|
||||
Build convert(String name, BuildScriptBase buildScript) {
|
||||
final BuildDelegate delegate
|
||||
if (buildScript.extending != null) {
|
||||
def extendingFrom = buildScriptGetter.getBuildInfo(buildScript.extending)
|
||||
def build = this.convert(buildScript.extending, extendingFrom)
|
||||
delegate = this.getFromBuild(build)
|
||||
} else {
|
||||
delegate = new BuildDelegate()
|
||||
}
|
||||
def cl = buildScript.buildClosure
|
||||
cl.delegate = delegate
|
||||
cl()
|
||||
this.getFromDelegate(name, delegate)
|
||||
}
|
||||
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript;
|
||||
|
||||
import com.jessebrault.ssg.util.Monoid;
|
||||
import org.jgrapht.Graph;
|
||||
import org.jgrapht.graph.DefaultEdge;
|
||||
import org.jgrapht.graph.DirectedAcyclicGraph;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public final class BuildGraph {
|
||||
|
||||
private static void addAncestorEdges(
|
||||
Graph<BuildSpec, DefaultEdge> graph,
|
||||
BuildSpec buildSpec,
|
||||
Collection<BuildSpec> allBuildSpecs
|
||||
) {
|
||||
if (!graph.containsVertex(buildSpec)) {
|
||||
throw new IllegalStateException("Given buildSpec " + buildSpec.getName() + " is not in the given graph.");
|
||||
}
|
||||
for (final var extendingName : buildSpec.getExtending()) {
|
||||
final var ancestor = allBuildSpecs.stream()
|
||||
.filter(bs -> extendingName.equals(bs.getName()))
|
||||
.findAny()
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"Could not find ancestor " + extendingName + " for buildSpec " + buildSpec.getName() + "."
|
||||
));
|
||||
graph.addEdge(ancestor, buildSpec);
|
||||
addAncestorEdges(graph, ancestor, allBuildSpecs);
|
||||
}
|
||||
}
|
||||
|
||||
private final Graph<BuildSpec, DefaultEdge> graph;
|
||||
|
||||
public BuildGraph(Collection<BuildSpec> buildSpecs) {
|
||||
this.graph = new DirectedAcyclicGraph<>(DefaultEdge.class);
|
||||
for (final var buildSpec : buildSpecs) {
|
||||
if (!this.graph.containsVertex(buildSpec)) {
|
||||
this.graph.addVertex(buildSpec);
|
||||
}
|
||||
addAncestorEdges(this.graph, buildSpec, buildSpecs);
|
||||
}
|
||||
}
|
||||
|
||||
public List<BuildSpec> getParents(BuildSpec start) {
|
||||
return this.graph.incomingEdgesOf(start).stream()
|
||||
.map(this.graph::getEdgeSource)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public BuildIntermediate toIntermediate(
|
||||
BuildSpec rootSpec,
|
||||
Monoid<BuildIntermediate> buildIntermediateMonoid,
|
||||
BiFunction<BuildIntermediate, BuildSpec, BuildIntermediate> parentAndSpecToIntermediate
|
||||
) {
|
||||
final List<BuildSpec> parents = this.getParents(rootSpec);
|
||||
if (parents.size() == 0) {
|
||||
return parentAndSpecToIntermediate.apply(buildIntermediateMonoid.getZero(), rootSpec);
|
||||
} else {
|
||||
final List<BuildIntermediate> parentIntermediates = parents.stream()
|
||||
.map(parent -> this.toIntermediate(parent, buildIntermediateMonoid, parentAndSpecToIntermediate))
|
||||
.toList();
|
||||
final BuildIntermediate parentsReduced = parentIntermediates.stream()
|
||||
.reduce(buildIntermediateMonoid.getZero(), (bi0, bi1) ->
|
||||
buildIntermediateMonoid.getConcat().apply(bi0, bi1)
|
||||
);
|
||||
return parentAndSpecToIntermediate.apply(parentsReduced, rootSpec);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript;
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec;
|
||||
import com.jessebrault.ssg.task.TaskFactory;
|
||||
import com.jessebrault.ssg.task.TaskFactorySpec;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public interface BuildIntermediate {
|
||||
BuildSpec getBuildSpec();
|
||||
Function<Build, OutputDir> getOutputDirFunction();
|
||||
SiteSpec getSiteSpec();
|
||||
Map<String, Object> getGlobals();
|
||||
TypesContainer getTypes();
|
||||
SourceProviders getSources();
|
||||
Collection<TaskFactorySpec<TaskFactory>> getTaskFactorySpecs();
|
||||
Collection<String> getIncludedBuilds();
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
import com.jessebrault.ssg.task.TaskFactory
|
||||
import com.jessebrault.ssg.task.TaskFactorySpec
|
||||
import com.jessebrault.ssg.util.Monoid
|
||||
import com.jessebrault.ssg.util.Monoids
|
||||
|
||||
import java.util.function.Function
|
||||
|
||||
final class BuildMonoids {
|
||||
|
||||
static final Monoid<Function<Build, OutputDir>> outputDirFunctionMonoid = OutputDirFunctions.DEFAULT_MONOID
|
||||
static final Monoid<SiteSpec> siteSpecMonoid = SiteSpec.DEFAULT_MONOID
|
||||
static final Monoid<Map<String, Object>> globalsMonoid = Monoids.getMapMonoid()
|
||||
static final Monoid<TypesContainer> typesMonoid = TypesContainer.DEFAULT_MONOID
|
||||
static final Monoid<SourceProviders> sourcesMonoid = SourceProviders.DEFAULT_MONOID
|
||||
|
||||
static final Monoid<Collection<TaskFactorySpec<TaskFactory>>> taskFactoriesMonoid =
|
||||
Monoids.getMergeCollectionMonoid(
|
||||
TaskFactorySpec.SAME_NAME_AND_SUPPLIER_EQ,
|
||||
TaskFactorySpec.DEFAULT_SEMIGROUP
|
||||
)
|
||||
|
||||
static final Monoid<Collection<String>> includedBuildsMonoid = Monoids.getCollectionMonoid()
|
||||
|
||||
static Monoid<BuildIntermediate> buildIntermediateMonoid = Monoids.of(SyntheticBuildIntermediate.getEmpty())
|
||||
{ bi0, bi1 ->
|
||||
new SyntheticBuildIntermediate(
|
||||
BuildSpec.get(
|
||||
name: "SyntheticBuildSpec(${ bi0.buildSpec.name }, ${ bi1.buildSpec.name })",
|
||||
isAbstract: true,
|
||||
extending: [],
|
||||
buildClosure: { }
|
||||
),
|
||||
outputDirFunctionMonoid.concat.apply(bi0.outputDirFunction, bi1.outputDirFunction),
|
||||
siteSpecMonoid.concat.apply(bi0.siteSpec, bi1.siteSpec),
|
||||
globalsMonoid.concat.apply(bi0.globals, bi1.globals),
|
||||
typesMonoid.concat.apply(bi0.types, bi1.types),
|
||||
sourcesMonoid.concat.apply(bi0.sources, bi1.sources),
|
||||
taskFactoriesMonoid.concat.apply(bi0.taskFactorySpecs, bi1.taskFactorySpecs),
|
||||
includedBuildsMonoid.concat.apply(bi0.includedBuilds, bi1.includedBuilds)
|
||||
)
|
||||
}
|
||||
|
||||
private BuildMonoids() {}
|
||||
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.buildscript.delegates.BuildDelegate
|
||||
import groovy.transform.PackageScope
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import org.jetbrains.annotations.Nullable
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.slf4j.Marker
|
||||
@ -9,70 +10,47 @@ import org.slf4j.MarkerFactory
|
||||
|
||||
import static java.util.Objects.requireNonNull
|
||||
|
||||
@SuppressWarnings('unused')
|
||||
abstract class BuildScriptBase extends Script {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(BuildScriptBase)
|
||||
protected static final Marker enter = MarkerFactory.getMarker('ENTER')
|
||||
protected static final Marker exit = MarkerFactory.getMarker('EXIT')
|
||||
static final Logger logger = LoggerFactory.getLogger(BuildScriptBase)
|
||||
static final Marker enter = MarkerFactory.getMarker('ENTER')
|
||||
static final Marker exit = MarkerFactory.getMarker('EXIT')
|
||||
|
||||
private static Collection<String> convertExtendingArg(Object arg) {
|
||||
arg instanceof Collection<String> ? arg as Collection<String>
|
||||
: arg instanceof String ? [arg] as Collection<String> : []
|
||||
private String extending
|
||||
private Closure buildClosure
|
||||
private File projectRoot
|
||||
|
||||
File getProjectRoot() {
|
||||
requireNonNull(this.projectRoot)
|
||||
}
|
||||
|
||||
protected final Collection<BuildSpec> buildSpecs = []
|
||||
|
||||
/**
|
||||
* args keys and values:
|
||||
* <ul>
|
||||
* <li><code>name: String<code></li>
|
||||
* <li><code>extending?: String | Collection<String></code></li>
|
||||
* </ul>
|
||||
*
|
||||
* @param args
|
||||
* @param buildClosure
|
||||
*/
|
||||
void abstractBuild(
|
||||
Map<String, Object> args,
|
||||
@DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||
Closure<?> buildClosure
|
||||
) {
|
||||
final Collection<String> extending = convertExtendingArg(args.extending)
|
||||
this.buildSpecs << BuildSpec.get(
|
||||
name: requireNonNull(args.name as String),
|
||||
isAbstract: true,
|
||||
extending: extending,
|
||||
buildClosure: buildClosure
|
||||
)
|
||||
void setProjectRoot(File projectRoot) {
|
||||
this.projectRoot = requireNonNull(projectRoot)
|
||||
}
|
||||
|
||||
/**
|
||||
* args keys and values:
|
||||
* <ul>
|
||||
* <li><code>name: String<code></li>
|
||||
* <li><code>extending?: String | Collection<String></code></li>
|
||||
* </ul>
|
||||
*
|
||||
* @param args
|
||||
* @param buildClosure
|
||||
*/
|
||||
void build(
|
||||
Map<String, Object> args,
|
||||
@DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||
Closure<?> buildClosure
|
||||
) {
|
||||
final Collection<String> extending = convertExtendingArg(args.extending)
|
||||
this.buildSpecs << BuildSpec.get(
|
||||
name: requireNonNull(args.name as String),
|
||||
isAbstract: false,
|
||||
extending: extending,
|
||||
buildClosure: buildClosure
|
||||
)
|
||||
File file(String name) {
|
||||
new File(this.projectRoot, name)
|
||||
}
|
||||
|
||||
@PackageScope
|
||||
Collection<BuildSpec> getBuildSpecs() {
|
||||
this.buildSpecs
|
||||
void build(@Nullable String extending, @DelegatesTo(value = BuildDelegate) Closure buildClosure) {
|
||||
this.extending = extending
|
||||
this.buildClosure = buildClosure
|
||||
}
|
||||
|
||||
void build(@DelegatesTo(value = BuildDelegate) Closure buildClosure) {
|
||||
this.extending = null
|
||||
this.buildClosure = buildClosure
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
@Nullable String getExtending() {
|
||||
this.extending
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
Closure getBuildClosure() {
|
||||
this.buildClosure
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import java.util.function.Consumer
|
||||
|
||||
interface BuildScriptConfiguratorFactory {
|
||||
Consumer<BuildScriptBase> get()
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.util.ExtensionUtil
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.stc.ClosureParams
|
||||
import groovy.transform.stc.SimpleType
|
||||
import org.codehaus.groovy.control.CompilerConfiguration
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.slf4j.Marker
|
||||
import org.slf4j.MarkerFactory
|
||||
|
||||
import java.util.function.Consumer
|
||||
|
||||
@NullCheck
|
||||
final class BuildScriptRunner {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BuildScriptRunner)
|
||||
private static final Marker enter = MarkerFactory.getMarker('ENTER')
|
||||
private static final Marker exit = MarkerFactory.getMarker('EXIT')
|
||||
|
||||
private static Collection<Build> runBase(BuildScriptBase base) {
|
||||
base.run()
|
||||
BuildSpecUtil.getBuilds(base.getBuildSpecs())
|
||||
}
|
||||
|
||||
static Collection<Build> runClosureScript(
|
||||
@DelegatesTo(value = BuildScriptBase, strategy = Closure.DELEGATE_FIRST)
|
||||
@ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.buildscript.BuildScriptBase')
|
||||
Closure<?> scriptBody
|
||||
) {
|
||||
def base = new BuildScriptBase() {
|
||||
|
||||
@Override
|
||||
Object run() {
|
||||
scriptBody.delegate = this
|
||||
scriptBody.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
scriptBody.call(this)
|
||||
}
|
||||
|
||||
}
|
||||
runBase(base)
|
||||
}
|
||||
|
||||
private final GroovyClassLoader buildScriptClassLoader
|
||||
|
||||
BuildScriptRunner(Collection<URL> classLoaderUrls) {
|
||||
this.buildScriptClassLoader = new GroovyClassLoader(
|
||||
Thread.currentThread().contextClassLoader,
|
||||
new CompilerConfiguration().tap {
|
||||
scriptBaseClass = BuildScriptBase.name
|
||||
}
|
||||
)
|
||||
classLoaderUrls.each(this.buildScriptClassLoader::addURL)
|
||||
}
|
||||
|
||||
GroovyClassLoader getBuildScriptClassLoader() {
|
||||
this.buildScriptClassLoader
|
||||
}
|
||||
|
||||
Collection<Build> runBuildScript(
|
||||
String scriptName,
|
||||
Map<String, Object> binding,
|
||||
Consumer<BuildScriptBase> configureBuildScript
|
||||
) {
|
||||
logger.trace(enter, 'scriptName: {}, binding: {}', scriptName, binding)
|
||||
Class<?> scriptClass = this.buildScriptClassLoader.loadClass(ExtensionUtil.stripExtension(scriptName))
|
||||
def scriptObject = scriptClass.getConstructor().newInstance()
|
||||
assert scriptObject instanceof BuildScriptBase
|
||||
scriptObject.setBinding(new Binding(binding))
|
||||
configureBuildScript.accept(scriptObject)
|
||||
def result = runBase(scriptObject)
|
||||
logger.trace(exit, 'result: {}', result)
|
||||
result
|
||||
}
|
||||
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.buildscript.delegates.BuildDelegate
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
|
||||
@NullCheck
|
||||
@EqualsAndHashCode(excludes = 'buildClosure')
|
||||
final class BuildSpec {
|
||||
|
||||
static BuildSpec getEmpty() {
|
||||
new BuildSpec('', false, [], { })
|
||||
}
|
||||
|
||||
static BuildSpec get(Map<String, Object> args) {
|
||||
new BuildSpec(
|
||||
args.name as String ?: '',
|
||||
args.isAbstract as boolean ?: false,
|
||||
args.extending as Collection<String> ?: [],
|
||||
args.buildClosure as Closure<?> ?: { }
|
||||
)
|
||||
}
|
||||
|
||||
static BuildSpec get(
|
||||
String name,
|
||||
boolean isAbstract,
|
||||
Collection<String> extending,
|
||||
@DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||
Closure<?> buildClosure
|
||||
) {
|
||||
new BuildSpec(name, isAbstract, extending, buildClosure)
|
||||
}
|
||||
|
||||
final String name
|
||||
final boolean isAbstract
|
||||
final Collection<String> extending
|
||||
final Closure<?> buildClosure
|
||||
|
||||
private BuildSpec(
|
||||
String name,
|
||||
boolean isAbstract,
|
||||
Collection<String> extending,
|
||||
@DelegatesTo(value = BuildDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||
Closure<?> buildClosure
|
||||
) {
|
||||
this.name = name
|
||||
this.isAbstract = isAbstract
|
||||
this.extending = extending
|
||||
this.buildClosure = buildClosure
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"BuildSpec(name: ${ this.name }, isAbstract: ${ this.isAbstract }, extending: ${ this.extending })"
|
||||
}
|
||||
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.buildscript.delegates.BuildDelegate
|
||||
import com.jessebrault.ssg.util.Monoid
|
||||
import groovy.transform.NullCheck
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.slf4j.Marker
|
||||
import org.slf4j.MarkerFactory
|
||||
|
||||
import java.util.function.BiFunction
|
||||
|
||||
@NullCheck
|
||||
final class BuildSpecUtil {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(BuildSpecUtil)
|
||||
private static final Marker enter = MarkerFactory.getMarker('ENTER')
|
||||
private static final Marker exit = MarkerFactory.getMarker('EXIT')
|
||||
|
||||
private static Build intermediateToBuild(BuildIntermediate intermediate) {
|
||||
Build.get(
|
||||
name: intermediate.buildSpec.name,
|
||||
outputDirFunction: intermediate.outputDirFunction,
|
||||
siteSpec: intermediate.siteSpec,
|
||||
globals: intermediate.globals,
|
||||
taskFactorySpecs: intermediate.taskFactorySpecs,
|
||||
includedBuilds: intermediate.includedBuilds
|
||||
)
|
||||
}
|
||||
|
||||
private static BuildIntermediate specToIntermediate(BuildSpec buildSpec, BuildIntermediate parent) {
|
||||
def d = new BuildDelegate()
|
||||
buildSpec.buildClosure.delegate = d
|
||||
buildSpec.buildClosure.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
buildSpec.buildClosure()
|
||||
new BuildDelegate.BuildDelegateBuildIntermediate(
|
||||
buildSpec,
|
||||
d,
|
||||
parent,
|
||||
BuildMonoids.siteSpecMonoid,
|
||||
BuildMonoids.globalsMonoid,
|
||||
BuildMonoids.typesMonoid,
|
||||
BuildMonoids.sourcesMonoid,
|
||||
BuildMonoids.taskFactoriesMonoid,
|
||||
BuildMonoids.includedBuildsMonoid
|
||||
)
|
||||
}
|
||||
|
||||
private static BuildIntermediate reduceWithParents(
|
||||
BuildSpec rootSpec,
|
||||
BuildGraph buildGraph,
|
||||
Monoid<BuildIntermediate> buildIntermediateMonoid,
|
||||
BiFunction<BuildIntermediate, BuildSpec, BuildIntermediate> parentAndSpecToIntermediate
|
||||
) {
|
||||
final List<BuildSpec> parents = buildGraph.getParents(rootSpec)
|
||||
if (parents.size() == 0) {
|
||||
parentAndSpecToIntermediate.apply(buildIntermediateMonoid.zero, rootSpec)
|
||||
} else {
|
||||
final List<BuildIntermediate> parentIntermediates = parents.collect {
|
||||
reduceWithParents(it, buildGraph, buildIntermediateMonoid, parentAndSpecToIntermediate)
|
||||
}
|
||||
final BuildIntermediate parentsReduced = parentIntermediates.inject(buildIntermediateMonoid.zero)
|
||||
{ acc, bi ->
|
||||
buildIntermediateMonoid.concat.apply(acc, bi)
|
||||
}
|
||||
parentAndSpecToIntermediate.apply(parentsReduced, rootSpec)
|
||||
}
|
||||
}
|
||||
|
||||
static Collection<Build> getBuilds(Collection<BuildSpec> buildSpecs) {
|
||||
logger.trace(enter, 'buildSpecs: {}', buildSpecs)
|
||||
def graph = new BuildGraph(buildSpecs)
|
||||
def intermediates = buildSpecs.findResults {
|
||||
if (it.isAbstract) {
|
||||
null
|
||||
} else {
|
||||
reduceWithParents(it, graph, BuildMonoids.buildIntermediateMonoid)
|
||||
{ parent, spec ->
|
||||
specToIntermediate(spec, parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
def builds = intermediates.collect { intermediateToBuild(it) }
|
||||
logger.trace(exit, 'builds: {}', builds)
|
||||
builds
|
||||
}
|
||||
|
||||
private BuildSpecUtil() {}
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.util.Diagnostic
|
||||
|
||||
final class BuildUtil {
|
||||
|
||||
static Collection<Diagnostic> diagnoseIncludedBuilds(Collection<Build> allBuilds) {
|
||||
allBuilds.inject([] as Collection<Diagnostic>) { allDiagnostics, build ->
|
||||
allDiagnostics + build.includedBuilds.inject([] as Collection<Diagnostic>) { buildDiagnostics, includedBuildName ->
|
||||
def includedBuild = allBuilds.find { it.name == includedBuildName }
|
||||
if (includedBuild == null) {
|
||||
buildDiagnostics + new Diagnostic(
|
||||
"The includedBuild ${ includedBuildName } is not in the collection of allBuilds"
|
||||
)
|
||||
} else {
|
||||
buildDiagnostics
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BuildUtil() {}
|
||||
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.html.PageToHtmlSpecProviders
|
||||
import com.jessebrault.ssg.html.PageToHtmlTaskFactory
|
||||
import com.jessebrault.ssg.html.TextToHtmlSpecProviders
|
||||
import com.jessebrault.ssg.html.TextToHtmlTaskFactory
|
||||
import com.jessebrault.ssg.page.PageTypes
|
||||
import com.jessebrault.ssg.page.PagesProviders
|
||||
import com.jessebrault.ssg.part.PartTypes
|
||||
import com.jessebrault.ssg.part.PartsProviders
|
||||
import com.jessebrault.ssg.template.TemplateTypes
|
||||
import com.jessebrault.ssg.template.TemplatesProviders
|
||||
import com.jessebrault.ssg.text.TextTypes
|
||||
import com.jessebrault.ssg.text.TextsProviders
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Supplier
|
||||
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
final class DefaultBuildScriptConfiguratorFactory implements BuildScriptConfiguratorFactory {
|
||||
|
||||
private final File baseDir
|
||||
private final Supplier<ClassLoader> classLoaderSupplier
|
||||
|
||||
@Override
|
||||
Consumer<BuildScriptBase> get() {
|
||||
return {
|
||||
it.build(name: 'default') {
|
||||
outputDirFunction = { Build build ->
|
||||
new OutputDir(new File(this.baseDir, build.name == 'default' ? 'build' : build.name))
|
||||
}
|
||||
|
||||
types {
|
||||
textTypes << TextTypes.MARKDOWN
|
||||
pageTypes << PageTypes.getGsp(['.gsp', '.ssg.gst'], this.classLoaderSupplier.get())
|
||||
templateTypes << TemplateTypes.getGsp(['.gsp', '.ssg.gst'], this.classLoaderSupplier.get())
|
||||
partTypes << PartTypes.getGsp(['.gsp', '.ssg.gst'], this.classLoaderSupplier.get())
|
||||
}
|
||||
|
||||
sources { base, types ->
|
||||
texts TextsProviders.from(new File(this.baseDir, 'texts'), types.textTypes)
|
||||
pages PagesProviders.from(new File(this.baseDir, 'pages'), types.pageTypes)
|
||||
templates TemplatesProviders.from(new File(this.baseDir, 'templates'), types.templateTypes)
|
||||
parts PartsProviders.from(new File(this.baseDir, 'parts'), types.partTypes)
|
||||
}
|
||||
|
||||
taskFactories { base, sources ->
|
||||
register('textToHtml', TextToHtmlTaskFactory::new) {
|
||||
it.specsProvider += TextToHtmlSpecProviders.from(sources)
|
||||
it.allTextsProvider += sources.textsProvider
|
||||
it.allPartsProvider += sources.partsProvider
|
||||
it.allModelsProvider += sources.modelsProvider
|
||||
}
|
||||
|
||||
register('pageToHtml', PageToHtmlTaskFactory::new) {
|
||||
it.specsProvider += PageToHtmlSpecProviders.from(sources.pagesProvider)
|
||||
it.allTextsProvider += sources.textsProvider
|
||||
it.allPartsProvider += sources.partsProvider
|
||||
it.allModelsProvider += sources.modelsProvider
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@NullCheck
|
||||
@TupleConstructor(includeFields = true)
|
||||
final class FileBuildScriptGetter {
|
||||
|
||||
private final File projectRoot
|
||||
private final GroovyClassLoader gcl
|
||||
|
||||
BuildScriptBase getBuildInfo(String name) {
|
||||
Class<?> scriptClass = this.gcl.loadClass(name, true, false)
|
||||
def scriptObject = scriptClass.getConstructor().newInstance()
|
||||
assert scriptObject instanceof BuildScriptBase
|
||||
scriptObject
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
|
||||
@NullCheck
|
||||
@EqualsAndHashCode
|
||||
final class OutputDir {
|
||||
|
||||
private final String path
|
||||
|
||||
OutputDir(String path) {
|
||||
this.path = path
|
||||
}
|
||||
|
||||
OutputDir(File file) {
|
||||
this(file.path)
|
||||
}
|
||||
|
||||
File asFile() {
|
||||
new File(this.path)
|
||||
}
|
||||
|
||||
String asString() {
|
||||
this.path
|
||||
}
|
||||
|
||||
Object asType(Class<?> clazz) {
|
||||
switch (clazz) {
|
||||
case File -> this.asFile()
|
||||
case String -> this.asString()
|
||||
default -> throw new IllegalArgumentException('cannot cast to a class other than File or String')
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"OutputDir(path: ${ this.path })"
|
||||
}
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.util.Monoid
|
||||
import com.jessebrault.ssg.util.Monoids
|
||||
|
||||
import java.util.function.Function
|
||||
|
||||
final class OutputDirFunctions {
|
||||
|
||||
static final Function<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(
|
||||
Function<Build, OutputDir> f0,
|
||||
Function<Build, OutputDir> f1
|
||||
) {
|
||||
f0 == OutputDirFunctions.DEFAULT ? f1 : f0
|
||||
}
|
||||
|
||||
static Function<Build, OutputDir> of(File dir) {
|
||||
return { new OutputDir(dir) }
|
||||
}
|
||||
|
||||
static Function<Build, OutputDir> of(String path) {
|
||||
return { new OutputDir(path) }
|
||||
}
|
||||
|
||||
private OutputDirFunctions() {}
|
||||
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.model.Model
|
||||
import com.jessebrault.ssg.page.Page
|
||||
import com.jessebrault.ssg.part.Part
|
||||
import com.jessebrault.ssg.provider.CollectionProvider
|
||||
import com.jessebrault.ssg.provider.CollectionProviders
|
||||
import com.jessebrault.ssg.template.Template
|
||||
import com.jessebrault.ssg.text.Text
|
||||
import com.jessebrault.ssg.util.Monoid
|
||||
import com.jessebrault.ssg.util.Monoids
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@NullCheck
|
||||
@EqualsAndHashCode
|
||||
final class SourceProviders {
|
||||
|
||||
static final Monoid<SourceProviders> DEFAULT_MONOID = Monoids.of(getEmpty(), SourceProviders::concat)
|
||||
|
||||
static SourceProviders concat(SourceProviders sp0, SourceProviders sp1) {
|
||||
new SourceProviders(
|
||||
sp0.textsProvider + sp1.textsProvider,
|
||||
sp0.modelsProvider + sp1.modelsProvider,
|
||||
sp0.pagesProvider + sp1.pagesProvider,
|
||||
sp0.templatesProvider + sp1.templatesProvider,
|
||||
sp0.partsProvider + sp1.partsProvider,
|
||||
sp0.custom + sp1.custom
|
||||
)
|
||||
}
|
||||
|
||||
static SourceProviders get(Map<String, Object> args) {
|
||||
new SourceProviders(
|
||||
args.textsProvider as CollectionProvider<Text>
|
||||
?: CollectionProviders.getEmpty() as CollectionProvider<Text>,
|
||||
args.modelsProvider as CollectionProvider<Model<Object>>
|
||||
?: CollectionProviders.getEmpty() as CollectionProvider<Model<Object>>,
|
||||
args.pagesProvider as CollectionProvider<Page>
|
||||
?: CollectionProviders.getEmpty() as CollectionProvider<Page>,
|
||||
args.templatesProvider as CollectionProvider<Template>
|
||||
?: CollectionProviders.getEmpty() as CollectionProvider<Template>,
|
||||
args.partsProvider as CollectionProvider<Part>
|
||||
?: CollectionProviders.getEmpty() as CollectionProvider<Part>,
|
||||
args.custom as Map<String, CollectionProvider<?>> ?: [:]
|
||||
)
|
||||
}
|
||||
|
||||
static SourceProviders getEmpty() {
|
||||
new SourceProviders(
|
||||
CollectionProviders.getEmpty(),
|
||||
CollectionProviders.getEmpty(),
|
||||
CollectionProviders.getEmpty(),
|
||||
CollectionProviders.getEmpty(),
|
||||
CollectionProviders.getEmpty(),
|
||||
[:]
|
||||
)
|
||||
}
|
||||
|
||||
final CollectionProvider<Text> textsProvider
|
||||
final CollectionProvider<Model<Object>> modelsProvider
|
||||
final CollectionProvider<Page> pagesProvider
|
||||
final CollectionProvider<Template> templatesProvider
|
||||
final CollectionProvider<Part> partsProvider
|
||||
|
||||
private final Map<String, CollectionProvider<Object>> custom
|
||||
|
||||
SourceProviders(
|
||||
CollectionProvider<Text> textsProvider,
|
||||
CollectionProvider<Model<Object>> modelsProvider,
|
||||
CollectionProvider<Page> pagesProvider,
|
||||
CollectionProvider<Template> templatesProvider,
|
||||
CollectionProvider<Part> partsProvider,
|
||||
Map<String, CollectionProvider<Object>> custom
|
||||
) {
|
||||
this.textsProvider = textsProvider
|
||||
this.modelsProvider = modelsProvider
|
||||
this.pagesProvider = pagesProvider
|
||||
this.templatesProvider = templatesProvider
|
||||
this.partsProvider = partsProvider
|
||||
this.custom = custom
|
||||
}
|
||||
|
||||
SourceProviders plus(SourceProviders other) {
|
||||
concat(this, other)
|
||||
}
|
||||
|
||||
def <T> CollectionProvider<T> getCustom(String name, Class<T> tClass) {
|
||||
this.custom.get(name) as CollectionProvider<T>
|
||||
}
|
||||
|
||||
void putCustom(String name, CollectionProvider<?> customProvider) {
|
||||
this.custom.put(name, customProvider as CollectionProvider<Object>)
|
||||
}
|
||||
|
||||
Map<String, CollectionProvider<Object>> getAllCustom() {
|
||||
this.custom
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"SourceProviders(textsProvider: ${ this.textsProvider }, modelsProvider: ${ this.modelsProvider }, " +
|
||||
"pagesProvider: ${ this.pagesProvider }, templatesProvider: ${ this.templatesProvider }, " +
|
||||
"partsProvider: ${ this.partsProvider })"
|
||||
}
|
||||
|
||||
}
|
@ -1,74 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
import com.jessebrault.ssg.task.TaskFactory
|
||||
import com.jessebrault.ssg.task.TaskFactorySpec
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
import java.util.function.Function
|
||||
|
||||
@TupleConstructor(defaults = false)
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode
|
||||
final class SyntheticBuildIntermediate implements BuildIntermediate {
|
||||
|
||||
static BuildIntermediate getEmpty() {
|
||||
new SyntheticBuildIntermediate(
|
||||
BuildSpec.getEmpty(),
|
||||
OutputDirFunctions.DEFAULT,
|
||||
SiteSpec.getBlank(),
|
||||
[:],
|
||||
TypesContainer.getEmpty(),
|
||||
SourceProviders.getEmpty(),
|
||||
[],
|
||||
[]
|
||||
)
|
||||
}
|
||||
|
||||
static BuildIntermediate get(Map<String, Object> args) {
|
||||
new SyntheticBuildIntermediate(
|
||||
args.buildSpec as BuildSpec ?: BuildSpec.getEmpty(),
|
||||
args.outputDirFunction as Function<Build, OutputDir> ?: OutputDirFunctions.DEFAULT,
|
||||
args.siteSpec as SiteSpec ?: SiteSpec.getBlank(),
|
||||
args.globals as Map<String, Object> ?: [:],
|
||||
args.types as TypesContainer ?: TypesContainer.getEmpty(),
|
||||
args.sources as SourceProviders ?: SourceProviders.getEmpty(),
|
||||
args.taskFactorySpecs as Collection<TaskFactorySpec<TaskFactory>> ?: [],
|
||||
args.includedBuilds as Collection<String> ?: []
|
||||
)
|
||||
}
|
||||
|
||||
static BuildIntermediate get(
|
||||
BuildSpec buildSpec,
|
||||
Function<Build, OutputDir> outputDirFunction,
|
||||
SiteSpec siteSpec,
|
||||
Map<String, Object> globals,
|
||||
TypesContainer types,
|
||||
SourceProviders sources,
|
||||
Collection<TaskFactorySpec<TaskFactory>> taskFactorySpecs,
|
||||
Collection<String> includedBuilds
|
||||
) {
|
||||
new SyntheticBuildIntermediate(
|
||||
buildSpec,
|
||||
outputDirFunction,
|
||||
siteSpec,
|
||||
globals,
|
||||
types,
|
||||
sources,
|
||||
taskFactorySpecs,
|
||||
includedBuilds
|
||||
)
|
||||
}
|
||||
|
||||
final BuildSpec buildSpec
|
||||
final Function<Build, OutputDir> outputDirFunction
|
||||
final SiteSpec siteSpec
|
||||
final Map<String, Object> globals
|
||||
final TypesContainer types
|
||||
final SourceProviders sources
|
||||
final Collection<TaskFactorySpec<TaskFactory>> taskFactorySpecs
|
||||
final Collection<String> includedBuilds
|
||||
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.page.PageType
|
||||
import com.jessebrault.ssg.part.PartType
|
||||
import com.jessebrault.ssg.template.TemplateType
|
||||
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.NullCheck
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@TupleConstructor(defaults = false)
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode
|
||||
final class TypesContainer {
|
||||
|
||||
static final Monoid<TypesContainer> DEFAULT_MONOID = Monoids.of(getEmpty(), TypesContainer::concat)
|
||||
|
||||
static TypesContainer getEmpty() {
|
||||
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) {
|
||||
new TypesContainer(
|
||||
tc0.textTypes + tc1.textTypes,
|
||||
tc0.pageTypes + tc1.pageTypes,
|
||||
tc0.templateTypes + tc1.templateTypes,
|
||||
tc0.partTypes + tc1.partTypes
|
||||
)
|
||||
}
|
||||
|
||||
final Collection<TextType> textTypes
|
||||
final Collection<PageType> pageTypes
|
||||
final Collection<TemplateType> templateTypes
|
||||
final Collection<PartType> partTypes
|
||||
|
||||
TypesContainer plus(TypesContainer other) {
|
||||
concat(this, other)
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"TypesContainer(textTypes: ${ this.textTypes }, pageTypes: ${ this.pageTypes }, " +
|
||||
"templateTypes: ${ this.templateTypes }, partTypes: ${ this.partTypes })"
|
||||
}
|
||||
|
||||
}
|
@ -1,283 +1,103 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
import com.jessebrault.ssg.buildscript.*
|
||||
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 com.jessebrault.ssg.model.Model
|
||||
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.UnaryOperator
|
||||
import groowt.util.fp.property.Property
|
||||
import groowt.util.fp.provider.DefaultNamedProvider
|
||||
import groowt.util.fp.provider.DefaultNamedSetProvider
|
||||
import groowt.util.fp.provider.DefaultSetProvider
|
||||
import groowt.util.fp.provider.NamedProvider
|
||||
import groowt.util.fp.provider.NamedSetProvider
|
||||
import groowt.util.fp.provider.Provider
|
||||
import groowt.util.fp.provider.SetProvider
|
||||
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
final class BuildDelegate {
|
||||
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
static final class BuildDelegateBuildIntermediate implements BuildIntermediate {
|
||||
final Property<String> siteName = Property.empty().tap {
|
||||
convention = 'An Ssg Site'
|
||||
}
|
||||
|
||||
private final BuildSpec buildSpec
|
||||
private final BuildDelegate delegate
|
||||
private final BuildIntermediate parent
|
||||
final Property<String> baseUrl = Property.empty().tap {
|
||||
convention = ''
|
||||
}
|
||||
|
||||
private final Monoid<SiteSpec> siteSpecMonoid
|
||||
private final Monoid<Map<String, Object>> globalsMonoid
|
||||
private final Monoid<TypesContainer> typesMonoid
|
||||
private final Monoid<SourceProviders> sourcesMonoid
|
||||
private final Monoid<Collection<TaskFactorySpec<TaskFactory>>> taskFactoriesMonoid
|
||||
private final Monoid<Collection<String>> includedBuildsMonoid
|
||||
final Property<File> outputDir = Property.empty().tap {
|
||||
convention = siteName.map { it.replace(' ', '-').toLowerCase() + '-build' }
|
||||
}
|
||||
|
||||
@Override
|
||||
BuildSpec getBuildSpec() {
|
||||
this.buildSpec
|
||||
final Property<Map<String, Object>> globals = Property.empty().tap {
|
||||
convention = [:]
|
||||
}
|
||||
|
||||
private final Set<Provider<File>> textsDirs = []
|
||||
private final Set<NamedProvider<Model>> models = []
|
||||
|
||||
void siteName(String siteName) {
|
||||
this.siteName.set(siteName)
|
||||
}
|
||||
|
||||
void siteName(Provider<String> siteNameProvider) {
|
||||
this.siteName.set(siteNameProvider)
|
||||
}
|
||||
|
||||
void baseUrl(String baseUrl) {
|
||||
this.baseUrl.set(baseUrl)
|
||||
}
|
||||
|
||||
void baseUrl(Provider<String> baseUrlProvider) {
|
||||
this.baseUrl.set(baseUrlProvider)
|
||||
}
|
||||
|
||||
void outputDir(File outputDir) {
|
||||
this.outputDir.set(outputDir)
|
||||
}
|
||||
|
||||
void outputDir(Provider<File> outputDirProvider) {
|
||||
this.outputDir.set(outputDirProvider)
|
||||
}
|
||||
|
||||
void globals(@DelegatesTo(value = GlobalsDelegate, strategy = Closure.DELEGATE_FIRST) Closure<?> globalsClosure) {
|
||||
def globalsDelegate = new GlobalsDelegate()
|
||||
globalsClosure.delegate = globalsDelegate
|
||||
globalsClosure.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
globalsClosure()
|
||||
this.globals.set {
|
||||
this.globals.get() + globalsDelegate
|
||||
}
|
||||
|
||||
@Override
|
||||
Function<Build, OutputDir> getOutputDirFunction() {
|
||||
this.delegate.outputDirFunction.getOrElse {
|
||||
this.delegate.outputDirFunctionMapper.match({ parent.outputDirFunction }) {
|
||||
it.apply(this.parent.outputDirFunction)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
SiteSpec getSiteSpec() {
|
||||
def siteSpecClosure = this.delegate.siteSpecClosure.getOrElse { return { } }
|
||||
def d = new SiteSpecDelegate(this.siteSpecMonoid)
|
||||
siteSpecClosure.delegate = d
|
||||
siteSpecClosure.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
siteSpecClosure(this.parent.siteSpec)
|
||||
if (this.delegate.siteSpecConcatBase.getOrElse { true }) {
|
||||
this.siteSpecMonoid.concat.apply(this.parent.siteSpec, d.result)
|
||||
} else {
|
||||
d.result
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Map<String, Object> getGlobals() {
|
||||
def globalsClosure = this.delegate.globalsClosure.getOrElse { return { } }
|
||||
def d = new GlobalsDelegate()
|
||||
globalsClosure.delegate = d
|
||||
globalsClosure.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
globalsClosure(this.parent.globals)
|
||||
if (this.delegate.globalsConcatBase.getOrElse { true }) {
|
||||
this.globalsMonoid.concat.apply(this.parent.globals, d.getResult())
|
||||
} else {
|
||||
d.getResult()
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
TypesContainer getTypes() {
|
||||
def typesClosure = this.delegate.typesClosure.getOrElse { return { } }
|
||||
def d = new TypesDelegate()
|
||||
typesClosure.delegate = d
|
||||
typesClosure.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
typesClosure(this.parent.types)
|
||||
if (this.delegate.typesConcatBase.getOrElse { true }) {
|
||||
this.typesMonoid.concat.apply(this.parent.types, d.result)
|
||||
} else {
|
||||
d.result
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
SourceProviders getSources() {
|
||||
def sourcesClosure = this.delegate.sourcesClosure.getOrElse { return { base, types -> } }
|
||||
def d = new SourceProvidersDelegate()
|
||||
sourcesClosure.delegate = d
|
||||
sourcesClosure.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
sourcesClosure(this.parent.sources, this.types)
|
||||
if (this.delegate.sourcesConcatBase.getOrElse { true }) {
|
||||
this.sourcesMonoid.concat.apply(this.parent.sources, d.result)
|
||||
} else {
|
||||
d.result
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<TaskFactorySpec<TaskFactory>> getTaskFactorySpecs() {
|
||||
def taskFactoriesClosure = this.delegate.taskFactoriesClosure.getOrElse { return { base, sources -> } }
|
||||
def d = new TaskFactoriesDelegate()
|
||||
taskFactoriesClosure.delegate = d
|
||||
taskFactoriesClosure.resolveStrategy = Closure.DELEGATE_FIRST
|
||||
taskFactoriesClosure(this.parent.taskFactorySpecs, this.sources)
|
||||
if (this.delegate.taskFactoriesConcatBase.getOrElse { true }) {
|
||||
this.taskFactoriesMonoid.concat.apply(this.parent.taskFactorySpecs, d.result)
|
||||
} else {
|
||||
d.result
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
Collection<String> getIncludedBuilds() {
|
||||
if (this.delegate.includedBuildsConcatBase.getOrElse { true }) {
|
||||
this.includedBuildsMonoid.concat.apply(this.parent.includedBuilds, this.delegate.includedBuilds)
|
||||
} else {
|
||||
this.delegate.includedBuilds
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
private final Mutable<Boolean> includedBuildsConcatBase = Mutables.getEmpty()
|
||||
private final Collection<String> includedBuilds = []
|
||||
|
||||
void setOutputDirFunction(Function<Build, OutputDir> outputDirFunction) {
|
||||
this.outputDirFunction.set(outputDirFunction)
|
||||
void textsDir(File textsDir) {
|
||||
this.textsDirs.add { textsDir }
|
||||
}
|
||||
|
||||
void setOutputDir(File file) {
|
||||
this.outputDirFunction.set { new OutputDir(file) }
|
||||
void textsDir(Provider<File> textsDirProvider) {
|
||||
this.textsDirs << textsDirProvider
|
||||
}
|
||||
|
||||
void setOutputDir(String path) {
|
||||
this.outputDirFunction.set { new OutputDir(path) }
|
||||
void textsDirs(Set<Provider<File>> textsDirProviders) {
|
||||
textsDirProviders.each { this.textsDir(it) }
|
||||
}
|
||||
|
||||
// Maps the *base*
|
||||
void outputDirFunction(UnaryOperator<Function<Build, OutputDir>> mapper) {
|
||||
this.outputDirFunctionMapper.set(mapper)
|
||||
SetProvider<File> getTextsDirs() {
|
||||
new DefaultSetProvider(this.textsDirs)
|
||||
}
|
||||
|
||||
void siteSpec(
|
||||
@DelegatesTo(value = SiteSpecDelegate, strategy = Closure.DELEGATE_FIRST)
|
||||
@ClosureParams(value = SimpleType, options = 'com.jessebrault.ssg.SiteSpec')
|
||||
Closure<?> siteSpecClosure
|
||||
) {
|
||||
this.siteSpec(true, siteSpecClosure)
|
||||
void models(@DelegatesTo(ModelsDelegate) Closure modelsClosure) {
|
||||
def modelsDelegate = new ModelsDelegate()
|
||||
modelsClosure.delegate = modelsDelegate
|
||||
modelsClosure()
|
||||
models.addAll(modelsDelegate.result)
|
||||
}
|
||||
|
||||
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 models(Set<NamedProvider<Model>> models) {
|
||||
this.models.addAll(models)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
void setConcatIncludedBuildsWithBase(boolean value) {
|
||||
this.includedBuildsConcatBase.set(value)
|
||||
}
|
||||
|
||||
void includeBuild(String buildName) {
|
||||
this.includedBuilds << buildName
|
||||
NamedSetProvider<Model> getModels() {
|
||||
new DefaultNamedSetProvider(this.models)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,49 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.model.Model
|
||||
import com.jessebrault.ssg.model.Models
|
||||
import groowt.util.fp.provider.DefaultNamedProvider
|
||||
import groowt.util.fp.provider.NamedProvider
|
||||
import groowt.util.fp.provider.Provider
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
|
||||
import java.util.function.Supplier
|
||||
|
||||
final class ModelsDelegate {
|
||||
|
||||
private final Map<String, Provider<Model>> modelsMap = [:]
|
||||
|
||||
void add(String name, Object modelObject) {
|
||||
this.modelsMap.put(name) { Models.of(name, modelObject ) }
|
||||
}
|
||||
|
||||
void add(Model model) {
|
||||
this.modelsMap.put(model.name) { model }
|
||||
}
|
||||
|
||||
void add(NamedProvider<Model> namedModelProvider) {
|
||||
this.modelsMap.put(namedModelProvider.name, namedModelProvider)
|
||||
}
|
||||
|
||||
void add(String name, Provider<Model> modelProvider) {
|
||||
this.modelsMap.put(name, modelProvider)
|
||||
}
|
||||
|
||||
void add(String name, Supplier objectSupplier) {
|
||||
this.modelsMap.put(name) { Models.ofSupplier(name, objectSupplier) }
|
||||
}
|
||||
|
||||
void addAll(Map<String, Object> namesAndModels) {
|
||||
namesAndModels.each { name, modelObject ->
|
||||
this.add(name, modelObject)
|
||||
}
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
Set<NamedProvider<Model>> getResult() {
|
||||
this.modelsMap.inject([] as Set<NamedProvider<Model>>) { acc, name, modelProvider ->
|
||||
acc << new DefaultNamedProvider(name, modelProvider)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
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,61 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.buildscript.SourceProviders
|
||||
import com.jessebrault.ssg.model.Model
|
||||
import com.jessebrault.ssg.page.Page
|
||||
import com.jessebrault.ssg.part.Part
|
||||
import com.jessebrault.ssg.provider.CollectionProvider
|
||||
import com.jessebrault.ssg.provider.CollectionProviders
|
||||
import com.jessebrault.ssg.template.Template
|
||||
import com.jessebrault.ssg.text.Text
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
|
||||
@NullCheck
|
||||
@EqualsAndHashCode
|
||||
final class SourceProvidersDelegate {
|
||||
|
||||
private CollectionProvider<Text> textsProvider = CollectionProviders.getEmpty()
|
||||
private CollectionProvider<Model<Object>> modelsProvider = CollectionProviders.getEmpty()
|
||||
private CollectionProvider<Page> pagesProvider = CollectionProviders.getEmpty()
|
||||
private CollectionProvider<Template> templatesProvider = CollectionProviders.getEmpty()
|
||||
private CollectionProvider<Part> partsProvider = CollectionProviders.getEmpty()
|
||||
|
||||
private final Map<String, CollectionProvider<Object>> custom = [:]
|
||||
|
||||
void texts(CollectionProvider<Text> textsProvider) {
|
||||
this.textsProvider += textsProvider
|
||||
}
|
||||
|
||||
void models(CollectionProvider<Model<?>> modelsProvider) {
|
||||
this.modelsProvider += modelsProvider
|
||||
}
|
||||
|
||||
void pages(CollectionProvider<Page> pagesProvider) {
|
||||
this.pagesProvider += pagesProvider
|
||||
}
|
||||
|
||||
void templates(CollectionProvider<Template> templatesProvider) {
|
||||
this.templatesProvider += templatesProvider
|
||||
}
|
||||
|
||||
void parts(CollectionProvider<Part> partsProvider) {
|
||||
this.partsProvider += partsProvider
|
||||
}
|
||||
|
||||
void custom(String name, CollectionProvider<?> customProvider) {
|
||||
this.custom.put(name, customProvider as CollectionProvider<Object>)
|
||||
}
|
||||
|
||||
SourceProviders getResult() {
|
||||
new SourceProviders(
|
||||
this.textsProvider,
|
||||
this.modelsProvider,
|
||||
this.pagesProvider,
|
||||
this.templatesProvider,
|
||||
this.partsProvider,
|
||||
this.custom
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.task.TaskFactory
|
||||
import com.jessebrault.ssg.task.TaskFactorySpec
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Supplier
|
||||
|
||||
@NullCheck
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
final class TaskFactoriesDelegate {
|
||||
|
||||
private final Collection<TaskFactorySpec<TaskFactory>> specs = []
|
||||
|
||||
private boolean isRegistered(String name) {
|
||||
this.specs.find { it.name == name } != null
|
||||
}
|
||||
|
||||
private void checkNotRegistered(String name) {
|
||||
if (this.isRegistered(name)) {
|
||||
throw new IllegalArgumentException("a TaskFactory is already registered by the name ${ name }")
|
||||
}
|
||||
}
|
||||
|
||||
void register(String name, Supplier<? extends TaskFactory> factorySupplier) {
|
||||
this.checkNotRegistered(name)
|
||||
this.specs << new TaskFactorySpec<>(name, factorySupplier, [])
|
||||
}
|
||||
|
||||
def <T extends TaskFactory> void register(
|
||||
String name,
|
||||
Supplier<T> factorySupplier,
|
||||
Consumer<T> factoryConfigurator
|
||||
) {
|
||||
this.checkNotRegistered(name)
|
||||
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(
|
||||
String name,
|
||||
Class<T> factoryClass, // Dummy so we get better auto-complete
|
||||
Consumer<T> factoryConfigurator
|
||||
) {
|
||||
if (!this.isRegistered(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.
|
||||
spec.configurators << (factoryConfigurator as Consumer<TaskFactory>)
|
||||
}
|
||||
|
||||
Collection<TaskFactorySpec<TaskFactory>> getResult() {
|
||||
this.specs
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package com.jessebrault.ssg.buildscript.delegates
|
||||
|
||||
import com.jessebrault.ssg.buildscript.TypesContainer
|
||||
import com.jessebrault.ssg.page.PageType
|
||||
import com.jessebrault.ssg.part.PartType
|
||||
import com.jessebrault.ssg.template.TemplateType
|
||||
import com.jessebrault.ssg.text.TextType
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
|
||||
@NullCheck
|
||||
@EqualsAndHashCode
|
||||
final class TypesDelegate {
|
||||
|
||||
final Collection<TextType> textTypes = []
|
||||
final Collection<PageType> pageTypes = []
|
||||
final Collection<TemplateType> templateTypes = []
|
||||
final Collection<PartType> partTypes = []
|
||||
|
||||
TypesContainer getResult() {
|
||||
new TypesContainer(this.textTypes, this.pageTypes, this.templateTypes, this.partTypes)
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
package com.jessebrault.ssg.model
|
||||
|
||||
import groowt.util.fp.provider.NamedProvider
|
||||
import groowt.util.fp.provider.Provider
|
||||
|
||||
import java.util.function.Supplier
|
||||
|
||||
final class Models {
|
||||
@ -8,10 +11,18 @@ final class Models {
|
||||
new SimpleModel<>(name, t)
|
||||
}
|
||||
|
||||
static <T> Model<T> fromSupplier(String name, Supplier<T> tClosure) {
|
||||
static <T> Model<T> ofSupplier(String name, Supplier<? extends T> tClosure) {
|
||||
new SupplierBasedModel<>(name, tClosure)
|
||||
}
|
||||
|
||||
static <T> Model<T> ofProvider(String name, Provider<? extends T> modelProvider) {
|
||||
new ProviderModel<T>(name, modelProvider)
|
||||
}
|
||||
|
||||
static <T> Model<T> ofNamedProvider(NamedProvider<? extends T> namedModelProvider) {
|
||||
new ProviderModel<T>(namedModelProvider.name, namedModelProvider)
|
||||
}
|
||||
|
||||
private Models() {}
|
||||
|
||||
}
|
||||
|
@ -1,28 +1,27 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
package com.jessebrault.ssg.model
|
||||
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
import java.util.function.Supplier
|
||||
import groowt.util.fp.provider.Provider
|
||||
|
||||
@PackageScope
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
final class SupplierBasedProvider<T> extends AbstractProvider<T> {
|
||||
@EqualsAndHashCode
|
||||
class ProviderModel<T> implements Model<T> {
|
||||
|
||||
private final Supplier<T> supplier
|
||||
final String name
|
||||
private final Provider<T> modelProvider
|
||||
|
||||
@Override
|
||||
T provide() {
|
||||
this.supplier.get()
|
||||
T get() {
|
||||
this.modelProvider.get()
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"SupplierBasedProvider(supplier: ${ this.supplier })"
|
||||
"ProviderModel($this.name)"
|
||||
}
|
||||
|
||||
}
|
@ -8,13 +8,17 @@ import groovy.transform.TupleConstructor
|
||||
import java.util.function.Supplier
|
||||
|
||||
@PackageScope
|
||||
@TupleConstructor(includeFields = true, defaults = false)
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
final class SupplierBasedModel<T> implements Model<T> {
|
||||
|
||||
final String name
|
||||
private final Supplier<T> supplier
|
||||
private final Supplier<? extends T> supplier
|
||||
|
||||
SupplierBasedModel(String name, Supplier<? extends T> supplier) {
|
||||
this.name = name
|
||||
this.supplier = supplier
|
||||
}
|
||||
|
||||
@Override
|
||||
T get() {
|
||||
|
@ -6,6 +6,7 @@ import java.util.Optional;
|
||||
import java.util.function.*;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@Deprecated
|
||||
public interface Mutable<T> {
|
||||
T get();
|
||||
void set(T t);
|
||||
|
@ -1,11 +0,0 @@
|
||||
package com.jessebrault.ssg.property
|
||||
|
||||
final class Properties {
|
||||
|
||||
static <T> Property<T> get() {
|
||||
new SimpleProperty<>()
|
||||
}
|
||||
|
||||
private Properties() {}
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package com.jessebrault.ssg.property
|
||||
|
||||
import com.jessebrault.ssg.provider.Provider
|
||||
|
||||
import java.util.function.Function
|
||||
import java.util.function.UnaryOperator
|
||||
|
||||
interface Property<T> extends Provider<T> {
|
||||
|
||||
void set(T t)
|
||||
void set(Provider<T> provider)
|
||||
void unset()
|
||||
|
||||
default void leftShift(T t) {
|
||||
this.set(t)
|
||||
}
|
||||
|
||||
default void leftShift(Provider<T> provider) {
|
||||
this.set(provider)
|
||||
}
|
||||
|
||||
T getConvention()
|
||||
void setConvention(T t)
|
||||
void setConvention(Provider<T> provider)
|
||||
void unsetConvention()
|
||||
|
||||
void map(UnaryOperator<T> operator)
|
||||
void flatMap(Function<T, Provider<T>> function)
|
||||
|
||||
default void rightShift(UnaryOperator<T> operator) {
|
||||
this.map(operator)
|
||||
}
|
||||
|
||||
default void rightShift(Function<T, Provider<T>> function) {
|
||||
this.flatMap(function)
|
||||
}
|
||||
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
package com.jessebrault.ssg.property
|
||||
|
||||
import com.jessebrault.ssg.provider.AbstractProvider
|
||||
import com.jessebrault.ssg.provider.Provider
|
||||
import com.jessebrault.ssg.provider.Providers
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.PackageScope
|
||||
|
||||
import java.util.function.Function
|
||||
import java.util.function.UnaryOperator
|
||||
|
||||
@PackageScope
|
||||
@NullCheck
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
final class SimpleProperty<T> extends AbstractProvider<T> implements Property<T> {
|
||||
|
||||
private Provider<T> convention = Providers.getEmpty()
|
||||
private Provider<T> tProvider = Providers.getEmpty()
|
||||
|
||||
@Override
|
||||
T provide() {
|
||||
this.tProvider.present ? this.tProvider.provide() : this.convention.provide()
|
||||
}
|
||||
|
||||
@Override
|
||||
void set(T t) {
|
||||
this.tProvider = Providers.of(t)
|
||||
}
|
||||
|
||||
@Override
|
||||
void set(Provider<T> provider) {
|
||||
this.tProvider = provider
|
||||
}
|
||||
|
||||
@Override
|
||||
void unset() {
|
||||
this.tProvider = Providers.getEmpty()
|
||||
}
|
||||
|
||||
@Override
|
||||
T getConvention() {
|
||||
this.convention.provide()
|
||||
}
|
||||
|
||||
@Override
|
||||
void setConvention(T t) {
|
||||
this.convention = Providers.of(t)
|
||||
}
|
||||
|
||||
@Override
|
||||
void setConvention(Provider<T> provider) {
|
||||
this.convention = provider
|
||||
}
|
||||
|
||||
@Override
|
||||
void unsetConvention() {
|
||||
this.convention = Providers.getEmpty()
|
||||
}
|
||||
|
||||
@Override
|
||||
void map(UnaryOperator<T> operator) {
|
||||
def oldTProvider = this.tProvider
|
||||
this.tProvider = Providers.fromSupplier {
|
||||
operator.apply(oldTProvider.provide())
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void flatMap(Function<T, Provider<T>> function) {
|
||||
def oldTProvider = this.tProvider
|
||||
this.tProvider = Providers.fromSupplier {
|
||||
function.apply(oldTProvider.provide()).provide()
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"SimpleProperty(convention: ${ this.convention }, tProvider: ${ this.tProvider })"
|
||||
}
|
||||
|
||||
}
|
@ -9,31 +9,16 @@ import groovy.transform.TupleConstructor
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
abstract class AbstractCollectionProvider<T> implements CollectionProvider<T> {
|
||||
|
||||
static <T> CollectionProvider<T> concat(
|
||||
CollectionProvider<T> cp,
|
||||
Provider<T> p
|
||||
) {
|
||||
new SupplierBasedCollectionProvider<>([cp], [p], {
|
||||
[*cp.provide(), p.provide()]
|
||||
})
|
||||
}
|
||||
|
||||
static <T> CollectionProvider<T> concat(
|
||||
CollectionProvider<T> cp0,
|
||||
CollectionProvider<T> cp1
|
||||
) {
|
||||
new SupplierBasedCollectionProvider<>([cp0, cp1], [], {
|
||||
new SupplierBasedCollectionProvider<>([cp0, cp1], {
|
||||
cp0.provide() + cp1.provide()
|
||||
})
|
||||
}
|
||||
|
||||
private final Collection<CollectionProvider<T>> collectionProviderChildren
|
||||
private final Collection<Provider<T>> providerChildren
|
||||
|
||||
@Override
|
||||
boolean contains(Provider<T> provider) {
|
||||
provider in this
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean contains(CollectionProvider<T> collectionProvider) {
|
||||
@ -68,36 +53,11 @@ abstract class AbstractCollectionProvider<T> implements CollectionProvider<T> {
|
||||
this.getChildrenOfType(DirectoryCollectionProvider)
|
||||
}
|
||||
|
||||
@Override
|
||||
CollectionProvider<T> plus(Provider<T> other) {
|
||||
concat(this, other)
|
||||
}
|
||||
|
||||
@Override
|
||||
CollectionProvider<T> plus(CollectionProvider<T> other) {
|
||||
concat(this, other)
|
||||
}
|
||||
|
||||
private boolean searchProviderChildrenFor(Provider<T> descendant) {
|
||||
this.providerChildren.inject(false) { acc, childProvider ->
|
||||
acc || descendant in childProvider
|
||||
}
|
||||
}
|
||||
|
||||
private boolean searchCollectionProviderChildrenFor(Provider<T> descendant) {
|
||||
this.collectionProviderChildren.inject(false) { acc, childProvider ->
|
||||
acc || descendant in childProvider
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isCase(Provider<T> provider) {
|
||||
provider in this.providerChildren
|
||||
|| this.searchProviderChildrenFor(provider)
|
||||
|| this.searchCollectionProviderChildrenFor(provider)
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isCase(CollectionProvider<T> collectionProvider) {
|
||||
collectionProvider == this
|
||||
|
@ -1,40 +0,0 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
|
||||
abstract class AbstractProvider<T> implements Provider<T> {
|
||||
|
||||
static <T> CollectionProvider<T> concat(
|
||||
Provider<T> p0,
|
||||
Provider<T> p1
|
||||
) {
|
||||
new SupplierBasedCollectionProvider<>([], [p0, p1], {
|
||||
[p0.provide(), p1.provide()]
|
||||
})
|
||||
}
|
||||
|
||||
static <T> CollectionProvider<T> concat(
|
||||
Provider<T> p0,
|
||||
CollectionProvider<T> p1
|
||||
) {
|
||||
new SupplierBasedCollectionProvider<>([p1], [p0], {
|
||||
[p0.provide(), *p1.provide()]
|
||||
})
|
||||
}
|
||||
|
||||
@Override
|
||||
CollectionProvider<T> plus(Provider<T> other) {
|
||||
concat(this, other)
|
||||
}
|
||||
|
||||
@Override
|
||||
CollectionProvider<T> plus(CollectionProvider<T> other) {
|
||||
concat(this, other)
|
||||
}
|
||||
|
||||
@Override
|
||||
CollectionProvider<T> asType(Class<CollectionProvider> collectionProviderClass) {
|
||||
new SupplierBasedCollectionProvider<>({
|
||||
[this.provide() as T]
|
||||
})
|
||||
}
|
||||
|
||||
}
|
@ -7,7 +7,6 @@ import java.util.Collection;
|
||||
public interface CollectionProvider<T> {
|
||||
Collection<T> provide();
|
||||
|
||||
boolean contains(Provider<T> provider);
|
||||
boolean contains(CollectionProvider<T> collectionProvider);
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@ -18,9 +17,7 @@ public interface CollectionProvider<T> {
|
||||
|
||||
Collection<DirectoryCollectionProvider<T>> getDirectoryCollectionProviderChildren();
|
||||
|
||||
CollectionProvider<T> plus(Provider<T> other);
|
||||
CollectionProvider<T> plus(CollectionProvider<T> other);
|
||||
|
||||
boolean isCase(Provider<T> provider);
|
||||
boolean isCase(CollectionProvider<T> collectionProvider);
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.PackageScope
|
||||
|
||||
@PackageScope
|
||||
@NullCheck
|
||||
@EqualsAndHashCode
|
||||
final class EmptyProvider<T> implements Provider<T> {
|
||||
|
||||
@Override
|
||||
T provide() {
|
||||
throw new NullPointerException('EmptyProvider cannot provide a value.')
|
||||
}
|
||||
|
||||
@Override
|
||||
CollectionProvider<T> plus(CollectionProvider<T> other) {
|
||||
CollectionProviders.fromSupplier {
|
||||
other.provide()
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
CollectionProvider<T> plus(Provider<T> other) {
|
||||
CollectionProviders.fromSupplier {
|
||||
[other.provide()] as Collection<T>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
CollectionProvider<T> asType(Class<CollectionProvider> collectionProviderClass) {
|
||||
CollectionProviders.fromCollection([]) as CollectionProvider<T>
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"EmptyProvider()"
|
||||
}
|
||||
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
|
||||
interface Provider<T> {
|
||||
T provide()
|
||||
CollectionProvider<T> plus(Provider<T> other)
|
||||
CollectionProvider<T> plus(CollectionProvider<T> other)
|
||||
CollectionProvider<T> asType(Class<CollectionProvider> collectionProviderClass)
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
|
||||
import groovy.transform.NullCheck
|
||||
|
||||
import java.util.function.Supplier
|
||||
|
||||
@NullCheck
|
||||
final class Providers {
|
||||
|
||||
static <T> Provider<T> getEmpty() {
|
||||
new EmptyProvider<>()
|
||||
}
|
||||
|
||||
static <T> Provider<T> of(T t) {
|
||||
new SimpleProvider<>(t)
|
||||
}
|
||||
|
||||
static <T> Provider<T> fromSupplier(Supplier<T> supplier) {
|
||||
new SupplierBasedProvider<>(supplier)
|
||||
}
|
||||
|
||||
static <T> CollectionProvider<T> concat(Provider<T> ...providers) {
|
||||
concat(List.of(providers))
|
||||
}
|
||||
|
||||
static <T> CollectionProvider<T> concat(Collection<Provider<T>> providers) {
|
||||
providers.inject(CollectionProviders.<T>getEmpty()) { acc, val ->
|
||||
acc + val
|
||||
}
|
||||
}
|
||||
|
||||
private Providers() {}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package com.jessebrault.ssg.provider
|
||||
|
||||
import groovy.transform.EqualsAndHashCode
|
||||
import groovy.transform.NullCheck
|
||||
import groovy.transform.PackageScope
|
||||
import groovy.transform.TupleConstructor
|
||||
|
||||
@PackageScope
|
||||
@TupleConstructor(defaults = false, includeFields = true)
|
||||
@NullCheck(includeGenerated = true)
|
||||
@EqualsAndHashCode(includeFields = true)
|
||||
final class SimpleProvider<T> extends AbstractProvider<T> {
|
||||
|
||||
private final T t
|
||||
|
||||
@Override
|
||||
T provide() {
|
||||
this.t
|
||||
}
|
||||
|
||||
@Override
|
||||
String toString() {
|
||||
"SimpleProvider(t: ${ this.t })"
|
||||
}
|
||||
|
||||
}
|
@ -15,15 +15,14 @@ final class SupplierBasedCollectionProvider<T> extends AbstractCollectionProvide
|
||||
|
||||
SupplierBasedCollectionProvider(
|
||||
Collection<CollectionProvider<T>> collectionProviderChildren,
|
||||
Collection<Provider<T>> providerChildren,
|
||||
Supplier<Collection<T>> supplier
|
||||
) {
|
||||
super(collectionProviderChildren, providerChildren)
|
||||
super(collectionProviderChildren)
|
||||
this.supplier = supplier
|
||||
}
|
||||
|
||||
SupplierBasedCollectionProvider(Supplier<Collection<T>> supplier) {
|
||||
this([], [], supplier)
|
||||
this([], supplier)
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2,6 +2,7 @@ package com.jessebrault.ssg.buildscript
|
||||
|
||||
import com.jessebrault.ssg.SiteSpec
|
||||
import groovy.transform.NullCheck
|
||||
import org.junit.jupiter.api.Disabled
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.extension.ExtendWith
|
||||
import org.mockito.Mock
|
||||
@ -10,7 +11,6 @@ import org.mockito.junit.jupiter.MockitoExtension
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Function
|
||||
|
||||
import static BuildScriptRunner.runClosureScript
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals
|
||||
import static org.mockito.Mockito.verify
|
||||
|
||||
@ -52,7 +52,7 @@ final class BuildScriptsTests {
|
||||
Map<String, Object> binding = [:],
|
||||
Consumer<BuildScriptBase> configureBase = { }
|
||||
) {
|
||||
new BuildScriptRunner(urls).runBuildScript(scriptName, binding, configureBase)
|
||||
new FileBuildScriptGetter(urls).getBuildInfo(scriptName, binding, configureBase)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -164,6 +164,8 @@ final class BuildScriptsTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
@Deprecated(forRemoval = true)
|
||||
void oneBuildWithAbstractParent() {
|
||||
def r = runClosureScript {
|
||||
abstractBuild(name: 'parent') {
|
||||
|
@ -20,11 +20,6 @@ abstract class AbstractCollectionProviderTests {
|
||||
|
||||
protected static final Logger logger = LoggerFactory.getLogger(AbstractCollectionProviderTests)
|
||||
|
||||
@SuppressWarnings('GrMethodMayBeStatic')
|
||||
protected Provider<Integer> getProvider(Integer t) {
|
||||
Providers.of(t)
|
||||
}
|
||||
|
||||
protected abstract CollectionProvider<Integer> getCollectionProvider(Collection<Integer> ts)
|
||||
|
||||
@Test
|
||||
@ -75,12 +70,10 @@ abstract class AbstractCollectionProviderTests {
|
||||
|
||||
@TestFactory
|
||||
Collection<DynamicTest> containsAndIsCaseProviderChildren() {
|
||||
def p0 = this.getProvider(0)
|
||||
def p1 = this.getCollectionProvider([])
|
||||
def sum = p0 + p1
|
||||
([
|
||||
contains: { CollectionProvider<Integer> p ->
|
||||
assertTrue(p.contains(p0))
|
||||
assertTrue(p.contains(p1))
|
||||
} as Consumer<CollectionProvider<Integer>>,
|
||||
in: { CollectionProvider<Integer> p ->
|
||||
|
10
cli/src/main/resources/com/jessebrault/ssg/default.groovy
Normal file
10
cli/src/main/resources/com/jessebrault/ssg/default.groovy
Normal file
@ -0,0 +1,10 @@
|
||||
import com.jessebrault.ssg.buildscript.BuildScriptBase
|
||||
import groovy.transform.BaseScript
|
||||
|
||||
@BaseScript
|
||||
BuildScriptBase base
|
||||
|
||||
build {
|
||||
siteName 'My Site'
|
||||
baseUrl 'https://mysite.com'
|
||||
}
|
10
cli/src/main/resources/com/jessebrault/ssg/preview.groovy
Normal file
10
cli/src/main/resources/com/jessebrault/ssg/preview.groovy
Normal file
@ -0,0 +1,10 @@
|
||||
import com.jessebrault.ssg.buildscript.BuildScriptBase
|
||||
import groovy.transform.BaseScript
|
||||
|
||||
@BaseScript
|
||||
BuildScriptBase base
|
||||
|
||||
build {
|
||||
extending 'default'
|
||||
baseUrl baseUrl.map { defaultBaseUrl -> defaultBaseUrl + '/preview' }
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
import com.jessebrault.ssg.buildscript.BuildScriptBase
|
||||
import groovy.transform.BaseScript
|
||||
|
||||
@BaseScript
|
||||
BuildScriptBase base
|
||||
|
||||
build {
|
||||
extending 'default'
|
||||
}
|
35
ssg-0.4.0.md
35
ssg-0.4.0.md
@ -24,10 +24,43 @@ Have the following layout of dirs and files. It is a combined gradle/ssg project
|
||||
- production.ssg.groovy: a 'production' build
|
||||
- preview.ssg.groovy: a 'preview' build
|
||||
- texts: a general folder for texts and other textual data, can be .md, .txt, .html, etc.
|
||||
- build.gradle: the root project build.gradle
|
||||
- build.gradle: the root project build.gradle
|
||||
- settings.gradle: the usual gradle settings
|
||||
|
||||
## Api TODO
|
||||
- [ ] Move from `Provider`/`Property` in `api` to `groowt.util.provider`.
|
||||
- [ ] Move from all the fp-util stuff to `groowt.util.fp`.
|
||||
- [ ] Get rid of graph-dependency.
|
||||
|
||||
## New Build Script DSL
|
||||
|
||||
Simple example:
|
||||
```groovy
|
||||
extendsFrom('default')
|
||||
|
||||
// isAbstract = true
|
||||
|
||||
siteName = 'Hello, World!'
|
||||
baseUrl = 'https://helloworld.com/'
|
||||
buildDir = new File('hello-world-build')
|
||||
|
||||
globals {
|
||||
someProp = 'Some property.'
|
||||
}
|
||||
|
||||
includedBuilds << 'anotherBuild'
|
||||
```
|
||||
|
||||
Example with models:
|
||||
```groovy
|
||||
Set<NamedModel> myModels = [
|
||||
new NamedModel(name: 'thing0'),
|
||||
new NamedModel(name: 'thing1')
|
||||
]
|
||||
|
||||
models {
|
||||
myModels.each {
|
||||
add(it.name, it)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user