Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
f32584e
poc generate code via plugin
aajtodd Nov 17, 2021
e028eaf
cleanup
aajtodd Nov 17, 2021
773416c
refactor package
aajtodd Nov 17, 2021
fa3f0cb
add todo
aajtodd Nov 17, 2021
13b0c80
remove erroneous kotlin version
aajtodd Nov 17, 2021
c0141e0
fix dependencies such that we only recompile when necessary
aajtodd Nov 18, 2021
db7a321
remove one layer
aajtodd Nov 18, 2021
4cbaae9
generate multiple projections at once using single task
aajtodd Nov 18, 2021
9607aa5
fix up-to-date check for generating the projection file
aajtodd Nov 18, 2021
2f0a1cf
cleanup package structure a bit
aajtodd Nov 18, 2021
6ff978e
add typed settings and register sso projection
aajtodd Nov 18, 2021
2f61f01
lint codegen plugin
aajtodd Nov 18, 2021
15533e4
add transform to only include particular operations
aajtodd Nov 18, 2021
7c6d9df
use node api from smithy to construct json
aajtodd Nov 18, 2021
bd85048
remove unused code
aajtodd Nov 18, 2021
26be6b7
add build settings
aajtodd Nov 18, 2021
9967458
fix name
aajtodd Nov 18, 2021
c274a30
add todo
aajtodd Nov 19, 2021
ee2524d
refactor to use task avoidance apis correctly and NamedObjectContainer
aajtodd Nov 19, 2021
0be8fa8
refactor the protocol tests build to use new plugin
aajtodd Nov 19, 2021
1aa59a8
relocate to nested codegen package
aajtodd Nov 22, 2021
9e0a5c4
move projection to dsl subpackage and rename
aajtodd Nov 22, 2021
1006525
refactor to allow multiple plugins and use extension to configure spe…
aajtodd Nov 22, 2021
bbbc81e
refactor task names; use explicit smithy-cli configuration
aajtodd Nov 22, 2021
d12aa1b
formatting
aajtodd Nov 22, 2021
ac0db90
refactor sdk build script to use codegen plugin
aajtodd Nov 22, 2021
cbcf713
Merge remote-tracking branch 'origin/main' into codegen-plugin
aajtodd Nov 30, 2021
d578b65
cleanup
aajtodd Dec 1, 2021
1779d8e
remove rollup CodegenTask
aajtodd Dec 1, 2021
f665b30
restore aws-config build for now
aajtodd Dec 1, 2021
5ac481f
Merge remote-tracking branch 'origin/main' into codegen-plugin
aajtodd Dec 3, 2021
de98c55
fix package description and version
aajtodd Dec 3, 2021
47237b6
Merge remote-tracking branch 'origin/main' into codegen-plugin
aajtodd Dec 7, 2021
2368e0d
pr feedback
aajtodd Dec 7, 2021
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
1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ val lintPaths = listOf(
"aws-runtime/**/*.kt",
"examples/**/*.kt",
"dokka-aws/**/*.kt",
"gradle/sdk-plugins/src/**/*.kt",
"services/**/*.kt",
"!services/*/generated-src/**/*.kt"
)
Expand Down
182 changes: 59 additions & 123 deletions codegen/protocol-tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,25 @@
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
import aws.sdk.kotlin.gradle.codegen.dsl.smithyKotlinPlugin
import software.amazon.smithy.gradle.tasks.SmithyBuild

plugins {
id("software.amazon.smithy")
id("aws.sdk.kotlin.codegen")
}

description = "Smithy protocol test suite"

buildscript {
val smithyVersion: String by project
dependencies {
classpath("software.amazon.smithy:smithy-cli:$smithyVersion")
}
}


val smithyVersion: String by project
dependencies {
implementation("software.amazon.smithy:smithy-aws-protocol-tests:$smithyVersion")
implementation(project(":codegen:smithy-aws-kotlin-codegen"))
}

data class ProtocolTest(val projectionName: String, val serviceShapeId: String, val sdkId: String? = null) {
val packageName: String = projectionName.toLowerCase().filter { it.isLetterOrDigit() }
}


