Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move AppName and PKG_VERSION #2389

Merged
merged 4 commits into from
Feb 23, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,21 @@ 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
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

Expand All @@ -39,21 +41,12 @@ class UserAgentDecorator : ClientCodegenDecorator {
return baseCustomizations + AppNameCustomization(codegenContext.runtimeConfig)
}

override fun libRsCustomizations(
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>,
): List<LibRsCustomization> {
// We are generating an AWS SDK, the service needs to have the AWS service trait
val serviceTrait = codegenContext.serviceShape.expectTrait<ServiceTrait>()
return baseCustomizations + ApiVersionAndPubUse(codegenContext.runtimeConfig, serviceTrait)
}

override fun operationCustomizations(
codegenContext: ClientCodegenContext,
operation: OperationShape,
baseCustomizations: List<OperationCustomization>,
): List<OperationCustomization> {
return baseCustomizations + UserAgentFeature(codegenContext.runtimeConfig)
return baseCustomizations + UserAgentFeature(codegenContext)
}

override fun extraSections(codegenContext: ClientCodegenContext): List<AdHocCustomization> {
Expand All @@ -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<ServiceTrait>()
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"),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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.")
Expand All @@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -55,7 +56,7 @@ class RequiredCustomizations : ClientCodegenDecorator {
codegenContext: ClientCodegenContext,
baseCustomizations: List<LibRsCustomization>,
): List<LibRsCustomization> =
baseCustomizations + CrateVersionCustomization() + AllowLintsCustomization()
baseCustomizations + AllowLintsCustomization()

override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
// Add rt-tokio feature for `ByteStream::from_path`
Expand All @@ -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)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 =")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,10 @@ class RustWriter private constructor(
t.fullyQualifiedName()
}

is RustModule -> {
t.fullyQualifiedPath()
}

is Symbol -> {
addDepsRecursively(t)
t.rustType().render(fullyQualified = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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())

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
""",
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ServerRequiredCustomizations : ServerCodegenDecorator {
codegenContext: ServerCodegenContext,
baseCustomizations: List<LibRsCustomization>,
): List<LibRsCustomization> =
baseCustomizations + CrateVersionCustomization() + AllowLintsCustomization()
baseCustomizations + AllowLintsCustomization()

override fun extras(codegenContext: ServerCodegenContext, rustCrate: RustCrate) {
// Add rt-tokio feature for `ByteStream::from_path`
Expand All @@ -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)
}
}
}