Introduced TaskInput and TaskOutput interfaces.
Some checks failed
StaticSiteGenerator Release / release (push) Has been cancelled

This commit is contained in:
JesseBrault0709 2023-05-15 18:31:46 +02:00
parent fa58875f88
commit 9cd303d317
16 changed files with 178 additions and 28 deletions

View File

@ -6,7 +6,6 @@ Here will be kept all of the various todos for this project, organized by releas
### Add ### Add
- [ ] Plan out plugin system such that we can create custom providers of texts, data, etc. - [ ] Plan out plugin system such that we can create custom providers of texts, data, etc.
- [ ] Provide a way to override `ssgBuilds` variables from the cli.
- [ ] Add `Watchable` interface/trait back; an abstraction over FS watching and other sources (such as a database, etc.). - [ ] Add `Watchable` interface/trait back; an abstraction over FS watching and other sources (such as a database, etc.).
- [ ] Explore `apply(Plugin)` in buildScripts. - [ ] Explore `apply(Plugin)` in buildScripts.
@ -17,19 +16,23 @@ Here will be kept all of the various todos for this project, organized by releas
### Add ### Add
- [ ] Write manual. - [ ] Write manual.
- [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. - [x] 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. - [ ] Still must work on 'default'-ing.
- [x] Write lots of tests for buildscript dsl, etc.
- [x] 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. - Make the delegates as dumb as possible; no more `getResult` methods; make different classes/object handle concat'ing and getting results.
- [x] Provide a way to override `ssgBuilds` variables from the cli.
### Fix ### Fix
- [ ] Update CHANGELOG to reflect the gsp-dsl changes. - [ ] Update CHANGELOG to reflect the gsp-dsl changes.
- [ ] `taskTypes` gone, use class name instead - [ ] `taskTypes` gone, use class name instead
- [ ] introduction of `models` - [ ] introduction of `models`
- [x] Change most instances of `Closure<Void>` to `Closure<?>` to help with IDE expectations. - [x] Change most instances of `Closure<Void>` to `Closure<?>` to help with IDE expectations.
- [ ] Fix auto-imports in build script so we don't need to import things.
- [ ] Re-introduce input/output concept to tasks, if possible
## Finished ## Finished

View File

@ -2,6 +2,7 @@ package com.jessebrault.ssg.html
import com.jessebrault.ssg.task.AbstractTask import com.jessebrault.ssg.task.AbstractTask
import com.jessebrault.ssg.task.Task import com.jessebrault.ssg.task.Task
import com.jessebrault.ssg.task.TaskInput
import com.jessebrault.ssg.util.Diagnostic import com.jessebrault.ssg.util.Diagnostic
import com.jessebrault.ssg.util.Result import com.jessebrault.ssg.util.Result
import groovy.transform.EqualsAndHashCode import groovy.transform.EqualsAndHashCode
@ -10,15 +11,26 @@ import org.jsoup.Jsoup
@NullCheck @NullCheck
@EqualsAndHashCode @EqualsAndHashCode
abstract class AbstractHtmlTask extends AbstractTask implements HtmlTask { abstract class AbstractHtmlTask<I extends TaskInput> extends AbstractTask implements HtmlTask {
final String path final String htmlPath
private final File buildDir final I input
final HtmlOutput output
AbstractHtmlTask(String name, String path, File buildDir) { AbstractHtmlTask(
String name,
String htmlPath,
I input,
File buildDir
) {
super(name) super(name)
this.path = path this.htmlPath = htmlPath
this.buildDir = buildDir this.input = input
this.output = new SimpleHtmlOutput(
"htmlOutput:${ htmlPath }",
new File(buildDir, htmlPath),
htmlPath
)
} }
protected abstract Result<String> transform(Collection<Task> allTasks) protected abstract Result<String> transform(Collection<Task> allTasks)
@ -33,16 +45,15 @@ abstract class AbstractHtmlTask extends AbstractTask implements HtmlTask {
def document = Jsoup.parse(content) def document = Jsoup.parse(content)
document.outputSettings().indentAmount(4) document.outputSettings().indentAmount(4)
def formatted = document.toString() def formatted = document.toString()
def target = new File(this.buildDir, this.path) this.output.file.createParentDirectories()
target.createParentDirectories() this.output.file.write(formatted)
target.write(formatted)
[] []
} }
} }
@Override @Override
String toString() { String toString() {
"AbstractHtmlTask(path: ${ this.path }, super: ${ super.toString() })" "AbstractHtmlTask(path: ${ this.htmlPath }, super: ${ super.toString() })"
} }
} }

View File

@ -0,0 +1,7 @@
package com.jessebrault.ssg.html
import com.jessebrault.ssg.task.FileOutput
interface HtmlOutput extends FileOutput {
String getHtmlPath()
}

View File

@ -1,7 +1,12 @@
package com.jessebrault.ssg.html package com.jessebrault.ssg.html
import com.jessebrault.ssg.task.Task import com.jessebrault.ssg.task.Task
import com.jessebrault.ssg.task.TaskInput
interface HtmlTask extends Task { interface HtmlTask extends Task {
String getPath() @Deprecated
String getHtmlPath()
TaskInput getInput()
HtmlOutput getOutput()
} }

View File

@ -2,6 +2,7 @@ package com.jessebrault.ssg.html
import com.jessebrault.ssg.SiteSpec import com.jessebrault.ssg.SiteSpec
import com.jessebrault.ssg.model.Model import com.jessebrault.ssg.model.Model
import com.jessebrault.ssg.model.ModelInput
import com.jessebrault.ssg.part.Part import com.jessebrault.ssg.part.Part
import com.jessebrault.ssg.render.RenderContext import com.jessebrault.ssg.render.RenderContext
import com.jessebrault.ssg.task.Task import com.jessebrault.ssg.task.Task
@ -14,7 +15,7 @@ import groovy.transform.NullCheck
@NullCheck @NullCheck
@EqualsAndHashCode @EqualsAndHashCode
final class ModelToHtmlTask<T> extends AbstractHtmlTask { final class ModelToHtmlTask<T> extends AbstractHtmlTask<ModelInput<T>> {
private final SiteSpec siteSpec private final SiteSpec siteSpec
private final Map<String, Object> globals private final Map<String, Object> globals
@ -25,7 +26,7 @@ final class ModelToHtmlTask<T> extends AbstractHtmlTask {
private final Collection<Part> allParts private final Collection<Part> allParts
ModelToHtmlTask( ModelToHtmlTask(
String path, String relativeHtmlPath,
TaskSpec taskSpec, TaskSpec taskSpec,
Model<T> model, Model<T> model,
Template template, Template template,
@ -33,7 +34,12 @@ final class ModelToHtmlTask<T> extends AbstractHtmlTask {
Collection<Model<Object>> allModels, Collection<Model<Object>> allModels,
Collection<Part> allParts Collection<Part> allParts
) { ) {
super("modelToHtml:${ path }", path, taskSpec.outputDir) super(
"modelToHtml:${ relativeHtmlPath }",
relativeHtmlPath,
new ModelInput<>(model.name, model),
taskSpec.outputDir
)
this.siteSpec = taskSpec.siteSpec this.siteSpec = taskSpec.siteSpec
this.globals = taskSpec.globals this.globals = taskSpec.globals
this.model = model this.model = model
@ -47,7 +53,7 @@ final class ModelToHtmlTask<T> extends AbstractHtmlTask {
protected Result<String> transform(Collection<Task> allTasks) { protected Result<String> transform(Collection<Task> allTasks) {
this.template.type.renderer.render(this.template, null, new RenderContext( this.template.type.renderer.render(this.template, null, new RenderContext(
sourcePath: this.model.name, sourcePath: this.model.name,
targetPath: this.path, targetPath: this.htmlPath,
tasks: allTasks, tasks: allTasks,
texts: this.allTexts, texts: this.allTexts,
models: this.allModels, models: this.allModels,

View File

@ -3,6 +3,7 @@ package com.jessebrault.ssg.html
import com.jessebrault.ssg.SiteSpec import com.jessebrault.ssg.SiteSpec
import com.jessebrault.ssg.model.Model import com.jessebrault.ssg.model.Model
import com.jessebrault.ssg.page.Page import com.jessebrault.ssg.page.Page
import com.jessebrault.ssg.page.PageInput
import com.jessebrault.ssg.part.Part import com.jessebrault.ssg.part.Part
import com.jessebrault.ssg.render.RenderContext import com.jessebrault.ssg.render.RenderContext
import com.jessebrault.ssg.task.Task import com.jessebrault.ssg.task.Task
@ -14,7 +15,7 @@ import groovy.transform.NullCheck
@NullCheck @NullCheck
@EqualsAndHashCode(includeFields = true, callSuper = true) @EqualsAndHashCode(includeFields = true, callSuper = true)
final class PageToHtmlTask extends AbstractHtmlTask { final class PageToHtmlTask extends AbstractHtmlTask<PageInput> {
private final SiteSpec siteSpec private final SiteSpec siteSpec
private final Map<String, Object> globals private final Map<String, Object> globals
@ -24,14 +25,19 @@ final class PageToHtmlTask extends AbstractHtmlTask {
private final Collection<Part> allParts private final Collection<Part> allParts
PageToHtmlTask( PageToHtmlTask(
String path, String relativeHtmlPath,
TaskSpec taskSpec, TaskSpec taskSpec,
Page page, Page page,
Collection<Text> allTexts, Collection<Text> allTexts,
Collection<Model<Object>> allModels, Collection<Model<Object>> allModels,
Collection<Part> allParts Collection<Part> allParts
) { ) {
super("pageToHtml:${ path }", path, taskSpec.outputDir) super(
"pageToHtml:${ relativeHtmlPath }",
relativeHtmlPath,
new PageInput(page.path, page),
taskSpec.outputDir
)
this.siteSpec = taskSpec.siteSpec this.siteSpec = taskSpec.siteSpec
this.globals = taskSpec.globals this.globals = taskSpec.globals
this.page = page this.page = page
@ -44,7 +50,7 @@ final class PageToHtmlTask extends AbstractHtmlTask {
protected Result<String> transform(Collection<Task> allTasks) { protected Result<String> transform(Collection<Task> allTasks) {
this.page.type.renderer.render(this.page, new RenderContext( this.page.type.renderer.render(this.page, new RenderContext(
this.page.path, this.page.path,
this.path, this.htmlPath,
allTasks, allTasks,
this.allTexts, this.allTexts,
this.allModels, this.allModels,

View File

@ -0,0 +1,15 @@
package com.jessebrault.ssg.html
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.PackageScope
import groovy.transform.TupleConstructor
@TupleConstructor(defaults = false)
@NullCheck(includeGenerated = true)
@EqualsAndHashCode
final class SimpleHtmlOutput implements HtmlOutput {
final String name
final File file
final String htmlPath
}

View File

@ -8,13 +8,14 @@ import com.jessebrault.ssg.task.Task
import com.jessebrault.ssg.task.TaskSpec import com.jessebrault.ssg.task.TaskSpec
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.text.TextInput
import com.jessebrault.ssg.util.Result import com.jessebrault.ssg.util.Result
import groovy.transform.EqualsAndHashCode import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck import groovy.transform.NullCheck
@NullCheck @NullCheck
@EqualsAndHashCode(includeFields = true, callSuper = true) @EqualsAndHashCode(includeFields = true, callSuper = true)
final class TextToHtmlTask extends AbstractHtmlTask { final class TextToHtmlTask extends AbstractHtmlTask<TextInput> {
private final SiteSpec siteSpec private final SiteSpec siteSpec
private final Map<String, Object> globals private final Map<String, Object> globals
@ -25,7 +26,7 @@ final class TextToHtmlTask extends AbstractHtmlTask {
private final Collection<Part> allParts private final Collection<Part> allParts
TextToHtmlTask( TextToHtmlTask(
String path, String relativeHtmlPath,
TaskSpec taskSpec, TaskSpec taskSpec,
Text text, Text text,
Template template, Template template,
@ -33,7 +34,12 @@ final class TextToHtmlTask extends AbstractHtmlTask {
Collection<Model<Object>> allModels, Collection<Model<Object>> allModels,
Collection<Part> allParts Collection<Part> allParts
) { ) {
super("textToHtml:${ path }", path, taskSpec.outputDir) super(
"textToHtml:${ relativeHtmlPath }",
relativeHtmlPath,
new TextInput(text.path, text),
taskSpec.outputDir
)
this.siteSpec = taskSpec.siteSpec this.siteSpec = taskSpec.siteSpec
this.globals = taskSpec.globals this.globals = taskSpec.globals
this.text = text this.text = text
@ -47,7 +53,7 @@ final class TextToHtmlTask extends AbstractHtmlTask {
protected Result<String> transform(Collection<Task> allTasks) { protected Result<String> transform(Collection<Task> allTasks) {
this.template.type.renderer.render(this.template, this.text, new RenderContext( this.template.type.renderer.render(this.template, this.text, new RenderContext(
this.text.path, this.text.path,
this.path, this.htmlPath,
allTasks, allTasks,
this.allTexts, this.allTexts,
this.allModels, this.allModels,

View File

@ -0,0 +1,14 @@
package com.jessebrault.ssg.model
import com.jessebrault.ssg.task.TaskInput
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.TupleConstructor
@TupleConstructor(defaults = false)
@NullCheck(includeGenerated = true)
@EqualsAndHashCode
final class ModelInput<T> implements TaskInput {
final String name
final Model<T> model
}

View File

@ -0,0 +1,14 @@
package com.jessebrault.ssg.page
import com.jessebrault.ssg.task.TaskInput
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.TupleConstructor
@TupleConstructor(defaults = false)
@NullCheck(includeGenerated = true)
@EqualsAndHashCode
final class PageInput implements TaskInput {
final String name
final Page page
}

View File

@ -0,0 +1,5 @@
package com.jessebrault.ssg.task
interface FileOutput extends TaskOutput {
File getFile()
}

View File

@ -0,0 +1,5 @@
package com.jessebrault.ssg.task
interface TaskInput {
String getName()
}

View File

@ -0,0 +1,5 @@
package com.jessebrault.ssg.task
interface TaskOutput {
String getName()
}

View File

@ -0,0 +1,14 @@
package com.jessebrault.ssg.text
import com.jessebrault.ssg.task.TaskInput
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import groovy.transform.TupleConstructor
@TupleConstructor(defaults = false)
@NullCheck(includeGenerated = true)
@EqualsAndHashCode
final class TextInput implements TaskInput {
final String name
final Text text
}

View File

@ -1,11 +1,13 @@
import com.jessebrault.ssg.html.HtmlOutput
import com.jessebrault.ssg.html.HtmlTask import com.jessebrault.ssg.html.HtmlTask
import com.jessebrault.ssg.task.Task import com.jessebrault.ssg.task.Task
import com.jessebrault.ssg.task.TaskInput
import com.jessebrault.ssg.util.Diagnostic import com.jessebrault.ssg.util.Diagnostic
final class TestHtmlTask implements HtmlTask { final class TestHtmlTask implements HtmlTask {
@Override @Override
String getPath() { String getHtmlPath() {
return null return null
} }
@ -19,4 +21,14 @@ final class TestHtmlTask implements HtmlTask {
return null return null
} }
@Override
TaskInput getInput() {
return null
}
@Override
HtmlOutput getOutput() {
return null
}
} }

View File

@ -169,7 +169,7 @@ interface StandardDslConsumerTests {
[] []
) )
this.doDslAssertionTest( this.doDslAssertionTest(
'<%= assert tasks.find { it.path == "testHtml" } != null %>', '<%= assert tasks.find { it.htmlPath == "testHtml" } != null %>',
new RenderContext(tasks: [task]) new RenderContext(tasks: [task])
) )
} }
@ -186,6 +186,28 @@ interface StandardDslConsumerTests {
) )
} }
@Test
default void htmlTaskInputAvailable() {
def t0 = blankTextToHtmlTask()
def t1 = blankPageToHtmlTask()
this.doDslAssertionTest(
'<% assert tasks.size() == 2 && ' +
'tasks.inject(true) { acc, task -> acc && task.input != null } %>',
new RenderContext(tasks: [t0, t1])
)
}
@Test
default void htmlTaskOutputAvailable() {
def t0 = blankTextToHtmlTask()
def t1 = blankPageToHtmlTask()
this.doDslAssertionTest(
'<% assert tasks.size() == 2 && ' +
'tasks.inject(true) { acc, task -> acc && task.output != null } %>',
new RenderContext(tasks: [t0, t1])
)
}
@Test @Test
default void taskTypesImported() { default void taskTypesImported() {
this.doDslAssertionTest('<%= assert Task && HtmlTask && ModelToHtmlTask && PageToHtmlTask && TextToHtmlTask %>') this.doDslAssertionTest('<%= assert Task && HtmlTask && ModelToHtmlTask && PageToHtmlTask && TextToHtmlTask %>')