// The following section exposes Smithy protocol test suites as gradle test targets
// for the configured protocols in [enabledProtocols].
val enabledProtocols = listOf(
Expand All @@ -41,157 +38,96 @@ val enabledProtocols = listOf(
ProtocolTest("machinelearning", "com.amazonaws.machinelearning#AmazonML_20141212", sdkId = "Machine Learning"),
)

// This project doesn't produce a JAR.
tasks["jar"].enabled = false

// Run the SmithyBuild task manually since this project needs the built JAR
// from smithy-aws-kotlin-codegen.
tasks["smithyBuildJar"].enabled = false

task("generateSmithyBuild") {
group = "codegen"
description = "generate smithy-build.json"
val buildFile = projectDir.resolve("smithy-build.json")
doFirst {
buildFile.writeText(generateSmithyBuild(enabledProtocols))
codegen {
enabledProtocols.forEach { test ->
projections.register(test.projectionName) {
transforms = listOf(
"""
{
"name": "includeServices",
"args": {
"services": ["${test.serviceShapeId}"]
}
}
"""
)

smithyKotlinPlugin {
serviceShapeId = test.serviceShapeId
packageName = "aws.sdk.kotlin.services.${test.packageName}"
packageVersion = "1.0"
sdkId = test.sdkId
buildSettings {
generateFullProject = true
optInAnnotations = listOf(
"aws.smithy.kotlin.runtime.util.InternalApi",
"aws.sdk.kotlin.runtime.InternalSdkApi"
)
}
}
}
}
outputs.file(buildFile)
}

// Remove generated model file for clean
tasks["clean"].doFirst {
delete("smithy-build.json")
}
tasks.named<SmithyBuild>("generateSmithyProjections") {
// NOTE: The protocol tests are published to maven as a jar, this ensures that
// the aws-protocol-tests dependency is found when generating code such that the `includeServices` transform
// actually works
addCompileClasspath = true

tasks.create<SmithyBuild>("generateSdk") {
group = "codegen"
// ensure the generated clients use the same version of the runtime as the aws aws-runtime
val smithyKotlinVersion: String by project
doFirst {
System.setProperty("smithy.kotlin.codegen.clientRuntimeVersion", smithyKotlinVersion)
}
addRuntimeClasspath = true
dependsOn(tasks["generateSmithyBuild"])
inputs.file(projectDir.resolve("smithy-build.json"))
// ensure smithy-aws-kotlin-codegen is up to date
inputs.files(configurations.compileClasspath)
}

// force rebuild every time while developing
tasks["generateSdk"].outputs.upToDateWhen { false }

data class ProtocolTest(val projectionName: String, val serviceShapeId: String, val sdkId: String? = null) {
val packageName: String
get() = projectionName.toLowerCase().filter { it.isLetterOrDigit() }
}


// Generates a smithy-build.json file by creating a new projection.
// The generated smithy-build.json file is not committed to git since
// it's rebuilt each time codegen is performed.
fun generateSmithyBuild(tests: List<ProtocolTest>): String {
val projections = tests.joinToString(",") { test ->
val sdkIdEntry = test.sdkId?.let { """"sdkId": "$it",""" } ?: ""
"""
"${test.projectionName}": {
"transforms": [
{
"name": "includeServices",
"args": {
"services": [
"${test.serviceShapeId}"
]
}
}
],
"plugins": {
"kotlin-codegen": {
"service": "${test.serviceShapeId}",
"package": {
"name": "aws.sdk.kotlin.services.${test.packageName}",
"version": "1.0"
},
$sdkIdEntry
"build": {
"rootProject": true,
"optInAnnotations": [
"aws.smithy.kotlin.runtime.util.InternalApi",
"aws.sdk.kotlin.runtime.InternalSdkApi"
]
}
}
}
}
"""
}
return """
{
"version": "1.0",
"projections": {
$projections
}
}
""".trimIndent()
}

open class ProtocolTestTask : DefaultTask() {
/**
* The protocol name
* The projection
*/
@get:Input
var protocol: String = ""
var projection: aws.sdk.kotlin.gradle.codegen.dsl.SmithyProjection? = null

/**
* The plugin name to use
*/
@get:Input
var plugin: String = ""

/**
* The build directory for the task
*/
val generatedBuildDir: File
@OutputDirectory
get() = project.buildDir.resolve("smithyprojections/${project.name}/$protocol/$plugin")

@TaskAction
fun runTests() {
require(protocol.isNotEmpty()) { "protocol name must be specified" }
require(plugin.isNotEmpty()) { "plugin name must be specified" }

println("[$protocol] buildDir: $generatedBuildDir")
if (!generatedBuildDir.exists()) {
throw GradleException("$generatedBuildDir does not exist")
val projection = requireNotNull(projection) { "projection is required task input" }
println("[${projection.name}] buildDir: ${projection.projectionRootDir}")
if (!projection.projectionRootDir.exists()) {
throw GradleException("${projection.projectionRootDir} does not exist")
}
val wrapper = if (System.getProperty("os.name").toLowerCase().contains("windows")) "gradlew.bat" else "gradlew"
val gradlew = project.rootProject.file(wrapper).absolutePath

// NOTE - this still requires us to publish to maven local.
project.exec {
workingDir = generatedBuildDir
workingDir = projection.projectionRootDir
executable = gradlew
args = listOf("test")
}
}
}

enabledProtocols.forEach {
val protocolName = it.projectionName
val codegenTask = tasks.getByName("generateSmithyProjections")
codegen.projections.forEach {
val protocolName = it.name

val protocolTestTask = tasks.register<ProtocolTestTask>("testProtocol-$protocolName") {
dependsOn(tasks["generateSdk"])
tasks.register<ProtocolTestTask>("testProtocol-$protocolName") {
dependsOn(codegenTask)
group = "Verification"
protocol = protocolName
plugin = "kotlin-codegen"
}.get()
projection = it
}

// FIXME This is a hack to work around how protocol tests aren't in the actual service model and thus codegen
// separately from service customizations.
tasks.create<Copy>("copyStaticFiles-$protocolName") {
val copyStaticFiles = tasks.register<Copy>("copyStaticFiles-$protocolName") {
group = "codegen"
from(rootProject.projectDir.resolve("services/$protocolName/common/src"))
into(protocolTestTask.generatedBuildDir.resolve("src/main/kotlin/"))
tasks["generateSdk"].finalizedBy(this)
into(it.projectionRootDir.resolve("src/main/kotlin/"))
}

codegenTask.finalizedBy(copyStaticFiles)
}

tasks.register("testAllProtocols") {
Expand Down
Loading