22 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
33 * SPDX-License-Identifier: Apache-2.0.
44 */
5+ import aws.sdk.kotlin.gradle.codegen.dsl.smithyKotlinPlugin
56import software.amazon.smithy.gradle.tasks.SmithyBuild
67
78plugins {
8- id(" software.amazon.smithy " )
9+ id(" aws.sdk.kotlin.codegen " )
910}
1011
1112description = " Smithy protocol test suite"
1213
13- buildscript {
14- val smithyVersion: String by project
15- dependencies {
16- classpath(" software.amazon.smithy:smithy-cli:$smithyVersion " )
17- }
18- }
19-
20-
2114val smithyVersion: String by project
2215dependencies {
2316 implementation(" software.amazon.smithy:smithy-aws-protocol-tests:$smithyVersion " )
24- implementation(project(" :codegen:smithy-aws-kotlin-codegen" ))
2517}
2618
19+ data class ProtocolTest (val projectionName : String , val serviceShapeId : String , val sdkId : String? = null ) {
20+ val packageName: String = projectionName.toLowerCase().filter { it.isLetterOrDigit() }
21+ }
22+
23+
2724// The following section exposes Smithy protocol test suites as gradle test targets
2825// for the configured protocols in [enabledProtocols].
2926val enabledProtocols = listOf (
@@ -41,157 +38,96 @@ val enabledProtocols = listOf(
4138 ProtocolTest (" machinelearning" , " com.amazonaws.machinelearning#AmazonML_20141212" , sdkId = " Machine Learning" ),
4239)
4340
44- // This project doesn't produce a JAR.
45- tasks[" jar" ].enabled = false
46-
47- // Run the SmithyBuild task manually since this project needs the built JAR
48- // from smithy-aws-kotlin-codegen.
49- tasks[" smithyBuildJar" ].enabled = false
50-
51- task(" generateSmithyBuild" ) {
52- group = " codegen"
53- description = " generate smithy-build.json"
54- val buildFile = projectDir.resolve(" smithy-build.json" )
55- doFirst {
56- buildFile.writeText(generateSmithyBuild(enabledProtocols))
41+ codegen {
42+ enabledProtocols.forEach { test ->
43+ projections.register(test.projectionName) {
44+ transforms = listOf (
45+ """
46+ {
47+ "name": "includeServices",
48+ "args": {
49+ "services": ["${test.serviceShapeId} "]
50+ }
51+ }
52+ """
53+ )
54+
55+ smithyKotlinPlugin {
56+ serviceShapeId = test.serviceShapeId
57+ packageName = " aws.sdk.kotlin.services.${test.packageName} "
58+ packageVersion = " 1.0"
59+ sdkId = test.sdkId
60+ buildSettings {
61+ generateFullProject = true
62+ optInAnnotations = listOf (
63+ " aws.smithy.kotlin.runtime.util.InternalApi" ,
64+ " aws.sdk.kotlin.runtime.InternalSdkApi"
65+ )
66+ }
67+ }
68+ }
5769 }
58- outputs.file(buildFile)
5970}
6071
61- // Remove generated model file for clean
62- tasks[" clean" ].doFirst {
63- delete(" smithy-build.json" )
64- }
72+ tasks.named<SmithyBuild >(" generateSmithyProjections" ) {
73+ // NOTE: The protocol tests are published to maven as a jar, this ensures that
74+ // the aws-protocol-tests dependency is found when generating code such that the `includeServices` transform
75+ // actually works
76+ addCompileClasspath = true
6577
66- tasks.create<SmithyBuild >(" generateSdk" ) {
67- group = " codegen"
6878 // ensure the generated clients use the same version of the runtime as the aws aws-runtime
6979 val smithyKotlinVersion: String by project
7080 doFirst {
7181 System .setProperty(" smithy.kotlin.codegen.clientRuntimeVersion" , smithyKotlinVersion)
7282 }
73- addRuntimeClasspath = true
74- dependsOn(tasks[" generateSmithyBuild" ])
75- inputs.file(projectDir.resolve(" smithy-build.json" ))
76- // ensure smithy-aws-kotlin-codegen is up to date
77- inputs.files(configurations.compileClasspath)
78- }
79-
80- // force rebuild every time while developing
81- tasks[" generateSdk" ].outputs.upToDateWhen { false }
82-
83- data class ProtocolTest (val projectionName : String , val serviceShapeId : String , val sdkId : String? = null ) {
84- val packageName: String
85- get() = projectionName.toLowerCase().filter { it.isLetterOrDigit() }
86- }
87-
88-
89- // Generates a smithy-build.json file by creating a new projection.
90- // The generated smithy-build.json file is not committed to git since
91- // it's rebuilt each time codegen is performed.
92- fun generateSmithyBuild (tests : List <ProtocolTest >): String {
93- val projections = tests.joinToString(" ," ) { test ->
94- val sdkIdEntry = test.sdkId?.let { """ "sdkId": "$it ",""" } ? : " "
95- """
96- "${test.projectionName} ": {
97- "transforms": [
98- {
99- "name": "includeServices",
100- "args": {
101- "services": [
102- "${test.serviceShapeId} "
103- ]
104- }
105- }
106- ],
107- "plugins": {
108- "kotlin-codegen": {
109- "service": "${test.serviceShapeId} ",
110- "package": {
111- "name": "aws.sdk.kotlin.services.${test.packageName} ",
112- "version": "1.0"
113- },
114- $sdkIdEntry
115- "build": {
116- "rootProject": true,
117- "optInAnnotations": [
118- "aws.smithy.kotlin.runtime.util.InternalApi",
119- "aws.sdk.kotlin.runtime.InternalSdkApi"
120- ]
121- }
122- }
123- }
124- }
125- """
126- }
127- return """
128- {
129- "version": "1.0",
130- "projections": {
131- $projections
132- }
133- }
134- """ .trimIndent()
13583}
13684
13785open class ProtocolTestTask : DefaultTask () {
13886 /* *
139- * The protocol name
87+ * The projection
14088 */
14189 @get:Input
142- var protocol : String = " "
90+ var projection : aws.sdk.kotlin.gradle.codegen.dsl. SmithyProjection ? = null
14391
144- /* *
145- * The plugin name to use
146- */
147- @get:Input
148- var plugin: String = " "
149-
150- /* *
151- * The build directory for the task
152- */
153- val generatedBuildDir: File
154- @OutputDirectory
155- get() = project.buildDir.resolve(" smithyprojections/${project.name} /$protocol /$plugin " )
15692
15793 @TaskAction
15894 fun runTests () {
159- require(protocol.isNotEmpty()) { " protocol name must be specified" }
160- require(plugin.isNotEmpty()) { " plugin name must be specified" }
161-
162- println (" [$protocol ] buildDir: $generatedBuildDir " )
163- if (! generatedBuildDir.exists()) {
164- throw GradleException (" $generatedBuildDir does not exist" )
95+ val projection = requireNotNull(projection) { " projection is required task input" }
96+ println (" [${projection.name} ] buildDir: ${projection.projectionRootDir} " )
97+ if (! projection.projectionRootDir.exists()) {
98+ throw GradleException (" ${projection.projectionRootDir} does not exist" )
16599 }
166100 val wrapper = if (System .getProperty(" os.name" ).toLowerCase().contains(" windows" )) " gradlew.bat" else " gradlew"
167101 val gradlew = project.rootProject.file(wrapper).absolutePath
168102
169103 // NOTE - this still requires us to publish to maven local.
170104 project.exec {
171- workingDir = generatedBuildDir
105+ workingDir = projection.projectionRootDir
172106 executable = gradlew
173107 args = listOf (" test" )
174108 }
175109 }
176110}
177111
178- enabledProtocols.forEach {
179- val protocolName = it.projectionName
112+ val codegenTask = tasks.getByName(" generateSmithyProjections" )
113+ codegen.projections.forEach {
114+ val protocolName = it.name
180115
181- val protocolTestTask = tasks.register<ProtocolTestTask >(" testProtocol-$protocolName " ) {
182- dependsOn(tasks[ " generateSdk " ] )
116+ tasks.register<ProtocolTestTask >(" testProtocol-$protocolName " ) {
117+ dependsOn(codegenTask )
183118 group = " Verification"
184- protocol = protocolName
185- plugin = " kotlin-codegen"
186- }.get()
119+ projection = it
120+ }
187121
188122 // FIXME This is a hack to work around how protocol tests aren't in the actual service model and thus codegen
189123 // separately from service customizations.
190- tasks.create<Copy >(" copyStaticFiles-$protocolName " ) {
124+ val copyStaticFiles = tasks.register<Copy >(" copyStaticFiles-$protocolName " ) {
125+ group = " codegen"
191126 from(rootProject.projectDir.resolve(" services/$protocolName /common/src" ))
192- into(protocolTestTask.generatedBuildDir.resolve(" src/main/kotlin/" ))
193- tasks[" generateSdk" ].finalizedBy(this )
127+ into(it.projectionRootDir.resolve(" src/main/kotlin/" ))
194128 }
129+
130+ codegenTask.finalizedBy(copyStaticFiles)
195131}
196132
197133tasks.register(" testAllProtocols" ) {
0 commit comments