Skip to content

Commit

Permalink
common scope dependencies are configured with sane defaults in multis…
Browse files Browse the repository at this point in the history
…cope projects.
  • Loading branch information
PerryAJ authored Dec 13, 2022
1 parent 3edaa44 commit c04241e
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 49 deletions.
2 changes: 1 addition & 1 deletion generator/generator-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ tasks {
dependencies {
// Align versions of all Kotlin components
implementation(platform("org.jetbrains.kotlin:kotlin-bom"))

// Use SLF4J api for logging, logger implementation to be provided by lib consumer
api(libs.slf4jApi)

// Use the Kotlin test library.
// testImplementation(libs.bundles.kotlinTest)
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
testImplementation(kotlin("test-junit"))

// support logging in tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,28 @@ class IntegrationTests {
applyExecPermissions(workingDir.resolve("gradlew"))
}
val cmd = command(this)
val process = ProcessBuilder(*(cmd.toTypedArray()))
.directory(workingDir.toFile())
.redirectOutput(ProcessBuilder.Redirect.INHERIT)
.redirectError(ProcessBuilder.Redirect.INHERIT)
.start()
var result: String = ""

val result = process.inputStream.bufferedReader().readText()
ProcessBuilder(*(cmd.toTypedArray()))
.directory(workingDir.toFile())
.redirectOutput(ProcessBuilder.Redirect.PIPE)
.redirectErrorStream(true)
.start().also { process ->
process.inputStream.bufferedReader().run {
while (true) {
readLine()?.let { line ->
result += "$line\n"
} ?: break
}
}

process.waitFor(60, TimeUnit.SECONDS)
if (process.isAlive) {
result += "TIMEOUT occurred\n"
process.destroy()
}
}

if (!process.waitFor(60, TimeUnit.SECONDS)) {
process.destroy()
throw RuntimeException("execution timed out: $this")
}
if (process.exitValue() != 0) {
throw RuntimeException("execution failed with code ${process.exitValue()}: $this")
}
return result
}

Expand All @@ -109,21 +116,21 @@ class IntegrationTests {

val projectRootDir: Path = ModuleGenerator.generate(config)

var processOutput = "build".runCommand(projectRootDir)
val processOutput = "build".runCommand(projectRootDir)
assertTrue(processOutput.contains("BUILD SUCCESSFUL"))
}
}

