From 726cdfeb99b6b911c246f77b87d9db49d2359331 Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Thu, 2 Feb 2023 11:59:13 -0800 Subject: [PATCH 1/2] Move `AppName` and `PKG_VERSION` --- .../smithy/rustsdk/UserAgentDecorator.kt | 67 ++++++++++--------- .../codegen/client/smithy/ClientRustModule.kt | 16 +++++ .../customize/RequiredCustomizations.kt | 9 ++- .../protocol/MakeOperationGenerator.kt | 3 +- .../protocol/ProtocolTestGenerator.kt | 5 +- .../rust/codegen/core/rustlang/RustWriter.kt | 4 ++ .../rust/codegen/core/smithy/RuntimeType.kt | 1 - .../CrateVersionCustomization.kt | 28 ++++---- .../codegen/server/smithy/ServerRustModule.kt | 2 + .../ServerRequiredCustomizations.kt | 6 +- 10 files changed, 89 insertions(+), 52 deletions(-) diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt index 8a2a27f66f..0fa2c5f66b 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/UserAgentDecorator.kt @@ -9,6 +9,8 @@ import software.amazon.smithy.aws.traits.ServiceTrait import software.amazon.smithy.model.shapes.OperationShape import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator +import software.amazon.smithy.rust.codegen.client.smithy.featureGatedConfigModule +import software.amazon.smithy.rust.codegen.client.smithy.featureGatedMetaModule import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ConfigCustomization import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig import software.amazon.smithy.rust.codegen.core.rustlang.Writable @@ -16,12 +18,12 @@ 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.RuntimeConfig +import software.amazon.smithy.rust.codegen.core.smithy.RustCrate +import software.amazon.smithy.rust.codegen.core.smithy.customizations.CrateVersionCustomization import software.amazon.smithy.rust.codegen.core.smithy.customize.AdHocCustomization import software.amazon.smithy.rust.codegen.core.smithy.customize.OperationCustomization import software.amazon.smithy.rust.codegen.core.smithy.customize.OperationSection import software.amazon.smithy.rust.codegen.core.smithy.customize.adhocCustomization -import software.amazon.smithy.rust.codegen.core.smithy.generators.LibRsCustomization -import software.amazon.smithy.rust.codegen.core.smithy.generators.LibRsSection import software.amazon.smithy.rust.codegen.core.util.dq import software.amazon.smithy.rust.codegen.core.util.expectTrait @@ -39,21 +41,12 @@ class UserAgentDecorator : ClientCodegenDecorator { return baseCustomizations + AppNameCustomization(codegenContext.runtimeConfig) } - override fun libRsCustomizations( - codegenContext: ClientCodegenContext, - baseCustomizations: List, - ): List { - // We are generating an AWS SDK, the service needs to have the AWS service trait - val serviceTrait = codegenContext.serviceShape.expectTrait() - return baseCustomizations + ApiVersionAndPubUse(codegenContext.runtimeConfig, serviceTrait) - } - override fun operationCustomizations( codegenContext: ClientCodegenContext, operation: OperationShape, baseCustomizations: List, ): List { - return baseCustomizations + UserAgentFeature(codegenContext.runtimeConfig) + return baseCustomizations + UserAgentFeature(codegenContext) } override fun extraSections(codegenContext: ClientCodegenContext): List { @@ -65,44 +58,54 @@ class UserAgentDecorator : ClientCodegenDecorator { } /** - * Adds a static `API_METADATA` variable to the crate root containing the serviceId & the version of the crate for this individual service + * Adds a static `API_METADATA` variable to the crate `config` containing the serviceId & the version of the crate for this individual service */ - private class ApiVersionAndPubUse(private val runtimeConfig: RuntimeConfig, serviceTrait: ServiceTrait) : - LibRsCustomization() { - private val serviceId = serviceTrait.sdkId.lowercase().replace(" ", "") - override fun section(section: LibRsSection): Writable = when (section) { - is LibRsSection.Body -> writable { - // PKG_VERSION comes from CrateVersionGenerator - rust( - "static API_METADATA: #1T::ApiMetadata = #1T::ApiMetadata::new(${serviceId.dq()}, PKG_VERSION);", - AwsRuntimeType.awsHttp(runtimeConfig).resolve("user_agent"), - ) + override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) { + val runtimeConfig = codegenContext.runtimeConfig - // Re-export the app name so that it can be specified in config programmatically without an explicit dependency - rustTemplate( - "pub use #{AppName};", - "AppName" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("app_name::AppName"), - ) - } + // We are generating an AWS SDK, the service needs to have the AWS service trait + val serviceTrait = codegenContext.serviceShape.expectTrait() + val serviceId = serviceTrait.sdkId.lowercase().replace(" ", "") + + rustCrate.withModule(codegenContext.featureGatedMetaModule()) { + rustTemplate( + """ + pub(crate) static API_METADATA: #{user_agent}::ApiMetadata = + #{user_agent}::ApiMetadata::new(${serviceId.dq()}, #{PKG_VERSION}); + """, + "user_agent" to AwsRuntimeType.awsHttp(runtimeConfig).resolve("user_agent"), + "PKG_VERSION" to CrateVersionCustomization.pkgVersion(codegenContext.featureGatedMetaModule()), + ) + } - else -> emptySection + rustCrate.withModule(codegenContext.featureGatedConfigModule()) { + // Re-export the app name so that it can be specified in config programmatically without an explicit dependency + rustTemplate( + "pub use #{AppName};", + "AppName" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("app_name::AppName"), + ) } } - private class UserAgentFeature(private val runtimeConfig: RuntimeConfig) : OperationCustomization() { + private class UserAgentFeature( + private val codegenContext: ClientCodegenContext, + ) : OperationCustomization() { + private val runtimeConfig = codegenContext.runtimeConfig + override fun section(section: OperationSection): Writable = when (section) { is OperationSection.MutateRequest -> writable { rustTemplate( """ let mut user_agent = #{ua_module}::AwsUserAgent::new_from_environment( #{Env}::real(), - crate::API_METADATA.clone(), + #{meta}::API_METADATA.clone(), ); if let Some(app_name) = _config.app_name() { user_agent = user_agent.with_app_name(app_name.clone()); } ${section.request}.properties_mut().insert(user_agent); """, + "meta" to codegenContext.featureGatedMetaModule(), "ua_module" to AwsRuntimeType.awsHttp(runtimeConfig).resolve("user_agent"), "Env" to AwsRuntimeType.awsTypes(runtimeConfig).resolve("os_shim_internal::Env"), ) diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt index 53fe9c6921..746306f11e 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt @@ -20,6 +20,9 @@ import software.amazon.smithy.rust.codegen.core.util.hasTrait * Modules for code generated client crates. */ object ClientRustModule { + /** crate */ + val root = RustModule.LibRs + /** crate::client */ val client = Client.self object Client { @@ -33,6 +36,7 @@ object ClientRustModule { val Config = RustModule.public("config", documentation = "Configuration for the service.") val Error = RustModule.public("error", documentation = "All error types that operations can return. Documentation on these types is copied from the model.") val Operation = RustModule.public("operation", documentation = "All operations that this crate can perform.") + val Meta = RustModule.public("meta", documentation = "Information about this crate.") val Model = RustModule.public("model", documentation = "Data structures used by operation inputs/outputs. Documentation on these types is copied from the model.") val Input = RustModule.public("input", documentation = "Input structures for operations. Documentation on these types is copied from the model.") val Output = RustModule.public("output", documentation = "Output structures for operations. Documentation on these types is copied from the model.") @@ -57,3 +61,15 @@ object ClientModuleProvider : ModuleProvider { override fun moduleForEventStreamError(eventStream: UnionShape): RustModule.LeafModule = ClientRustModule.Error } + +// TODO(CrateReorganization): Remove when cleaning up `enableNewCrateOrganizationScheme` +fun ClientCodegenContext.featureGatedConfigModule() = when (settings.codegenConfig.enableNewCrateOrganizationScheme) { + true -> ClientRustModule.Config + else -> ClientRustModule.root +} + +// TODO(CrateReorganization): Remove when cleaning up `enableNewCrateOrganizationScheme` +fun ClientCodegenContext.featureGatedMetaModule() = when (settings.codegenConfig.enableNewCrateOrganizationScheme) { + true -> ClientRustModule.Meta + else -> ClientRustModule.root +} diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt index 77f5041a90..ef434c7ae5 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/customize/RequiredCustomizations.kt @@ -14,6 +14,7 @@ import software.amazon.smithy.rust.codegen.client.smithy.customizations.HttpVers import software.amazon.smithy.rust.codegen.client.smithy.customizations.IdempotencyTokenGenerator import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyConfigCustomization import software.amazon.smithy.rust.codegen.client.smithy.customizations.ResiliencyReExportCustomization +import software.amazon.smithy.rust.codegen.client.smithy.featureGatedMetaModule 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.smithy.RustCrate @@ -55,7 +56,7 @@ class RequiredCustomizations : ClientCodegenDecorator { codegenContext: ClientCodegenContext, baseCustomizations: List, ): List = - baseCustomizations + CrateVersionCustomization() + AllowLintsCustomization() + baseCustomizations + AllowLintsCustomization() override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) { // Add rt-tokio feature for `ByteStream::from_path` @@ -69,5 +70,11 @@ class RequiredCustomizations : ClientCodegenDecorator { rustCrate.withModule(ClientRustModule.Types) { pubUseSmithyTypes(codegenContext, codegenContext.model)(this) } + + codegenContext.featureGatedMetaModule().also { metaModule -> + rustCrate.withModule(metaModule) { + CrateVersionCustomization.extras(rustCrate, metaModule) + } + } } } diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/MakeOperationGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/MakeOperationGenerator.kt index 541af1ceb5..3c37049eb3 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/MakeOperationGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/MakeOperationGenerator.kt @@ -8,6 +8,7 @@ package software.amazon.smithy.rust.codegen.client.smithy.generators.protocol import software.amazon.smithy.aws.traits.ServiceTrait import software.amazon.smithy.model.shapes.BlobShape import software.amazon.smithy.model.shapes.OperationShape +import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule import software.amazon.smithy.rust.codegen.client.smithy.generators.http.RequestBindingGenerator import software.amazon.smithy.rust.codegen.core.rustlang.Attribute import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter @@ -54,7 +55,7 @@ open class MakeOperationGenerator( ?: codegenContext.serviceShape.id.getName(codegenContext.serviceShape) private val codegenScope = arrayOf( - "config" to RuntimeType.Config, + "config" to ClientRustModule.Config, "header_util" to RuntimeType.smithyHttp(runtimeConfig).resolve("header"), "http" to RuntimeType.Http, "HttpRequestBuilder" to RuntimeType.HttpRequestBuilder, diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/ProtocolTestGenerator.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/ProtocolTestGenerator.kt index 5aa6f2ee56..d73ae506d9 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/ProtocolTestGenerator.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/generators/protocol/ProtocolTestGenerator.kt @@ -19,6 +19,7 @@ import software.amazon.smithy.protocoltests.traits.HttpRequestTestsTrait import software.amazon.smithy.protocoltests.traits.HttpResponseTestCase import software.amazon.smithy.protocoltests.traits.HttpResponseTestsTrait import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext +import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule import software.amazon.smithy.rust.codegen.client.smithy.generators.clientInstantiator import software.amazon.smithy.rust.codegen.core.rustlang.Attribute import software.amazon.smithy.rust.codegen.core.rustlang.Attribute.Companion.allow @@ -168,12 +169,12 @@ class ProtocolTestGenerator( } ?: writable { } rustTemplate( """ - let builder = #{Config}::Config::builder().with_test_defaults().endpoint_resolver("https://example.com"); + let builder = #{config}::Config::builder().with_test_defaults().endpoint_resolver("https://example.com"); #{customParams} let config = builder.build(); """, - "Config" to RuntimeType.Config, + "config" to ClientRustModule.Config, "customParams" to customParams, ) writeInline("let input =") diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustWriter.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustWriter.kt index 67eb7f4b7a..553e30205e 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustWriter.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustWriter.kt @@ -705,6 +705,10 @@ class RustWriter private constructor( t.fullyQualifiedName() } + is RustModule -> { + t.fullyQualifiedPath() + } + is Symbol -> { addDepsRecursively(t) t.rustType().render(fullyQualified = true) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt index 5dcb704c83..24c284cb37 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/RuntimeType.kt @@ -241,7 +241,6 @@ data class RuntimeType(val path: String, val dependency: RustDependency? = null) val Tracing = CargoDependency.Tracing.toType() // codegen types - val Config = RuntimeType("crate::config") val ConstrainedTrait = RuntimeType("crate::constrained::Constrained", InlineDependency.constrained()) val MaybeConstrained = RuntimeType("crate::constrained::MaybeConstrained", InlineDependency.constrained()) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/customizations/CrateVersionCustomization.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/customizations/CrateVersionCustomization.kt index eca5503050..93db223c20 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/customizations/CrateVersionCustomization.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/customizations/CrateVersionCustomization.kt @@ -5,24 +5,24 @@ package software.amazon.smithy.rust.codegen.core.smithy.customizations +import software.amazon.smithy.rust.codegen.core.rustlang.RustModule import software.amazon.smithy.rust.codegen.core.rustlang.rust -import software.amazon.smithy.rust.codegen.core.rustlang.writable -import software.amazon.smithy.rust.codegen.core.smithy.generators.LibRsCustomization -import software.amazon.smithy.rust.codegen.core.smithy.generators.LibRsSection +import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType +import software.amazon.smithy.rust.codegen.core.smithy.RustCrate /** * Add `PGK_VERSION` const in lib.rs to enable knowing the version of the current module */ -class CrateVersionCustomization : LibRsCustomization() { - override fun section(section: LibRsSection) = - writable { - if (section is LibRsSection.Body) { - rust( - """ - /// Crate version number. - pub static PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); - """, - ) - } +object CrateVersionCustomization { + fun pkgVersion(module: RustModule): RuntimeType = RuntimeType(module.fullyQualifiedPath() + "::PKG_VERSION") + + fun extras(rustCrate: RustCrate, module: RustModule) = + rustCrate.withModule(module) { + rust( + """ + /// Crate version number. + pub static PKG_VERSION: &str = env!("CARGO_PKG_VERSION"); + """, + ) } } diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRustModule.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRustModule.kt index 674b2eaea2..f1fc45a2bf 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRustModule.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerRustModule.kt @@ -17,6 +17,8 @@ import software.amazon.smithy.rust.codegen.core.smithy.traits.SyntheticOutputTra import software.amazon.smithy.rust.codegen.core.util.hasTrait object ServerRustModule { + val root = RustModule.LibRs + val Error = RustModule.public("error", documentation = "All error types that operations can return. Documentation on these types is copied from the model.") val Operation = RustModule.public("operation", documentation = "All operations that this crate can perform.") val Model = RustModule.public("model", documentation = "Data structures used by operation inputs/outputs. Documentation on these types is copied from the model.") diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/customizations/ServerRequiredCustomizations.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/customizations/ServerRequiredCustomizations.kt index 7104cb9451..477495afd8 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/customizations/ServerRequiredCustomizations.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/customizations/ServerRequiredCustomizations.kt @@ -30,7 +30,7 @@ class ServerRequiredCustomizations : ServerCodegenDecorator { codegenContext: ServerCodegenContext, baseCustomizations: List, ): List = - baseCustomizations + CrateVersionCustomization() + AllowLintsCustomization() + baseCustomizations + AllowLintsCustomization() override fun extras(codegenContext: ServerCodegenContext, rustCrate: RustCrate) { // Add rt-tokio feature for `ByteStream::from_path` @@ -39,5 +39,9 @@ class ServerRequiredCustomizations : ServerCodegenDecorator { rustCrate.withModule(ServerRustModule.Types) { pubUseSmithyTypes(codegenContext, codegenContext.model)(this) } + + rustCrate.withModule(ServerRustModule.root) { + CrateVersionCustomization.extras(rustCrate, ServerRustModule.root) + } } } From d515b8e11252c8c369f0ca67fba4f916167e6b1a Mon Sep 17 00:00:00 2001 From: John DiSanti Date: Wed, 22 Feb 2023 14:04:47 -0800 Subject: [PATCH 2/2] Fix merge issue --- .../smithy/rust/codegen/client/smithy/ClientRustModule.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt index 131bf12a8a..8f9fb58b5e 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientRustModule.kt @@ -139,12 +139,6 @@ fun ClientCodegenContext.featureGatedCustomizeModule() = when (settings.codegenC ) } -// TODO(CrateReorganization): Remove when cleaning up `enableNewCrateOrganizationScheme` -fun ClientCodegenContext.featureGatedConfigModule() = when (settings.codegenConfig.enableNewCrateOrganizationScheme) { - true -> ClientRustModule.Config - else -> ClientRustModule.root -} - // TODO(CrateReorganization): Remove when cleaning up `enableNewCrateOrganizationScheme` fun ClientCodegenContext.featureGatedMetaModule() = when (settings.codegenConfig.enableNewCrateOrganizationScheme) { true -> ClientRustModule.Meta