Unverified Commit ad133fd3 authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Resolve runtime crate versions from manifests first (#3351)

This PR changes codegen-core's build-time runtime crate version
resolution to pull versions from the actual runtime crate manifest
files, only changing them to the version numbers in gradle.properties if
they use the special `0.0.0-smithy-rs-head` version number. This is a
prerequisite step in allowing independent crate versioning.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
parent b2b91af4
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -100,8 +100,7 @@ fun generateSmithyBuild(services: AwsServices): String {
                "plugins": {
                    "rust-client-codegen": {
                        "runtimeConfig": {
                            "relativePath": "../",
                            "version": "DEFAULT"
                            "relativePath": "../"
                        },
                        "codegen": {
                            "includeFluentClient": false,
+5 −2
Original line number Diff line number Diff line
@@ -15,8 +15,11 @@ fun rewriteCrateVersion(
    )

/**
 * Smithy runtime crate versions in smithy-rs are all `0.0.0-smithy-rs-head`. When copying over to the AWS SDK,
 * these should be changed to the smithy-rs version.
 * Dependently versioned Smithy runtime crate versions in smithy-rs are all `0.0.0-smithy-rs-head`.
 * When copying over to the AWS SDK, these should be changed to the corresponding
 * stable/unstable runtime crate version from gradle.properties.
 *
 * In the future when all the runtime crates are independently versioned, this can be removed.
 */
fun rewriteRuntimeCrateVersion(
    version: String,
+53 −34
Original line number Diff line number Diff line
@@ -53,47 +53,66 @@ fun gitCommitHash(): String {
}

val generateSmithyRuntimeCrateVersion by tasks.registering {
    fun kv(key: String, value: String) = "\"$key\": \"$value\""
    // generate the version of the runtime to use as a resource.
    // this keeps us from having to manually change version numbers in multiple places
    // Generate the version of the runtime to use as a resource.
    // This keeps us from having to manually change version numbers in multiple places.
    val resourcesDir = layout.buildDirectory.dir("resources/main/software/amazon/smithy/rust/codegen/core")
    val versionFile = resourcesDir.get().file("runtime-crate-version.txt")
    outputs.file(versionFile)
    val versionsFile = resourcesDir.get().file("runtime-crate-versions.json")
    outputs.file(versionsFile)

    val stableCrateVersion = project.properties["smithy.rs.runtime.crate.stable.version"].toString()
    val unstableCrateVersion = project.properties["smithy.rs.runtime.crate.unstable.version"].toString()
    inputs.property("crateVersion", stableCrateVersion)
    // version format must be in sync with `software.amazon.smithy.rust.codegen.core.Version`
    val version = StringBuilder().append("{")
    version.append(kv("githash", gitCommitHash())).append(",")
    version.append(kv("stableVersion", stableCrateVersion)).append(",")
    version.append(kv("unstableVersion", unstableCrateVersion)).append(",")
    // hack for internal build
    val smithyStableCrates = listOf(
        // AWS crates
        "aws-config",
        "aws-credential-types",
        "aws-runtime",
        "aws-runtime-api",
        "aws-sigv4",
        "aws-types",

        // smithy crates
        "aws-smithy-async",
        "aws-smithy-runtime-api",
        "aws-smithy-runtime",
        "aws-smithy-types",
    )
    inputs.property("stableCrateVersion", stableCrateVersion)
    inputs.property("unstableCrateVersion", stableCrateVersion)

    val runtimeCrates =
        smithyStableCrates.joinToString(separator = ",", prefix = "{", postfix = "}") { crate ->
            kv(crate, stableCrateVersion)
    val cargoTomls = mutableListOf<File>()
    for (runtimePath in arrayOf("../rust-runtime", "../aws/rust-runtime")) {
        for (path in project.projectDir.resolve(runtimePath).listFiles()!!) {
            val manifestPath = path.resolve("Cargo.toml")
            if (manifestPath.exists()) {
                cargoTomls.add(manifestPath)
                inputs.file(manifestPath)
            }
        }
    }

    version.append(""""runtimeCrates": $runtimeCrates""").append("}")

    sourceSets.main.get().output.dir(resourcesDir)
    doLast {
        versionFile.asFile.writeText(version.toString())
        // Version format must be kept in sync with `software.amazon.smithy.rust.codegen.core.Version`
        versionsFile.asFile.writeText(
            StringBuilder().append("{\n").also { json ->
                fun StringBuilder.keyVal(key: String, value: String) = append("\"$key\": \"$value\"")

                json.append("  ").keyVal("gitHash", gitCommitHash()).append(",\n")
                json.append("  \"runtimeCrates\": {\n")
                json.append(
                    cargoTomls.map { path ->
                        path.parentFile.name to path.readLines()
                    }
                        .filter { (name, manifestLines) ->
                            val publish = manifestLines.none { line -> line == "publish = false" }
                            // HACK: The experimental/unpublished typescript runtime crate needs
                            // to be included since it is referenced by the code generator and tested in CI.
                            publish || name == "aws-smithy-http-server-typescript"
                        }
                        .map { (name, manifestLines) ->
                            val stable = manifestLines.any { line -> line == "stable = true" }
                            val versionLine = manifestLines.first { line -> line.startsWith("version = \"") }
                            val maybeVersion = versionLine.slice(("version = \"".length)..(versionLine.length - 2))
                            val version = if (maybeVersion == "0.0.0-smithy-rs-head") {
                                when (stable) {
                                    true -> stableCrateVersion
                                    else -> unstableCrateVersion
                                }
                            } else {
                                maybeVersion
                            }
                            "    \"$name\": \"$version\""
                        }
                        .joinToString(",\n"),
                )
                json.append("  }\n")
            }.append("}").toString(),
        )
    }
}

+4 −18
Original line number Diff line number Diff line
@@ -9,41 +9,27 @@ import software.amazon.smithy.codegen.core.CodegenException
import software.amazon.smithy.model.node.Node

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

data class Version(
    val fullVersion: String,
    val stableCrateVersion: String,
    val unstableCrateVersion: String,
    val gitHash: String,
    val crates: Map<String, String>,
) {
    companion object {
        // Version must be in the "{smithy_rs_version}\n{git_commit_hash}" format
        fun parse(content: String): Version {
            val node = Node.parse(content).expectObjectNode()
            val githash = node.expectStringMember("githash").value
            val stableVersion = node.expectStringMember("stableVersion").value
            val unstableVersion = node.expectStringMember("unstableVersion").value
            return Version(
                "$stableVersion-$githash",
                stableCrateVersion = stableVersion,
                unstableCrateVersion = unstableVersion,
                node.expectStringMember("gitHash").value,
                node.expectObjectMember("runtimeCrates").members.map {
                    it.key.value to it.value.expectStringNode().value
                }.toMap(),
            )
        }

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

        fun stableCrateVersion(): String = fromDefaultResource().stableCrateVersion

        fun unstableCrateVersion(): String = fromDefaultResource().unstableCrateVersion

        fun crateVersion(crate: String): String {
            val version = fromDefaultResource()
            return version.crates[crate] ?: version.unstableCrateVersion
            return version.crates[crate] ?: throw CodegenException("unknown version number for runtime crate $crate")
        }

        fun fromDefaultResource(): Version =
+0 −11
Original line number Diff line number Diff line
@@ -5,7 +5,6 @@

package software.amazon.smithy.rust.codegen.core.smithy

import software.amazon.smithy.codegen.core.CodegenException
import software.amazon.smithy.codegen.core.Symbol
import software.amazon.smithy.model.node.Node
import software.amazon.smithy.model.node.ObjectNode
@@ -27,8 +26,6 @@ import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.util.orNull
import java.util.Optional

private const val DEFAULT_KEY = "DEFAULT"

/**
 * Location of the runtime crates (aws-smithy-http, aws-smithy-types etc.)
 *
@@ -53,14 +50,6 @@ fun RuntimeCrateLocation.crateLocation(crateName: String): DependencyLocation {
    }
}

fun defaultRuntimeCrateVersion(): String {
    try {
        return Version.stableCrateVersion()
    } catch (ex: Exception) {
        throw CodegenException("failed to get crate version which sets the default client-runtime version", ex)
    }
}

/**
 * A mapping from crate name to a user-specified version.
 */
Loading