Skip to content

Commit

Permalink
Generate MSRV in Kotlin file (#3869)
Browse files Browse the repository at this point in the history
Currently, when generating Rust crates, the MSRV is read from
`gradle.properties` by determining the project root using `git
rev-parse`. However, some build environments smithy-rs needs to build on
don't have `git` available.

This commit uses Gradle's `rootDir` to determine the project root, and
generates a Kotlin file exposing the MSRV as part of a Gradle build task
that is then published as part of `codegen-core.jar`. This also has the
benefit that consumers of smithy-rs can read the MSRV from there.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
  • Loading branch information
david-perez authored Oct 10, 2024
1 parent 2470341 commit e6b154b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 24 deletions.
40 changes: 40 additions & 0 deletions codegen-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import java.io.ByteArrayOutputStream
import java.util.Properties

plugins {
kotlin("jvm")
Expand Down Expand Up @@ -53,6 +54,44 @@ fun gitCommitHash(): String {
}
}

// Define the directory where the generated Kotlin file will be placed
val generatedSrcDir = layout.buildDirectory.dir("generated/src/main/kotlin")

sourceSets {
main {
kotlin {
srcDir(generatedSrcDir)
}
}
}

val generateBuildEnvironmentConstants = tasks.register("generateBuildEnvironmentConstants") {
// Specify that the task generates sources.
val outputDir = generatedSrcDir.get().asFile
outputs.dir(outputDir)

doLast {
// Load properties from `gradle.properties`.
val properties = Properties()
val gradlePropertiesFile = file("${rootDir}/gradle.properties")
properties.load(gradlePropertiesFile.inputStream())

val rustMsrv = properties.getProperty("rust.msrv")

// Generate the Kotlin file.
val generatedFile = file("$outputDir/BuildEnvironment.kt")
generatedFile.writeText("""
// This file is automatically generated. Do not modify manually.
package software.amazon.smithy.rust.codegen.core.generated
object BuildEnvironment {
const val MSRV: String = "$rustMsrv"
const val PROJECT_DIR: String = "$rootDir"
}
""".trimIndent())
}
}

val generateSmithyRuntimeCrateVersion by tasks.registering {
// Generate the version of the runtime to use as a resource.
// This keeps us from having to manually change version numbers in multiple places.
Expand Down Expand Up @@ -125,6 +164,7 @@ java {
tasks.compileKotlin {
kotlinOptions.jvmTarget = "11"
dependsOn(generateSmithyRuntimeCrateVersion)
dependsOn(generateBuildEnvironmentConstants)
}

// Reusable license copySpec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import software.amazon.smithy.model.loader.ModelAssembler
import software.amazon.smithy.model.node.Node
import software.amazon.smithy.model.node.ObjectNode
import software.amazon.smithy.model.shapes.ShapeId
import software.amazon.smithy.rust.codegen.core.generated.BuildEnvironment
import software.amazon.smithy.rust.codegen.core.rustlang.Attribute
import software.amazon.smithy.rust.codegen.core.rustlang.CargoDependency
import software.amazon.smithy.rust.codegen.core.rustlang.DependencyScope
Expand All @@ -40,11 +41,10 @@ import software.amazon.smithy.rust.codegen.core.util.letIf
import software.amazon.smithy.rust.codegen.core.util.orNullIfEmpty
import software.amazon.smithy.rust.codegen.core.util.runCommand
import java.io.File
import java.io.FileInputStream
import java.nio.file.Files
import java.nio.file.Files.createTempDirectory
import java.nio.file.Path
import java.util.Properties
import kotlin.io.path.Path
import kotlin.io.path.absolutePathString
import kotlin.io.path.writeText

Expand All @@ -56,8 +56,6 @@ val TestModuleDocProvider =
}
}

val projectRootDir by lazy { File("git rev-parse --show-toplevel".runCommand().replace("\n", "")) }

/**
* Waiting for Kotlin to stabilize their temp directory functionality
*/
Expand All @@ -73,23 +71,14 @@ private fun tempDir(directory: File? = null): File {
* This function returns the minimum supported Rust version, as specified in the `gradle.properties` file
* located at the root of the project.
*/
fun msrv(): String {
val properties = Properties()
val propertiesFilePath = projectRootDir.resolve("gradle.properties")

FileInputStream(propertiesFilePath).use { inputStream ->
properties.load(inputStream)
}

return properties.getProperty("rust.msrv")
}
fun msrv(): String = BuildEnvironment.MSRV

/**
* Generates the `rust-toolchain.toml` file in the specified directory.
*
* The compiler version is set in `gradle.properties` under the `rust.msrv` property.
* The Gradle task `GenerateMsrvTask` generates the Kotlin class
* `software.amazon.smithy.rust.codegen.core.Msrv` and writes the value of `rust.msrv` into it.
* The Gradle task `generateRustMsrvFile` generates the Kotlin class
* `software.amazon.smithy.rust.codegen.core.generated.RustMsrv.kt` and writes the value of `rust.msrv` into it.
*/
private fun File.generateRustToolchainToml() {
resolve("rust-toolchain.toml").writeText(
Expand Down Expand Up @@ -123,7 +112,7 @@ object TestWorkspace {
private val subprojects = mutableListOf<String>()

private val cargoLock: File by lazy {
projectRootDir.resolve("aws/sdk/Cargo.lock")
File(BuildEnvironment.PROJECT_DIR).resolve("aws/sdk/Cargo.lock")
}

init {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import io.kotest.matchers.booleans.shouldBeTrue
import io.kotest.matchers.paths.shouldExist
import io.kotest.matchers.shouldNotBe
import org.junit.jupiter.api.Test
import software.amazon.smithy.rust.codegen.core.generated.BuildEnvironment
import software.amazon.smithy.rust.codegen.core.testutil.asSmithyModel
import software.amazon.smithy.rust.codegen.core.testutil.generatePluginContext
import software.amazon.smithy.rust.codegen.core.testutil.projectRootDir
import java.io.File
import java.nio.file.Files.createTempDirectory
import java.util.regex.Pattern

Expand Down Expand Up @@ -48,7 +49,7 @@ internal class RustToolChainTomlTest {

// Read the MSRV written in `gradle.properties` file.
val msrvPattern = Pattern.compile("rust\\.msrv=(.+)")
val gradlePropertiesPath = projectRootDir.resolve("gradle.properties")
val gradlePropertiesPath = File(BuildEnvironment.PROJECT_DIR).resolve("gradle.properties")
val msrv =
gradlePropertiesPath.useLines { lines ->
lines.firstNotNullOfOrNull { line ->
Expand All @@ -75,12 +76,11 @@ internal class RustToolChainTomlTest {

// There should be a [toolchain] table, and it must have a key called 'channel' whose value must
// match the `rust.msrv` specified in gradle.properties.
toolchainSection != null &&
toolchainSection.any { line ->
channelPattern.matcher(line).let { matcher ->
matcher.find() && matcher.group(1) == msrv
}
toolchainSection.any { line ->
channelPattern.matcher(line).let { matcher ->
matcher.find() && matcher.group(1) == msrv
}
}
}

channelMatches.shouldBeTrue()
Expand Down

0 comments on commit e6b154b

Please sign in to comment.