diff --git a/platformUI/build.gradle.kts b/platformUI/build.gradle.kts index 5f13799..9ad06af 100644 --- a/platformUI/build.gradle.kts +++ b/platformUI/build.gradle.kts @@ -15,7 +15,6 @@ */ import com.github.gradle.node.yarn.task.YarnTask -import org.gradle.api.logging.LogLevel.INFO node { // Retrieve tested versions of Node, Npm and Yarn from the version catalog (see gradle/libs.versions.toml) @@ -41,11 +40,7 @@ dependencies { // TODO: Future webapp improvement; implement a parallel NPM / package-lock based approach. Yarn does not like having a package lock in the same build. internal val gui = project.file("gui") -internal val buildDirs = arrayOf("gui/node_modules", "gui_dist", "gui/.quasar") - -val compileXtc by tasks.existing { - dependsOn(yarnQuasarBuild) -} +internal val buildDirs = arrayOf("gui/node_modules", "gui/dist", "gui/.quasar") /** * By adding the gui/dist folder as a resource directory, the build will also treat @@ -57,26 +52,34 @@ val compileXtc by tasks.existing { sourceSets.main { xtc { resources { - srcDir(file("gui/dist/")) + srcDir(files("gui/dist/")) } } } val clean by tasks.existing { - delete(layout.files(*buildDirs)) + doLast { + for (buildDir in buildDirs) { + logger.info("Want to clean build dir: $buildDir") + delete(layout.files(buildDir)) + } + } } -// The yarnSetup task is just referenced here for type safety. We can also refer to it by name below, -// instead of to the variable "yarnSetup", but that is more brittle, and if we rename the task, any references -// to it might accidentally be forgotten. -val yarnSetup by tasks.existing - -val yarnAddQuasar by tasks.registering(YarnTask::class) { - dependsOn(yarnSetup) +/** + * Task that will make sure yarn updates all node_modules. + */ +val yarnAddDependencies by tasks.registering(YarnTask::class) { workingDir = gui + dependsOn(tasks.yarnSetup) + // Tag this task as a producer of the "node_modules" directory, implicitly ensuring that any changes // to the resolved node_modules will make its dependents rebuild properly. - outputs.file("node_modules") + outputs.dir("gui/node_modules") + + // Add a dependency to quasar. If one exists in the yarn/lock file, it may be used instead, so + // if the state of global/local installation changed, that may still rebuild, though, if it's + // not installed in both places. val quasarGlobal = providers.gradleProperty("org.xtclang.platform.quasarGlobal") args = buildList { add("add") @@ -88,27 +91,67 @@ val yarnAddQuasar by tasks.registering(YarnTask::class) { } doFirst { - logger.lifecycle("Task '$name' installing Quasar (${if (quasarGlobal.isPresent && quasarGlobal.get().toBoolean()) "globally" else "locally, only for ${rootProject.name}"}.") - printTaskOutputs(INFO) + logger.lifecycle("Task '$name' installing Quasar (${if (quasarGlobal.isPresent && quasarGlobal.get().toBoolean()) "globally" else "locally, only for ${rootProject.name})"}.") + printTaskInputsAndOutputs(LogLevel.INFO) } } +/** + * Task that defines the inputs and outputs for the Quasar webapp, and builds it. This means that the task + * should detect, e.g. if someone changes index.html or a single Vue file, and then rerun the task. Otherwise + * the task will be treated as "up to date". + */ val yarnQuasarBuild by tasks.registering(YarnTask::class) { - dependsOn(yarnAddQuasar) workingDir = gui - outputs.files() - args = listOf("--ignore-engines", "quasar", "build") + dependsOn(yarnAddDependencies) + + inputs.files("gui/public") + inputs.files("gui/index.html", "gui/src") + outputs.dir("gui/.quasar") + outputs.dir("gui/dist/spa") // Declare output file collection, even though empty, or we can never cache the yarnQuasarBuild task. + args = listOf("quasar", "build") doLast { - printTaskOutputs(INFO) + printTaskInputsAndOutputs(LogLevel.INFO) } } -internal fun Task.printTaskOutputs(level: LogLevel = LogLevel.LIFECYCLE) { +/** + * Compile the XTC PlatformUI Module. + */ +val compileXtc by tasks.existing { + dependsOn(verifySourceSets) + dependsOn(yarnQuasarBuild) +} + +val processResources by tasks.existing { + dependsOn(yarnQuasarBuild) +} + +val verifySourceSets by tasks.registering { + dependsOn(processResources) + mustRunAfter(yarnQuasarBuild) + sourceSets.forEach { + logger.info("*** Source Set: $it") + it.resources.files.forEach { + logger.info("** Resource: $it") + } + } +} + +private fun Task.printTaskInputsAndOutputs(level: LogLevel = LogLevel.LIFECYCLE) { + val inputFiles = inputs.files.asFileTree + logger.log(level, "Inputs: $name: ${inputFiles.toList()}") val outputFiles = outputs.files.asFileTree - val n = outputFiles.count() + logger.log(level, "Outputs: $name: ${outputFiles.toList()}") + val ni = inputFiles.count() + val no = outputFiles.count() logger.log(level, "${project.name} Task '$name' finished.") - logger.log(level, "${project.name} Outputs (count: $n):") + logger.log(level, "${project.name} Inputs (count: $no):") + inputs.files.asFileTree.forEachIndexed { + i, it -> logger.log(level, "${project.name} '$name' input $i (of $ni): $it") + } + logger.log(level, "${project.name} Outputs (count: $no):") outputs.files.asFileTree.forEachIndexed { - i, it -> logger.log(level, "${project.name} '$name' output $i (of $n): $it") + i, it -> logger.log(level, "${project.name} '$name' output $i (of $no): $it") } } diff --git a/platformUI/gui/src/App.vue b/platformUI/gui/src/App.vue index 5a2ae0d..38442ee 100644 --- a/platformUI/gui/src/App.vue +++ b/platformUI/gui/src/App.vue @@ -8,4 +8,4 @@ import { defineComponent } from 'vue' export default defineComponent({ name: 'App' }) - \ No newline at end of file +