Skip to content

Commit e850447

Browse files
authored
feat: remove deprecated shapes since one date until another date (#1100)
1 parent bfd5dec commit e850447

File tree

5 files changed

+128
-2
lines changed

5 files changed

+128
-2
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"id": "c79af2ed-bfad-4196-bf5c-87d647ecbcd1",
3+
"type": "feature",
4+
"description": "**BREAKING**: Remove operations/fields which were marked deprecated before 11/28/2023. See [this discussion post](https://github.com/awslabs/aws-sdk-kotlin/discussions/1103) for more details.",
5+
"requiresMinorVersionBump": true
6+
}

codegen/sdk/build.gradle.kts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fun awsServiceProjections(): Provider<List<SmithyProjection>> {
112112
importPaths.add(service.modelExtrasDir)
113113
}
114114
imports = importPaths
115-
transforms = transformsForService(service) ?: emptyList()
115+
transforms = (transformsForService(service) ?: emptyList()) + removeDeprecatedShapesTransform("2023-11-28")
116116

117117
smithyKotlinPlugin {
118118
serviceShapeId = service.serviceShapeId
@@ -155,6 +155,15 @@ fun transformsForService(service: AwsService): List<String>? {
155155
}
156156
}
157157

158+
fun removeDeprecatedShapesTransform(removeDeprecatedShapesUntil: String): String = """
159+
{
160+
"name": "AwsSdkKotlinRemoveDeprecatedShapes",
161+
"args": {
162+
"until": "$removeDeprecatedShapesUntil"
163+
}
164+
}
165+
""".trimIndent()
166+
158167
val discoveredServices: List<AwsService> by lazy { discoverServices() }
159168

160169
// The root namespace prefix for SDKs
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package aws.sdk.kotlin.codegen.transforms
6+
7+
import software.amazon.smithy.build.TransformContext
8+
import software.amazon.smithy.build.transforms.ConfigurableProjectionTransformer
9+
import software.amazon.smithy.kotlin.codegen.model.getTrait
10+
import software.amazon.smithy.kotlin.codegen.utils.getOrNull
11+
import software.amazon.smithy.model.Model
12+
import software.amazon.smithy.model.shapes.Shape
13+
import software.amazon.smithy.model.traits.DeprecatedTrait
14+
import java.time.DateTimeException
15+
import java.time.LocalDate
16+
import java.time.format.DateTimeFormatter
17+
import java.util.function.Predicate
18+
19+
// A date formatter used to parse Smithy @deprecated trait's `since` field
20+
private val DEPRECATED_SINCE_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd")
21+
22+
class RemoveDeprecatedShapes : ConfigurableProjectionTransformer<RemoveDeprecatedShapes.Config>() {
23+
class Config {
24+
var until: String = "1970-01-01" // yyyy-MM-dd
25+
}
26+
27+
override fun getName(): String = "AwsSdkKotlinRemoveDeprecatedShapes"
28+
29+
override fun getConfigType(): Class<Config> = Config::class.java
30+
31+
/**
32+
* Filter out shapes which have a [DeprecatedTrait] with a `since` property _date_ set, up to [Config.until].
33+
* NOTE: Smithy supports modeling `since` as a version _or_ date, this transformer only considers those modeled as a date.
34+
*/
35+
override fun transformWithConfig(context: TransformContext, config: Config): Model {
36+
val until = requireNotNull(config.until.toLocalDate()) { "Failed to parse configured `until` date ${config.until}" }
37+
println("Removing deprecated shapes using the configured `until` date $until")
38+
39+
return context.transformer.removeShapesIf(context.model, shouldRemoveDeprecatedShape(until))
40+
}
41+
}
42+
43+
internal fun shouldRemoveDeprecatedShape(removeDeprecatedShapesUntil: LocalDate) = Predicate<Shape> { shape ->
44+
val since = shape.getTrait<DeprecatedTrait>()?.since?.getOrNull() ?: return@Predicate false
45+
46+
val deprecatedDate = since.toLocalDate() ?: return@Predicate false.also {
47+
println("Failed to parse `since` field $since as a date, skipping removal of deprecated shape $shape")
48+
}
49+
50+
deprecatedDate < removeDeprecatedShapesUntil
51+
}
52+
53+
/**
54+
* Parses a string of yyyy-MM-dd format to [LocalDate], returning `null` if parsing fails.
55+
*/
56+
internal fun String.toLocalDate(): LocalDate? = try { LocalDate.parse(this, DEPRECATED_SINCE_DATE_FORMATTER) } catch (e: DateTimeException) { null }
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
aws.sdk.kotlin.codegen.transforms.IncludeOperations
1+
aws.sdk.kotlin.codegen.transforms.IncludeOperations
2+
aws.sdk.kotlin.codegen.transforms.RemoveDeprecatedShapes
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package aws.sdk.kotlin.codegen.transforms
6+
7+
import software.amazon.smithy.model.shapes.FloatShape
8+
import software.amazon.smithy.model.shapes.Shape
9+
import software.amazon.smithy.model.shapes.ShapeId
10+
import software.amazon.smithy.model.traits.DeprecatedTrait
11+
import kotlin.test.Test
12+
import kotlin.test.assertFalse
13+
import kotlin.test.assertTrue
14+
15+
class RemoveDeprecatedShapesTest {
16+
private fun shapeDeprecatedSince(since: String?): Shape {
17+
val deprecatedTrait = DeprecatedTrait.builder()
18+
.since(since)
19+
.build()
20+
21+
return FloatShape.builder()
22+
.addTrait(deprecatedTrait)
23+
.id(ShapeId.from("aws.sdk.kotlin#testing"))
24+
.build()
25+
}
26+
27+
@Test
28+
fun testShouldBeRemoved() {
29+
val shape = shapeDeprecatedSince("2022-01-01")
30+
val removeDeprecatedShapesUntil = "2023-01-01".toLocalDate()!!
31+
assertTrue(shouldRemoveDeprecatedShape(removeDeprecatedShapesUntil).test(shape))
32+
}
33+
34+
@Test
35+
fun testShouldNotBeRemoved() {
36+
val shape = shapeDeprecatedSince("2024-01-01")
37+
val removeDeprecatedShapesUntil = "2023-01-01".toLocalDate()!!
38+
assertFalse(shouldRemoveDeprecatedShape(removeDeprecatedShapesUntil).test(shape))
39+
}
40+
41+
@Test
42+
fun testShouldNotBeRemovedIfDeprecatedSameDay() {
43+
val shape = shapeDeprecatedSince("2023-01-01")
44+
val removeDeprecatedShapesUntil = "2023-01-01".toLocalDate()!!
45+
assertFalse(shouldRemoveDeprecatedShape(removeDeprecatedShapesUntil).test(shape))
46+
}
47+
48+
@Test
49+
fun testShouldNotBeRemovedIfMissingSinceField() {
50+
val shape = shapeDeprecatedSince(null)
51+
val removeDeprecatedShapesUntil = "2023-01-01".toLocalDate()!!
52+
assertFalse(shouldRemoveDeprecatedShape(removeDeprecatedShapesUntil).test(shape))
53+
}
54+
}

0 commit comments

Comments
 (0)