Repository: smithy-lang/smithy
Pull request #2453 (2024-11-12 19:21:49)

Converting existing gradle DSL from groovy to kotlin.
**Why is this needed ?**
This is the first step in moving to a more consistent and composable experience for gradle configuration in the smithy repository. Writing it in kotlin to make it more expressive as compared to groovy. This commit just converts the existing gradle build from groovy to kotlin.

**Next steps:**
Once this change is merged, few other PRs will follow to introduce nice features such as `buildSrc` plugins to enhance configurability of how each sub project builds in this package. It will introduce flexibility in things such as allowing each subproject to compile with different JVM toolchain, and much more.

**Testing**
- `gradle clean && gradle build`.
- Any more testing? 


---
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.


JordonPhillips: We deliberately switched to groovy from kotlin, though I don't remember the context on why. @kstich did it iirc and he might remember.

Patch:
diff --git a/build.gradle b/build.gradle.kts
similarity index 58%
rename from build.gradle
rename to build.gradle.kts
index 439b6d610..5de3130ef 100644
--- a/build.gradle
+++ b/build.gradle.kts
@@ -13,28 +13,27 @@
  * permissions and limitations under the License.
  */
 
-import java.util.stream.Collectors
 import com.github.spotbugs.snom.Effort
+import org.jreleaser.model.Active
+import org.gradle.api.tasks.testing.logging.TestExceptionFormat
 
 plugins {
-    id "java-library"
-    id "maven-publish"
-    id "signing"
-    id "checkstyle"
-    id "jacoco"
-    id "com.github.spotbugs" version "6.0.8"
-    id "io.codearte.nexus-staging" version "0.30.0"
-    id "me.champeau.jmh" version "0.7.2"
-    id "com.github.johnrengelman.shadow" version "7.1.2"
-    id "org.jreleaser" version "1.12.0" apply false
+    `java-library`
+    `maven-publish`
+    signing
+    checkstyle
+    jacoco
+    id("com.github.spotbugs") version "6.0.8"
+    id("io.codearte.nexus-staging") version "0.30.0"
+    id("me.champeau.jmh") version "0.7.2"
+    id("com.github.johnrengelman.shadow") version "7.1.2"
+    id("org.jreleaser") version "1.12.0" apply false
 }
 
-ext {
-    // Load the Smithy version from VERSION.
-    libraryVersion = project.file("VERSION").getText('UTF-8').replace(System.lineSeparator(), "")
-}
+// Load the Smithy version from VERSION.
+val libraryVersion = project.file("VERSION").readText().trim()
 
