Skip to content

Commit

Permalink
Fix re-export of SdkError (#2931)
Browse files Browse the repository at this point in the history
  • Loading branch information
aws-sdk-rust-ci authored Aug 22, 2023
2 parents 9570983 + 790de79 commit 9943a1f
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 165 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
name: Acquire Base Image
needs: save-docker-login-token
if: ${{ github.event.pull_request.head.repo.full_name == 'awslabs/smithy-rs' }}
runs-on: ubuntu-latest
runs-on: smithy_ubuntu-latest_8-core
env:
ENCRYPTED_DOCKER_PASSWORD: ${{ needs.save-docker-login-token.outputs.docker-login-password }}
DOCKER_LOGIN_TOKEN_PASSPHRASE: ${{ secrets.DOCKER_LOGIN_TOKEN_PASSPHRASE }}
Expand Down
15 changes: 14 additions & 1 deletion .github/workflows/update-sdk-next.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
# This workflow updates the `next` branch with freshly generated
# code from the latest smithy-rs and models that reside in aws-sdk-rust.

# Allow only one release to run at a time
concurrency:
group: update-aws-sdk-next
cancel-in-progress: true

name: Update `aws-sdk-rust/next`
on:
workflow_dispatch:
inputs:
generate_ref:
description: |
Which branch/commit/tag of smithy-rs to use to generate aws-sdk-rust/next. Defaults to `main`.
required: true
type: string
default: main

jobs:
update-next:
Expand All @@ -13,7 +26,7 @@ jobs:
uses: actions/checkout@v3
with:
repository: awslabs/smithy-rs
ref: main
ref: ${{ inputs.generate_ref }}
path: smithy-rs
- name: Check out `aws-sdk-rust`
uses: actions/checkout@v3
Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,18 @@ references = ["smithy-rs#2907", "aws-sdk-rust#864"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
author = "jdisanti"

[[aws-sdk-rust]]
message = "Fixed re-exported `SdkError` type. The previous release had the wrong type for `SdkError`, which caused projects to fail to compile when upgrading."
references = ["smithy-rs#2931", "aws-sdk-rust#875"]
meta = { "breaking" = true, "tada" = false, "bug" = true }
author = "jdisanti"

[[smithy-rs]]
message = "Fixed re-exported `SdkError` type. The previous release had the wrong type for `SdkError` when generating code for orchestrator mode, which caused projects to fail to compile when upgrading."
references = ["smithy-rs#2931", "aws-sdk-rust#875"]
meta = { "breaking" = true, "tada" = false, "bug" = true, "target" = "client" }
author = "jdisanti"

[[smithy-rs]]
message = "Logging via `#[instrument]` in the `aws_smithy_runtime::client::orchestrator` module is now emitted at the `DEBUG` level to reduce the amount of logging when emitted at the `INFO` level."
references = ["smithy-rs#2934", "aws-sdk-rust#872"]
Expand Down
23 changes: 6 additions & 17 deletions aws/sdk/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* SPDX-License-Identifier: Apache-2.0
*/

import aws.sdk.AwsExamplesLayout
import aws.sdk.AwsServices
import aws.sdk.Membership
import aws.sdk.discoverServices
Expand Down Expand Up @@ -246,22 +245,12 @@ tasks.register<ExecRustBuildTool>("fixExampleManifests") {

toolPath = sdkVersionerToolPath
binaryName = "sdk-versioner"
arguments = when (AwsExamplesLayout.detect(project)) {
AwsExamplesLayout.Flat -> listOf(
"use-path-and-version-dependencies",
"--isolate-crates",
"--sdk-path", "../../sdk",
"--versions-toml", outputDir.resolve("versions.toml").absolutePath,
outputDir.resolve("examples").absolutePath,
)
AwsExamplesLayout.Workspaces -> listOf(
"use-path-and-version-dependencies",
"--isolate-crates",
"--sdk-path", sdkOutputDir.absolutePath,
"--versions-toml", outputDir.resolve("versions.toml").absolutePath,
outputDir.resolve("examples").absolutePath,
)
}
arguments = listOf(
"use-path-and-version-dependencies",
"--sdk-path", sdkOutputDir.absolutePath,
"--versions-toml", outputDir.resolve("versions.toml").absolutePath,
outputDir.resolve("examples").absolutePath,
)

outputs.dir(outputDir)
dependsOn("relocateExamples", "generateVersionManifest")
Expand Down
44 changes: 3 additions & 41 deletions buildSrc/src/main/kotlin/aws/sdk/ServiceLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,6 @@ data class RootTest(
val manifestName: String,
)

// TODO(https://github.com/awslabs/smithy-rs/issues/2810): We can remove the `Flat` layout after the switch
// to `Workspaces` has been released. This can be checked by looking at the `examples/` directory in aws-sdk-rust's
// main branch.
//
// The `Flat` layout is retained for backwards compatibility so that the next release process can succeed.
enum class AwsExamplesLayout {
/**
* Directory layout for examples used prior to June 26, 2023,
* where each example was in the `rust_dev_preview/` root directory and
* was considered to be its own workspace.
*
* This layout had issues with CI in terms of time to compile and disk space required
* since the dependencies would get recompiled for every example.
*/
Flat,

/**
* Current directory layout where there are a small number of workspaces
* rooted in `rust_dev_preview/`.
*/
Workspaces,
;

companion object {
fun detect(project: Project): AwsExamplesLayout = if (project.projectDir.resolve("examples/Cargo.toml").exists()) {
AwsExamplesLayout.Flat
} else {
AwsExamplesLayout.Workspaces
}
}
}

class AwsServices(
private val project: Project,
services: List<AwsService>,
Expand All @@ -77,15 +45,9 @@ class AwsServices(

val examples: List<String> by lazy {
val examplesRoot = project.projectDir.resolve("examples")
if (AwsExamplesLayout.detect(project) == AwsExamplesLayout.Flat) {
examplesRoot.listFiles { file -> !file.name.startsWith(".") }.orEmpty().toList()
.filter { file -> manifestCompatibleWithGeneratedServices(file) }
.map { "examples/${it.name}" }
} else {
examplesRoot.listFiles { file ->
!file.name.startsWith(".") && file.isDirectory() && file.resolve("Cargo.toml").exists()
}.orEmpty().toList().map { "examples/${it.name}" }
}
examplesRoot.listFiles { file ->
!file.name.startsWith(".") && file.isDirectory() && file.resolve("Cargo.toml").exists()
}.orEmpty().toList().map { "examples/${it.name}" }
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationCus
import software.amazon.smithy.rust.codegen.client.smithy.generators.ServiceRuntimePluginCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization
import software.amazon.smithy.rust.codegen.core.rustlang.Feature
import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.smithy.RustCrate
import software.amazon.smithy.rust.codegen.core.smithy.customizations.AllowLintsCustomization
import software.amazon.smithy.rust.codegen.core.smithy.customizations.CrateVersionCustomization
import software.amazon.smithy.rust.codegen.core.smithy.customizations.pubUseSmithyErrorTypes
import software.amazon.smithy.rust.codegen.core.smithy.customizations.pubUseSmithyPrimitives
import software.amazon.smithy.rust.codegen.core.smithy.generators.LibRsCustomization
import software.amazon.smithy.rust.codegen.core.util.letIf
Expand Down Expand Up @@ -79,6 +81,8 @@ class RequiredCustomizations : ClientCodegenDecorator {
baseCustomizations + AllowLintsCustomization()

override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
val rc = codegenContext.runtimeConfig

// Add rt-tokio feature for `ByteStream::from_path`
rustCrate.mergeFeature(Feature("rt-tokio", true, listOf("aws-smithy-http/rt-tokio")))

Expand All @@ -91,7 +95,29 @@ class RequiredCustomizations : ClientCodegenDecorator {
pubUseSmithyPrimitives(codegenContext, codegenContext.model)(this)
}
rustCrate.withModule(ClientRustModule.Error) {
pubUseSmithyErrorTypes(codegenContext)(this)
// TODO(enableNewSmithyRuntimeCleanup): Change SdkError to a `pub use` after changing the generic's default
rust("/// Error type returned by the client.")
if (codegenContext.smithyRuntimeMode.generateOrchestrator) {
rustTemplate(
"pub type SdkError<E, R = #{R}> = #{SdkError}<E, R>;",
"SdkError" to RuntimeType.sdkError(rc),
"R" to RuntimeType.smithyRuntimeApi(rc).resolve("client::orchestrator::HttpResponse"),
)
} else {
rustTemplate(
"pub type SdkError<E, R = #{R}> = #{SdkError}<E, R>;",
"SdkError" to RuntimeType.sdkError(rc),
"R" to RuntimeType.smithyHttp(rc).resolve("operation::Response"),
)
}
rustTemplate(
"""
pub use #{DisplayErrorContext};
pub use #{ProvideErrorMetadata};
""",
"DisplayErrorContext" to RuntimeType.smithyTypes(rc).resolve("error::display::DisplayErrorContext"),
"ProvideErrorMetadata" to RuntimeType.smithyTypes(rc).resolve("error::metadata::ProvideErrorMetadata"),
)
}

ClientRustModule.Meta.also { metaModule ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,12 @@ import software.amazon.smithy.model.Model
import software.amazon.smithy.model.shapes.Shape
import software.amazon.smithy.model.shapes.StructureShape
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.CodegenContext
import software.amazon.smithy.rust.codegen.core.smithy.CodegenTarget
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.util.hasEventStreamMember
import software.amazon.smithy.rust.codegen.core.util.hasStreamingMember
import software.amazon.smithy.rust.codegen.core.util.letIf

private data class PubUseType(
val type: RuntimeType,
val shouldExport: (Model) -> Boolean,
val alias: String? = null,
)

/** Returns true if the model has normal streaming operations (excluding event streams) */
private fun hasStreamingOperations(model: Model): Boolean {
Expand All @@ -48,62 +40,34 @@ private fun hasBlobs(model: Model): Boolean = structUnionMembersMatchPredicate(m
/** Returns true if the model uses any timestamp shapes */
private fun hasDateTimes(model: Model): Boolean = structUnionMembersMatchPredicate(model, Shape::isTimestampShape)

/** Returns a list of types that should be re-exported for the given model */
internal fun pubUseTypes(codegenContext: CodegenContext, model: Model): List<RuntimeType> =
pubUseTypesThatShouldBeExported(codegenContext, model).map { it.type }

private fun pubUseTypesThatShouldBeExported(codegenContext: CodegenContext, model: Model): List<PubUseType> {
val runtimeConfig = codegenContext.runtimeConfig
return (
listOf(
PubUseType(RuntimeType.blob(runtimeConfig), ::hasBlobs),
PubUseType(RuntimeType.dateTime(runtimeConfig), ::hasDateTimes),
PubUseType(RuntimeType.format(runtimeConfig), ::hasDateTimes, "DateTimeFormat"),
) + RuntimeType.smithyHttp(runtimeConfig).let { http ->
listOf(
PubUseType(http.resolve("byte_stream::ByteStream"), ::hasStreamingOperations),
PubUseType(http.resolve("byte_stream::AggregatedBytes"), ::hasStreamingOperations),
PubUseType(http.resolve("byte_stream::error::Error"), ::hasStreamingOperations, "ByteStreamError"),
PubUseType(http.resolve("body::SdkBody"), ::hasStreamingOperations),
)
}
).filter { pubUseType -> pubUseType.shouldExport(model) }
}

/** Adds re-export statements for Smithy primitives */
fun pubUseSmithyPrimitives(codegenContext: CodegenContext, model: Model): Writable = writable {
val types = pubUseTypesThatShouldBeExported(codegenContext, model)
if (types.isNotEmpty()) {
types.forEach {
val useStatement = if (it.alias == null) {
"pub use #T;"
} else {
"pub use #T as ${it.alias};"
}
rust(useStatement, it.type)
}
val rc = codegenContext.runtimeConfig
if (hasBlobs(model)) {
rustTemplate("pub use #{Blob};", "Blob" to RuntimeType.blob(rc))
}
}

/** Adds re-export statements for error types */
fun pubUseSmithyErrorTypes(codegenContext: CodegenContext): Writable = writable {
val runtimeConfig = codegenContext.runtimeConfig
val reexports = listOf(
listOf(
RuntimeType.smithyHttp(runtimeConfig).let { http ->
PubUseType(http.resolve("result::SdkError"), { _ -> true })
},
),
RuntimeType.smithyTypes(runtimeConfig).let { types ->
listOf(PubUseType(types.resolve("error::display::DisplayErrorContext"), { _ -> true }))
// Only re-export `ProvideErrorMetadata` for clients
.letIf(codegenContext.target == CodegenTarget.CLIENT) { list ->
list +
listOf(PubUseType(types.resolve("error::metadata::ProvideErrorMetadata"), { _ -> true }))
}
},
).flatten()
reexports.forEach { reexport ->
rust("pub use #T;", reexport.type)
if (hasDateTimes(model)) {
rustTemplate(
"""
pub use #{DateTime};
pub use #{Format} as DateTimeFormat;
""",
"DateTime" to RuntimeType.dateTime(rc),
"Format" to RuntimeType.format(rc),
)
}
if (hasStreamingOperations(model)) {
rustTemplate(
"""
pub use #{ByteStream};
pub use #{AggregatedBytes};
pub use #{Error} as ByteStreamError;
pub use #{SdkBody};
""",
"ByteStream" to RuntimeType.smithyHttp(rc).resolve("byte_stream::ByteStream"),
"AggregatedBytes" to RuntimeType.smithyHttp(rc).resolve("byte_stream::AggregatedBytes"),
"Error" to RuntimeType.smithyHttp(rc).resolve("byte_stream::error::Error"),
"SdkBody" to RuntimeType.smithyHttp(rc).resolve("body::SdkBody"),
)
}
}
Loading

0 comments on commit 9943a1f

Please sign in to comment.