Refactoring of all file providers; all paths now include extension.

This commit is contained in:
Jesse Brault 2023-02-14 15:33:15 +01:00
parent 99836856d7
commit 076bc9bc52
11 changed files with 128 additions and 149 deletions

View File

@ -32,10 +32,10 @@ abstract class AbstractBuildCommand extends AbstractSubCommand {
def gspPart = new PartType(['.gsp'], new GspPartRenderer())
def gspSpecialPage = new SpecialPageType(['.gsp'], new GspSpecialPageRenderer())
def defaultTextsProvider = new TextFileTextsProvider([markdownText], new File('texts'))
def defaultTemplatesProvider = new TemplateFileTemplatesProvider([gspTemplate], new File('templates'))
def defaultPartsProvider = new PartFilePartsProvider([gspPart], new File('parts'))
def defaultSpecialPagesProvider = new SpecialPageFileSpecialPagesProvider([gspSpecialPage], new File('specialPages'))
def defaultTextsProvider = new TextFileTextsProvider(new File('texts'), [markdownText])
def defaultTemplatesProvider = new TemplateFileTemplatesProvider(new File('templates'), [gspTemplate])
def defaultPartsProvider = new PartFilePartsProvider(new File('parts'), [gspPart])
def defaultSpecialPagesProvider = new SpecialPageFileSpecialPagesProvider(new File('specialPages'), [gspSpecialPage])
def defaultConfig = new Config(
textProviders: [defaultTextsProvider],

View File

@ -1,55 +1,38 @@
package com.jessebrault.ssg.part
import com.jessebrault.ssg.provider.WithWatchableDir
import groovy.io.FileType
import com.jessebrault.ssg.provider.AbstractFileCollectionProvider
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import org.jetbrains.annotations.Nullable
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import static com.jessebrault.ssg.util.ExtensionsUtil.getExtension
@NullCheck
@EqualsAndHashCode(includeFields = true)
class PartFilePartsProvider implements PartsProvider, WithWatchableDir {
class PartFilePartsProvider extends AbstractFileCollectionProvider<Part> implements PartsProvider {
private static final Logger logger = LoggerFactory.getLogger(PartFilePartsProvider)
private final Collection<PartType> partTypes
private final File partsDir
PartFilePartsProvider(Collection<PartType> partTypes, File partsDir) {
this.partTypes = partTypes
this.partsDir = partsDir
this.watchableDir = this.partsDir
PartFilePartsProvider(File partsDir, Collection<PartType> partTypes) {
super(partsDir)
this.partTypes = Objects.requireNonNull(partTypes)
}
private PartType getPartType(File file) {
def path = file.path
private @Nullable PartType getPartType(String extension) {
this.partTypes.find {
it.ids.contains(getExtension(path))
it.ids.contains(extension)
}
}
@Override
Collection<Part> provide() {
if (!partsDir.isDirectory()) {
logger.warn('partsDir {} does not exist or is not a directory; skipping and providing no Parts', this.partsDir)
[]
} else {
def parts = []
this.partsDir.eachFileRecurse(FileType.FILES) {
def type = this.getPartType(it)
if (type != null) {
def relativePath = this.partsDir.relativePath(it)
logger.debug('found part {}', relativePath)
parts << new Part(relativePath, type, it.text)
} else {
logger.warn('ignoring {} since there is no partType for it', it)
}
}
parts
protected @Nullable Part transformFileToT(File file, String relativePath, String extension) {
def partType = getPartType(extension)
if (!partType) {
logger.warn('there is no PartType for {}, ignoring', relativePath)
}
partType ? new Part(relativePath, partType, file.text) : null
}
@Override
@ -59,7 +42,7 @@ class PartFilePartsProvider implements PartsProvider, WithWatchableDir {
@Override
String toString() {
"PartFilePartsProvider(partsDir: ${ this.partsDir }, partTypes: ${ this.partTypes })"
"PartFilePartsProvider(partsDir: ${ this.dir }, partTypes: ${ this.partTypes })"
}
}

View File

@ -0,0 +1,40 @@
package com.jessebrault.ssg.provider
import groovy.io.FileType
import org.jetbrains.annotations.Nullable
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import static com.jessebrault.ssg.util.ExtensionsUtil.getExtension
abstract class AbstractFileCollectionProvider<T> implements Provider<Collection<T>>, WithWatchableDir {
private static final Logger logger = LoggerFactory.getLogger(AbstractFileCollectionProvider)
protected final File dir
AbstractFileCollectionProvider(File dir) {
this.dir = Objects.requireNonNull(dir)
this.watchableDir = dir
}
protected abstract @Nullable T transformFileToT(File file, String relativePath, String extension)
@Override
Collection<T> provide() {
if (!this.dir.isDirectory()) {
logger.warn('{} does not exist or is not a directory; skipping', this.dir)
[]
} else {
def ts = []
this.dir.eachFileRecurse(FileType.FILES) {
def t = transformFileToT(it, this.dir.relativePath(it), getExtension(it.path))
if (t) {
ts << t
}
}
ts
}
}
}

View File

@ -1,57 +1,39 @@
package com.jessebrault.ssg.specialpage
import com.jessebrault.ssg.provider.WithWatchableDir
import groovy.io.FileType
import com.jessebrault.ssg.provider.AbstractFileCollectionProvider
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import org.jetbrains.annotations.Nullable
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import static com.jessebrault.ssg.util.ExtensionsUtil.getExtension
import static com.jessebrault.ssg.util.ExtensionsUtil.stripExtension
@NullCheck
@EqualsAndHashCode(includeFields = true)
class SpecialPageFileSpecialPagesProvider implements SpecialPagesProvider, WithWatchableDir {
class SpecialPageFileSpecialPagesProvider extends AbstractFileCollectionProvider<SpecialPage>
implements SpecialPagesProvider {
private static final Logger logger = LoggerFactory.getLogger(SpecialPageFileSpecialPagesProvider)
private final Collection<SpecialPageType> specialPageTypes
private final File specialPagesDir
SpecialPageFileSpecialPagesProvider(Collection<SpecialPageType> specialPageTypes, File specialPagesDir) {
this.specialPageTypes = specialPageTypes
this.specialPagesDir = specialPagesDir
this.watchableDir = this.specialPagesDir
SpecialPageFileSpecialPagesProvider(File specialPagesDir, Collection<SpecialPageType> specialPageTypes) {
super(specialPagesDir)
this.specialPageTypes = Objects.requireNonNull(specialPageTypes)
}
private SpecialPageType getSpecialPageType(File file) {
def path = file.path
private @Nullable SpecialPageType getSpecialPageType(String extension) {
this.specialPageTypes.find {
it.ids.contains(getExtension(path))
it.ids.contains(extension)
}
}
@Override
Collection<SpecialPage> provide() {
if (!this.specialPagesDir.isDirectory()) {
logger.warn('specialPagesDir {} does not exist or is not a directory; skipping and providing no SpecialPages', this.specialPagesDir)
[]
} else {
def specialPages = []
this.specialPagesDir.eachFileRecurse(FileType.FILES) {
def type = this.getSpecialPageType(it)
if (type != null) {
def relativePath = this.specialPagesDir.relativePath(it)
def path = stripExtension(relativePath)
logger.info('found specialPage {} with type {}', path, type)
specialPages << new SpecialPage(it.text, path, type)
} else {
logger.warn('ignoring {} since there is no specialPageType for it', it)
}
}
specialPages
protected @Nullable SpecialPage transformFileToT(File file, String relativePath, String extension) {
def specialPageType = getSpecialPageType(extension)
if (!specialPageType) {
logger.warn('there is no SpecialPageType for {}, ignoring', relativePath)
}
specialPageType ? new SpecialPage(file.text, relativePath, specialPageType) : null
}
@Override
@ -61,7 +43,8 @@ class SpecialPageFileSpecialPagesProvider implements SpecialPagesProvider, WithW
@Override
String toString() {
"SpecialPageFileSpecialPagesProvider(specialPagesDir: ${ this.specialPagesDir }, specialPageTypes: ${ this.specialPageTypes })"
"SpecialPageFileSpecialPagesProvider(specialPagesDir: ${ this.dir }, " +
"specialPageTypes: ${ this.specialPageTypes })"
}
}

View File

@ -1,55 +1,38 @@
package com.jessebrault.ssg.template
import com.jessebrault.ssg.provider.WithWatchableDir
import groovy.io.FileType
import com.jessebrault.ssg.provider.AbstractFileCollectionProvider
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import org.jetbrains.annotations.Nullable
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import static com.jessebrault.ssg.util.ExtensionsUtil.getExtension
@NullCheck
@EqualsAndHashCode(includeFields = true)
class TemplateFileTemplatesProvider implements TemplatesProvider, WithWatchableDir {
class TemplateFileTemplatesProvider extends AbstractFileCollectionProvider<Template> implements TemplatesProvider {
private static final Logger logger = LoggerFactory.getLogger(TemplateFileTemplatesProvider)
private final Collection<TemplateType> templateTypes
private final File templatesDir
TemplateFileTemplatesProvider(Collection<TemplateType> templateTypes, File templatesDir) {
this.templateTypes = templateTypes
this.templatesDir = templatesDir
this.watchableDir = this.templatesDir
TemplateFileTemplatesProvider(File templatesDir, Collection<TemplateType> templateTypes) {
super(templatesDir)
this.templateTypes = Objects.requireNonNull(templateTypes)
}
private TemplateType getType(File file) {
def path = file.path
private @Nullable TemplateType getType(String extension) {
this.templateTypes.find {
it.ids.contains(getExtension(path))
it.ids.contains(extension)
}
}
@Override
Collection<Template> provide() {
if (!this.templatesDir.isDirectory()) {
logger.warn('templatesDir {} does not exist or is not a directory; skipping and providing no Templates', this.templatesDir)
[]
} else {
def templates = []
this.templatesDir.eachFileRecurse(FileType.FILES) {
def type = this.getType(it)
if (type != null) {
def relativePath = this.templatesDir.relativePath(it)
logger.debug('found template {}', relativePath)
templates << new Template(it.text, relativePath, type)
} else {
logger.warn('ignoring {} because there is no templateType for it', it)
}
}
templates
protected Template transformFileToT(File file, String relativePath, String extension) {
def templateType = getType(extension)
if (templateType == null) {
logger.warn('there is no TemplateType for template {}, ignoring', relativePath)
}
templateType ? new Template(file.text, relativePath, templateType) : null
}
@Override
@ -59,7 +42,7 @@ class TemplateFileTemplatesProvider implements TemplatesProvider, WithWatchableD
@Override
String toString() {
"TemplateFileTemplatesProvider(templatesDir: ${ this.templatesDir }, templateTypes: ${ this.templateTypes })"
"TemplateFileTemplatesProvider(templatesDir: ${ this.dir }, templateTypes: ${ this.templateTypes })"
}
}

View File

@ -1,57 +1,38 @@
package com.jessebrault.ssg.text
import com.jessebrault.ssg.provider.WithWatchableDir
import groovy.io.FileType
import com.jessebrault.ssg.provider.AbstractFileCollectionProvider
import groovy.transform.EqualsAndHashCode
import groovy.transform.NullCheck
import org.jetbrains.annotations.Nullable
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import static com.jessebrault.ssg.util.ExtensionsUtil.getExtension
import static com.jessebrault.ssg.util.ExtensionsUtil.stripExtension
@NullCheck
@EqualsAndHashCode(includeFields = true)
class TextFileTextsProvider implements TextsProvider, WithWatchableDir {
class TextFileTextsProvider extends AbstractFileCollectionProvider<Text> implements TextsProvider {
private static final Logger logger = LoggerFactory.getLogger(TextFileTextsProvider)
private final Collection<TextType> textTypes
private final File textsDir
TextFileTextsProvider(Collection<TextType> textTypes, File textsDir) {
this.textTypes = textTypes
this.textsDir = textsDir
this.watchableDir = this.textsDir
TextFileTextsProvider(File textsDir, Collection<TextType> textTypes) {
super(textsDir)
this.textTypes = Objects.requireNonNull(textTypes)
}
private TextType getTextType(File file) {
def path = file.path
private TextType getTextType(String extension) {
this.textTypes.find {
it.ids.contains(getExtension(path))
it.ids.contains(extension)
}
}
@Override
Collection<Text> provide() {
if (!this.textsDir.isDirectory()) {
logger.warn('textsDir {} does not exist or is not a directory; skipping and providing no Texts', this.textsDir)
[]
} else {
def textFiles = []
this.textsDir.eachFileRecurse(FileType.FILES) {
def type = this.getTextType(it)
if (type != null) {
def relativePath = this.textsDir.relativePath(it)
def path = stripExtension(relativePath)
logger.debug('found textFile {} with type {}', path, type)
textFiles << new Text(it.text, path, type)
} else {
logger.warn('ignoring {} because there is no textType for it', it)
}
}
textFiles
protected @Nullable Text transformFileToT(File file, String relativePath, String extension) {
def textType = getTextType(extension)
if (!textType) {
logger.warn('no TextType for text {}, ignoring', file.path)
}
textType ? new Text(file.text, relativePath, textType) : null
}
@Override
@ -61,7 +42,7 @@ class TextFileTextsProvider implements TextsProvider, WithWatchableDir {
@Override
String toString() {
"TextFileTextsProvider(textsDir: ${ this.textsDir }, textTypes: ${ this.textTypes })"
"TextFileTextsProvider(textsDir: ${ this.dir }, textTypes: ${ this.textTypes })"
}
}

View File

@ -41,10 +41,10 @@ class SimpleStaticSiteGeneratorIntegrationTests {
def gspPartType = new PartType(['.gsp'], new GspPartRenderer())
def gspSpecialPageType = new SpecialPageType(['.gsp'], new GspSpecialPageRenderer())
def textsProvider = new TextFileTextsProvider([markdownTextType], this.textsDir)
def templatesProvider = new TemplateFileTemplatesProvider([gspTemplateType], this.templatesDir)
def partsProvider = new PartFilePartsProvider([gspPartType], this.partsDir)
def specialPagesProvider = new SpecialPageFileSpecialPagesProvider([gspSpecialPageType], this.specialPagesDir)
def textsProvider = new TextFileTextsProvider(this.textsDir, [markdownTextType])
def templatesProvider = new TemplateFileTemplatesProvider(this.templatesDir, [gspTemplateType])
def partsProvider = new PartFilePartsProvider(this.partsDir, [gspPartType])
def specialPagesProvider = new SpecialPageFileSpecialPagesProvider(this.specialPagesDir, [gspSpecialPageType])
def config = new Config(
textProviders: [textsProvider],

View File

@ -4,10 +4,11 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.mockito.Mockito.mock
class PartFilePartsProviderTests {
private static final PartType gspPartType = new PartType(['.gsp'], null)
private static final PartType gspPartType = new PartType(['.gsp'], mock(PartRenderer))
private File partsDir
private PartsProvider partsProvider
@ -15,7 +16,7 @@ class PartFilePartsProviderTests {
@BeforeEach
void beforeEach() {
this.partsDir = File.createTempDir()
partsProvider = new PartFilePartsProvider([gspPartType], this.partsDir)
partsProvider = new PartFilePartsProvider(this.partsDir, [gspPartType])
}
@Test

View File

@ -4,10 +4,11 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.mockito.Mockito.mock
class SpecialPageFileSpecialPagesProviderTests {
private static final SpecialPageType gspType = new SpecialPageType(['.gsp'], null)
private static final SpecialPageType gspType = new SpecialPageType(['.gsp'], mock(SpecialPageRenderer))
private File specialPagesDir
private SpecialPagesProvider specialPagesProvider
@ -15,7 +16,7 @@ class SpecialPageFileSpecialPagesProviderTests {
@BeforeEach
void beforeEach() {
this.specialPagesDir = File.createTempDir()
this.specialPagesProvider = new SpecialPageFileSpecialPagesProvider([gspType], this.specialPagesDir)
this.specialPagesProvider = new SpecialPageFileSpecialPagesProvider(this.specialPagesDir, [gspType])
}
@Test
@ -26,7 +27,7 @@ class SpecialPageFileSpecialPagesProviderTests {
def r = this.specialPagesProvider.provide()
assertEquals(1, r.size())
def f0 = r[0]
assertEquals('test', f0.path)
assertEquals('test.gsp', f0.path)
assertEquals('<%= "Hello, World!" %>', f0.text)
assertEquals(gspType, f0.type)
}
@ -40,7 +41,7 @@ class SpecialPageFileSpecialPagesProviderTests {
def r = this.specialPagesProvider.provide()
assertEquals(1, r.size())
def f0 = r[0]
assertEquals('nested/nested', f0.path)
assertEquals('nested/nested.gsp', f0.path)
assertEquals('<%= "Hello, World!" %>', f0.text)
assertEquals(gspType, f0.type)
}

View File

@ -4,10 +4,11 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.mockito.Mockito.mock
class PageTemplatesProviderTests {
class TemplateFileTemplatesProviderTests {
private static final TemplateType gspType = new TemplateType(['.gsp'], null)
private static final TemplateType gspType = new TemplateType(['.gsp'], mock(TemplateRenderer))
private File templatesDir
private TemplatesProvider templatesProvider
@ -15,7 +16,7 @@ class PageTemplatesProviderTests {
@BeforeEach
void beforeEach() {
this.templatesDir = File.createTempDir()
this.templatesProvider = new TemplateFileTemplatesProvider([gspType], this.templatesDir)
this.templatesProvider = new TemplateFileTemplatesProvider(this.templatesDir, [gspType])
}
@Test

View File

@ -4,10 +4,16 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import static org.junit.jupiter.api.Assertions.assertEquals
import static org.mockito.Mockito.mock
class TextFileTextsProviderTests {
private static final TextType markdownType = new TextType(['.md'], null, null, null)
private static final TextType markdownType = new TextType(
['.md'],
mock(TextRenderer),
mock(FrontMatterGetter),
mock(ExcerptGetter)
)
private File textsDir
private TextsProvider textsProvider
@ -15,7 +21,7 @@ class TextFileTextsProviderTests {
@BeforeEach
void beforeEach() {
this.textsDir = File.createTempDir()
this.textsProvider = new TextFileTextsProvider([markdownType], this.textsDir)
this.textsProvider = new TextFileTextsProvider(this.textsDir, [markdownType])
}
@Test
@ -25,7 +31,7 @@ class TextFileTextsProviderTests {
def r = this.textsProvider.provide()
assertEquals(1, r.size())
def f0 = r[0]
assertEquals('test', f0.path)
assertEquals('test.md', f0.path)
assertEquals('**Hello, World!**', f0.text)
assertEquals(markdownType, f0.type)
}
@ -39,7 +45,7 @@ class TextFileTextsProviderTests {
def r = this.textsProvider.provide()
assertEquals(1, r.size())
def f0 = r[0]
assertEquals('nested/nested', f0.path)
assertEquals('nested/nested.md', f0.path)
assertEquals('**Hello!**', f0.text)
assertEquals(markdownType, f0.type)
}