-println "Smithy version: '${libraryVersion}'"
+println("Smithy version: '$libraryVersion'")
 
 allprojects {
     group = "software.amazon.smithy"
@@ -43,10 +42,10 @@ allprojects {
 
 // JReleaser publishes artifacts from a local staging repository, rather than maven local.
 // https://jreleaser.org/guide/latest/examples/maven/staging-artifacts.html#_gradle
-def stagingDirectory = rootProject.layout.buildDirectory.dir("staging")
+val stagingDirectory = rootProject.layout.buildDirectory.dir("staging")
 
 subprojects {
-    apply plugin: "java-library"
+    apply(plugin = "java-library")
 
     java {
         sourceCompatibility = JavaVersion.VERSION_1_8
@@ -59,44 +58,40 @@ subprojects {
     }
 
     dependencies {
-        testImplementation "org.junit.jupiter:junit-jupiter-api:5.10.0"
-        testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.10.0"
-        testImplementation "org.junit.jupiter:junit-jupiter-params:5.10.0"
-        testImplementation "org.hamcrest:hamcrest:2.1"
-        testCompileOnly "org.apiguardian:apiguardian-api:1.1.2"
+        testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")
+        testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.10.0")
+        testImplementation("org.junit.jupiter:junit-jupiter-params:5.10.0")
+        testImplementation("org.hamcrest:hamcrest:2.1")
+        testCompileOnly("org.apiguardian:apiguardian-api:1.1.2")
     }
 
     // Reusable license copySpec for building JARs
-    def licenseSpec = copySpec {
-        from "${project.rootDir}/LICENSE"
-        from "${project.rootDir}/NOTICE"
+    val licenseSpec = copySpec {
+        from("${project.rootDir}/LICENSE")
+        from("${project.rootDir}/NOTICE")
     }
 
     // Set up tasks that build source and javadoc jars.
-    task sourcesJar(type: Jar) {
+    tasks.register<Jar>("sourcesJar") {
         metaInf.with(licenseSpec)
-        from {
-            sourceSets.main.allSource
-        }
-        archiveClassifier = "sources"
+        from(sourceSets.main.get().allSource)
+        archiveClassifier.set("sources")
     }
 
     // Build a javadoc JAR too.
-    task javadocJar(type: Jar) {
+    tasks.register<Jar>("javadocJar") {
         metaInf.with(licenseSpec)
-        from {
-            tasks.javadoc
-        }
-        archiveClassifier = "javadoc"
+        from(tasks.javadoc)
+        archiveClassifier.set("javadoc")
     }
 
     // Include an Automatic-Module-Name in all JARs.
-    afterEvaluate { Project project ->
+    afterEvaluate {
         tasks.jar {
             metaInf.with(licenseSpec)
-            inputs.property("moduleName", project.ext["moduleName"])
+            inputs.property("moduleName", project.extra.get("moduleName"))
             manifest {
-                attributes "Automatic-Module-Name": project.ext["moduleName"]
+                attributes("Automatic-Module-Name" to project.extra.get("moduleName"))
             }
         }
     }
@@ -106,29 +101,32 @@ subprojects {
 
     // ==== Tests ====
     // https://docs.gradle.org/current/samples/sample_java_multi_project_with_junit5_tests.html
-    test {
+    tasks.test {
         useJUnitPlatform()
     }
+
     // Log on passed, skipped, and failed test events if the `-Plog-tests` property is set.
     // https://docs.gradle.org/current/javadoc/org/gradle/api/tasks/testing/logging/TestLoggingContainer.html
     if (project.hasProperty("log-tests")) {
-        test {
+        tasks.test {
             testLogging {
-                events = ["passed", "skipped", "failed"]
-                exceptionFormat = "full"
+                events("passed", "skipped", "failed")
+                exceptionFormat = TestExceptionFormat.FULL
             }
         }
     }
 
     // ==== Maven ====
-    apply plugin: "maven-publish"
-    apply plugin: "signing"
-    apply plugin: "com.github.johnrengelman.shadow"
+    apply(plugin = "maven-publish")
+    apply(plugin = "signing")
+    apply(plugin = "com.github.johnrengelman.shadow")
 
     // This is a little hacky, but currently needed to build a shadowed CLI JAR and smithy-syntax JAR with the same
     // customizations as other JARs.
     if (project.name != "smithy-cli" && project.name != "smithy-syntax") {
-        tasks.shadowJar.enabled = false
+        tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
+            isEnabled = false
+        }
     }
 
     publishing {
@@ -136,16 +134,16 @@ subprojects {
             // JReleaser's `publish` task publishes to all repositories, so only configure one.
             maven {
                 name = "localStaging"
-                url = stagingDirectory
+                url = uri(stagingDirectory)
             }
         }
 
         publications {
-            mavenJava(MavenPublication) { publication ->
-                if (tasks.shadowJar.enabled) {
-                    project.shadow.component(publication)
+            create<MavenPublication>("mavenJava") {
+                if (tasks.findByName("shadowJar")?.enabled == true) {
+                    project.shadow.component(this)
                 } else {
-                    publication.from(components["java"])
+                    from(components["java"])
                 }
 
                 // Ship the source and javadoc jars.
@@ -153,7 +151,7 @@ subprojects {
                 artifact(tasks["javadocJar"])
 
                 // Include extra information in the POMs.
-                project.afterEvaluate {
+                afterEvaluate {
                     pom {
                         name.set(project.ext["displayName"].toString())
                         description.set(project.description)
@@ -186,89 +184,93 @@ subprojects {
         if (project.hasProperty("signingKey") && project.hasProperty("signingPassword")) {
             signing {
                 useInMemoryPgpKeys(
-                        (String) project.property("signingKey"),
-                        (String) project.property("signingPassword"))
+                    project.property("signingKey").toString(),
+                    project.property("signingPassword").toString()
+                )
                 sign(publishing.publications["mavenJava"])
             }
         }
     }
 
-    task copyMavenMetadataForDevelopment(type: Copy) {
-        from('build/tmp/publishMavenJavaPublicationToMavenLocal') {
-            rename 'module-maven-metadata.xml', 'maven-metadata.xml'
+    tasks.register<Copy>("copyMavenMetadataForDevelopment") {
+        from("build/tmp/publishMavenJavaPublicationToMavenLocal") {
+            rename("module-maven-metadata.xml", "maven-metadata.xml")
         }
-
-        def wdir = System.getProperty("user.home") + '/.m2/repository/software/amazon/smithy/' + project.name
+        val wdir = "${System.getProperty("user.home")}/.m2/repository/software/amazon/smithy/${project.name}"
         into(wdir)
     }
 
-    publishToMavenLocal.finalizedBy(copyMavenMetadataForDevelopment)
+    tasks.publishToMavenLocal {
+        finalizedBy("copyMavenMetadataForDevelopment")
+    }
 
     // ==== CheckStyle ====
     // https://docs.gradle.org/current/userguide/checkstyle_plugin.html
-    apply plugin: "checkstyle"
-    tasks["checkstyleTest"].enabled = false
+    apply(plugin = "checkstyle")
+    tasks.named("checkstyleTest") {
+        enabled = false
+    }
 
     // ==== Code coverage ====
     // https://docs.gradle.org/current/userguide/jacoco_plugin.html
-    apply plugin: "jacoco"
+    apply(plugin = "jacoco")
+
     // report is always generated after tests run
-    test {
-        finalizedBy jacocoTestReport
+    tasks.test {
+        finalizedBy(tasks.jacocoTestReport)
     }
+
     // tests are required to run before generating the report
-    jacocoTestReport {
-        dependsOn test
-    }
-    jacocoTestReport {
+    tasks.jacocoTestReport {
+        dependsOn(tasks.test)
         reports {
             xml.required.set(false)
             csv.required.set(false)
-            html.destination file("$buildDir/reports/jacoco")
+            html.outputLocation.set(file("$buildDir/reports/jacoco"))
         }
     }
 
     // ==== Spotbugs ====
     // https://plugins.gradle.org/plugin/com.github.spotbugs
-    apply plugin: "com.github.spotbugs"
+    apply(plugin = "com.github.spotbugs")
     // We don't need to lint tests.
-    tasks["spotbugsTest"].enabled = false
+    tasks.named("spotbugsTest") {
+        enabled = false
+    }
     // Configure the bug filter for spotbugs.
     spotbugs {
-        effort = Effort.MAX
-        excludeFilter = file("${project.rootDir}/config/spotbugs/filter.xml")
+        effort.set(Effort.MAX)
+        excludeFilter.set(file("${project.rootDir}/config/spotbugs/filter.xml"))
     }
 }
 
 // The root project doesn't produce a JAR.
-tasks["jar"].enabled = false
+tasks.named("jar") {
+    enabled = false
+}
 
 // ==== Javadoc ====
-project.afterEvaluate {
+afterEvaluate {
     tasks.javadoc {
         title = "Smithy API ${version}"
         setDestinationDir(file("${project.buildDir}/docs/javadoc/latest"))
         // Build a consolidated javadoc of all subprojects.
-        source(project.subprojects.stream().map({
-            project(it.path).sourceSets.main.allJava
-        }).collect(Collectors.toList()))
-        classpath = files(project.subprojects.stream()
-                .map({project(it.path).sourceSets.main.compileClasspath})
-                .collect(Collectors.toList()))
+        source(subprojects.map { project(it.path).sourceSets.main.get().allJava })
+        classpath = files(subprojects.map { project(it.path).sourceSets.main.get().compileClasspath })
     }
 }
 
 // Disable HTML doclint to work around heading tag sequence validation
 // inconsistencies between JDK15 and earlier Java versions.
 allprojects {
-    tasks.withType(Javadoc) {
-        options.addStringOption('Xdoclint:-html', '-quiet')
-        // Fixed in JDK 12: https://bugs.openjdk.java.net/browse/JDK-8215291
-        // --no-module-directories does not exist in JDK 8 and is removed in 13
-        if (JavaVersion.current().isJava9()
-                || JavaVersion.current().isJava10()
-                || JavaVersion.current().isJava11()) {
-            options.addBooleanOption('-no-module-directories', true)
+    tasks.withType<Javadoc> {
+        (options as StandardJavadocDocletOptions).apply {
+            addStringOption("Xdoclint:-html", "-quiet")
+            // Fixed in JDK 12: https://bugs.openjdk.java.net/browse/JDK-8215291
+            // --no-module-directories does not exist in JDK 8 and is removed in 13
+            if (JavaVersion.current().run { isJava9 || isJava10 || isJava11 }) {
+                addBooleanOption("-no-module-directories", true)
+            }
         }
     }
 }
@@ -276,31 +278,31 @@ allprojects {
 // We're using JReleaser in the smithy-cli subproject, so we want to have a flag to control
 // which JReleaser configuration to use to prevent conflicts
 if (project.hasProperty("release.main")) {
-    apply plugin: 'org.jreleaser'
+    apply(plugin = "org.jreleaser")
 
-    jreleaser {
-        dryrun = false
+    extensions.configure<org.jreleaser.gradle.plugin.JReleaserExtension> {
+        dryrun.set(false)
 
         // Used for creating and pushing the version tag, but this configuration ensures that
         // an actual GitHub release isn't created (since the CLI release does that)
         release {
             github {
-                skipRelease = true
-                tagName = '{{projectVersion}}'
+                skipRelease.set(true)
+                tagName.set("{{projectVersion}}")
             }
         }
 
         // Used to announce a release to configured announcers.
         // https://jreleaser.org/guide/latest/reference/announce/index.html
         announce {
-            active = "NEVER"
+            active.set(Active.NEVER)
         }
 
         // Signing configuration.
         // https://jreleaser.org/guide/latest/reference/signing.html
         signing {
-            active = "ALWAYS"
-            armored = true
+            active.set(Active.ALWAYS)
+            armored.set(true)
         }
 
         // Configuration for deploying to Maven Central.
@@ -308,16 +310,16 @@ if (project.hasProperty("release.main")) {
         deploy {
             maven {
                 nexus2 {
-                    'maven-central' {
-                        active = "ALWAYS"
-                        url = "https://aws.oss.sonatype.org/service/local"
-                        snapshotUrl = "https://aws.oss.sonatype.org/content/repositories/snapshots"
-                        closeRepository = true
-                        releaseRepository = true
+                    create("maven-central") {
+                        active.set(Active.ALWAYS)
+                        url.set("https://aws.oss.sonatype.org/service/local")
+                        snapshotUrl.set("https://aws.oss.sonatype.org/content/repositories/snapshots")
+                        closeRepository.set(true)
+                        releaseRepository.set(true)
                         stagingRepository(stagingDirectory.get().toString())
                     }
                 }
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
deleted file mode 100644
index 43e27305e..000000000
--- a/settings.gradle
+++ /dev/null
@@ -1,39 +0,0 @@
-pluginManagement {
-    repositories {
-        mavenLocal()
-        mavenCentral()
-        gradlePluginPortal()
-    }
-}
-
-rootProject.name = "smithy"
-include ":smithy-aws-iam-traits"
-include ":smithy-aws-traits"
-include ":smithy-aws-apigateway-traits"
-include ":smithy-aws-apigateway-openapi"
-include ":smithy-aws-protocol-tests"
-include ":smithy-cli"
-include ":smithy-codegen-core"
-include ":smithy-build"
-include ":smithy-model"
-include ":smithy-diff"
-include ":smithy-linters"
-include ":smithy-mqtt-traits"
-include ":smithy-jsonschema"
-include ":smithy-openapi"
-include ":smithy-openapi-traits"
-include ":smithy-utils"
-include ":smithy-protocol-test-traits"
-include ':smithy-jmespath'
-include ":smithy-waiters"
-include ":smithy-aws-cloudformation-traits"
-include ":smithy-aws-cloudformation"
-include ":smithy-validation-model"
-include ":smithy-rules-engine"
-include ":smithy-smoke-test-traits"
-include ":smithy-syntax"
-include ":smithy-aws-endpoints"
-include ":smithy-aws-smoke-test-model"
-include ":smithy-protocol-traits"
-include ":smithy-protocol-tests"
-include ":smithy-trait-codegen"
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 000000000..e3703ba73
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,45 @@
+pluginManagement {
+    repositories {
+        mavenLocal()
+        mavenCentral()
+        gradlePluginPortal()
+    }
+
+    plugins {
+        val smithyGradleVersion : String by settings
+        id("software.amazon.smithy.gradle.smithy-jar") version smithyGradleVersion
+    }
+}
+
+rootProject.name = "smithy"
+
+include(":smithy-aws-iam-traits")
+include(":smithy-aws-traits")
+include(":smithy-aws-apigateway-traits")
+include(":smithy-aws-apigateway-openapi")
+include(":smithy-aws-protocol-tests")
+include(":smithy-cli")
+include(":smithy-codegen-core")
+include(":smithy-build")
+include(":smithy-model")
+include(":smithy-diff")
+include(":smithy-linters")
+include(":smithy-mqtt-traits")
+include(":smithy-jsonschema")
+include(":smithy-openapi")
+include(":smithy-openapi-traits")
+include(":smithy-utils")
+include(":smithy-protocol-test-traits")
+include(":smithy-jmespath")
+include(":smithy-waiters")
+include(":smithy-aws-cloudformation-traits")
+include(":smithy-aws-cloudformation")
+include(":smithy-validation-model")
+include(":smithy-rules-engine")
+include(":smithy-smoke-test-traits")
+include(":smithy-syntax")
+include(":smithy-aws-endpoints")
+include(":smithy-aws-smoke-test-model")
+include(":smithy-protocol-traits")
+include(":smithy-protocol-tests")
+include(":smithy-trait-codegen")
\ No newline at end of file
diff --git a/smithy-aws-apigateway-openapi/build.gradle b/smithy-aws-apigateway-openapi/build.gradle.kts
similarity index 76%
rename from smithy-aws-apigateway-openapi/build.gradle
rename to smithy-aws-apigateway-openapi/build.gradle.kts
index 4406baa44..a69559c85 100644
--- a/smithy-aws-apigateway-openapi/build.gradle
+++ b/smithy-aws-apigateway-openapi/build.gradle.kts
@@ -16,12 +16,10 @@
 description = "This module provides support for converting the Amazon API Gateway " +
         "Smithy traits when converting a Smithy model to OpenAPI3."
 
-ext {
-    displayName = "Smithy :: Amazon API Gateway OpenAPI Support"
-    moduleName = "software.amazon.smithy.aws.apigateway.openapi"
-}
+extra["displayName"] = "Smithy :: Amazon API Gateway OpenAPI Support"
+extra["moduleName"] = "software.amazon.smithy.aws.apigateway.openapi"
 
 dependencies {
-    api project(":smithy-openapi")
-    api project(":smithy-aws-apigateway-traits")
+    api(project(":smithy-aws-apigateway-traits"))
+    api(project(":smithy-openapi"))
 }
diff --git a/smithy-aws-apigateway-traits/build.gradle b/smithy-aws-apigateway-traits/build.gradle.kts
similarity index 80%
rename from smithy-aws-apigateway-traits/build.gradle
rename to smithy-aws-apigateway-traits/build.gradle.kts
index 5f43439a2..8813ee0b8 100644
--- a/smithy-aws-apigateway-traits/build.gradle
+++ b/smithy-aws-apigateway-traits/build.gradle.kts
@@ -15,11 +15,9 @@
 
 description = "This module provides Smithy traits and validators for API Gateway."
 
-ext {
-    displayName = "Smithy :: AWS :: API Gateway Traits"
-    moduleName = "software.amazon.smithy.aws.apigateway.traits"
-}
+extra["displayName"] = "Smithy :: AWS :: API Gateway Traits"
+extra["moduleName"] = "software.amazon.smithy.aws.apigateway.traits"
 
 dependencies {
-    api project(":smithy-aws-traits")
+    api(project(":smithy-aws-traits"))
 }
diff --git a/smithy-aws-cloudformation-traits/build.gradle b/smithy-aws-cloudformation-traits/build.gradle.kts
similarity index 80%
rename from smithy-aws-cloudformation-traits/build.gradle
rename to smithy-aws-cloudformation-traits/build.gradle.kts
index 6c5a68a81..cc713c618 100644
--- a/smithy-aws-cloudformation-traits/build.gradle
+++ b/smithy-aws-cloudformation-traits/build.gradle.kts
@@ -15,11 +15,9 @@
 
 description = "This module provides Smithy traits and validators for CloudFormation."
 
-ext {
-    displayName = "Smithy :: AWS :: CloudFormation Traits"
-    moduleName = "software.amazon.smithy.aws.cloudformation.traits"
-}
+extra["displayName"] = "Smithy :: AWS :: CloudFormation Traits"
+extra["moduleName"] = "software.amazon.smithy.aws.cloudformation.traits"
 
 dependencies {
-    api project(":smithy-model")
+    api(project(":smithy-model"))
 }
diff --git a/smithy-aws-cloudformation/build.gradle b/smithy-aws-cloudformation/build.gradle.kts
similarity index 71%
rename from smithy-aws-cloudformation/build.gradle
rename to smithy-aws-cloudformation/build.gradle.kts
index 927f066bc..a9ff1b095 100644
--- a/smithy-aws-cloudformation/build.gradle
+++ b/smithy-aws-cloudformation/build.gradle.kts
@@ -15,22 +15,20 @@
 
 description = "This module contains support for converting Smithy resources to CloudFormation Resource Schemas."
 
-ext {
-    displayName = "Smithy :: Cloudformation Conversion"
-    moduleName = "software.amazon.smithy.cloudformation.converter"
-}
+extra["displayName"] = "Smithy :: Cloudformation Conversion"
+extra["moduleName"] = "software.amazon.smithy.cloudformation.converter"
 
 // Necessary to load the everit JSON Schema validator.
 repositories {
-    maven { url "https://jitpack.io" }
+    maven { url = uri("https://jitpack.io") }
 }
 
 dependencies {
-    api project(":smithy-build")
-    api project(":smithy-jsonschema")
-    api project(":smithy-aws-cloudformation-traits")
-    api project(":smithy-aws-iam-traits")
-    api project(":smithy-aws-traits")
+    api(project(":smithy-build"))
+    api(project(":smithy-jsonschema"))
+    api(project(":smithy-aws-cloudformation-traits"))
+    api(project(":smithy-aws-iam-traits"))
+    api(project(":smithy-aws-traits"))
 
     // For use in validating schemas used in tests against the supplied
     // CloudFormation definition schema.
diff --git a/smithy-aws-endpoints/build.gradle b/smithy-aws-endpoints/build.gradle
deleted file mode 100644
index 2fdbcadae..000000000
--- a/smithy-aws-endpoints/build.gradle
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-description = "AWS specific components for managing endpoints in Smithy"
-
-ext {
-    displayName = "Smithy :: AWS Endpoints Components"
-    moduleName = "software.amazon.smithy.aws.endpoints"
-}
-
-dependencies {
-    api project(":smithy-aws-traits")
-    api project(":smithy-diff")
-    api project(":smithy-rules-engine")
-    api project(":smithy-model")
-    api project(":smithy-utils")
-}
diff --git a/smithy-aws-endpoints/build.gradle.kts b/smithy-aws-endpoints/build.gradle.kts
new file mode 100644
index 000000000..ade669e8b
--- /dev/null
+++ b/smithy-aws-endpoints/build.gradle.kts
@@ -0,0 +1,17 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+description = "AWS specific components for managing endpoints in Smithy"
+
+extra["displayName"] = "Smithy :: AWS Endpoints Components"
+extra["moduleName"] = "software.amazon.smithy.aws.endpoints"
+
+dependencies {
+    api(project(":smithy-aws-traits"))
+    api(project(":smithy-diff"))
+    api(project(":smithy-rules-engine"))
+    api(project(":smithy-model"))
+    api(project(":smithy-utils"))
+}
diff --git a/smithy-aws-iam-traits/build.gradle b/smithy-aws-iam-traits/build.gradle.kts
similarity index 81%
rename from smithy-aws-iam-traits/build.gradle
rename to smithy-aws-iam-traits/build.gradle.kts
index 2f9cb8250..b923ed37e 100644
--- a/smithy-aws-iam-traits/build.gradle
+++ b/smithy-aws-iam-traits/build.gradle.kts
@@ -15,11 +15,9 @@
 
 description = "This module provides Smithy traits and validators for IAM."
 
-ext {
-    displayName = "Smithy :: AWS :: IAM Traits"
-    moduleName = "software.amazon.smithy.aws.iam.traits"
-}
+extra["displayName"] = "Smithy :: AWS :: IAM Traits"
+extra["moduleName"] = "software.amazon.smithy.aws.iam.traits"
 
 dependencies {
-    api project(":smithy-aws-traits")
+    api(project(":smithy-aws-traits"))
 }
diff --git a/smithy-aws-traits/build.gradle b/smithy-aws-traits/build.gradle.kts
similarity index 79%
rename from smithy-aws-traits/build.gradle
rename to smithy-aws-traits/build.gradle.kts
index af2ac03b0..4ff2ca248 100644
--- a/smithy-aws-traits/build.gradle
+++ b/smithy-aws-traits/build.gradle.kts
@@ -15,12 +15,10 @@
 
 description = "This module provides Smithy traits and validators that are used by most AWS services."
 
-ext {
-    displayName = "Smithy :: AWS Core Traits"
-    moduleName = "software.amazon.smithy.aws.traits"
-}
+extra["displayName"] = "Smithy :: AWS Core Traits"
+extra["moduleName"] = "software.amazon.smithy.aws.traits"
 
 dependencies {
-    api project(":smithy-diff")
-    api project(":smithy-model")
+    api(project(":smithy-diff"))
+    api(project(":smithy-model"))
 }
diff --git a/smithy-build/build.gradle b/smithy-build/build.gradle.kts
similarity index 77%
rename from smithy-build/build.gradle
rename to smithy-build/build.gradle.kts
index 20a502b25..69e087c93 100644
--- a/smithy-build/build.gradle
+++ b/smithy-build/build.gradle.kts
@@ -16,15 +16,13 @@
 description = "This module is a library used to validate Smithy models, create filtered " +
         "projections of a model, and generate build artifacts."
 
-ext {
-    displayName = "Smithy :: Build"
-    moduleName = "software.amazon.smithy.build"
-}
+extra["displayName"] = "Smithy :: Build"
+extra["moduleName"] = "software.amazon.smithy.build"
 
 dependencies {
-    api project(":smithy-utils")
-    api project(":smithy-model")
+    api(project(":smithy-utils"))
+    api(project(":smithy-model"))
 
     // Allows testing of annotation processor
-    testImplementation "com.google.testing.compile:compile-testing:0.21.0"
+    testImplementation("com.google.testing.compile:compile-testing:0.21.0")
 }
diff --git a/smithy-codegen-core/build.gradle b/smithy-codegen-core/build.gradle.kts
similarity index 77%
rename from smithy-codegen-core/build.gradle
rename to smithy-codegen-core/build.gradle.kts
index 6db84184c..be76cb102 100644
--- a/smithy-codegen-core/build.gradle
+++ b/smithy-codegen-core/build.gradle.kts
@@ -16,13 +16,11 @@
 description = "This module provides a code generation framework for generating clients, " +
         "servers, documentation, and other artifacts for various languages from Smithy models."
 
-ext {
-    displayName = "Smithy :: Code Generation Framework"
-    moduleName = "software.amazon.smithy.codegen.core"
-}
+extra["displayName"] = "Smithy :: Code Generation Framework"
+extra["moduleName"] = "software.amazon.smithy.codegen.core"
 
 dependencies {
-    api project(":smithy-utils")
-    api project(":smithy-model")
-    api project(":smithy-build")
+    api(project(":smithy-utils"))
+    api(project(":smithy-model"))
+    api(project(":smithy-build"))
 }
diff --git a/smithy-diff/build.gradle b/smithy-diff/build.gradle.kts
similarity index 82%
rename from smithy-diff/build.gradle
rename to smithy-diff/build.gradle.kts
index c50e85535..2aa8d3a00 100644
--- a/smithy-diff/build.gradle
+++ b/smithy-diff/build.gradle.kts
@@ -16,12 +16,10 @@
 description = "This module detects differences between two Smithy models, identifying " +
         "changes that are safe and changes that are backward incompatible."
 
-ext {
-    displayName = "Smithy :: Diff"
-    moduleName = "software.amazon.smithy.diff"
-}
+extra["displayName"] = "Smithy :: Diff"
+extra["moduleName"] = "software.amazon.smithy.diff"
 
 dependencies {
-    api project(":smithy-utils")
-    api project(":smithy-model")
+    api(project(":smithy-utils"))
+    api(project(":smithy-model"))
 }
diff --git a/smithy-jmespath/build.gradle b/smithy-jmespath/build.gradle.kts
similarity index 86%
rename from smithy-jmespath/build.gradle
rename to smithy-jmespath/build.gradle.kts
index 108157efd..58c218a15 100644
--- a/smithy-jmespath/build.gradle
+++ b/smithy-jmespath/build.gradle.kts
@@ -15,7 +15,5 @@
 
 description = "A standalone JMESPath parser"
 
-ext {
-    displayName = "Smithy :: JMESPath"
-    moduleName = "software.amazon.smithy.jmespath"
-}
+extra["displayName"] = "Smithy :: JMESPath"
+extra["moduleName"] = "software.amazon.smithy.jmespath"
diff --git a/smithy-jsonschema/build.gradle b/smithy-jsonschema/build.gradle.kts
similarity index 78%
rename from smithy-jsonschema/build.gradle
rename to smithy-jsonschema/build.gradle.kts
index f9a37d2db..9f53f128a 100644
--- a/smithy-jsonschema/build.gradle
+++ b/smithy-jsonschema/build.gradle.kts
@@ -15,12 +15,10 @@
 
 description = "This module contains support for converting a Smithy model to JSON Schema."
 
-ext {
-    displayName = "Smithy :: JSON Schema Conversion"
-    moduleName = "software.amazon.smithy.jsonschema"
-}
+extra["displayName"] = "Smithy :: JSON Schema Conversion"
+extra["moduleName"] = "software.amazon.smithy.jsonschema"
 
 dependencies {
-    api project(":smithy-utils")
-    api project(":smithy-model")
+    api(project(":smithy-utils"))
+    api(project(":smithy-model"))
 }
diff --git a/smithy-linters/build.gradle b/smithy-linters/build.gradle.kts
similarity index 81%
rename from smithy-linters/build.gradle
rename to smithy-linters/build.gradle.kts
index 1c0a8c90e..767e5e5b1 100644
--- a/smithy-linters/build.gradle
+++ b/smithy-linters/build.gradle.kts
@@ -16,12 +16,10 @@
 description = "This module provides support for customizable linters declared in the " +
         "metadata section of a Smithy model."
 
-ext {
-    displayName = "Smithy :: Linters"
-    moduleName = "software.amazon.smithy.linters"
-}
+extra["displayName"] = "Smithy :: Linters"
+extra["moduleName"] = "software.amazon.smithy.linters"
 
 dependencies {
-    api project(":smithy-model")
-    api project(":smithy-utils")
+    api(project(":smithy-model"))
+    api(project(":smithy-utils"))
 }
diff --git a/smithy-model/build.gradle b/smithy-model/build.gradle.kts
similarity index 72%
rename from smithy-model/build.gradle
rename to smithy-model/build.gradle.kts
index 07d7918e5..36950e4f9 100644
--- a/smithy-model/build.gradle
+++ b/smithy-model/build.gradle.kts
@@ -16,22 +16,24 @@
 description = "This module provides the core implementation of loading, validating, " +
         "traversing, mutating, and serializing a Smithy model."
 
-ext {
-    displayName = "Smithy :: Model"
-    moduleName = "software.amazon.smithy.model"
-}
+extra["displayName"] = "Smithy :: Model"
+extra["moduleName"] = "software.amazon.smithy.model"
 
-apply plugin: "me.champeau.jmh"
+plugins {
+    id("me.champeau.jmh")
+}
 
 dependencies {
-    api project(":smithy-utils")
-    jmh project(":smithy-utils")
+    api(project(":smithy-utils"))
+    jmh(project(":smithy-utils"))
 }
 
 jmh {
     timeUnit = "us"
 }
 
-processJmhResources {
-    duplicatesStrategy = DuplicatesStrategy.WARN
-}
+tasks {
+    processJmhResources {
+        duplicatesStrategy = DuplicatesStrategy.WARN
+    }
+}
\ No newline at end of file
diff --git a/smithy-mqtt-traits/build.gradle b/smithy-mqtt-traits/build.gradle.kts
similarity index 79%
rename from smithy-mqtt-traits/build.gradle
rename to smithy-mqtt-traits/build.gradle.kts
index e1709a000..8ffe3cede 100644
--- a/smithy-mqtt-traits/build.gradle
+++ b/smithy-mqtt-traits/build.gradle.kts
@@ -15,12 +15,10 @@
 
 description = "This module provides the implementation of MQTT binding traits for Smithy."
 
-ext {
-    displayName = "Smithy :: MQTT Traits"
-    moduleName = "software.amazon.smithy.mqtt.traits"
-}
+extra["displayName"] = "Smithy :: MQTT Traits"
+extra["moduleName"] = "software.amazon.smithy.mqtt.traits"
 
 dependencies {
-    api project(":smithy-utils")
-    api project(":smithy-model")
+    api(project(":smithy-utils"))
+    api(project(":smithy-model"))
 }
diff --git a/smithy-openapi-traits/build.gradle b/smithy-openapi-traits/build.gradle.kts
similarity index 62%
rename from smithy-openapi-traits/build.gradle
rename to smithy-openapi-traits/build.gradle.kts
index b671893fd..2f480a508 100644
--- a/smithy-openapi-traits/build.gradle
+++ b/smithy-openapi-traits/build.gradle.kts
@@ -5,11 +5,9 @@
 
 description = "This module provides Smithy traits that are used in converting a Smithy model to OpenAPI."
 
-ext {
-    displayName = "Smithy :: OpenAPI Traits"
-    moduleName = "software.amazon.smithy.openapi.traits"
-}
+extra["displayName"] = "Smithy :: OpenAPI Traits"
+extra["moduleName"] = "software.amazon.smithy.openapi.traits"
 
 dependencies {
-    api project(":smithy-model")
+    api(project(":smithy-model"))
 }
diff --git a/smithy-openapi/build.gradle b/smithy-openapi/build.gradle.kts
similarity index 69%
rename from smithy-openapi/build.gradle
rename to smithy-openapi/build.gradle.kts
index 5cc5ba831..8bee24615 100644
--- a/smithy-openapi/build.gradle
+++ b/smithy-openapi/build.gradle.kts
@@ -15,15 +15,13 @@
 
 description = "This module contains support for converting a Smithy model to OpenAPI."
 
-ext {
-    displayName = "Smithy :: OpenAPI Conversion"
-    moduleName = "software.amazon.smithy.openapi"
-}
+extra["displayName"] = "Smithy :: OpenAPI Conversion"
+extra["moduleName"] = "software.amazon.smithy.openapi"
 
 dependencies {
-    api project(":smithy-model")
-    api project(":smithy-build")
-    api project(":smithy-jsonschema")
-    api project(":smithy-aws-traits")
-    api project(":smithy-openapi-traits")
+    api(project(":smithy-model"))
+    api(project(":smithy-build"))
+    api(project(":smithy-jsonschema"))
+    api(project(":smithy-aws-traits"))
+    api(project(":smithy-openapi-traits"))
 }
diff --git a/smithy-protocol-traits/build.gradle b/smithy-protocol-traits/build.gradle.kts
similarity index 55%
rename from smithy-protocol-traits/build.gradle
rename to smithy-protocol-traits/build.gradle.kts
index c269a7e00..6010827ff 100644
--- a/smithy-protocol-traits/build.gradle
+++ b/smithy-protocol-traits/build.gradle.kts
@@ -5,12 +5,10 @@
 
 description = "This module provides the implementation of protocol traits for Smithy."
 
-ext {
-    displayName = "Smithy :: Protocol Traits"
-    moduleName = "software.amazon.smithy.protocol.traits"
-}
+extra["displayName"] = "Smithy :: Protocol Traits"
+extra["moduleName"] = "software.amazon.smithy.protocol.traits"
 
 dependencies {
-    api project(":smithy-utils")
-    api project(":smithy-model")
+    api(project(":smithy-utils"))
+    api(project(":smithy-model"))
 }
diff --git a/smithy-rules-engine/build.gradle b/smithy-rules-engine/build.gradle
deleted file mode 100644
index 2b8df453d..000000000
--- a/smithy-rules-engine/build.gradle
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-description = "Smithy rules engine Language and traits"
-
-ext {
-    displayName = "Smithy :: Rules Engine"
-    moduleName = "software.amazon.smithy.rulesengine"
-}
-
-dependencies {
-    api project(":smithy-model")
-    api project(":smithy-utils")
-    api project(":smithy-jmespath")
-}
diff --git a/smithy-rules-engine/build.gradle.kts b/smithy-rules-engine/build.gradle.kts
new file mode 100644
index 000000000..509386798
--- /dev/null
+++ b/smithy-rules-engine/build.gradle.kts
@@ -0,0 +1,15 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+description = "Smithy rules engine Language and traits"
+
+extra["displayName"] = "Smithy :: Rules Engine"
+extra["moduleName"] = "software.amazon.smithy.rulesengine"
+
+dependencies {
+    api(project(":smithy-model"))
+    api(project(":smithy-utils"))
+    api(project(":smithy-jmespath"))
+}
diff --git a/smithy-syntax/build.gradle b/smithy-syntax/build.gradle
deleted file mode 100644
index 68284cd33..000000000
--- a/smithy-syntax/build.gradle
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- *  http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
-
-description = "Provides a parse tree and formatter for Smithy models."
-
-ext {
-    displayName = "Smithy :: Syntax"
-    moduleName = "software.amazon.smithy.syntax"
-}
-
-dependencies {
-    api project(":smithy-utils")
-    api project(":smithy-model")
-    implementation "com.opencastsoftware:prettier4j:0.1.1"
-
-    // This is needed to export these as dependencies since we aren't shading them.
-    shadow project(":smithy-model")
-    shadow project(":smithy-utils")
-}
-
-shadowJar {
-    // Replace the normal JAR with the shaded JAR. We don't want to publish a JAR that isn't shaded.
-    archiveClassifier = ''
-
-    mergeServiceFiles()
-
-    // Shade and relocate prettier4j.
-    relocate('com.opencastsoftware.prettier4j', 'software.amazon.smithy.syntax.shaded.prettier4j')
-
-    // Despite the "shadow" configuration under dependencies, we unfortunately need to also list here that
-    // smithy-model and smithy-utils aren't shaded. These are normal dependencies that we want consumers to resolve.
-    dependencies {
-        exclude(project(':smithy-utils'))
-        exclude(project(':smithy-model'))
-    }
-}
-
-tasks['jar'].finalizedBy(tasks['shadowJar'])
diff --git a/smithy-syntax/build.gradle.kts b/smithy-syntax/build.gradle.kts
new file mode 100644
index 000000000..e68282759
--- /dev/null
+++ b/smithy-syntax/build.gradle.kts
@@ -0,0 +1,52 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+description = "Provides a parse tree and formatter for Smithy models."
+
+extra["displayName"] = "Smithy :: Syntax"
+extra["moduleName"] = "software.amazon.smithy.syntax"
+
+dependencies {
+    api(project(":smithy-utils"))
+    api(project(":smithy-model"))
+    implementation("com.opencastsoftware:prettier4j:0.1.1")
+
+    // This is needed to export these as dependencies since we aren't shading them.
+    shadow(project(":smithy-model"))
+    shadow(project(":smithy-utils"))
+}
+
+tasks {
+    shadowJar {
+        // Replace the normal JAR with the shaded JAR. We don't want to publish a JAR that isn't shaded.
+        archiveClassifier.set("")
+
+        mergeServiceFiles()
+
+        // Shade and relocate prettier4j.
+        relocate("com.opencastsoftware.prettier4j", "software.amazon.smithy.syntax.shaded.prettier4j")
+
+        // Despite the "shadow" configuration under dependencies, we unfortunately need to also list here that
+        // smithy-model and smithy-utils aren't shaded. These are normal dependencies that we want consumers to resolve.
+        dependencies {
+            exclude(project(":smithy-utils"))
+            exclude(project(":smithy-model"))
+        }
+    }
+
+    jar {
+        finalizedBy(shadowJar)
+    }
+}
\ No newline at end of file
diff --git a/smithy-trait-codegen/build.gradle b/smithy-trait-codegen/build.gradle
deleted file mode 100644
index 72408d68f..000000000
--- a/smithy-trait-codegen/build.gradle
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-description = "Plugin for Generating Trait Code from Smithy Models"
-
-ext {
-    displayName = "Smithy :: Trait Code Generation"
-    moduleName = "software.amazon.smithy.traitcodegen"
-}
-
-dependencies {
-    implementation project(":smithy-codegen-core")
-}
-
-// Set up Integration testing source sets
-sourceSets {
-    create("it") {
-        compileClasspath += sourceSets.main.output + configurations["testRuntimeClasspath"] + configurations["testCompileClasspath"]
-        runtimeClasspath += output + compileClasspath + sourceSets.test.runtimeClasspath + sourceSets.test.output
-
-        // Pull in the generated trait files
-        java {
-            srcDir("$buildDir/integ/")
-        }
-        // Add generated service provider file to resources
-        resources {
-            srcDirs += "$buildDir/generated-resources"
-        }
-    }
-}
-
-// Execute building of trait classes using an executable class
-// These traits will then be passed in to the integration test (it)
-// source set
-tasks.register("generateTraits", JavaExec) {
-    classpath = sourceSets.test.runtimeClasspath + sourceSets.test.output
-    mainClass = "software.amazon.smithy.traitcodegen.PluginExecutor"
-}
-
-// Copy generated META-INF files to a new generated-resources directory to
-// make it easy to include as resource srcDir
-def generatedMetaInf = new File("$buildDir/integ/META-INF")
-def destResourceDir = new File("$buildDir/generated-resources", "META-INF")
-tasks.register("copyGeneratedSrcs", Copy) {
-    from generatedMetaInf
-    into destResourceDir
-    dependsOn("generateTraits")
-}
-
-
-// Add the integ test task
-tasks.register("integ", Test) {
-    useJUnitPlatform()
-    testClassesDirs = sourceSets.it.output.classesDirs
-    classpath = sourceSets.it.runtimeClasspath
-}
-
-// Do not run checkstyle on generated trait classes
-tasks["checkstyleIt"].enabled = false
-
-// Force correct ordering so generated sources are available
-tasks["compileItJava"].dependsOn("generateTraits")
-tasks["compileItJava"].dependsOn("copyGeneratedSrcs")
-tasks["processItResources"].dependsOn("copyGeneratedSrcs")
-tasks["integ"].mustRunAfter("generateTraits")
-tasks["integ"].mustRunAfter("copyGeneratedSrcs")
-
-// Always run integ tests after base tests
-tasks["test"].finalizedBy("integ")
-
-// dont run spotbugs on integ tests
-tasks["spotbugsIt"].enabled(false)
diff --git a/smithy-trait-codegen/build.gradle.kts b/smithy-trait-codegen/build.gradle.kts
new file mode 100644
index 000000000..07719f8f6
--- /dev/null
+++ b/smithy-trait-codegen/build.gradle.kts
@@ -0,0 +1,89 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+description = "Plugin for Generating Trait Code from Smithy Models"
+
+extra["displayName"] = "Smithy :: Trait Code Generation"
+extra["moduleName"] = "software.amazon.smithy.traitcodegen"
+
+dependencies {
+    implementation(project(":smithy-codegen-core"))
+}
+
+// Set up Integration testing source sets
+sourceSets {
+    create("it") {
+        val main by getting
+        val test by getting
+
+        compileClasspath += main.output +
+                configurations["testRuntimeClasspath"] +
+                configurations["testCompileClasspath"]
+
+        runtimeClasspath += output +
+                compileClasspath +
+                test.runtimeClasspath +
+                test.output
+
+        java {
+            srcDir("${layout.buildDirectory.get()}/integ/")
+        }
+
+        resources {
+            srcDirs(layout.buildDirectory.dir("generated-resources").get())
+        }
+    }
+}
+
+// Execute building of trait classes using an executable class
+// These traits will then be passed in to the integration test (it)
+// source set
+tasks.register<JavaExec>("generateTraits") {
+    classpath = sourceSets.test.get().runtimeClasspath + sourceSets.test.get().output
+    mainClass.set("software.amazon.smithy.traitcodegen.PluginExecutor")
+}
+
+// Copy generated META-INF files to a new generated-resources directory to
+// make it easy to include as resource srcDir
+val generatedMetaInf = File("$buildDir/integ/META-INF")
+val destResourceDir = File("$buildDir/generated-resources/META-INF")
+tasks.register<Copy>("copyGeneratedSrcs") {
+    from(generatedMetaInf)
+    into(destResourceDir)
+    dependsOn("generateTraits")
+}
+
+// Add the integ test task
+tasks.register<Test>("integ") {
+    useJUnitPlatform()
+    testClassesDirs = sourceSets["it"].output.classesDirs
+    classpath = sourceSets["it"].runtimeClasspath
+}
+
+tasks {
+    named("checkstyleIt") {
+        enabled = false
+    }
+
+    named("compileItJava") {
+        dependsOn("generateTraits", "copyGeneratedSrcs")
+    }
+
+    named("processItResources") {
+        dependsOn("copyGeneratedSrcs")
+    }
+
+    named("integ") {
+        mustRunAfter("generateTraits", "copyGeneratedSrcs")
+    }
+
+    named("test") {
+        finalizedBy("integ")
+    }
+
+    named("spotbugsIt") {
+        enabled = false
+    }
+}
\ No newline at end of file
diff --git a/smithy-utils/build.gradle b/smithy-utils/build.gradle.kts
similarity index 86%
rename from smithy-utils/build.gradle
rename to smithy-utils/build.gradle.kts
index 0fbcbc7fc..7699b76ca 100644
--- a/smithy-utils/build.gradle
+++ b/smithy-utils/build.gradle.kts
@@ -15,7 +15,6 @@
 
 description = "This module contains utility classes and interfaces for Smithy."
 
-ext {
-    displayName = "Smithy :: Utilities"
-    moduleName = "software.amazon.smithy.utils"
-}
+extra["displayName"] = "Smithy :: Utilities"
+extra["moduleName"] = "software.amazon.smithy.utils"
+
diff --git a/smithy-validation-model/build.gradle b/smithy-validation-model/build.gradle.kts
similarity index 70%
rename from smithy-validation-model/build.gradle
rename to smithy-validation-model/build.gradle.kts
index 509a4a24f..d2ac2b936 100644
--- a/smithy-validation-model/build.gradle
+++ b/smithy-validation-model/build.gradle.kts
@@ -14,22 +14,24 @@
  */
 
 plugins {
-    id "software.amazon.smithy.gradle.smithy-jar" version "$smithyGradleVersion"
+    id("software.amazon.smithy.gradle.smithy-jar")
 }
 
 description = "This module provides support for validation in Smithy server SDKs"
 
-ext {
-    displayName = "Smithy :: Validation Support"
-    moduleName = "software.amazon.smithy.validation.model"
-}
+extra["displayName"] = "Smithy :: Validation Support"
+extra["moduleName"] = "software.amazon.smithy.validation.model"
 
 dependencies {
-    implementation project(path: ":smithy-cli", configuration: "shadow")
+    implementation(project(path = ":smithy-cli", configuration = "shadow"))
 }
 
-tasks["sourcesJar"].dependsOn("smithyJarStaging")
+tasks {
+    sourcesJar {
+        dependsOn("smithyJarStaging")
+    }
+}
 
 smithy {
     smithyBuildConfigs.set(project.files())
-}
+}
\ No newline at end of file
diff --git a/smithy-waiters/build.gradle b/smithy-waiters/build.gradle.kts
similarity index 78%
rename from smithy-waiters/build.gradle
rename to smithy-waiters/build.gradle.kts
index 435a74083..fed5565e2 100644
--- a/smithy-waiters/build.gradle
+++ b/smithy-waiters/build.gradle.kts
@@ -15,12 +15,10 @@
 
 description = "Defines Smithy waiters."
 
-ext {
-    displayName = "Smithy :: Waiters"
-    moduleName = "software.amazon.smithy.waiters"
-}
+extra["displayName"] = "Smithy :: Waiters"
+extra["moduleName"] = "software.amazon.smithy.waiters"
 
 dependencies {
-    api project(":smithy-model")
-    api project(":smithy-jmespath")
-}
+    api(project(":smithy-model"))
+    api(project(":smithy-jmespath"))
+}
\ No newline at end of file


Test patch:
diff --git a/smithy-aws-protocol-tests/build.gradle b/smithy-aws-protocol-tests/build.gradle.kts
similarity index 58%
rename from smithy-aws-protocol-tests/build.gradle
rename to smithy-aws-protocol-tests/build.gradle.kts
index e477c53f7..a03b7aa9b 100644
--- a/smithy-aws-protocol-tests/build.gradle
+++ b/smithy-aws-protocol-tests/build.gradle.kts
@@ -14,25 +14,25 @@
  */
 
 plugins {
-    id "software.amazon.smithy.gradle.smithy-jar" version "$smithyGradleVersion"
+    id("software.amazon.smithy.gradle.smithy-jar")
 }
 
 description = "Defines protocol tests for AWS HTTP protocols."
 
-ext {
-    displayName = "Smithy :: AWS :: Protocol Tests"
-    moduleName = "software.amazon.smithy.aws.protocoltests"
-}
+extra["displayName"] = "Smithy :: AWS :: Protocol Tests"
+extra["moduleName"] = "software.amazon.smithy.aws.protocoltests"
 
 dependencies {
-    implementation project(path: ":smithy-cli", configuration: "shadow")
-    implementation project(":smithy-protocol-test-traits")
-    implementation project(":smithy-protocol-traits")
-    implementation project(":smithy-aws-traits")
-    api project(":smithy-validation-model")
+    implementation(project(path = ":smithy-cli", configuration = "shadow"))
+    implementation(project(":smithy-protocol-test-traits"))
+    implementation(project(":smithy-protocol-traits"))
+    implementation(project(":smithy-aws-traits"))
+    api(project(":smithy-validation-model"))
 }
 
-tasks["sourcesJar"].dependsOn("smithyJarStaging")
+tasks.sourcesJar {
+    dependsOn("smithyJarStaging")
+}
 
 smithy {
     format.set(false)
diff --git a/smithy-aws-smoke-test-model/build.gradle b/smithy-aws-smoke-test-model/build.gradle.kts
similarity index 53%
rename from smithy-aws-smoke-test-model/build.gradle
rename to smithy-aws-smoke-test-model/build.gradle.kts
index ddc313f67..4d59232d7 100644
--- a/smithy-aws-smoke-test-model/build.gradle
+++ b/smithy-aws-smoke-test-model/build.gradle.kts
@@ -6,10 +6,10 @@
 description = "Defines shapes used by AWS for modeling smoke tests"
 
 ext {
-    displayName = "Smithy :: AWS :: Smoke Test :: Model"
-    moduleName = "software.amazon.smithy.aws.smoketest.model"
+    extra["displayName"] = "Smithy :: AWS :: Smoke Test :: Model"
+    extra["moduleName"] = "software.amazon.smithy.aws.smoketest.model"
 }
 
 dependencies {
-    api project(":smithy-smoke-test-traits")
+    api(project(":smithy-smoke-test-traits"))
 }
diff --git a/smithy-protocol-test-traits/build.gradle b/smithy-protocol-test-traits/build.gradle.kts
similarity index 80%
rename from smithy-protocol-test-traits/build.gradle
rename to smithy-protocol-test-traits/build.gradle.kts
index d2ac79edb..1e1c1f4a5 100644
--- a/smithy-protocol-test-traits/build.gradle
+++ b/smithy-protocol-test-traits/build.gradle.kts
@@ -15,11 +15,9 @@
 
 description = "Defines protocol test traits."
 
-ext {
-    displayName = "Smithy :: Protocol Test Traits"
-    moduleName = "software.amazon.smithy.protocoltest.traits"
-}
+extra["displayName"] = "Smithy :: Protocol Test Traits"
+extra["moduleName"] = "software.amazon.smithy.protocoltest.traits"
 
 dependencies {
-    api project(":smithy-model")
+    api(project(":smithy-model"))
 }
diff --git a/smithy-protocol-tests/build.gradle b/smithy-protocol-tests/build.gradle
deleted file mode 100644
index b27bd37cc..000000000
--- a/smithy-protocol-tests/build.gradle
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0
- */
-
-plugins {
-    id "software.amazon.smithy.gradle.smithy-jar" version "$smithyGradleVersion"
-}
-
-description = "Defines protocol tests for Smithy HTTP protocols."
-
-ext {
-    displayName = "Smithy :: Protocol Tests"
-    moduleName = "software.amazon.smithy.protocoltests"
-}
-
-dependencies {
-    implementation project(path: ":smithy-cli", configuration: "shadow")
-    implementation project(":smithy-protocol-test-traits")
-    implementation project(":smithy-protocol-traits")
-    api project(":smithy-validation-model")
-}
-
-tasks["sourcesJar"].dependsOn("smithyJarStaging")
-
-smithy {
-    format.set(false)
-    smithyBuildConfigs.set(project.files())
-}
diff --git a/smithy-protocol-tests/build.gradle.kts b/smithy-protocol-tests/build.gradle.kts
new file mode 100644
index 000000000..5912f06aa
--- /dev/null
+++ b/smithy-protocol-tests/build.gradle.kts
@@ -0,0 +1,31 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+plugins {
+    id("software.amazon.smithy.gradle.smithy-jar")
+}
+
+description = "Defines protocol tests for Smithy HTTP protocols."
+
+extra["displayName"] = "Smithy :: Protocol Tests"
+extra["moduleName"] = "software.amazon.smithy.protocoltests"
+
+dependencies {
+    implementation(project(path= ":smithy-cli", configuration= "shadow"))
+    implementation(project(":smithy-protocol-test-traits"))
+    implementation(project(":smithy-protocol-traits"))
+    api(project(":smithy-validation-model"))
+}
+
+tasks{
+    sourcesJar {
+        dependsOn("smithyJarStaging")
+    }
+}
+
+smithy {
+    format.set(false)
+    smithyBuildConfigs.set(project.files())
+}
diff --git a/smithy-smoke-test-traits/build.gradle b/smithy-smoke-test-traits/build.gradle.kts
similarity index 80%
rename from smithy-smoke-test-traits/build.gradle
rename to smithy-smoke-test-traits/build.gradle.kts
index 0dd359c84..7254c3353 100644
--- a/smithy-smoke-test-traits/build.gradle
+++ b/smithy-smoke-test-traits/build.gradle.kts
@@ -15,11 +15,9 @@
 
 description = "Defines smoke test traits."
 
-ext {
-    displayName = "Smithy :: Smoke Test Traits"
-    moduleName = "software.amazon.smithy.smoketest.traits"
-}
+extra["displayName"] = "Smithy :: Smoke Test Traits"
+extra["moduleName"] = "software.amazon.smithy.smoketest.traits"
 
 dependencies {
-    api project(":smithy-model")
+    api(project(":smithy-model"))
 }