Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configuration cache improvements for kobwebExport #556

Merged
merged 2 commits into from
Jun 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,13 @@ class KobwebApplicationPlugin @Inject constructor(
"Cleans all site artifacts generated by a previous export"
)
kobwebCleanSiteTask.configure {
val traceConfig = kobwebBlock.app.export.traceConfig
val projectRoot = projectLayout.projectDirectory.asFile
doLast {
kobwebBlock.app.export.traceConfig.orNull?.let { traceConfig -> project.delete(traceConfig.root) }
project.delete(kobwebConf.server.files.prod.siteRoot)
traceConfig.orNull?.let { traceConfig ->
projectRoot.resolve(traceConfig.root.toFile()).deleteRecursively()
}
projectRoot.resolve(kobwebConf.server.files.prod.siteRoot).deleteRecursively()
}
}
val kobwebCleanFolderTask = project.tasks.register<KobwebTask>(
Expand All @@ -190,6 +194,7 @@ class KobwebApplicationPlugin @Inject constructor(
val kobwebExportTask = project.tasks
.register<KobwebExportTask>(
"kobwebExport",
appBlock.export,
KobwebExportConfInputs(kobwebConf),
exportLayout,
)
Expand Down Expand Up @@ -326,6 +331,8 @@ class KobwebApplicationPlugin @Inject constructor(

kobwebExportTask.configure {
appDataFile.set(kobwebCacheAppDataTask.flatMap { it.appDataFile })
publicPath.set(kobwebBlock.publicPath)
legacyRouteRedirectStrategy.set(appBlock.legacyRouteRedirectStrategy)
// Exporting ALWAYS spins up a dev server, so that way it loads the files it needs from dev locations
// before outputting them into a final prod folder.
check(env == ServerEnvironment.DEV)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import com.microsoft.playwright.TimeoutError
import com.microsoft.playwright.Tracing
import com.varabyte.kobweb.common.navigation.RoutePrefix
import com.varabyte.kobweb.gradle.application.extensions.AppBlock
import com.varabyte.kobweb.gradle.application.extensions.app
import com.varabyte.kobweb.gradle.application.extensions.export
import com.varabyte.kobweb.gradle.application.util.PlaywrightCache
import com.varabyte.kobweb.gradle.application.util.kebabCaseToCamelCase
import com.varabyte.kobweb.gradle.core.tasks.KobwebModuleTask
Expand All @@ -19,7 +17,7 @@ import com.varabyte.kobweb.server.api.SiteLayout
import kotlinx.serialization.json.Json
import org.gradle.api.GradleException
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Provider
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Nested
Expand Down Expand Up @@ -54,16 +52,19 @@ class KobwebExportConfInputs(
}

abstract class KobwebExportTask @Inject constructor(
private val exportBlock: AppBlock.ExportBlock,
@get:Nested val confInputs: KobwebExportConfInputs,
@get:Input val siteLayout: SiteLayout,
) : KobwebModuleTask("Export the Kobweb project into a static site") {
@get:InputFile
abstract val appDataFile: RegularFileProperty

@get:Input
abstract val publicPath: Property<String>

@get:Input
@get:Optional
val legacyRouteRedirectStrategy: Provider<AppBlock.LegacyRouteRedirectStrategy> =
kobwebBlock.app.legacyRouteRedirectStrategy
abstract val legacyRouteRedirectStrategy: Property<AppBlock.LegacyRouteRedirectStrategy>

@OutputDirectory
fun getSiteDir(): File {
Expand Down Expand Up @@ -120,8 +121,8 @@ abstract class KobwebExportTask @Inject constructor(

private fun Browser.takeSnapshot(route: String, url: String): String {
newContext().use { context ->
kobwebBlock.app.export.timeout.orNull?.let { context.setDefaultTimeout(it.toDouble(DurationUnit.MILLISECONDS)) }
val traceConfig = kobwebBlock.app.export.traceConfig.orNull
exportBlock.timeout.orNull?.let { context.setDefaultTimeout(it.toDouble(DurationUnit.MILLISECONDS)) }
val traceConfig = exportBlock.traceConfig.orNull
?.takeIf { it.filter(route) }
if (traceConfig != null) {
val traceRoot = traceConfig.root
Expand Down Expand Up @@ -193,7 +194,7 @@ abstract class KobwebExportTask @Inject constructor(
}

frontendData.pages.takeIf { it.isNotEmpty() }?.let { pages ->
val browser = kobwebBlock.app.export.browser.get()
val browser = exportBlock.browser.get()
PlaywrightCache().install(browser)
Playwright.create(
Playwright.CreateOptions().setEnv(
Expand All @@ -218,7 +219,7 @@ abstract class KobwebExportTask @Inject constructor(
.filter { !it.contains('{') }
.filter { route ->
val ctx = AppBlock.ExportBlock.ExportFilterContext(route)
(kobwebBlock.app.export.filter.orNull?.invoke(ctx) ?: true)
(exportBlock.filter.orNull?.invoke(ctx) ?: true)
.also { shouldExport ->
if (!shouldExport) {
logger.lifecycle("\nSkipped export for \"$route\".")
Expand All @@ -228,7 +229,7 @@ abstract class KobwebExportTask @Inject constructor(
.map { route -> AppBlock.ExportBlock.RouteConfig(route) }
.toSet()
.let { pageRoutes ->
pageRoutes + kobwebBlock.app.export.extraRoutes.orNull.orEmpty()
pageRoutes + exportBlock.extraRoutes.orNull.orEmpty()
}
.takeIf { routes -> routes.isNotEmpty() }
?.forEach { routeConfig ->
Expand Down Expand Up @@ -268,7 +269,7 @@ abstract class KobwebExportTask @Inject constructor(
?: run {
val noPagesExportedMessage = buildString {
append("No pages were found to export.")
if (kobwebBlock.app.export.filter.isPresent) {
if (exportBlock.filter.isPresent) {
append(" This may be because your build script's `kobweb.app.export.filter` is filtering out all pages.")
}
}
Expand Down Expand Up @@ -298,7 +299,7 @@ abstract class KobwebExportTask @Inject constructor(
}

try {
if (kobwebBlock.app.export.forceCopyingForRedirects.get()) throw IOException("Forcefully abort symbolic link step")
if (exportBlock.forceCopyingForRedirects.get()) throw IOException("Forcefully abort symbolic link step")

pagesRoot.walkTopDown().forEach { file ->
if (file.isDirectory) {
Expand Down Expand Up @@ -366,7 +367,7 @@ abstract class KobwebExportTask @Inject constructor(
// defined by the site.
getResourceFilesJsWithRoots().forEach { rootAndFile ->
// Drop the leading slash so we don't confuse File resolve logic
val relativePath = rootAndFile.relativeFile.invariantSeparatorsPath.substringAfter(getPublicPath()).drop(1)
val relativePath = rootAndFile.relativeFile.invariantSeparatorsPath.substringAfter(publicPath.get()).drop(1)
if (relativePath == "index.html" && siteLayout.isStatic) return@forEach

(if (relativePath != "index.html") resourcesRoot else systemRoot)
Expand All @@ -393,7 +394,7 @@ abstract class KobwebExportTask @Inject constructor(
scriptFile.copyTo(destFile, overwrite = true)
}

if (kobwebBlock.app.export.includeSourceMap.get()) {
if (exportBlock.includeSourceMap.get()) {
val scriptMapFile = File("${scriptFile}.map")
val destFile = systemRoot.resolve(scriptMapFile.name)
scriptMapFile.copyTo(destFile, overwrite = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
package com.varabyte.kobweb.gradle.core.tasks

import com.varabyte.kobweb.gradle.core.extensions.KobwebBlock
import com.varabyte.kobweb.gradle.core.extensions.kobwebBlock
import com.varabyte.kobweb.gradle.core.kmp.jsTarget
import com.varabyte.kobweb.gradle.core.util.RootAndFile
import com.varabyte.kobweb.gradle.core.util.getResourceFilesWithRoots
import com.varabyte.kobweb.gradle.core.util.getSourceFilesWithRoots
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal

/**
* Base class for any task that needs to know about any source / resources related to Kobweb in the current module.
*/
abstract class KobwebModuleTask(desc: String) : KobwebTask(desc) {
@get:Internal
val kobwebBlock: KobwebBlock = project.kobwebBlock

@Internal
fun getResourceFilesJsWithRoots(): Sequence<RootAndFile> = project.getResourceFilesWithRoots(project.jsTarget)
.filter { rootAndFile -> rootAndFile.relativeFile.invariantSeparatorsPath.startsWith("${getPublicPath()}/") }
.filter { rootAndFile -> rootAndFile.relativeFile.invariantSeparatorsPath.startsWith("$publicPath/") }

@Internal
fun getSourceFilesJsWithRoots(): Sequence<RootAndFile> = project.getSourceFilesWithRoots(project.jsTarget)
Expand All @@ -27,6 +22,5 @@ abstract class KobwebModuleTask(desc: String) : KobwebTask(desc) {
* The path of public resources inside the project's resources folder, e.g. "public" ->
* "src/jsMain/resources/public"
*/
@Input
fun getPublicPath(): String = kobwebBlock.publicPath.get()
private val publicPath = project.kobwebBlock.publicPath.get()
}