Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .github/actions/minor-version-bump/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Minor version bump
description: Verifies branch is ready to merge before minor version bump
runs:
using: composite
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Configure Gradle
uses: awslabs/aws-kotlin-repo-tools/.github/actions/configure-gradle@main

- name: Verify minor version bump
shell: bash
run: ./gradlew verifyMinorVersionBump
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fun Project.configureLinting(lintPaths: List<String>) {
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.SHADOWED))
}
}
ktlint("aws.sdk.kotlin.gradle:ktlint-rules:$repoToolsVersion")
ktlint("aws.sdk.kotlin.gradle:style-rules:$repoToolsVersion")
}

// add the buildscript classpath which should pick up our custom ktlint-rules (via runtimeOnly dep on this plugin)
Expand Down
Original file line number Diff line number Diff line change
@@ -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.artifacts.VersionCatalogsExtension
import org.gradle.api.attributes.Bundling
import org.gradle.api.tasks.JavaExec
import org.gradle.kotlin.dsl.*
import org.gradle.kotlin.dsl.getByType
import org.gradle.language.base.plugins.LifecycleBasePlugin

/**
* Configures Gradle task for minor-version-bump-specific Ktlint rules.
*/
fun Project.configureMinorVersionStrategyRules(lintPaths: List<String>) {
verifyRootProject { "Task configuration is expected to be configured on the root project" }

val ktlintVersion = object {} // Can't use Project.javaClass because that's using the Gradle classloader
.javaClass
.getResource("ktlint-version.txt")
?.readText()
?: error("Missing ktlint-version.txt")

val repoToolsVersion = extensions
.getByType<VersionCatalogsExtension>()
.named("libs")
.findVersion("aws-kotlin-repo-tools-version")
.get()
.requiredVersion

val minorVersionBumpKtlint by configurations.creating

dependencies {
minorVersionBumpKtlint("com.pinterest.ktlint:ktlint-cli:$ktlintVersion") {
attributes {
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.SHADOWED))
}
}
minorVersionBumpKtlint("aws.sdk.kotlin.gradle:minor-version-rules:$repoToolsVersion")
}

tasks.register<JavaExec>("verifyMinorVersionBump") {
group = LifecycleBasePlugin.VERIFICATION_GROUP
description = "Check minor version bump rules"
classpath = minorVersionBumpKtlint
mainClass.set("com.pinterest.ktlint.Main")
args = lintPaths
}
}
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ dependencies {
}
}

ktlint(project(":ktlint-rules"))
ktlint(project(":ktlint:style-rules"))
}

