diff --git a/build-plugins/build.gradle.kts b/build-plugins/build.gradle.kts index d9b7e9f..8880a07 100644 --- a/build-plugins/build.gradle.kts +++ b/build-plugins/build.gradle.kts @@ -23,6 +23,8 @@ repositories { dependencies { implementation(gradleApi()) implementation(kotlin("gradle-plugin", "1.8.22")) + // make our custom lint rules available to the buildscript classpath + runtimeOnly(project(":ktlint-rules")) } group = "aws.sdk.kotlin" diff --git a/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/dsl/CodeStyle.kt b/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/dsl/CodeStyle.kt new file mode 100644 index 0000000..1bdfe0c --- /dev/null +++ b/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/dsl/CodeStyle.kt @@ -0,0 +1,54 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.sdk.kotlin.gradle.dsl + +import aws.sdk.kotlin.gradle.util.verifyRootProject +import org.gradle.api.Project +import org.gradle.api.attributes.Bundling +import org.gradle.api.tasks.JavaExec +import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.named +import org.gradle.kotlin.dsl.register + +/** + * Configure lint rules for the project + * @param lintPaths list of paths relative to the project root to lint (or not lint). + */ +fun Project.configureLinting(lintPaths: List) { + verifyRootProject { "Kotlin SDK lint configuration is expected to be configured on the root project" } + + val ktlint = configurations.create("ktlint") { + attributes { + attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) + } + } + + // TODO - is there anyway to align this with the version from libs.versions.toml in this project/repo + val ktlintVersion = "0.48.1" + dependencies { + ktlint("com.pinterest:ktlint:$ktlintVersion") + } + + // add the buildscript classpath which should pickup our custom ktlint-rules (via runtimeOnly dep on this plugin) + // plus any custom rules added by consumer + val execKtlintClaspath = ktlint + buildscript.configurations.getByName("classpath") + tasks.register("ktlint") { + description = "Check Kotlin code style." + group = "Verification" + classpath = execKtlintClaspath + mainClass.set("com.pinterest.ktlint.Main") + args = lintPaths + jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED") + } + + tasks.register("ktlintFormat") { + description = "Auto fix Kotlin code style violations" + group = "formatting" + classpath = execKtlintClaspath + mainClass.set("com.pinterest.ktlint.Main") + args = listOf("-F") + lintPaths + jvmArgs("--add-opens", "java.base/java.lang=ALL-UNNAMED") + } +} diff --git a/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/KmpDefaultsPlugin.kt b/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/KmpDefaultsPlugin.kt index a5d46de..39cebfe 100644 --- a/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/KmpDefaultsPlugin.kt +++ b/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/KmpDefaultsPlugin.kt @@ -4,6 +4,7 @@ */ package aws.sdk.kotlin.gradle.kmp +import aws.sdk.kotlin.gradle.util.verifyRootProject import org.gradle.api.Plugin import org.gradle.api.Project @@ -15,7 +16,10 @@ import org.gradle.api.Project */ class KmpDefaultsPlugin : Plugin { override fun apply(target: Project) { - target.logger.info("applying kmp defaults plugin to $target") - target.configureKmpTargets() + with(target) { + logger.info("applying kmp defaults plugin to $target") + verifyRootProject { "AWS SDK KmpDefaultsPlugin requires installation into root project" } + configureKmpTargets() + } } } diff --git a/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/KmpProjectExt.kt b/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/KmpProjectExt.kt new file mode 100644 index 0000000..8d100ec --- /dev/null +++ b/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/KmpProjectExt.kt @@ -0,0 +1,19 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package aws.sdk.kotlin.gradle.kmp + +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.the +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension + +/** + * Allows configuration from parent projects subprojects/allprojects block when they haven't configured the KMP + * plugin but the subproject has applied it. The extension is otherwise not visible. + */ +fun Project.kotlin(block: KotlinMultiplatformExtension.() -> Unit) { + configure(block) +} +val Project.kotlin: KotlinMultiplatformExtension get() = the() diff --git a/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/ProjectExt.kt b/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/util/ProjectExt.kt similarity index 78% rename from build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/ProjectExt.kt rename to build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/util/ProjectExt.kt index 1ae216b..e0fd4a5 100644 --- a/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/kmp/ProjectExt.kt +++ b/build-plugins/src/main/kotlin/aws/sdk/kotlin/gradle/util/ProjectExt.kt @@ -2,26 +2,15 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -package aws.sdk.kotlin.gradle.kmp +package aws.sdk.kotlin.gradle.util +import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.api.plugins.ExtraPropertiesExtension -import org.gradle.kotlin.dsl.configure import org.gradle.kotlin.dsl.extra -import org.gradle.kotlin.dsl.the -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import java.io.File import java.util.* -/** - * Allows configuration from parent projects subprojects/allprojects block when they haven't configured the KMP - * plugin but the subproject has applied it. The extension is otherwise not visible. - */ -fun Project.kotlin(block: KotlinMultiplatformExtension.() -> Unit) { - configure(block) -} -val Project.kotlin: KotlinMultiplatformExtension get() = the() - public fun ExtraPropertiesExtension.getOrNull(name: String): T? { if (!has(name)) return null @Suppress("UNCHECKED_CAST") @@ -68,3 +57,12 @@ inline fun Project.typedProp(name: String): T? { else -> error("unknown type ${T::class} for property $name") } } + +public inline fun Project.verifyRootProject(lazyMessage: () -> Any) { + if (rootProject != this) { + val message = lazyMessage() + throw AwsSdkGradleException(message.toString()) + } +} + +class AwsSdkGradleException(message: String) : GradleException(message) diff --git a/build.gradle.kts b/build.gradle.kts index acd23f5..fa11e52 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,6 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ allprojects { + group = "aws.sdk.kotlin" + repositories { mavenCentral() } diff --git a/ktlint-rules/build.gradle.kts b/ktlint-rules/build.gradle.kts index 9e13c58..a7f59dc 100644 --- a/ktlint-rules/build.gradle.kts +++ b/ktlint-rules/build.gradle.kts @@ -1,3 +1,9 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + /* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 @@ -11,16 +17,27 @@ plugins { kotlin { sourceSets { - val main by getting { + main { dependencies { implementation(libs.ktlint.core) } } - val test by getting { + test { dependencies { implementation(libs.ktlint.test) } } } } + +tasks.withType { + kotlinOptions { + jvmTarget = "1.8" + } +} + +tasks.withType { + sourceCompatibility = JavaVersion.VERSION_1_8.toString() + targetCompatibility = JavaVersion.VERSION_1_8.toString() +}