mirror of https://github.com/smithy-lang/smithy-rs
Set MSRV in rust-toolchain.toml using the gradle.property (#3841)
The `rust-toolchain.toml` file for tests now uses the `rust.msrv` value from the `gradle.properties` file. This PR also fixes an issue where the `rust-toolchain.toml` file was not created in the overridden test directory when `overrideTestDir` was set. This caused the installed compiler version to be used, resulting in errors with the latest compiler and preventing the use of `overrideTestDir`. Closes: #2048 --------- Co-authored-by: Fahad Zubair <fahadzub@amazon.com>
This commit is contained in:
parent
abd28bc71e
commit
684c15f39c
|
@ -40,9 +40,11 @@ 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.absolutePathString
|
||||
import kotlin.io.path.writeText
|
||||
|
||||
|
@ -54,6 +56,8 @@ val TestModuleDocProvider =
|
|||
}
|
||||
}
|
||||
|
||||
val projectRootDir by lazy { File("git rev-parse --show-toplevel".runCommand().replace("\n", "")) }
|
||||
|
||||
/**
|
||||
* Waiting for Kotlin to stabilize their temp directory functionality
|
||||
*/
|
||||
|
@ -65,6 +69,38 @@ 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")
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
private fun File.generateRustToolchainToml() {
|
||||
resolve("rust-toolchain.toml").writeText(
|
||||
// Help rust select the right version when we run cargo test.
|
||||
"""
|
||||
[toolchain]
|
||||
channel = "${msrv()}"
|
||||
""".trimIndent(),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Cargo workspace shared among all tests
|
||||
*
|
||||
|
@ -87,8 +123,7 @@ object TestWorkspace {
|
|||
private val subprojects = mutableListOf<String>()
|
||||
|
||||
private val cargoLock: File by lazy {
|
||||
val projectDir = "git rev-parse --show-toplevel".runCommand().replace("\n", "")
|
||||
File(projectDir).resolve("aws/sdk/Cargo.lock")
|
||||
projectRootDir.resolve("aws/sdk/Cargo.lock")
|
||||
}
|
||||
|
||||
init {
|
||||
|
@ -121,12 +156,7 @@ object TestWorkspace {
|
|||
version = "0.0.1"
|
||||
""".trimIndent(),
|
||||
)
|
||||
newProject.resolve("rust-toolchain.toml").writeText(
|
||||
// help rust select the right version when we run cargo test
|
||||
// TODO(https://github.com/smithy-lang/smithy-rs/issues/2048): load this from the msrv property using a
|
||||
// method as we do for runtime crate versions
|
||||
"[toolchain]\nchannel = \"1.78.0\"\n",
|
||||
)
|
||||
newProject.generateRustToolchainToml()
|
||||
// ensure there at least an empty lib.rs file to avoid broken crates
|
||||
newProject.resolve("src").mkdirs()
|
||||
newProject.resolve("src/lib.rs").writeText("")
|
||||
|
@ -181,7 +211,11 @@ fun generatePluginContext(
|
|||
runtimeConfig: RuntimeConfig? = null,
|
||||
overrideTestDir: File? = null,
|
||||
): Pair<PluginContext, Path> {
|
||||
val testDir = overrideTestDir ?: TestWorkspace.subproject()
|
||||
val testDir =
|
||||
overrideTestDir?.apply {
|
||||
mkdirs()
|
||||
generateRustToolchainToml()
|
||||
} ?: TestWorkspace.subproject()
|
||||
val moduleName = "test_${testDir.nameWithoutExtension}"
|
||||
val testPath = testDir.toPath()
|
||||
val manifest = FileManifest.create(testPath)
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package software.amazon.smithy.rust.codegen.core.util
|
||||
|
||||
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.testutil.asSmithyModel
|
||||
import software.amazon.smithy.rust.codegen.core.testutil.generatePluginContext
|
||||
import software.amazon.smithy.rust.codegen.core.testutil.projectRootDir
|
||||
import java.nio.file.Files.createTempDirectory
|
||||
import java.util.regex.Pattern
|
||||
|
||||
internal class RustToolChainTomlTest {
|
||||
val model =
|
||||
"""
|
||||
namespace test
|
||||
|
||||
service TestService {
|
||||
version: "123",
|
||||
operations: [TestOperation]
|
||||
}
|
||||
|
||||
operation TestOperation {
|
||||
input:= {}
|
||||
output:= {}
|
||||
}
|
||||
""".asSmithyModel(smithyVersion = "2")
|
||||
|
||||
@Test
|
||||
fun `override test directory in integration test has a rust-toolchain toml file`() {
|
||||
val dir = createTempDirectory("smithy-test").toFile()
|
||||
val (_, path) = generatePluginContext(model, overrideTestDir = dir)
|
||||
path.shouldExist()
|
||||
val rustToolchainTomlPath = path.resolve("rust-toolchain.toml")
|
||||
rustToolchainTomlPath.shouldExist()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `rust-toolchain toml file has correct value from gradle properties for rust-msrv`() {
|
||||
val (_, path) = generatePluginContext(model)
|
||||
val rustToolchainTomlPath = path.resolve("rust-toolchain.toml")
|
||||
rustToolchainTomlPath.shouldExist()
|
||||
|
||||
// Read the MSRV written in `gradle.properties` file.
|
||||
val msrvPattern = Pattern.compile("rust\\.msrv=(.+)")
|
||||
val gradlePropertiesPath = projectRootDir.resolve("gradle.properties")
|
||||
val msrv =
|
||||
gradlePropertiesPath.useLines { lines ->
|
||||
lines.firstNotNullOfOrNull { line ->
|
||||
msrvPattern.matcher(line).let { matcher ->
|
||||
if (matcher.find()) matcher.group(1) else null
|
||||
}
|
||||
}
|
||||
}
|
||||
msrv shouldNotBe null
|
||||
|
||||
// Read `channel = (\d+)` from `rust-toolchain.toml` file, and
|
||||
// ensure it matches the one in `gradle.properties`.
|
||||
val toolchainPattern = Pattern.compile("\\[toolchain]")
|
||||
val channelPattern = Pattern.compile("channel\\s*=\\s*\"(.+)\"")
|
||||
|
||||
val channelMatches =
|
||||
rustToolchainTomlPath.toFile().useLines { lines ->
|
||||
// Skip lines until the [toolchain] table is found, then take all lines until the next table.
|
||||
val toolchainSection =
|
||||
lines
|
||||
.dropWhile { !toolchainPattern.matcher(it).find() }
|
||||
.drop(1)
|
||||
.takeWhile { !it.trim().startsWith("[") }
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
channelMatches.shouldBeTrue()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue