Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 5 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
[*.{kt,kts}]
ktlint_code_style = intellij_idea

# ktlint line length enforcement
max_line_length = 120
ktlint_ignore_back_ticked_identifier = true

# ktlint rules to disable
ktlint_standard_no-wildcard-imports = disabled
ktlint_standard_filename = disabled
Expand All @@ -9,4 +13,4 @@ ktlint_standard_backing-property-naming = disabled
# enable trailing commas per JetBrains recommendation
# (https://kotlinlang.org/docs/coding-conventions.html#trailing-commas)
ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma = true
24 changes: 23 additions & 1 deletion build-plugins/build-support/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ repositories {

dependencies {
// make our custom lint rules available to the buildscript classpath
runtimeOnly(project(":ktlint-rules"))
runtimeOnly(project(":ktlint-rules")) {
// Ensure that kotlin-compiler-embeddable isn't included in the buildscript classpath in consuming modules
exclude(group = "org.jetbrains.kotlin", module = "kotlin-compiler-embeddable")
}
implementation(libs.nexusPublishPlugin)
compileOnly(gradleApi())
implementation("aws.sdk.kotlin:s3:1.1.+")
Expand All @@ -36,7 +39,26 @@ gradlePlugin {
}
}

val generateKtlintVersion by tasks.registering {
// generate the version of the runtime to use as a resource.
// this keeps us from having to manually change version numbers in multiple places
val resourcesDir = layout.buildDirectory.dir("resources/main/aws/sdk/kotlin/gradle/dsl").get()

val versionCatalog = rootProject.file("gradle/libs.versions.toml")
inputs.file(versionCatalog)

val versionFile = file("$resourcesDir/ktlint-version.txt")
outputs.file(versionFile)

val version = libs.ktlint.cli.ruleset.core.get().version
sourceSets.main.get().output.dir(resourcesDir)
doLast {
versionFile.writeText("$version")
}
}

tasks.withType<KotlinCompile> {
dependsOn(generateKtlintVersion)
compilerOptions {
jvmTarget.set(JvmTarget.JVM_1_8)
freeCompilerArgs.add("-opt-in=kotlin.RequiresOptIn")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,21 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin
fun Project.configureLinting(lintPaths: List<String>) {
verifyRootProject { "Kotlin SDK lint configuration is expected to be configured on the root project" }

val ktlintVersion = object {} // Can't use Project.javaClass because that's using the Gradle classloader
.javaClass
.getResource("ktlint-version.txt")
?.readText()
?: error("Missing ktlint-version.txt")

val ktlint by configurations.creating

dependencies {
val ktlintVersion = "1.3.0"
ktlint("com.pinterest.ktlint:ktlint-cli:$ktlintVersion") {
attributes {
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
}
// Ensure that kotlin-compiler-embeddable isn't included in the buildscript classpath in consuming modules
exclude(group = "org.jetbrains.kotlin", module = "kotlin-compiler-embeddable")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ fun Project.configurePublishing(repoName: String, githubOrganization: String = "
onlyIf {
isAvailableForPublication(project, publication).also {
if (!it) {
logger.warn("Skipping publication, project=${project.name}; publication=${publication.name}; group=${publication.groupId}")
logger.warn(
"Skipping publication, project=${project.name}; publication=${publication.name}; group=${publication.groupId}",
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ internal abstract class AnalyzeArtifactSizeMetrics : DefaultTask() {
init {
metricsFile.convention(project.layout.buildDirectory.file(OUTPUT_PATH + "artifact-size-metrics.csv"))
analysisFile.convention(project.layout.buildDirectory.file(OUTPUT_PATH + "artifact-analysis.md"))
hasSignificantChangeFile.convention(project.layout.buildDirectory.file(OUTPUT_PATH + "has-significant-change.txt"))
hasSignificantChangeFile.convention(
project.layout.buildDirectory.file(
OUTPUT_PATH + "has-significant-change.txt",
),
)
}

private val pluginConfig = project.rootProject.extensions.getByType(ArtifactSizeMetricsPluginConfig::class.java)
Expand Down Expand Up @@ -75,7 +79,8 @@ internal abstract class AnalyzeArtifactSizeMetrics : DefaultTask() {
},
) { latestReleaseMetrics ->
file.writeText(
latestReleaseMetrics.body?.decodeToString() ?: throw GradleException("Metrics from latest release are empty"),
latestReleaseMetrics.body?.decodeToString()
?: throw GradleException("Metrics from latest release are empty"),
)
}
}
Expand Down Expand Up @@ -129,7 +134,8 @@ internal abstract class AnalyzeArtifactSizeMetrics : DefaultTask() {
var artifactRequiresAttention = false

val ordinary = StringBuilder()
.appendLine("<details>") // See: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-collapsed-sections
// See: https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-collapsed-sections
.appendLine("<details>")
.appendLine("<summary>Changed in size</summary>")
.appendLine()
.append(tableHeader)
Expand All @@ -145,9 +151,21 @@ internal abstract class AnalyzeArtifactSizeMetrics : DefaultTask() {
append("|")
append(metric.key)
append("|")
if (metric.value.currentSize == 0L) append("(does not exist)") else append("%,d".format(metric.value.currentSize))
if (metric.value.currentSize ==
0L
) {
append("(does not exist)")
} else {
append("%,d".format(metric.value.currentSize))
}
append("|")
if (metric.value.latestReleaseSize == 0L) append("(does not exist)") else append("%,d".format(metric.value.latestReleaseSize))
if (metric.value.latestReleaseSize ==
0L
) {
append("(does not exist)")
} else {
append("%,d".format(metric.value.latestReleaseSize))
}
append("|")
append("%,d".format(metric.value.delta))
append("|")
Expand All @@ -174,7 +192,8 @@ internal abstract class AnalyzeArtifactSizeMetrics : DefaultTask() {
if (artifactOrdinaryChange) appendLine(ordinary)
}

private fun ArtifactSizeMetric.requiresAttention() = this.percentage > pluginConfig.significantChangeThresholdPercentage || this.percentage.isNaN()
private fun ArtifactSizeMetric.requiresAttention() =
this.percentage > pluginConfig.significantChangeThresholdPercentage || this.percentage.isNaN()

private data class ArtifactSizeMetric(
val currentSize: Long,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,25 @@ class ArtifactSizeMetricsPlugin : Plugin<Project> {

target.registerRootProjectArtifactSizeMetricsTask(tasks)

target.tasks.register<CollectDelegatedArtifactSizeMetrics>("collectDelegatedArtifactSizeMetrics") { group = TASK_GROUP }
target.tasks.register<CollectDelegatedArtifactSizeMetrics>("collectDelegatedArtifactSizeMetrics") {
group =
TASK_GROUP
}
target.tasks.register<AnalyzeArtifactSizeMetrics>("analyzeArtifactSizeMetrics") { group = TASK_GROUP }
target.tasks.register<PutArtifactSizeMetricsInCloudWatch>("putArtifactSizeMetricsInCloudWatch") { group = TASK_GROUP }
target.tasks.register<PutArtifactSizeMetricsInCloudWatch>("putArtifactSizeMetricsInCloudWatch") {
group =
TASK_GROUP
}
target.tasks.register<SaveArtifactSizeMetrics>("saveArtifactSizeMetrics") { group = TASK_GROUP }
}
}

private fun Project.subprojectArtifactSizeMetricsTask(): TaskProvider<CollectArtifactSizeMetrics> = tasks.register<CollectArtifactSizeMetrics>("artifactSizeMetrics") {
group = TASK_GROUP
onlyIf { tasks.findByName("jvmJar") != null }
dependsOn(tasks.withType<Jar>())
}
private fun Project.subprojectArtifactSizeMetricsTask(): TaskProvider<CollectArtifactSizeMetrics> =
tasks.register<CollectArtifactSizeMetrics>("artifactSizeMetrics") {
group = TASK_GROUP
onlyIf { tasks.findByName("jvmJar") != null }
dependsOn(tasks.withType<Jar>())
}

private fun Project.registerRootProjectArtifactSizeMetricsTask(
subProjects: List<TaskProvider<CollectArtifactSizeMetrics>>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@ internal abstract class CollectDelegatedArtifactSizeMetrics : DefaultTask() {
fun collect() {
val pullRequestNumber = project.findProperty("pullRequest")?.toString()?.takeIf { it.isNotEmpty() }
val releaseTag = project.findProperty("release")?.toString()?.takeIf { it.isNotEmpty() }
val identifier = pullRequestNumber ?: releaseTag ?: throw AwsSdkGradleException("Please specify a pull request or release number")
val identifier =
pullRequestNumber ?: releaseTag
?: throw AwsSdkGradleException("Please specify a pull request or release number")

val artifactSizeMetricsFileKeys = getFileKeys(identifier) ?: throw AwsSdkGradleException("Unable to list objects from artifact size metrics bucket")
val artifactSizeMetricsFileKeys =
getFileKeys(identifier)
?: throw AwsSdkGradleException("Unable to list objects from artifact size metrics bucket")
val artifactSizeMetricsFiles = getFiles(artifactSizeMetricsFileKeys)
val combined = combine(artifactSizeMetricsFiles)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ public inline fun Project.verifyRootProject(lazyMessage: () -> Any) {
* @return The property as a String
*/
fun Project.stringPropertyNotNull(property: String): String = findProperty(property)?.toString()?.also {
check(it.isNotEmpty()) { "The $property property is set to empty \"-P$property=\" (no value set). Please specify a value." }
check(it.isNotEmpty()) {
"The $property property is set to empty \"-P$property=\" (no value set). Please specify a value."
}
} ?: throw AwsSdkGradleException("The $property property is not set. Please set a value: \"-P$property=YOUR_VALUE\"")

class AwsSdkGradleException(message: String) : GradleException(message)
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ fun Project.configureKmpTargets() {
pluginManager.withPlugin("kotlin-multiplatform") {
val kmpExt = extensions.findByType(kmpExtensionClass)
if (kmpExt == null) {
logger.info("$name: skipping KMP configuration because multiplatform plugin has not been configured properly")
logger.info(
"$name: skipping KMP configuration because multiplatform plugin has not been configured properly",
)
return@withPlugin
}

Expand Down
3 changes: 2 additions & 1 deletion build-plugins/smithy-build/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ gradlePlugin {
val awsKotlinSmithyBuildPlugin by creating {
id = "aws.sdk.kotlin.gradle.smithybuild"
implementationClass = "aws.sdk.kotlin.gradle.codegen.SmithyBuildPlugin"
description = "A plugin that wraps smithy gradle base plugin and provides a DSL for generating smithy-build.json dynamically"
description =
"A plugin that wraps smithy gradle base plugin and provides a DSL for generating smithy-build.json dynamically"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ open class SmithyBuildExtension(private val project: Project) {
* @param projectionName the name of the projection to get the output path for
* @param pluginName the name of the plugin to get the output path for
*/
public fun getProjectionPath(projectionName: String, pluginName: String): Provider<Path> = SmithyUtils.getProjectionOutputDirProperty(project).map {
// FIXME - smithy gradle plugin expects the input file to pass "isDirectory"
// but that flag is only true IFF the path exists AND is a directory
// see https://github.com/smithy-lang/smithy-gradle-plugin/issues/113
it.asFile.mkdirs()
SmithyUtils.getProjectionPluginPath(it.asFile, projectionName, pluginName)
}
public fun getProjectionPath(projectionName: String, pluginName: String): Provider<Path> =
SmithyUtils.getProjectionOutputDirProperty(project).map {
// FIXME - smithy gradle plugin expects the input file to pass "isDirectory"
// but that flag is only true IFF the path exists AND is a directory
// see https://github.com/smithy-lang/smithy-gradle-plugin/issues/113
it.asFile.mkdirs()
SmithyUtils.getProjectionPluginPath(it.asFile, projectionName, pluginName)
}
}

// smithy-kotlin specific extensions
Expand All @@ -42,12 +43,14 @@ open class SmithyBuildExtension(private val project: Project) {
*
* @param projectionName the name of the projection to use
*/
public fun SmithyBuildExtension.smithyKotlinProjectionPath(projectionName: String): Provider<Path> = getProjectionPath(projectionName, "kotlin-codegen")
public fun SmithyBuildExtension.smithyKotlinProjectionPath(projectionName: String): Provider<Path> =
getProjectionPath(projectionName, "kotlin-codegen")

/**
* Get the default generated kotlin source directory for the `smithy-kotlin` plugin.
* This is equivalent to `smithyBuild.getProjectionPath(projectionName, "kotlin-codegen")
*
* @param projectionName the name of the projection to use
*/
public fun SmithyBuildExtension.smithyKotlinProjectionSrcDir(projectionName: String): Provider<Path> = smithyKotlinProjectionPath(projectionName).map { it.resolve("src/main/kotlin") }
public fun SmithyBuildExtension.smithyKotlinProjectionSrcDir(projectionName: String): Provider<Path> =
smithyKotlinProjectionPath(projectionName).map { it.resolve("src/main/kotlin") }
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ class SmithyBuildPlugin : Plugin<Project> {
registerCodegenTasks()
}

private fun Project.installExtension() = extensions.create(SMITHY_BUILD_EXTENSION_NAME, SmithyBuildExtension::class.java, project)
private fun Project.installExtension() =
extensions.create(SMITHY_BUILD_EXTENSION_NAME, SmithyBuildExtension::class.java, project)

private fun Project.registerCodegenTasks() {
val generateSmithyBuild = tasks.register<GenerateSmithyBuild>(TASK_GENERATE_SMITHY_BUILD) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ open class SmithyKotlinApiSettings : ToNode {
return result
}

override fun toString(): String = "SmithyKotlinApiSettings(visibility=$visibility, nullabilityCheckMode=$nullabilityCheckMode, defaultValueSerializationMode=$defaultValueSerializationMode, enableEndpointAuthProvider=$enableEndpointAuthProvider)"
override fun toString(): String =
"SmithyKotlinApiSettings(visibility=$visibility, nullabilityCheckMode=$nullabilityCheckMode, defaultValueSerializationMode=$defaultValueSerializationMode, enableEndpointAuthProvider=$enableEndpointAuthProvider)"
}

open class SmithyKotlinBuildSettings : ToNode {
Expand Down Expand Up @@ -91,7 +92,8 @@ open class SmithyKotlinBuildSettings : ToNode {
return result
}

override fun toString(): String = "SmithyKotlinBuildSettings(generateFullProject=$generateFullProject, generateDefaultBuildFiles=$generateDefaultBuildFiles, optInAnnotations=$optInAnnotations)"
override fun toString(): String =
"SmithyKotlinBuildSettings(generateFullProject=$generateFullProject, generateDefaultBuildFiles=$generateDefaultBuildFiles, optInAnnotations=$optInAnnotations)"
}

open class SmithyKotlinPluginSettings : SmithyBuildPluginSettings {
Expand Down Expand Up @@ -158,7 +160,8 @@ open class SmithyKotlinPluginSettings : SmithyBuildPluginSettings {
return obj.build()
}

override fun toString(): String = "SmithyKotlinPluginSettings(pluginName='$pluginName', serviceShapeId=$serviceShapeId, packageName=$packageName, packageVersion=$packageVersion, packageDescription=$packageDescription, sdkId=$sdkId, buildSettings=$buildSettings, apiSettings=$apiSettings)"
override fun toString(): String =
"SmithyKotlinPluginSettings(pluginName='$pluginName', serviceShapeId=$serviceShapeId, packageName=$packageName, packageVersion=$packageVersion, packageDescription=$packageDescription, sdkId=$sdkId, buildSettings=$buildSettings, apiSettings=$apiSettings)"
}

fun SmithyProjection.smithyKotlinPlugin(configure: SmithyKotlinPluginSettings.() -> Unit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@ import java.util.*
* Get the [SmithyBuildExtension] instance configured for the project
*/
internal val Project.smithyBuildExtension: SmithyBuildExtension
get() = ((this as ExtensionAware).extensions[SMITHY_BUILD_EXTENSION_NAME] as? SmithyBuildExtension) ?: error("SmithyBuildPlugin has not been applied")
get() = ((this as ExtensionAware).extensions[SMITHY_BUILD_EXTENSION_NAME] as? SmithyBuildExtension)
?: error("SmithyBuildPlugin has not been applied")

internal fun ObjectNode.Builder.withObjectMember(key: String, block: ObjectNode.Builder.() -> Unit): ObjectNode.Builder {
internal fun ObjectNode.Builder.withObjectMember(
key: String,
block: ObjectNode.Builder.() -> Unit,
): ObjectNode.Builder {
val builder = ObjectNode.objectNodeBuilder()
builder.apply(block)
return withMember(key, builder.build())
Expand All @@ -36,7 +40,8 @@ internal fun ObjectNode.Builder.withNullableMember(key: String, member: Boolean?
return withMember(key, member)
}

internal fun <T : ToNode> ObjectNode.Builder.withNullableMember(key: String, member: T?): ObjectNode.Builder = withOptionalMember(key, Optional.ofNullable(member))
internal fun <T : ToNode> ObjectNode.Builder.withNullableMember(key: String, member: T?): ObjectNode.Builder =
withOptionalMember(key, Optional.ofNullable(member))

internal fun ObjectNode.Builder.withArrayMember(key: String, member: List<String>): ObjectNode.Builder = apply {
val arrNode = member.map { Node.from(it) }.let { ArrayNode.fromNodes(it) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class GenerateSmithyBuildTaskTest {
fun testDefaults() {
val testProj = ProjectBuilder.builder().build()
val task = testProj.tasks.create<GenerateSmithyBuild>("generateSmithyBuild")
assertEquals(task.generatedOutput.get().asFile.path, testProj.layout.buildDirectory.file("smithy-build.json").get().asFile.path)
assertEquals(
task.generatedOutput.get().asFile.path,
testProj.layout.buildDirectory.file("smithy-build.json").get().asFile.path,
)
}

@Test
Expand Down
2 changes: 2 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ dependencies {
attributes {
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL))
}
// Ensure that kotlin-compiler-embeddable isn't included in the buildscript classpath
exclude(group = "org.jetbrains.kotlin", module = "kotlin-compiler-embeddable")
}
ktlint(project(":ktlint-rules"))
}
Expand Down
Loading