diff --git a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/ModuleGenerator.kt b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/ModuleGenerator.kt index f5ed406..466801b 100644 --- a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/ModuleGenerator.kt +++ b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/ModuleGenerator.kt @@ -96,10 +96,23 @@ object ModuleGenerator { writeSettingsFile(context) writeRootBuildScript(context) writeGradleWrapperResources(context) + writeVersionCatalog(context) return context.getRootDirectory() } + /** + * Writes the gradle version catalog (`gradle/libs.versions.toml`) used by subproject buildscripts, + * matching the layout used by ignition-sdk-examples. + */ + private fun writeVersionCatalog(context: ModuleGeneratorContext) { + val catalogFile = context.getRootDirectory().resolve("gradle/libs.versions.toml") + catalogFile.createAndFillFromResource( + "templates/version-catalog/libs.versions.toml", + context.getTemplateReplacements(), + ) + } + /** * Writes the gradle wrapper, allowing the user to build the module without gradle installed. */ @@ -164,10 +177,11 @@ object ModuleGenerator { } val dependencies = - DefaultDependencies.ARTIFACTS[projectScope]?.toDependencyFormat(context.config.buildDsl) ?: "" + DefaultDependencies.CATALOG_LIBS[projectScope]?.toDependencyFormat(context.config.buildDsl) ?: "" rootBuildScript.toFile().appendText( """ + | |dependencies { | $dependencies |} diff --git a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/DefaultDependencies.kt b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/DefaultDependencies.kt index 37c4f33..027f9c6 100644 --- a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/DefaultDependencies.kt +++ b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/DefaultDependencies.kt @@ -1,41 +1,44 @@ package io.ia.ignition.module.generator.api -import io.ia.ignition.module.generator.api.TemplateMarker.SDK_VERSION_PLACEHOLDER - object DefaultDependencies { // default gradle version const val GRADLE_VERSION = "9.3.1" + // default Ignition SDK / platform version for generated projects (matches ignition-sdk-examples 8.3 line) + const val IGNITION_SDK_VERSION = "8.3.0" + // default plugin configuration for the root build.gradle val MODL_PLUGIN: String = "id(\"io.ia.sdk.modl\") version(\"${TemplateMarker.MODL_PLUGIN_VERSION.key}\")" - // example - // "com.inductiveautomation.ignitionsdk:client-api:${'$'}{sdk_version}" - val ARTIFACTS: Map> = mapOf( + /** + * Version-catalog aliases for each scope, matching entries in + * `templates/version-catalog/libs.versions.toml` (and ignition-sdk-examples). + * Hyphens in the TOML library key become dots: ignition-gateway-api -> libs.ignition.gateway.api + */ + val CATALOG_LIBS: Map> = mapOf( ProjectScope.CLIENT to setOf( - "com.inductiveautomation.ignitionsdk:client-api:$SDK_VERSION_PLACEHOLDER", - "com.inductiveautomation.ignitionsdk:vision-client-api:$SDK_VERSION_PLACEHOLDER", - "com.inductiveautomation.ignitionsdk:ignition-common:$SDK_VERSION_PLACEHOLDER", + "libs.ignition.client.api", + "libs.ignition.vision.client.api", + "libs.ignition.common", ), ProjectScope.COMMON to setOf( - "com.inductiveautomation.ignitionsdk:ignition-common:$SDK_VERSION_PLACEHOLDER", + "libs.ignition.common", ), ProjectScope.DESIGNER to setOf( - "com.inductiveautomation.ignitionsdk:designer-api:$SDK_VERSION_PLACEHOLDER", - "com.inductiveautomation.ignitionsdk:ignition-common:$SDK_VERSION_PLACEHOLDER", + "libs.ignition.designer.api", + "libs.ignition.common", ), ProjectScope.GATEWAY to setOf( - "com.inductiveautomation.ignitionsdk:ignition-common:$SDK_VERSION_PLACEHOLDER", - "com.inductiveautomation.ignitionsdk:gateway-api:$SDK_VERSION_PLACEHOLDER", + "libs.ignition.common", + "libs.ignition.gateway.api", ), ) fun Set.toDependencyFormat( - dsl: GradleDsl, + @Suppress("UNUSED_PARAMETER") dsl: GradleDsl, configuration: String = "compileOnly", - ): String = map { artifact -> - val version = dsl.artifactSdkVersion() - "$configuration(\"${artifact.replace(SDK_VERSION_PLACEHOLDER.toString(), version)}\")" + ): String = map { catalogAlias -> + "$configuration($catalogAlias)" }.joinToString(separator = "\n ") } diff --git a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/GeneratorConfigBuilder.kt b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/GeneratorConfigBuilder.kt index b1583fa..22855b9 100644 --- a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/GeneratorConfigBuilder.kt +++ b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/GeneratorConfigBuilder.kt @@ -21,7 +21,9 @@ class GeneratorConfigBuilder { private var customReplacements: Map = emptyMap() private var buildDsl: GradleDsl = GROOVY private var projectLanguage: SourceFileType = JAVA - private var settingsDsl: GradleDsl = GROOVY + + // When null, [build] aligns settings DSL with [buildDsl] (kotlin buildscripts get settings.gradle.kts). + private var settingsDsl: GradleDsl? = null private var gradleWrapperVersion: String = GRADLE_VERSION private var debugPluginConfig: Boolean = false private var rootPluginConfig: String = "" @@ -64,7 +66,8 @@ class GeneratorConfigBuilder { packageName = packageName, scopes = scopes, parentDir = parentDir, - settingsDsl = settingsDsl, + // Match settings language to buildscripts unless the caller overrode settingsDsl. + settingsDsl = settingsDsl ?: buildDsl, buildDsl = buildDsl, projectLanguage = projectLanguage, gradleWrapperVersion = gradleWrapperVersion, diff --git a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/GradleDsl.kt b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/GradleDsl.kt index 760d812..03e845d 100644 --- a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/GradleDsl.kt +++ b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/api/GradleDsl.kt @@ -12,7 +12,7 @@ enum class GradleDsl { fun settingsFilename(): String = when (this) { GROOVY -> "settings.gradle" - KOTLIN -> "templates/settings.gradle.kts" + KOTLIN -> "settings.gradle.kts" } fun mapAssociator(): String = when (this) { diff --git a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/data/ModuleGeneratorContext.kt b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/data/ModuleGeneratorContext.kt index 2bcec66..aca9499 100644 --- a/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/data/ModuleGeneratorContext.kt +++ b/generator/generator-core/src/main/kotlin/io/ia/ignition/module/generator/data/ModuleGeneratorContext.kt @@ -82,7 +82,7 @@ class ModuleGeneratorContext(override val config: GeneratorConfig) : GeneratorCo private fun buildDependencyEntries(scopes: List): Map = mutableMapOf().apply { scopes.forEach { scope -> TemplateMarker.dependencyKeyForScope(scope)?.let { tm -> - this[tm.key] = DefaultDependencies.ARTIFACTS[scope]?.toDependencyFormat(config.buildDsl) ?: "" + this[tm.key] = DefaultDependencies.CATALOG_LIBS[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\"))" diff --git a/generator/generator-core/src/main/resources/templates/buildscript/root.build.gradle b/generator/generator-core/src/main/resources/templates/buildscript/root.build.gradle index a9d9167..db56512 100644 --- a/generator/generator-core/src/main/resources/templates/buildscript/root.build.gradle +++ b/generator/generator-core/src/main/resources/templates/buildscript/root.build.gradle @@ -12,7 +12,8 @@ plugins { } ext { - sdk_version = "8.1.20" + // Keep in sync with [versions].ignition in gradle/libs.versions.toml + sdk_version = "8.3.0" } allprojects { diff --git a/generator/generator-core/src/main/resources/templates/buildscript/root.build.gradle.kts b/generator/generator-core/src/main/resources/templates/buildscript/root.build.gradle.kts index 2d7299c..a5797d9 100644 --- a/generator/generator-core/src/main/resources/templates/buildscript/root.build.gradle.kts +++ b/generator/generator-core/src/main/resources/templates/buildscript/root.build.gradle.kts @@ -11,7 +11,8 @@ plugins { } -val sdk_version by extra("8.1.20") +// Keep in sync with [versions].ignition in gradle/libs.versions.toml +val sdk_version by extra("8.3.0") allprojects { version = "0.0.1-SNAPSHOT" diff --git a/generator/generator-core/src/main/resources/templates/config/modlPluginConfig.groovy b/generator/generator-core/src/main/resources/templates/config/modlPluginConfig.groovy index bc82f44..de76be7 100644 --- a/generator/generator-core/src/main/resources/templates/config/modlPluginConfig.groovy +++ b/generator/generator-core/src/main/resources/templates/config/modlPluginConfig.groovy @@ -94,3 +94,15 @@ ignitionModule { */ // } + +/* + * Convenience task that runs clean on all projects and removes the root .gradle cache directory. + * Mirrors the cleanup helper used in ignition-sdk-examples. + */ +tasks.register("deepClean") { + dependsOn(allprojects.collect { it.path + ":clean" }) + description = "Executes clean tasks and removes the root .gradle directory." + doLast { + delete(file(".gradle")) + } +} diff --git a/generator/generator-core/src/main/resources/templates/config/modlPluginConfig.kts b/generator/generator-core/src/main/resources/templates/config/modlPluginConfig.kts index ea3727f..59860ec 100644 --- a/generator/generator-core/src/main/resources/templates/config/modlPluginConfig.kts +++ b/generator/generator-core/src/main/resources/templates/config/modlPluginConfig.kts @@ -95,3 +95,15 @@ ignitionModule { */ // } + +/* + * Convenience task that runs clean on all projects and removes the root .gradle cache directory. + * Mirrors the cleanup helper used in ignition-sdk-examples. + */ +val deepClean by tasks.registering { + dependsOn(allprojects.map { "${it.path}:clean" }) + description = "Executes clean tasks and removes the root .gradle directory." + doLast { + delete(file(".gradle")) + } +} diff --git a/generator/generator-core/src/main/resources/templates/hook/DesignerHook.java b/generator/generator-core/src/main/resources/templates/hook/DesignerHook.java index e538624..fb053d5 100644 --- a/generator/generator-core/src/main/resources/templates/hook/DesignerHook.java +++ b/generator/generator-core/src/main/resources/templates/hook/DesignerHook.java @@ -10,10 +10,15 @@ */ public class DesignerHook extends AbstractDesignerModuleHook { - // override additonal methods as requried + // override additional methods as required @Override public void startup(DesignerContext context, LicenseState activationState) throws Exception { - // implelement functionality as required + // implement functionality as required + } + + @Override + public void shutdown() { + // cleanup as required } } diff --git a/generator/generator-core/src/main/resources/templates/hook/DesignerHook.kt b/generator/generator-core/src/main/resources/templates/hook/DesignerHook.kt index c8df153..82cfa66 100644 --- a/generator/generator-core/src/main/resources/templates/hook/DesignerHook.kt +++ b/generator/generator-core/src/main/resources/templates/hook/DesignerHook.kt @@ -8,12 +8,16 @@ import com.inductiveautomation.ignition.designer.model.DesignerContext /** * This is the Designer-scope module hook. The minimal implementation contains a startup method. */ -class DesignerHook: AbstractDesignerModuleHook() { +class DesignerHook : AbstractDesignerModuleHook() { - // override additonal methods as requried + // override additional methods as required - @Throws(Exception) + @Throws(Exception::class) override fun startup(context: DesignerContext, activationState: LicenseState) { // implement functionality as required } + + override fun shutdown() { + // cleanup as required + } } diff --git a/generator/generator-core/src/main/resources/templates/hook/GatewayHook.java b/generator/generator-core/src/main/resources/templates/hook/GatewayHook.java index d41300d..7962b95 100644 --- a/generator/generator-core/src/main/resources/templates/hook/GatewayHook.java +++ b/generator/generator-core/src/main/resources/templates/hook/GatewayHook.java @@ -1,26 +1,16 @@ package .gateway; -import java.util.List; -import java.util.Optional; -import javax.servlet.http.HttpServletResponse; - import com.inductiveautomation.ignition.common.licensing.LicenseState; -import com.inductiveautomation.ignition.common.project.resource.adapter.ResourceTypeAdapterRegistry; -import com.inductiveautomation.ignition.gateway.dataroutes.RouteGroup; import com.inductiveautomation.ignition.gateway.model.AbstractGatewayModuleHook; import com.inductiveautomation.ignition.gateway.model.GatewayContext; -import com.inductiveautomation.ignition.gateway.web.models.ConfigCategory; -import com.inductiveautomation.ignition.gateway.web.models.IConfigTab; -import com.inductiveautomation.ignition.gateway.web.models.SystemMap; -import com.inductiveautomation.ignition.gateway.web.pages.config.overviewmeta.ConfigOverviewContributor; -import com.inductiveautomation.ignition.gateway.web.pages.status.overviewmeta.OverviewContributor; /** * Class which is instantiated by the Ignition platform when the module is loaded in the gateway scope. + * Override additional AbstractGatewayModuleHook methods as needed for your module. */ public class GatewayHook extends AbstractGatewayModuleHook { /** - * Called to before startup. This is the chance for the module to add its extension points and update persistent + * Called before startup. This is the chance for the module to add its extension points and update persistent * records and schemas. None of the managers will be started up at this point, but the extension point managers will * accept extension point types. */ @@ -40,7 +30,7 @@ public void startup(LicenseState activationState) { /** * Called to shutdown this module. Note that this instance will never be started back up - a new one will be created - * if a restart is desired + * if a restart is desired. */ @Override public void shutdown() { @@ -48,107 +38,10 @@ public void shutdown() { } /** - * A list (may be null or empty) of panels to display in the config section. Note that any config panels that are - * part of a category that doesn't exist already or isn't included in {@link #getConfigCategories()} will - * not be shown. - */ - @Override - public List getConfigPanels() { - return null; - } - - /** - * A list (may be null or empty) of custom config categories needed by any panels returned by {@link - * #getConfigPanels()} - */ - @Override - public List getConfigCategories() { - return null; - } - - /** - * @return the path to a folder in one of the module's gateway jar files that should be mounted at - * /res/module-id/foldername - */ - @Override - public Optional getMountedResourceFolder() { - return Optional.empty(); - } - - /** - * Provides a chance for the module to mount any route handlers it wants. These will be active at - * /main/data/module-id/* See {@link RouteGroup} for details. Will be called after startup(). - */ - @Override - public void mountRouteHandlers(RouteGroup routes) { - - } - - /** - * Used by the mounting underneath /res/module-id/* and /main/data/module-id/* as an alternate mounting path instead - * of your module id, if present. - */ - @Override - public Optional getMountPathAlias() { - return Optional.empty(); - } - - /** - * @return {@code true} if this is a "free" module, i.e. it does not participate in the licensing system. This is - * equivalent to the now defunct FreeModule attribute that could be specified in module.xml. + * @return {@code true} if this is a "free" module, i.e. it does not participate in the licensing system. */ @Override public boolean isFreeModule() { - return false; - } - - /** - * Implement this method to contribute meta data to the Status section's Systems / Overview page. - */ - @Override - public Optional getStatusOverviewContributor() { - return Optional.empty(); - } - - /** - * Implement this method to contribute meta data to the Configure section's Overview page. - */ - @Override - public Optional getConfigOverviewContributor() { - return Optional.empty(); - } - - /** - * Register any {@link ResourceTypeAdapter}s this module needs with with {@code registry}. - *

- * ResourceTypeAdapters are used to adapt a legacy (7.9 or prior) resource type name or payload into a nicer format - * for the Ignition 8.0 project resource system.Ò Only override this method for modules that aren't known by the - * {@link ResourceTypeAdapterRegistry} already. - *

- * This method is called before {@link #setup(GatewayContext)} or {@link #startup(LicenseState)}. - * - * @param registry the shared {@link ResourceTypeAdapterRegistry} instance. - */ - @Override - public void initializeResourceTypeAdapterRegistry(ResourceTypeAdapterRegistry registry) { - - } - - /** - * Called prior to a 'mounted resource request' being fulfilled by requests to the mounted resource servlet serving - * resources from /res/module-id/ (or /res/alias/ if {@link GatewayModuleHook#getMountPathAlias} is implemented). It - * is called after the target resource has been successfully located. - * - *

- * Primarily intended as an opportunity to amend/alter the response's headers for purposes such as establishing - * Cache-Control. By default, Ignition sets no additional headers on a resource request. - *

- * - * @param resourcePath path to the resource being returned by the mounted resource request - * @param response the response to read/amend. - */ - @Override - public void onMountedResourceRequest(String resourcePath, HttpServletResponse response) { - + return true; } } diff --git a/generator/generator-core/src/main/resources/templates/hook/GatewayHook.kt b/generator/generator-core/src/main/resources/templates/hook/GatewayHook.kt index fe83360..6636f68 100644 --- a/generator/generator-core/src/main/resources/templates/hook/GatewayHook.kt +++ b/generator/generator-core/src/main/resources/templates/hook/GatewayHook.kt @@ -1,46 +1,39 @@ package .gateway -import com.inductiveautomation.ignition.common.expressions.ExpressionFunctionManager import com.inductiveautomation.ignition.common.licensing.LicenseState -import com.inductiveautomation.ignition.common.script.ScriptManager -import com.inductiveautomation.ignition.common.xmlserialization.deserialization.XMLDeserializer -import com.inductiveautomation.ignition.common.xmlserialization.serialization.XMLSerializer -import com.inductiveautomation.ignition.gateway.AbstractGatewayModuleHook -import com.inductiveautomation.ignition.gateway.clientcomm.ClientReqSession -import com.inductiveautomation.ignition.gateway.web.models.INamedTab +import com.inductiveautomation.ignition.gateway.model.AbstractGatewayModuleHook +import com.inductiveautomation.ignition.gateway.model.GatewayContext /** - * Gateway scoped hook implementation + * Class which is instantiated by the Ignition platform when the module is loaded in the gateway scope. + * Override additional AbstractGatewayModuleHook methods as needed for your module. */ -class GatewayHook: AbstractGatewayModuleHook() { - - - fun getRPCHandler(session: ClientReqSession?, projectName: String?): Any? { - return null +class GatewayHook : AbstractGatewayModuleHook() { + + /** + * Called before startup. This is the chance for the module to add its extension points and update persistent + * records and schemas. None of the managers will be started up at this point, but the extension point managers will + * accept extension point types. + */ + override fun setup(context: GatewayContext) { } - val homepagePanels: List? - get() = null - - val statusPanels: List? - get() = null - - fun configureDeserializer(deserializer: XMLDeserializer?) { - + /** + * Called to initialize the module. Will only be called once. Persistence interface is available, but only in + * read-only mode. + */ + override fun startup(activationState: LicenseState) { } - fun configureSerializer(serializer: XMLSerializer?) { - + /** + * Called to shutdown this module. Note that this instance will never be started back up - a new one will be created + * if a restart is desired. + */ + override fun shutdown() { } - fun configureFunctionFactory(factory: ExpressionFunctionManager?) { - } - - fun notifyLicenseStateChanged(licenseState: LicenseState?) { - - } - - fun initializeScriptManager(manager: ScriptManager?) { - - } + /** + * @return true if this is a "free" module, i.e. it does not participate in the licensing system. + */ + override fun isFreeModule(): Boolean = true } diff --git a/generator/generator-core/src/main/resources/templates/version-catalog/libs.versions.toml b/generator/generator-core/src/main/resources/templates/version-catalog/libs.versions.toml index 38d012d..22b16a9 100644 --- a/generator/generator-core/src/main/resources/templates/version-catalog/libs.versions.toml +++ b/generator/generator-core/src/main/resources/templates/version-catalog/libs.versions.toml @@ -1,31 +1,32 @@ [versions] # Library/Dependency Versions -ignitionSdk = "" +# Keep in sync with sdk_version in the root buildscript (requiredIgnitionVersion). +ignition = "8.3.0" [libraries] -# Dependencies referencable in buildscripts. Note that dashes are replaced by periods in the buildscript reference. -# batik-swing -> libs.batik.swing -ignition-alarmNotificationCommon = { module = "com.inductiveautomation.ignitionsdk:alarm-notification-common", version.ref = "ignitionSdk" } -ignition-alarmNotificationDesigner = { module = "com.inductiveautomation.ignitionsdk:alarm-notification-designer", version.ref = "ignitionSdk" } -ignition-alarmNotificationGatewayApi = { module = "com.inductiveautomation.ignitionsdk:alarm-notification-gateway-api", version.ref = "ignitionSdk" } -ignition-clientApi = { module = "com.inductiveautomation.ignitionsdk:client-api", version.ref = "ignitionSdk" } -ignition-clientLauncher = { module = "com.inductiveautomation.ignitionsdk:client-launcher", version.ref = "ignitionSdk" } -ignition-common = { module = "com.inductiveautomation.ignitionsdk:ignition-common", version.ref = "ignitionSdk" } -ignition-designerApi = { module = "com.inductiveautomation.ignitionsdk:designer-api", version.ref = "ignitionSdk" } -ignition-designerLauncher = { module = "com.inductiveautomation.ignitionsdk:designer-launcher", version.ref = "ignitionSdk" } -ignition-driverApi = { module = "com.inductiveautomation.ignitionsdk:driver-api", version.ref = "ignitionSdk" } -ignition-gatewayApi = { module = "com.inductiveautomation.ignitionsdk:gateway-api", version.ref = "ignitionSdk" } -ignition-perspectiveCommon = { module = "com.inductiveautomation.ignitionsdk:perspective-common", version.ref = "ignitionSdk" } -ignition-perspectiveDesigner = { module = "com.inductiveautomation.ignitionsdk:perspective-designer", version.ref = "ignitionSdk" } -ignition-perspectiveGateway = { module = "com.inductiveautomation.ignitionsdk:perspective-gateway", version.ref = "ignitionSdk" } -ignition-reportingCommon = { module = "com.inductiveautomation.ignitionsdk:reporting-common", version.ref = "ignitionSdk" } -ignition-reportingDesigner = { module = "com.inductiveautomation.ignitionsdk:reporting-designer", version.ref = "ignitionSdk" } -ignition-reportingGateway = { module = "com.inductiveautomation.ignitionsdk:reporting-gateway", version.ref = "ignitionSdk" } -ignition-sfcClient = { module = "com.inductiveautomation.ignitionsdk:sfc-client", version.ref = "ignitionSdk" } -ignition-sfcCommon = { module = "com.inductiveautomation.ignitionsdk:sfc-common", version.ref = "ignitionSdk" } -ignition-sfcDesigner = { module = "com.inductiveautomation.ignitionsdk:sfc-designer", version.ref = "ignitionSdk" } -ignition-sfcGatewayApi = { module = "com.inductiveautomation.ignitionsdk:sfc-gateway-api", version.ref = "ignitionSdk" } -ignition-tagHistorian = { module = "com.inductiveautomation.ignitionsdk:tag-historian", version.ref = "ignitionSdk" } -ignition-visionClientApi = { module = "com.inductiveautomation.ignitionsdk:vision-client-api", version.ref = "ignitionSdk" } -ignition-visionCommon = { module = "com.inductiveautomation.ignitionsdk:vision-common", version.ref = "ignitionSdk" } -ignition-visionDesignerApi = { module = "com.inductiveautomation.ignitionsdk:vision-designer-api", version.ref = "ignitionSdk" } +# Dependencies referencable in buildscripts. Note that hyphens become dots in the +# buildscript reference: ignition-gateway-api -> libs.ignition.gateway.api +ignition-alarm-notification-common = { module = "com.inductiveautomation.ignitionsdk:alarm-notification-common", version.ref = "ignition" } +ignition-alarm-notification-designer = { module = "com.inductiveautomation.ignitionsdk:alarm-notification-designer", version.ref = "ignition" } +ignition-alarm-notification-gateway-api = { module = "com.inductiveautomation.ignitionsdk:alarm-notification-gateway-api", version.ref = "ignition" } +ignition-client-api = { module = "com.inductiveautomation.ignitionsdk:client-api", version.ref = "ignition" } +ignition-client-launcher = { module = "com.inductiveautomation.ignitionsdk:client-launcher", version.ref = "ignition" } +ignition-common = { module = "com.inductiveautomation.ignitionsdk:ignition-common", version.ref = "ignition" } +ignition-designer-api = { module = "com.inductiveautomation.ignitionsdk:designer-api", version.ref = "ignition" } +ignition-designer-launcher = { module = "com.inductiveautomation.ignitionsdk:designer-launcher", version.ref = "ignition" } +ignition-driver-api = { module = "com.inductiveautomation.ignitionsdk:driver-api", version.ref = "ignition" } +ignition-gateway-api = { module = "com.inductiveautomation.ignitionsdk:gateway-api", version.ref = "ignition" } +ignition-perspective-common = { module = "com.inductiveautomation.ignitionsdk:perspective-common", version.ref = "ignition" } +ignition-perspective-designer = { module = "com.inductiveautomation.ignitionsdk:perspective-designer", version.ref = "ignition" } +ignition-perspective-gateway = { module = "com.inductiveautomation.ignitionsdk:perspective-gateway", version.ref = "ignition" } +ignition-reporting-common = { module = "com.inductiveautomation.ignitionsdk:reporting-common", version.ref = "ignition" } +ignition-reporting-designer = { module = "com.inductiveautomation.ignitionsdk:reporting-designer", version.ref = "ignition" } +ignition-reporting-gateway = { module = "com.inductiveautomation.ignitionsdk:reporting-gateway", version.ref = "ignition" } +ignition-sfc-client = { module = "com.inductiveautomation.ignitionsdk:sfc-client", version.ref = "ignition" } +ignition-sfc-common = { module = "com.inductiveautomation.ignitionsdk:sfc-common", version.ref = "ignition" } +ignition-sfc-designer = { module = "com.inductiveautomation.ignitionsdk:sfc-designer", version.ref = "ignition" } +ignition-sfc-gateway-api = { module = "com.inductiveautomation.ignitionsdk:sfc-gateway-api", version.ref = "ignition" } +ignition-tag-historian = { module = "com.inductiveautomation.ignitionsdk:tag-historian", version.ref = "ignition" } +ignition-vision-client-api = { module = "com.inductiveautomation.ignitionsdk:vision-client-api", version.ref = "ignition" } +ignition-vision-common = { module = "com.inductiveautomation.ignitionsdk:vision-common", version.ref = "ignition" } +ignition-vision-designer-api = { module = "com.inductiveautomation.ignitionsdk:vision-designer-api", version.ref = "ignition" } diff --git a/generator/generator-core/src/test/kotlin/io/ia/ignition/module/generator/ModuleGeneratorTest.kt b/generator/generator-core/src/test/kotlin/io/ia/ignition/module/generator/ModuleGeneratorTest.kt index 58743d0..c1f57eb 100644 --- a/generator/generator-core/src/test/kotlin/io/ia/ignition/module/generator/ModuleGeneratorTest.kt +++ b/generator/generator-core/src/test/kotlin/io/ia/ignition/module/generator/ModuleGeneratorTest.kt @@ -124,6 +124,7 @@ class ModuleGeneratorTest { assertNull(t) assertNotNull(projDir) + // Default builder uses Groovy buildscripts, which aligns settings DSL to Groovy as well. val settingsFile = projDir.resolve("settings.gradle") val settingsText = settingsFile.toFile().readText(Charsets.UTF_8) assertTrue(Files.exists(settingsFile)) @@ -134,6 +135,32 @@ class ModuleGeneratorTest { assertTrue(settingsText.contains(projDirName.toString())) } + @Test + fun `kotlin buildscript project gets settings_gradle_kts and version catalog`() { + val parentDir = tempFolder.newFolder().toPath() + val config = GeneratorConfigBuilder() + .moduleName("Catalog Check") + .packageName("bot.skynet.terminator") + .parentDir(parentDir) + .scopes("G") + .buildscriptDsl(GradleDsl.KOTLIN) + .build() + + val projDir = ModuleGenerator.generate(config) + assertTrue(Files.exists(projDir.resolve("settings.gradle.kts"))) + assertFalse(Files.exists(projDir.resolve("settings.gradle"))) + + val catalog = projDir.resolve("gradle/libs.versions.toml") + assertTrue(Files.exists(catalog), "version catalog should be written") + val catalogText = catalog.toFile().readText(Charsets.UTF_8) + assertTrue(catalogText.contains("ignition = \"8.3.0\"")) + assertTrue(catalogText.contains("ignition-gateway-api")) + + val rootBuild = projDir.resolve("build.gradle.kts").toFile().readText(Charsets.UTF_8) + assertTrue(rootBuild.contains("sdk_version by extra(\"8.3.0\")")) + assertTrue(rootBuild.contains("val deepClean by tasks.registering")) + } + @Test fun `G project has appropriate module configuration`() { val parentDir = tempFolder.newFolder().toPath() @@ -208,10 +235,14 @@ class ModuleGeneratorTest { assertTrue(content.contains(expected)) assertTrue(content.contains("dependencies {")) val gwDeps = """ - | compileOnly("com.inductiveautomation.ignitionsdk:ignition-common:${'$'}sdk_version") - | compileOnly("com.inductiveautomation.ignitionsdk:gateway-api:${'$'}sdk_version") + | compileOnly(libs.ignition.common) + | compileOnly(libs.ignition.gateway.api) """.trimMargin() assertTrue(content.contains(gwDeps), "buildscript should include '$gwDeps'") + assertTrue( + Files.exists(projDir.resolve("gradle/libs.versions.toml")), + "version catalog should be written for single-dir projects", + ) } @Test @@ -254,8 +285,8 @@ class ModuleGeneratorTest { assertTrue(content.contains(expected)) assertTrue(content.contains("dependencies {")) val gwDeps = """ - | compileOnly("com.inductiveautomation.ignitionsdk:ignition-common:${'$'}{rootProject.extra["sdk_version"]}") - | compileOnly("com.inductiveautomation.ignitionsdk:gateway-api:${'$'}{rootProject.extra["sdk_version"]}") + | compileOnly(libs.ignition.common) + | compileOnly(libs.ignition.gateway.api) """.trimMargin() assertTrue(content.contains(gwDeps), "buildscript should include '$gwDeps'") }