Cli much better interface and user experience.
This commit is contained in:
parent
0b95f4662d
commit
90db278e39
@ -0,0 +1,89 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.buildscript.GroovyBuildScriptRunner
|
||||
import com.jessebrault.ssg.part.GspPartRenderer
|
||||
import com.jessebrault.ssg.part.PartFilePartsProvider
|
||||
import com.jessebrault.ssg.part.PartType
|
||||
import com.jessebrault.ssg.specialpage.GspSpecialPageRenderer
|
||||
import com.jessebrault.ssg.specialpage.SpecialPageFileSpecialPagesProvider
|
||||
import com.jessebrault.ssg.specialpage.SpecialPageType
|
||||
import com.jessebrault.ssg.template.GspTemplateRenderer
|
||||
import com.jessebrault.ssg.template.TemplateFileTemplatesProvider
|
||||
import com.jessebrault.ssg.template.TemplateType
|
||||
import com.jessebrault.ssg.text.MarkdownExcerptGetter
|
||||
import com.jessebrault.ssg.text.MarkdownFrontMatterGetter
|
||||
import com.jessebrault.ssg.text.MarkdownTextRenderer
|
||||
import com.jessebrault.ssg.text.TextFileTextsProvider
|
||||
import com.jessebrault.ssg.text.TextType
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
|
||||
abstract class AbstractBuildCommand extends AbstractSubCommand {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(AbstractBuildCommand)
|
||||
|
||||
protected final Collection<Build> builds = []
|
||||
protected final StaticSiteGenerator ssg
|
||||
|
||||
AbstractBuildCommand() {
|
||||
// Configure
|
||||
def markdownText = new TextType(['.md'], new MarkdownTextRenderer(), new MarkdownFrontMatterGetter(), new MarkdownExcerptGetter())
|
||||
def gspTemplate = new TemplateType(['.gsp'], new GspTemplateRenderer())
|
||||
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 defaultConfig = new Config(
|
||||
textProviders: [defaultTextsProvider],
|
||||
templatesProviders: [defaultTemplatesProvider],
|
||||
partsProviders: [defaultPartsProvider],
|
||||
specialPagesProviders: [defaultSpecialPagesProvider]
|
||||
)
|
||||
def defaultGlobals = [:]
|
||||
|
||||
// Run build script, if applicable
|
||||
if (new File('ssgBuilds.groovy').exists()) {
|
||||
logger.info('found buildScript: ssgBuilds.groovy')
|
||||
def buildScriptRunner = new GroovyBuildScriptRunner()
|
||||
this.builds.addAll(buildScriptRunner.runBuildScript('ssgBuilds.groovy', defaultConfig, defaultGlobals))
|
||||
logger.debug('after running ssgBuilds.groovy, builds: {}', this.builds)
|
||||
}
|
||||
|
||||
if (this.builds.empty) {
|
||||
// Add default build
|
||||
builds << new Build('default', defaultConfig, defaultGlobals, new File('build'))
|
||||
}
|
||||
|
||||
// Get ssg object
|
||||
this.ssg = new SimpleStaticSiteGenerator()
|
||||
}
|
||||
|
||||
protected final Integer doBuild() {
|
||||
logger.traceEntry('builds: {}, ssg: {}', this.builds, this.ssg)
|
||||
|
||||
def hadDiagnostics = false
|
||||
// Do each build
|
||||
this.builds.each {
|
||||
def result = this.ssg.generate(it)
|
||||
if (result.v1.size() > 0) {
|
||||
hadDiagnostics = true
|
||||
result.v1.each {
|
||||
logger.error(it.message)
|
||||
}
|
||||
} else {
|
||||
result.v2.each { GeneratedPage generatedPage ->
|
||||
def target = new File(it.outDir, generatedPage.path + '.html')
|
||||
target.createParentDirectories()
|
||||
target.write(generatedPage.html)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.traceExit(hadDiagnostics ? 1 : 0)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import org.apache.logging.log4j.Level
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
import org.apache.logging.log4j.core.LoggerContext
|
||||
import picocli.CommandLine
|
||||
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
abstract class AbstractSubCommand implements Callable<Integer> {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(AbstractSubCommand)
|
||||
|
||||
@CommandLine.ParentCommand
|
||||
StaticSiteGeneratorCli cli
|
||||
|
||||
abstract Integer doSubCommand()
|
||||
|
||||
@Override
|
||||
Integer call() {
|
||||
logger.traceEntry()
|
||||
|
||||
// Setup Loggers
|
||||
def context = (LoggerContext) LogManager.getContext(false)
|
||||
def configuration = context.getConfiguration()
|
||||
def rootLoggerConfig = configuration.getRootLogger()
|
||||
|
||||
if (this.cli.logLevel?.info) {
|
||||
rootLoggerConfig.level = Level.INFO
|
||||
} else if (this.cli.logLevel?.debug) {
|
||||
rootLoggerConfig.level = Level.DEBUG
|
||||
} else if (this.cli.logLevel?.trace) {
|
||||
rootLoggerConfig.level = Level.TRACE
|
||||
} else {
|
||||
rootLoggerConfig.level = Level.WARN
|
||||
}
|
||||
|
||||
context.updateLoggers()
|
||||
|
||||
// Run SubCommand
|
||||
logger.traceExit(this.doSubCommand())
|
||||
}
|
||||
|
||||
}
|
21
cli/src/main/groovy/com/jessebrault/ssg/SsgBuild.groovy
Normal file
21
cli/src/main/groovy/com/jessebrault/ssg/SsgBuild.groovy
Normal file
@ -0,0 +1,21 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
import picocli.CommandLine
|
||||
|
||||
@CommandLine.Command(
|
||||
name = 'build',
|
||||
mixinStandardHelpOptions = true,
|
||||
description = 'Builds the project.'
|
||||
)
|
||||
class SsgBuild extends AbstractBuildCommand {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(SsgBuild)
|
||||
|
||||
@Override
|
||||
Integer doSubCommand() {
|
||||
this.doBuild()
|
||||
}
|
||||
|
||||
}
|
54
cli/src/main/groovy/com/jessebrault/ssg/SsgInit.groovy
Normal file
54
cli/src/main/groovy/com/jessebrault/ssg/SsgInit.groovy
Normal file
@ -0,0 +1,54 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
import picocli.CommandLine
|
||||
|
||||
@CommandLine.Command(
|
||||
name = 'init',
|
||||
mixinStandardHelpOptions = true,
|
||||
description = 'Generates a blank project, optionally with some basic files.'
|
||||
)
|
||||
class SsgInit extends AbstractSubCommand {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(SsgInit)
|
||||
|
||||
@CommandLine.Option(names = ['-s', '--skeleton'], description = 'Include some basic files in the generated project.')
|
||||
boolean withSkeletonFiles
|
||||
|
||||
@Override
|
||||
Integer doSubCommand() {
|
||||
logger.traceEntry()
|
||||
new FileTreeBuilder().with {
|
||||
// Generate dirs
|
||||
dir('texts') {
|
||||
if (this.withSkeletonFiles) {
|
||||
file('hello.md', this.getClass().getResource('/hello.md').text)
|
||||
}
|
||||
}
|
||||
dir('templates') {
|
||||
if (this.withSkeletonFiles) {
|
||||
file('hello.gsp', this.getClass().getResource('/hello.gsp').text)
|
||||
}
|
||||
}
|
||||
dir('parts') {
|
||||
if (this.withSkeletonFiles) {
|
||||
file('head.gsp', this.getClass().getResource('/head.gsp').text)
|
||||
}
|
||||
}
|
||||
dir('specialPages') {
|
||||
if (this.withSkeletonFiles) {
|
||||
file('specialPage.gsp', this.getClass().getResource('/specialPage.gsp').text)
|
||||
}
|
||||
}
|
||||
|
||||
// Generate ssgBuilds.groovy
|
||||
if (this.withSkeletonFiles) {
|
||||
file('ssgBuilds.groovy', this.getClass().getResource('/ssgBuilds.groovy').text)
|
||||
} else {
|
||||
file('ssgBuilds.groovy', this.getClass().getResource('/ssgBuildsBasic.groovy').text)
|
||||
}
|
||||
}
|
||||
logger.traceExit(0)
|
||||
}
|
||||
}
|
116
cli/src/main/groovy/com/jessebrault/ssg/SsgWatch.groovy
Normal file
116
cli/src/main/groovy/com/jessebrault/ssg/SsgWatch.groovy
Normal file
@ -0,0 +1,116 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.provider.WithWatchableDir
|
||||
import groovy.io.FileType
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
import picocli.CommandLine
|
||||
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardWatchEventKinds
|
||||
import java.nio.file.WatchEvent
|
||||
import java.nio.file.WatchKey
|
||||
|
||||
@CommandLine.Command(
|
||||
name = 'watch',
|
||||
mixinStandardHelpOptions = true,
|
||||
description = 'Run in watch mode, rebuilding the project whenever files are created/updated/deleted.'
|
||||
)
|
||||
class SsgWatch extends AbstractBuildCommand {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(SsgWatch)
|
||||
|
||||
@Override
|
||||
Integer doSubCommand() {
|
||||
logger.traceEntry()
|
||||
|
||||
// Setup watchService and watchKeys
|
||||
def watchService = FileSystems.getDefault().newWatchService()
|
||||
Map<WatchKey, Path> watchKeys = [:]
|
||||
|
||||
// Our Closure to register a directory path
|
||||
def registerPath = { Path path ->
|
||||
if (!Files.isDirectory(path)) {
|
||||
throw new IllegalArgumentException('path must be a directory, given: ' + path)
|
||||
}
|
||||
logger.debug('registering dir with path: {}', path)
|
||||
def watchKey = path.register(
|
||||
watchService,
|
||||
StandardWatchEventKinds.ENTRY_CREATE,
|
||||
StandardWatchEventKinds.ENTRY_DELETE,
|
||||
StandardWatchEventKinds.ENTRY_MODIFY
|
||||
)
|
||||
watchKeys[watchKey] = path
|
||||
logger.debug('watchKeys: {}', watchKeys)
|
||||
}
|
||||
|
||||
// Get all base watchableDirs
|
||||
Collection<WithWatchableDir> watchableProviders = []
|
||||
this.builds.each {
|
||||
it.config.textProviders.each {
|
||||
if (it instanceof WithWatchableDir) {
|
||||
watchableProviders << it
|
||||
}
|
||||
}
|
||||
it.config.templatesProviders.each {
|
||||
if (it instanceof WithWatchableDir) {
|
||||
watchableProviders << it
|
||||
}
|
||||
}
|
||||
it.config.partsProviders.each {
|
||||
if (it instanceof WithWatchableDir) {
|
||||
watchableProviders << it
|
||||
}
|
||||
}
|
||||
it.config.specialPagesProviders.each {
|
||||
if (it instanceof WithWatchableDir) {
|
||||
watchableProviders << it
|
||||
}
|
||||
}
|
||||
}
|
||||
// register them and their child directories using the Closure above
|
||||
watchableProviders.each {
|
||||
def baseDirFile = it.watchableDir
|
||||
registerPath(baseDirFile.toPath())
|
||||
baseDirFile.eachFile(FileType.DIRECTORIES) {
|
||||
registerPath(it.toPath())
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection GroovyInfiniteLoopStatement
|
||||
while (true) {
|
||||
def watchKey = watchService.take()
|
||||
def path = watchKeys[watchKey]
|
||||
if (path == null) {
|
||||
logger.warn('unexpected watchKey: {}', watchKey)
|
||||
} else {
|
||||
watchKey.pollEvents().each {
|
||||
assert it instanceof WatchEvent<Path>
|
||||
def childName = it.context()
|
||||
def childPath = path.resolve(childName)
|
||||
if (it.kind() == StandardWatchEventKinds.ENTRY_CREATE && Files.isDirectory(childPath)) {
|
||||
registerPath(childPath)
|
||||
} else if (Files.isRegularFile(childPath)) {
|
||||
logger.debug('detected {} for regularFile with path {}', it.kind(), childPath)
|
||||
def t = new Thread({
|
||||
this.doBuild()
|
||||
})
|
||||
t.setName('workerThread')
|
||||
t.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
def valid = watchKey.reset()
|
||||
if (!valid) {
|
||||
def removedPath = watchKeys.remove(watchKey)
|
||||
logger.debug('removed path: {}', removedPath)
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection GroovyUnreachableStatement
|
||||
logger.traceExit(0)
|
||||
}
|
||||
|
||||
}
|
@ -1,45 +1,15 @@
|
||||
package com.jessebrault.ssg
|
||||
|
||||
import com.jessebrault.ssg.buildscript.GroovyBuildScriptRunner
|
||||
import com.jessebrault.ssg.part.GspPartRenderer
|
||||
import com.jessebrault.ssg.part.PartFilePartsProvider
|
||||
import com.jessebrault.ssg.part.PartType
|
||||
import com.jessebrault.ssg.provider.WithWatchableDir
|
||||
import com.jessebrault.ssg.specialpage.GspSpecialPageRenderer
|
||||
import com.jessebrault.ssg.specialpage.SpecialPageFileSpecialPagesProvider
|
||||
import com.jessebrault.ssg.specialpage.SpecialPageType
|
||||
import com.jessebrault.ssg.template.GspTemplateRenderer
|
||||
import com.jessebrault.ssg.template.TemplateFileTemplatesProvider
|
||||
import com.jessebrault.ssg.template.TemplateType
|
||||
import com.jessebrault.ssg.text.MarkdownExcerptGetter
|
||||
import com.jessebrault.ssg.text.MarkdownFrontMatterGetter
|
||||
import com.jessebrault.ssg.text.MarkdownTextRenderer
|
||||
import com.jessebrault.ssg.text.TextFileTextsProvider
|
||||
import com.jessebrault.ssg.text.TextType
|
||||
import groovy.io.FileType
|
||||
import org.apache.logging.log4j.Level
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.apache.logging.log4j.Logger
|
||||
import org.apache.logging.log4j.core.LoggerContext
|
||||
import picocli.CommandLine
|
||||
|
||||
import java.nio.file.FileSystems
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardWatchEventKinds
|
||||
import java.nio.file.WatchEvent
|
||||
import java.nio.file.WatchKey
|
||||
import java.util.concurrent.Callable
|
||||
|
||||
@CommandLine.Command(
|
||||
name = 'ssg',
|
||||
mixinStandardHelpOptions = true,
|
||||
version = '0.0.1-SNAPSHOT',
|
||||
description = 'Generates a set of html files from a given configuration.'
|
||||
description = 'Generates a set of html files from a given configuration.',
|
||||
subcommands = [SsgInit, SsgBuild, SsgWatch]
|
||||
)
|
||||
class StaticSiteGeneratorCli implements Callable<Integer> {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(StaticSiteGeneratorCli)
|
||||
class StaticSiteGeneratorCli {
|
||||
|
||||
static void main(String[] args) {
|
||||
System.exit(new CommandLine(StaticSiteGeneratorCli).execute(args))
|
||||
@ -61,187 +31,4 @@ class StaticSiteGeneratorCli implements Callable<Integer> {
|
||||
@CommandLine.ArgGroup(exclusive = true, heading = 'Log Level')
|
||||
LogLevel logLevel
|
||||
|
||||
@CommandLine.Option(names = ['-w', '--watch'], description = 'Run in watch mode.')
|
||||
boolean watch
|
||||
|
||||
@Override
|
||||
Integer call() {
|
||||
logger.traceEntry()
|
||||
|
||||
// Setup Loggers
|
||||
def context = (LoggerContext) LogManager.getContext(false)
|
||||
def configuration = context.getConfiguration()
|
||||
def rootLoggerConfig = configuration.getRootLogger()
|
||||
|
||||
if (this.logLevel?.info) {
|
||||
rootLoggerConfig.level = Level.INFO
|
||||
} else if (this.logLevel?.debug) {
|
||||
rootLoggerConfig.level = Level.DEBUG
|
||||
} else if (this.logLevel?.trace) {
|
||||
rootLoggerConfig.level = Level.TRACE
|
||||
} else {
|
||||
rootLoggerConfig.level = Level.WARN
|
||||
}
|
||||
|
||||
context.updateLoggers()
|
||||
|
||||
// Configure
|
||||
def markdownText = new TextType(['.md'], new MarkdownTextRenderer(), new MarkdownFrontMatterGetter(), new MarkdownExcerptGetter())
|
||||
def gspTemplate = new TemplateType(['.gsp'], new GspTemplateRenderer())
|
||||
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 defaultConfig = new Config(
|
||||
textProviders: [defaultTextsProvider],
|
||||
templatesProviders: [defaultTemplatesProvider],
|
||||
partsProviders: [defaultPartsProvider],
|
||||
specialPagesProviders: [defaultSpecialPagesProvider]
|
||||
)
|
||||
def defaultGlobals = [:]
|
||||
|
||||
Collection<Build> builds = []
|
||||
|
||||
// Run build script, if applicable
|
||||
if (new File('ssgBuilds.groovy').exists()) {
|
||||
logger.info('found buildScript: ssgBuilds.groovy')
|
||||
def buildScriptRunner = new GroovyBuildScriptRunner()
|
||||
builds.addAll(buildScriptRunner.runBuildScript('ssgBuilds.groovy', defaultConfig, defaultGlobals))
|
||||
logger.debug('after running ssgBuilds.groovy, builds: {}', builds)
|
||||
}
|
||||
|
||||
if (builds.empty) {
|
||||
// Add default build
|
||||
builds << new Build('default', defaultConfig, defaultGlobals, new File('build'))
|
||||
}
|
||||
|
||||
// Get ssg object
|
||||
def ssg = new SimpleStaticSiteGenerator()
|
||||
|
||||
if (this.watch) {
|
||||
generate(builds, ssg)
|
||||
watch(builds, ssg)
|
||||
} else {
|
||||
generate(builds, ssg)
|
||||
}
|
||||
}
|
||||
|
||||
private static Integer generate(Collection<Build> builds, StaticSiteGenerator ssg) {
|
||||
logger.traceEntry('builds: {}, ssg: {}', builds, ssg)
|
||||
|
||||
def hadDiagnostics = false
|
||||
// Do each build
|
||||
builds.each {
|
||||
def result = ssg.generate(it)
|
||||
if (result.v1.size() > 0) {
|
||||
hadDiagnostics = true
|
||||
result.v1.each {
|
||||
logger.error(it.message)
|
||||
}
|
||||
} else {
|
||||
result.v2.each { GeneratedPage generatedPage ->
|
||||
def target = new File(it.outDir, generatedPage.path + '.html')
|
||||
target.createParentDirectories()
|
||||
target.write(generatedPage.html)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logger.traceExit(hadDiagnostics ? 1 : 0)
|
||||
}
|
||||
|
||||
private static Integer watch(Collection<Build> builds, StaticSiteGenerator ssg) {
|
||||
logger.traceEntry('builds: {}, ssg: {}', builds, ssg)
|
||||
|
||||
// Setup watchService and watchKeys
|
||||
def watchService = FileSystems.getDefault().newWatchService()
|
||||
Map<WatchKey, Path> watchKeys = [:]
|
||||
|
||||
// Our Closure to register a directory path
|
||||
def registerPath = { Path path ->
|
||||
if (!Files.isDirectory(path)) {
|
||||
throw new IllegalArgumentException('path must be a directory, given: ' + path)
|
||||
}
|
||||
logger.debug('registering dir with path: {}', path)
|
||||
def watchKey = path.register(
|
||||
watchService,
|
||||
StandardWatchEventKinds.ENTRY_CREATE,
|
||||
StandardWatchEventKinds.ENTRY_DELETE,
|
||||
StandardWatchEventKinds.ENTRY_MODIFY
|
||||
)
|
||||
watchKeys[watchKey] = path
|
||||
logger.debug('watchKeys: {}', watchKeys)
|
||||
}
|
||||
|
||||
// Get all base watchableDirs
|
||||
Collection<WithWatchableDir> watchableProviders = []
|
||||
builds.each {
|
||||
it.config.textProviders.each {
|
||||
if (it instanceof WithWatchableDir) {
|
||||
watchableProviders << it
|
||||
}
|
||||
}
|
||||
it.config.templatesProviders.each {
|
||||
if (it instanceof WithWatchableDir) {
|
||||
watchableProviders << it
|
||||
}
|
||||
}
|
||||
it.config.partsProviders.each {
|
||||
if (it instanceof WithWatchableDir) {
|
||||
watchableProviders << it
|
||||
}
|
||||
}
|
||||
it.config.specialPagesProviders.each {
|
||||
if (it instanceof WithWatchableDir) {
|
||||
watchableProviders << it
|
||||
}
|
||||
}
|
||||
}
|
||||
// register them and their child directories using the Closure above
|
||||
watchableProviders.each {
|
||||
def baseDirFile = it.watchableDir
|
||||
registerPath(baseDirFile.toPath())
|
||||
baseDirFile.eachFile(FileType.DIRECTORIES) {
|
||||
registerPath(it.toPath())
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection GroovyInfiniteLoopStatement
|
||||
while (true) {
|
||||
def watchKey = watchService.take()
|
||||
def path = watchKeys[watchKey]
|
||||
if (path == null) {
|
||||
logger.warn('unexpected watchKey: {}', watchKey)
|
||||
} else {
|
||||
watchKey.pollEvents().each {
|
||||
assert it instanceof WatchEvent<Path>
|
||||
def childName = it.context()
|
||||
def childPath = path.resolve(childName)
|
||||
if (it.kind() == StandardWatchEventKinds.ENTRY_CREATE && Files.isDirectory(childPath)) {
|
||||
registerPath(childPath)
|
||||
} else if (Files.isRegularFile(childPath)) {
|
||||
logger.debug('detected {} for regularFile with path {}', it.kind(), childPath)
|
||||
def t = new Thread({
|
||||
generate(builds, ssg)
|
||||
})
|
||||
t.setName('workerThread')
|
||||
t.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
def valid = watchKey.reset()
|
||||
if (!valid) {
|
||||
def removedPath = watchKeys.remove(watchKey)
|
||||
logger.debug('removed path: {}', removedPath)
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection GroovyUnreachableStatement
|
||||
logger.traceExit(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
3
cli/src/main/resources/head.gsp
Normal file
3
cli/src/main/resources/head.gsp
Normal file
@ -0,0 +1,3 @@
|
||||
<head>
|
||||
<title><%= binding.title %></title>
|
||||
</head>
|
10
cli/src/main/resources/hello.gsp
Normal file
10
cli/src/main/resources/hello.gsp
Normal file
@ -0,0 +1,10 @@
|
||||
<html>
|
||||
<%
|
||||
out << parts['head.gsp'].render([
|
||||
title: "${ globals.siteTitle }: ${ frontMatter.title }"
|
||||
])
|
||||
%>
|
||||
<body>
|
||||
<%= text %>
|
||||
</body>
|
||||
</html>
|
5
cli/src/main/resources/hello.md
Normal file
5
cli/src/main/resources/hello.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
template: hello.gsp
|
||||
title: Greeting
|
||||
---
|
||||
# Hello, World!
|
8
cli/src/main/resources/specialPage.gsp
Normal file
8
cli/src/main/resources/specialPage.gsp
Normal file
@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>${ globals.siteTitle }: Special Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<%= texts.find { it.path == 'hello' }.render() %>
|
||||
</body>
|
||||
</html>
|
14
cli/src/main/resources/ssgBuilds.groovy
Normal file
14
cli/src/main/resources/ssgBuilds.groovy
Normal file
@ -0,0 +1,14 @@
|
||||
// This file was auto-generated by the ssg init command.
|
||||
|
||||
build {
|
||||
name = 'My Simple Build'
|
||||
outDir = new File('mySimpleBuild')
|
||||
|
||||
config {
|
||||
// Config options here
|
||||
}
|
||||
|
||||
globals {
|
||||
siteTitle = 'My Simple Site'
|
||||
}
|
||||
}
|
1
cli/src/main/resources/ssgBuildsBasic.groovy
Normal file
1
cli/src/main/resources/ssgBuildsBasic.groovy
Normal file
@ -0,0 +1 @@
|
||||
// This file was auto-generated by the ssg init command.
|
Loading…
Reference in New Issue
Block a user