val lintPaths = listOf(
Expand Down
1 change: 0 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ aws-sdk-cloudwatch = { module = "aws.sdk.kotlin:cloudwatch", version.ref = "aws-
aws-sdk-s3 = { module = "aws.sdk.kotlin:s3", version.ref = "aws-sdk-version" }
ktlint-cli = { module = "com.pinterest.ktlint:ktlint-cli", version.ref = "ktlint" }
ktlint-cli-ruleset-core = { module = "com.pinterest.ktlint:ktlint-cli-ruleset-core", version.ref = "ktlint" }
ktlint-test = {module = "com.pinterest.ktlint:ktlint-test", version.ref = "ktlint" }
nexus-publish-plugin = { module = "io.github.gradle-nexus:publish-plugin", version.ref = "nexus-plugin-version" }
jreleaser-plugin = { module = "org.jreleaser:jreleaser-gradle-plugin", version.ref = "jreleaser-plugin-version" }
smithy-model = { module = "software.amazon.smithy:smithy-model", version.ref = "smithy-version" }
Expand Down
59 changes: 59 additions & 0 deletions ktlint/minor-version-rules/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

description = "Lint rules for minor version bumps"

plugins {
`maven-publish`
kotlin("jvm")
}

kotlin {
sourceSets {
main {
dependencies {
implementation(libs.ktlint.cli.ruleset.core)
}
}

test {
dependencies {
implementation(kotlin("test"))
}
}
}
}

tasks.test {
testLogging {
events("passed", "skipped", "failed")
showStandardStreams = true
showStackTraces = true
showExceptions = true
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}

tasks.withType<KotlinCompile> {
compilerOptions {
jvmTarget.set(JvmTarget.JVM_1_8)
freeCompilerArgs.add("-Xjdk-release=1.8")
}
}

tasks.withType<JavaCompile> {
sourceCompatibility = JavaVersion.VERSION_1_8.toString()
targetCompatibility = JavaVersion.VERSION_1_8.toString()
}

publishing {
publications {
create<MavenPublication>("ktlintRules") {
from(components["kotlin"])
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.aws.ktlint.rules

import com.pinterest.ktlint.rule.engine.core.api.ElementType
import com.pinterest.ktlint.rule.engine.core.api.Rule
import com.pinterest.ktlint.rule.engine.core.api.RuleId
import org.jetbrains.kotlin.com.intellij.lang.ASTNode
import java.io.File
import java.util.Properties

/**
* Matches @DeprecatedUntilVersion with either named args (major=x, minor=y) or positional args (x, y)
*/
internal fun deprecatedUntilVersionRegex(major: Int, minor: Int): Regex =
Regex(
"""@DeprecatedUntilVersion\s*\(\s*(?:major\s*=\s*$major\s*,\s*minor\s*=\s*$minor\s*|\s*$major\s*,\s*$minor\s*)\s*\)""",
)

/**
* Creates a ktlint rule that detects APIs annotated with @DeprecatedUntilVersion for the upcoming minor version.
*/
class DeprecatedApiRule : Rule(RuleId("minor-version-strategy-rules:deprecated-apis"), About()) {
override fun beforeVisitChildNodes(
node: ASTNode,
autoCorrect: Boolean,
emit: (offset: Int, errorMessage: String, canBeAutoCorrected: Boolean) -> Unit,
) {
if (node.elementType == ElementType.ANNOTATION_ENTRY) {
val gradleProperties = Properties().apply {
load(File("gradle.properties").inputStream())
}

val sdkVersion = gradleProperties.getProperty("sdkVersion").split(".")
val majorVersion = sdkVersion[0].toInt()
val minorVersion = sdkVersion[1].toInt()

val regex = deprecatedUntilVersionRegex(majorVersion, minorVersion + 1)
if (regex.containsMatchIn(node.text)) {
emit(
node.startOffset,
"The deprecated API is scheduled for removal, please remove it before releasing the next minor version.",
true,
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
package software.aws.ktlint.rules

import com.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3
import com.pinterest.ktlint.rule.engine.core.api.RuleProvider
import com.pinterest.ktlint.rule.engine.core.api.RuleSetId

class MinorVersionRuleSetProvider : RuleSetProviderV3(RuleSetId("minor-version-strategy-rules")) {
override fun getRuleProviders() = setOf(
RuleProvider { DeprecatedApiRule() },
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

software.aws.ktlint.rules.MinorVersionRuleSetProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/

package software.aws.ktlint.rules

import kotlin.test.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue

class DeprecatedApiRuleTest {
fun runRegexTestCases(minor: Int, major: Int) {
val regex = deprecatedUntilVersionRegex(major, minor)

assertTrue(regex.containsMatchIn("@DeprecatedUntilVersion($major,$minor)"))
assertTrue(regex.containsMatchIn("@DeprecatedUntilVersion($major,$minor )"))
assertTrue(regex.containsMatchIn("@DeprecatedUntilVersion($major, $minor)"))
assertTrue(regex.containsMatchIn("@DeprecatedUntilVersion($major ,$minor)"))
assertTrue(regex.containsMatchIn("@DeprecatedUntilVersion( $major,$minor)"))
assertTrue(regex.containsMatchIn("@DeprecatedUntilVersion( $major , $minor )"))
assertTrue(regex.containsMatchIn("@DeprecatedUntilVersion(major=$major,minor=$minor)"))
assertTrue(regex.containsMatchIn("@DeprecatedUntilVersion( major= $major , minor= $minor )"))

assertFalse(regex.containsMatchIn("@DeprecatedUntilVersion"))
assertFalse(regex.containsMatchIn("@DeprecatedUntilVersion()"))
assertFalse(regex.containsMatchIn("@DeprecatedUntilVersion($minor,$minor)"))
assertFalse(regex.containsMatchIn("@DeprecatedUntilVersion($major,$major)"))
assertFalse(regex.containsMatchIn("@DeprecatedUntilVersion($minor,$major)"))
}

@Test
fun testRegex() {
runRegexTestCases(0, 1)
runRegexTestCases(1, 70)
runRegexTestCases(100, 1_000_000)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,6 @@ kotlin {
implementation(libs.ktlint.cli.ruleset.core)
}
}

test {
dependencies {
implementation(libs.ktlint.test)
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.pinterest.ktlint.cli.ruleset.core.api.RuleSetProviderV3
import com.pinterest.ktlint.rule.engine.core.api.RuleProvider
import com.pinterest.ktlint.rule.engine.core.api.RuleSetId

class CustomRuleSetProvider : RuleSetProviderV3(RuleSetId("aws-kotlin-repo-tools-rules")) {
class StyleRuleSetProvider : RuleSetProviderV3(RuleSetId("aws-kotlin-repo-tools-rules")) {
override fun getRuleProviders() = setOf(
RuleProvider { CopyrightHeaderRule() },
RuleProvider { ExpressionBodyRule() },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

software.aws.ktlint.rules.CustomRuleSetProvider
software.aws.ktlint.rules.StyleRuleSetProvider
3 changes: 2 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ dependencyResolutionManagement {
include(":build-plugins:build-support")
include(":build-plugins:kmp-conventions")
include(":build-plugins:smithy-build")
include(":ktlint-rules")
include(":ktlint:style-rules")
include(":ktlint:minor-version-rules")
Loading