@Test
fun `generated kotlin buildscript projects build successfully`() {
listOf(
TestConfig("The Greatness", "le.examp", "G", dir("v1")),
TestConfig("almost Greatness", "le.examp.odd", "GC", dir("v2")),
TestConfig("The greatness", "le.examp.whoa", "GCD", dir("v3")),
TestConfig("oncegreatness", "buenos.dias.amigo", "GCD", dir("v4")),
TestConfig("The Greatness", "le.pant", "CD", dir("v5")),
TestConfig("A Goodness", "come.va", "C", dir("v6")),
TestConfig("The number 1 Greatness", "bon.gior.nio", "D", dir("v7"))
TestConfig("The Greatness", "le.examp", "G", dir("v1_kts")),
TestConfig("almost Greatness", "le.examp.odd", "GC", dir("v2_kts")),
TestConfig("The greatness", "le.examp.whoa", "GCD", dir("v3_kts")),
TestConfig("oncegreatness", "buenos.dias.amigo", "GCD", dir("v4_kts")),
TestConfig("The Greatness", "le.pant", "CD", dir("v5_kts")),
TestConfig("A Goodness", "come.va", "C", dir("v6_kts")),
TestConfig("The number 1 Greatness", "bon.gior.nio", "D", dir("v7_kts"))
).forEach {
val config = GeneratorConfigBuilder()
.moduleName(it.moduleName)
Expand All @@ -136,6 +143,7 @@ class IntegrationTests {
val projectRootDir: Path = ModuleGenerator.generate(config)

val processOutput = "build".runCommand(projectRootDir)
println("OUTPUT:\n$processOutput")
assertTrue(processOutput.contains("BUILD SUCCESSFUL"))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.ia.ignition.module.generator.api

import io.ia.ignition.module.generator.api.TemplateMarker.SDK_VERSION_PLACEHOLDER

object DefaultDependencies {

// default gradle version
Expand All @@ -8,8 +10,6 @@ object DefaultDependencies {
// default plugin configuration for the root build.gradle
val MODL_PLUGIN: String = "id(\"io.ia.sdk.modl\") version(\"${TemplateMarker.MODL_PLUGIN_VERSION.key}\")"

const val SDK_VERSION_PLACEHOLDER = "<SDK_VERSION>"

// example
// "com.inductiveautomation.ignitionsdk:client-api:${'$'}{sdk_version}"
val ARTIFACTS: Map<ProjectScope, Set<String>> = mapOf(
Expand Down Expand Up @@ -37,7 +37,7 @@ object DefaultDependencies {
): String {
return map { artifact ->
val version = dsl.artifactSdkVersion()
"$configuration(\"${artifact.replace(SDK_VERSION_PLACEHOLDER, version)}\")"
"$configuration(\"${artifact.replace(SDK_VERSION_PLACEHOLDER.toString(), version)}\")"
}.joinToString(separator = "\n ")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ enum class ProjectScope(val folderName: String) {

/**
* Returns a list of valid ProjectScope elements according the the string. Lower case letters treated as
* upper case, and invalid scope characters in the String are ignored. Common scope *is* represented in
* upper case, and invalid scope characters in the String are ignored. Common scope *is* represented in
* the resulting list if the list includes more than one scope value.. Use [scopesFromShorthand] if needing
* the exact project scopes given a shorthand string.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package io.ia.ignition.module.generator.api

import io.ia.ignition.module.generator.api.ProjectScope.CLIENT
import io.ia.ignition.module.generator.api.ProjectScope.COMMON
import io.ia.ignition.module.generator.api.ProjectScope.DESIGNER
import io.ia.ignition.module.generator.api.ProjectScope.GATEWAY

/**
* Markers used in the various template files that are string replaced during assembly in order to create the
* appropriately named project elements.
Expand Down Expand Up @@ -86,15 +91,31 @@ enum class TemplateMarker(val key: String) {
*/
DESIGNER_DEPENDENCIES("//<DESIGNER_DEPENDENCIES>"),

DEPENDENCIES("//<DEPENDENCIES>"),

JAVA_TOOLING_CONFIG("//<JAVA_TOOLING>"),

SKIP_SIGNING_CONFIG("//<SKIP_MODULE_SIGNING>"),

MODL_PLUGIN_VERSION("<MODL_PLUGIN_VERSION>");
MODL_PLUGIN_VERSION("<MODL_PLUGIN_VERSION>"),

SDK_VERSION_PLACEHOLDER("<SDK_VERSION>");

fun keys(): List<String> {
return values().map { it.key }
}

override fun toString(): String {
return key
}

companion object {
fun dependencyKeyForScope(scope: ProjectScope): TemplateMarker? {
return when (scope) {
CLIENT -> TemplateMarker.CLIENT_DEPENDENCIES
DESIGNER -> TemplateMarker.DESIGNER_DEPENDENCIES
GATEWAY -> TemplateMarker.GATEWAY_DEPENDENCIES
COMMON -> TemplateMarker.COMMON_DEPENDENCIES
else -> null
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ import io.ia.ignition.module.generator.api.ProjectScope.GATEWAY
import io.ia.ignition.module.generator.api.SourceFileType.JAVA
import io.ia.ignition.module.generator.api.SourceFileType.KOTLIN
import io.ia.ignition.module.generator.api.TemplateMarker
import io.ia.ignition.module.generator.api.TemplateMarker.CLIENT_DEPENDENCIES
import io.ia.ignition.module.generator.api.TemplateMarker.COMMON_DEPENDENCIES
import io.ia.ignition.module.generator.api.TemplateMarker.DESIGNER_DEPENDENCIES
import io.ia.ignition.module.generator.api.TemplateMarker.GATEWAY_DEPENDENCIES
import io.ia.ignition.module.generator.api.TemplateMarker.HOOK_CLASS_CONFIG
import io.ia.ignition.module.generator.api.TemplateMarker.MODULE_CLASSNAME
import io.ia.ignition.module.generator.api.TemplateMarker.MODULE_FILENAME
Expand Down Expand Up @@ -75,20 +71,7 @@ class ModuleGeneratorContext(override val config: GeneratorConfig) : GeneratorCo
settingsHeaderReplacement()
rootPluginReplacement()
// populate the dependency replacements
scopes.forEach {
@Suppress("UNUSED_EXPRESSION")
when (it) {
CLIENT -> replacements[CLIENT_DEPENDENCIES.key] =
DefaultDependencies.ARTIFACTS[CLIENT]?.toDependencyFormat(config.buildDsl) ?: ""
DESIGNER -> replacements[DESIGNER_DEPENDENCIES.key] =
DefaultDependencies.ARTIFACTS[DESIGNER]?.toDependencyFormat(config.buildDsl) ?: ""
GATEWAY -> replacements[GATEWAY_DEPENDENCIES.key] =
DefaultDependencies.ARTIFACTS[GATEWAY]?.toDependencyFormat(config.buildDsl) ?: ""
COMMON -> replacements[COMMON_DEPENDENCIES.key] =
DefaultDependencies.ARTIFACTS[COMMON]?.toDependencyFormat(config.buildDsl) ?: ""
else -> ""
}
}
replacements.putAll(buildDependencyEntries(effectiveScopes))

// this is a quick hack to support arbitrary replacements for resource files. Works for now as all formal
// template replacements are enclosed in < > characters, making collisions unlikely.
Expand All @@ -97,6 +80,20 @@ class ModuleGeneratorContext(override val config: GeneratorConfig) : GeneratorCo
}
}

private fun buildDependencyEntries(scopes: List<ProjectScope>): Map<String, String> {
return mutableMapOf<String, String>().apply {
scopes.forEach { scope ->
TemplateMarker.dependencyKeyForScope(scope)?.let { tm ->
this[tm.key] = DefaultDependencies.ARTIFACTS[scope]?.toDependencyFormat(config.buildDsl) ?: ""
// if not a common scope and there is a common project, add it as a dependency to other scopes
if (scope != COMMON && scopes.size > 1) {
this[tm.key] = "${this[tm.key]}\n compileOnly(project(\":common\"))"
}
}
}
}
}

/**
* Establishes the pluginManagement, so that the plugin can resolve the module signer lib from nexus
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ data class SubProjectSettings(
val buildscriptLanguage: GradleDsl,
val projectLanguage: SourceFileType,
val scope: ProjectScope,
val dependencies: String = ""
) // optional dependencies injected into build file
val dependencies: String = "" // optional dependencies injected into build file
)

fun buildSubProjectSettings(context: GeneratorContext, scope: ProjectScope): SubProjectSettings {
val moduleRootDir = context.getRootDirectory()
Expand Down

0 comments on commit c04241e

Please sign in to comment.