Skip to content

Commit edab8cf

Browse files
authored
Fix runtime crate versions (#3260)
## Motivation and Context When the stable/unstable crate versions were split, this caused a regression in determining the crate version during codegen. This enhances our crate-version forwarding code to publish all the crate versions. For impact, see codegen-client-test. ## Description - Change the build artifact to be a JSON blob will all required versions. ## Testing - [ ] Audit diff ## Checklist <!--- If a checkbox below is not applicable, then please DELETE it rather than leaving it unchecked --> - [ ] I have updated `CHANGELOG.next.toml` if I made changes to the smithy-rs codegen or runtime crates - [ ] I have updated `CHANGELOG.next.toml` if I made changes to the AWS SDK, generated SDK code, or SDK runtime crates ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._
1 parent eb61ae3 commit edab8cf

File tree

9 files changed

+94
-151
lines changed

9 files changed

+94
-151
lines changed

aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/AwsCargoDependency.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import software.amazon.smithy.rust.codegen.core.smithy.RuntimeConfig
1010
import software.amazon.smithy.rust.codegen.core.smithy.crateLocation
1111

1212
fun RuntimeConfig.awsRuntimeCrate(name: String, features: Set<String> = setOf()): CargoDependency =
13-
CargoDependency(name, awsRoot().crateLocation(null), features = features)
13+
CargoDependency(name, awsRoot().crateLocation(name), features = features)
1414

1515
object AwsCargoDependency {
1616
fun awsConfig(runtimeConfig: RuntimeConfig) = runtimeConfig.awsRuntimeCrate("aws-config")

buildSrc/src/main/kotlin/CrateSet.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,6 @@ object CrateSet {
7979
)
8080

8181
val ENTIRE_SMITHY_RUNTIME = (AWS_SDK_SMITHY_RUNTIME + SERVER_SMITHY_RUNTIME).toSortedSet(compareBy { it.name })
82+
83+
val ALL_CRATES = AWS_SDK_RUNTIME + ENTIRE_SMITHY_RUNTIME
8284
}

codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/config/ServiceConfigGenerator.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,7 @@ class ServiceConfigGenerator(
476476
docs("Apply test defaults to the builder")
477477
rustBlock("pub fn apply_test_defaults(&mut self) -> &mut Self") {
478478
customizations.forEach { it.section(ServiceConfig.DefaultForTests("self"))(this) }
479+
rustTemplate("self.behavior_version = #{Some}(crate::config::BehaviorVersion::latest());", *preludeScope)
479480
rust("self")
480481
}
481482

codegen-core/build.gradle.kts

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,18 +53,47 @@ fun gitCommitHash(): String {
5353
}
5454

5555
val generateSmithyRuntimeCrateVersion by tasks.registering {
56+
fun kv(key: String, value: String) = "\"$key\": \"$value\""
5657
// generate the version of the runtime to use as a resource.
5758
// this keeps us from having to manually change version numbers in multiple places
5859
val resourcesDir = "$buildDir/resources/main/software/amazon/smithy/rust/codegen/core"
5960
val versionFile = file("$resourcesDir/runtime-crate-version.txt")
6061
outputs.file(versionFile)
61-
val crateVersion = project.properties["smithy.rs.runtime.crate.version"].toString()
62-
inputs.property("crateVersion", crateVersion)
62+
val stableCrateVersion = project.properties["smithy.rs.runtime.crate.stable.version"].toString()
63+
val unstableCrateVersion = project.properties["smithy.rs.runtime.crate.unstable.version"].toString()
64+
inputs.property("crateVersion", stableCrateVersion)
6365
// version format must be in sync with `software.amazon.smithy.rust.codegen.core.Version`
64-
val version = "$crateVersion\n${gitCommitHash()}"
66+
val version = StringBuilder().append("{")
67+
version.append(kv("githash", gitCommitHash())).append(",")
68+
version.append(kv("stableVersion", stableCrateVersion)).append(",")
69+
version.append(kv("unstableVersion", unstableCrateVersion)).append(",")
70+
// hack for internal build
71+
val smithyStableCrates = listOf(
72+
// AWS crates
73+
"aws-config",
74+
"aws-credential-types",
75+
"aws-runtime",
76+
"aws-runtime-api",
77+
"aws-sigv4",
78+
"aws-types",
79+
80+
// smithy crates
81+
"aws-smithy-async",
82+
"aws-smithy-runtime-api",
83+
"aws-smithy-runtime",
84+
"aws-smithy-types",
85+
)
86+
87+
val runtimeCrates =
88+
smithyStableCrates.joinToString(separator = ",", prefix = "{", postfix = "}") { crate ->
89+
kv(crate, stableCrateVersion)
90+
}
91+
92+
version.append(""""runtimeCrates": $runtimeCrates""").append("}")
93+
6594
sourceSets.main.get().output.dir(resourcesDir)
6695
doLast {
67-
versionFile.writeText(version)
96+
versionFile.writeText(version.toString())
6897
}
6998
}
7099

codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/Version.kt

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,49 @@
66
package software.amazon.smithy.rust.codegen.core
77

88
import software.amazon.smithy.codegen.core.CodegenException
9+
import software.amazon.smithy.model.node.Node
910

1011
// generated as part of the build, see codegen-core/build.gradle.kts
1112
private const val VERSION_FILENAME = "runtime-crate-version.txt"
1213

13-
data class Version(val fullVersion: String, val crateVersion: String) {
14+
data class Version(
15+
val fullVersion: String,
16+
val stableCrateVersion: String,
17+
val unstableCrateVersion: String,
18+
val crates: Map<String, String>,
19+
) {
1420
companion object {
1521
// Version must be in the "{smithy_rs_version}\n{git_commit_hash}" format
1622
fun parse(content: String): Version {
17-
val lines = content.lines()
18-
if (lines.size != 2) {
19-
throw IllegalArgumentException("Invalid version format, it should contain `2` lines but contains `${lines.size}` line(s)")
20-
}
21-
return Version(lines.joinToString("-"), lines.first())
23+
val node = Node.parse(content).expectObjectNode()
24+
val githash = node.expectStringMember("githash").value
25+
val stableVersion = node.expectStringMember("stableVersion").value
26+
val unstableVersion = node.expectStringMember("unstableVersion").value
27+
return Version(
28+
"$stableVersion-$githash",
29+
stableCrateVersion = stableVersion,
30+
unstableCrateVersion = unstableVersion,
31+
node.expectObjectMember("runtimeCrates").members.map {
32+
it.key.value to it.value.expectStringNode().value
33+
}.toMap(),
34+
)
2235
}
2336

2437
// Returns full version in the "{smithy_rs_version}-{git_commit_hash}" format
2538
fun fullVersion(): String =
2639
fromDefaultResource().fullVersion
2740

28-
fun crateVersion(): String =
29-
fromDefaultResource().crateVersion
41+
fun stableCrateVersion(): String =
42+
fromDefaultResource().stableCrateVersion
3043

31-
private fun fromDefaultResource(): Version = parse(
44+
fun unstableCrateVersion(): String =
45+
fromDefaultResource().unstableCrateVersion
46+
47+
fun crateVersion(crate: String): String {
48+
val version = fromDefaultResource()
49+
return version.crates[crate] ?: version.unstableCrateVersion
50+
}
51+
fun fromDefaultResource(): Version = parse(
3252
Version::class.java.getResource(VERSION_FILENAME)?.readText()
3353
?: throw CodegenException("$VERSION_FILENAME does not exist"),
3454
)

codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,21 @@ data class RuntimeCrateLocation(val path: String?, val versions: CrateVersionMap
4040
}
4141
}
4242

43-
fun RuntimeCrateLocation.crateLocation(crateName: String?): DependencyLocation {
44-
val version = crateName.let { versions.map[crateName] } ?: versions.map[DEFAULT_KEY]
43+
fun RuntimeCrateLocation.crateLocation(crateName: String): DependencyLocation {
44+
val version = crateName.let {
45+
versions.map[crateName]
46+
} ?: Version.crateVersion(crateName)
4547
return when (this.path) {
4648
// CratesIo needs an exact version. However, for local runtime crates we do not
4749
// provide a detected version unless the user explicitly sets one via the `versions` map.
48-
null -> CratesIo(version ?: defaultRuntimeCrateVersion())
49-
else -> Local(this.path, version)
50+
null -> CratesIo(version)
51+
else -> Local(this.path)
5052
}
5153
}
5254

5355
fun defaultRuntimeCrateVersion(): String {
5456
try {
55-
return Version.crateVersion()
57+
return Version.stableCrateVersion()
5658
} catch (ex: Exception) {
5759
throw CodegenException("failed to get crate version which sets the default client-runtime version", ex)
5860
}
@@ -94,10 +96,6 @@ data class RuntimeConfig(
9496
}
9597
}
9698

97-
val crateSrcPrefix: String = cratePrefix.replace("-", "_")
98-
99-
fun runtimeCratesPath(): String? = runtimeCrateLocation.path
100-
10199
fun smithyRuntimeCrate(
102100
runtimeCrateName: String,
103101
optional: Boolean = false,
@@ -324,7 +322,9 @@ data class RuntimeType(val path: String, val dependency: RustDependency? = null)
324322
fun smithyQuery(runtimeConfig: RuntimeConfig) = CargoDependency.smithyQuery(runtimeConfig).toType()
325323
fun smithyRuntime(runtimeConfig: RuntimeConfig) = CargoDependency.smithyRuntime(runtimeConfig).toType()
326324
fun smithyRuntimeApi(runtimeConfig: RuntimeConfig) = CargoDependency.smithyRuntimeApi(runtimeConfig).toType()
327-
fun smithyRuntimeApiClient(runtimeConfig: RuntimeConfig) = CargoDependency.smithyRuntimeApiClient(runtimeConfig).toType()
325+
fun smithyRuntimeApiClient(runtimeConfig: RuntimeConfig) =
326+
CargoDependency.smithyRuntimeApiClient(runtimeConfig).toType()
327+
328328
fun smithyTypes(runtimeConfig: RuntimeConfig) = CargoDependency.smithyTypes(runtimeConfig).toType()
329329
fun smithyXml(runtimeConfig: RuntimeConfig) = CargoDependency.smithyXml(runtimeConfig).toType()
330330
private fun smithyProtocolTest(runtimeConfig: RuntimeConfig) =

codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/VersionTest.kt

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class VersionTest {
2121
) {
2222
val version = Version.parse(content)
2323
version.fullVersion shouldBe fullVersion
24-
version.crateVersion shouldBe crateVersion
24+
version.stableCrateVersion shouldBe crateVersion
2525
}
2626

2727
@ParameterizedTest()
@@ -36,30 +36,15 @@ class VersionTest {
3636
@JvmStatic
3737
fun versionProvider() = listOf(
3838
Arguments.of(
39-
"0.47.0\n0198d26096eb1af510ce24766c921ffc5e4c191e",
40-
"0.47.0-0198d26096eb1af510ce24766c921ffc5e4c191e",
41-
"0.47.0",
39+
"""{ "stableVersion": "1.0.1", "unstableVersion": "0.60.1","githash": "0198d26096eb1af510ce24766c921ffc5e4c191e", "runtimeCrates": {} }""",
40+
"1.0.1-0198d26096eb1af510ce24766c921ffc5e4c191e",
41+
"1.0.1",
4242
),
4343
Arguments.of(
44-
"release-2022-08-04\ndb48039065bec890ef387385773b37154b555b14",
44+
"""{ "unstableVersion": "0.60.1", "stableVersion": "release-2022-08-04", "githash": "db48039065bec890ef387385773b37154b555b14", "runtimeCrates": {} }""",
4545
"release-2022-08-04-db48039065bec890ef387385773b37154b555b14",
4646
"release-2022-08-04",
4747
),
48-
Arguments.of(
49-
"0.30.0-alpha\na1dbbe2947de3c8bbbef9446eb442e298f83f200",
50-
"0.30.0-alpha-a1dbbe2947de3c8bbbef9446eb442e298f83f200",
51-
"0.30.0-alpha",
52-
),
53-
Arguments.of(
54-
"0.6-rc1.cargo\nc281800a185b34600b05f8b501a0322074184123",
55-
"0.6-rc1.cargo-c281800a185b34600b05f8b501a0322074184123",
56-
"0.6-rc1.cargo",
57-
),
58-
Arguments.of(
59-
"0.27.0-alpha.1\n643f2ee",
60-
"0.27.0-alpha.1-643f2ee",
61-
"0.27.0-alpha.1",
62-
),
6348
)
6449

6550
@JvmStatic

codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeTypeTest.kt

Lines changed: 12 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import org.junit.jupiter.params.ParameterizedTest
1111
import org.junit.jupiter.params.provider.Arguments
1212
import org.junit.jupiter.params.provider.MethodSource
1313
import software.amazon.smithy.model.node.Node
14+
import software.amazon.smithy.rust.codegen.core.Version
1415
import software.amazon.smithy.rust.codegen.core.rustlang.CratesIo
15-
import software.amazon.smithy.rust.codegen.core.rustlang.DependencyLocation
1616
import software.amazon.smithy.rust.codegen.core.rustlang.Local
1717
import java.util.Optional
1818

@@ -35,22 +35,20 @@ class RuntimeTypesTest {
3535
cfg.runtimeCrateLocation shouldBe RuntimeCrateLocation(null, CrateVersionMap(mapOf()))
3636
}
3737

38-
@ParameterizedTest
39-
@MethodSource("runtimeCrateLocationProvider")
40-
fun `runtimeCrateLocation provides dependency location`(
41-
path: String?,
42-
versions: CrateVersionMap,
43-
crateName: String?,
44-
expectedDependencyLocation: DependencyLocation,
45-
) {
46-
val crateLoc = RuntimeCrateLocation(path, versions)
47-
val depLoc = crateLoc.crateLocation(crateName)
48-
depLoc shouldBe expectedDependencyLocation
38+
@Test
39+
fun `runtimeCrateLocation provides dependency location`() {
40+
val crateLoc = RuntimeCrateLocation("/foo", CrateVersionMap(mapOf("aws-smithy-runtime-api" to "999.999")))
41+
crateLoc.crateLocation("aws-smithy-runtime") shouldBe Local("/foo", null)
42+
crateLoc.crateLocation("aws-smithy-runtime-api") shouldBe Local("/foo", null)
43+
crateLoc.crateLocation("aws-smithy-http") shouldBe Local("/foo", null)
44+
45+
val crateLocVersioned = RuntimeCrateLocation(null, CrateVersionMap(mapOf("aws-smithy-runtime-api" to "999.999")))
46+
crateLocVersioned.crateLocation("aws-smithy-runtime") shouldBe CratesIo(Version.stableCrateVersion())
47+
crateLocVersioned.crateLocation("aws-smithy-runtime-api") shouldBe CratesIo("999.999")
48+
crateLocVersioned.crateLocation("aws-smithy-http") shouldBe CratesIo(Version.unstableCrateVersion())
4949
}
5050

5151
companion object {
52-
@JvmStatic
53-
private val defaultVersion = defaultRuntimeCrateVersion()
5452

5553
@JvmStatic
5654
fun runtimeConfigProvider() = listOf(
@@ -90,97 +88,5 @@ class RuntimeTypesTest {
9088
RuntimeCrateLocation("/path", CrateVersionMap(mapOf("a" to "1.0", "b" to "2.0"))),
9189
),
9290
)
93-
94-
@JvmStatic
95-
fun runtimeCrateLocationProvider() = listOf(
96-
// If user specifies `relativePath` in `runtimeConfig`, then that always takes precedence over versions.
97-
Arguments.of(
98-
"/path",
99-
mapOf<String, String>(),
100-
null,
101-
Local("/path"),
102-
),
103-
Arguments.of(
104-
"/path",
105-
mapOf("a" to "1.0", "b" to "2.0"),
106-
null,
107-
Local("/path"),
108-
),
109-
Arguments.of(
110-
"/path",
111-
mapOf("DEFAULT" to "0.1", "a" to "1.0", "b" to "2.0"),
112-
null,
113-
Local("/path", "0.1"),
114-
),
115-
116-
// User does not specify the versions object.
117-
// The version number of the code-generator should be used as the version for all runtime crates.
118-
Arguments.of(
119-
null,
120-
mapOf<String, String>(),
121-
null,
122-
CratesIo(defaultVersion),
123-
),
124-
Arguments.of(
125-
null,
126-
mapOf<String, String>(),
127-
"a",
128-
CratesIo(defaultVersion),
129-
),
130-
131-
// User specifies versions object, setting explicit version numbers for some runtime crates.
132-
// Then the rest of the runtime crates use the code-generator's version as their version.
133-
Arguments.of(
134-
null,
135-
mapOf("a" to "1.0", "b" to "2.0"),
136-
null,
137-
CratesIo(defaultVersion),
138-
),
139-
Arguments.of(
140-
null,
141-
mapOf("a" to "1.0", "b" to "2.0"),
142-
"a",
143-
CratesIo("1.0"),
144-
),
145-
Arguments.of(
146-
null,
147-
mapOf("a" to "1.0", "b" to "2.0"),
148-
"b",
149-
CratesIo("2.0"),
150-
),
151-
Arguments.of(
152-
null,
153-
mapOf("a" to "1.0", "b" to "2.0"),
154-
"c",
155-
CratesIo(defaultVersion),
156-
),
157-
158-
// User specifies versions object, setting DEFAULT and setting version numbers for some runtime crates.
159-
// Then the specified version in DEFAULT is used for all runtime crates, except for those where the user specified a value for in the map.
160-
Arguments.of(
161-
null,
162-
mapOf("DEFAULT" to "0.1", "a" to "1.0", "b" to "2.0"),
163-
null,
164-
CratesIo("0.1"),
165-
),
166-
Arguments.of(
167-
null,
168-
mapOf("DEFAULT" to "0.1", "a" to "1.0", "b" to "2.0"),
169-
"a",
170-
CratesIo("1.0"),
171-
),
172-
Arguments.of(
173-
null,
174-
mapOf("DEFAULT" to "0.1", "a" to "1.0", "b" to "2.0"),
175-
"b",
176-
CratesIo("2.0"),
177-
),
178-
Arguments.of(
179-
null,
180-
mapOf("DEFAULT" to "0.1", "a" to "1.0", "b" to "2.0"),
181-
"c",
182-
CratesIo("0.1"),
183-
),
184-
)
18591
}
18692
}

codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerModuleGenerator.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ class PythonServerModuleGenerator(
237237

238238
// Render the codegeneration version as module attribute.
239239
private fun RustWriter.renderCodegenVersion() {
240-
rust("""m.add("CODEGEN_VERSION", "${Version.crateVersion()}")?;""")
240+
rust("""m.add("CODEGEN_VERSION", "${Version.stableCrateVersion()}")?;""")
241241
}
242242

243243
// Convert to symbol and check the namespace to figure out where they should be imported from.

0 commit comments

Comments
 (0)