From 93472dab536981b1778f3040382a371a89ab28af Mon Sep 17 00:00:00 2001 From: Joel McCance Date: Wed, 29 Apr 2020 11:02:16 -0500 Subject: [PATCH 1/2] Add ktlint plugin --- .editorconfig | 2 + buildSrc/build.gradle.kts | 6 ++ buildSrc/src/main/kotlin/KtlintPlugin.kt | 78 +++++++++++++++++++ .../src/main/kotlin/ProjectDefaultsPlugin.kt | 2 + 4 files changed, 88 insertions(+) create mode 100644 .editorconfig create mode 100644 buildSrc/src/main/kotlin/KtlintPlugin.kt diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..2ada4b5 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,2 @@ +[*.{kt,kts}] +disabled_rules=no-wildcard-imports diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 50f333e..bda7bec 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -4,6 +4,12 @@ plugins { gradlePlugin { plugins { + register("ktlint-plugin") { + id = "ktlint" + implementationClass = "KtlintPlugin" + description = "Format Kotlin files with ktlint" + } + register("project-defaults-plugin") { id = "project-defaults" implementationClass = "ProjectDefaultsPlugin" diff --git a/buildSrc/src/main/kotlin/KtlintPlugin.kt b/buildSrc/src/main/kotlin/KtlintPlugin.kt new file mode 100644 index 0000000..f1d5f0c --- /dev/null +++ b/buildSrc/src/main/kotlin/KtlintPlugin.kt @@ -0,0 +1,78 @@ +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration +import org.gradle.api.plugins.JavaPluginConvention +import org.gradle.api.tasks.JavaExec +import org.gradle.kotlin.dsl.* + +/** + * Provides tasks for checking and, where possible, fixing formatting and style errors using + * [ktlint](https://ktlint.github.io/). + */ +class KtlintPlugin : Plugin { + + override fun apply(project: Project) { + project.run { + val ktlint: Configuration by project.configurations.creating + + dependencies { + ktlint("com.pinterest", "ktlint", "0.36.0") + } + + tasks { + register("ktlintApplyToIdeaProject") { + description = "REPLACE IntelliJ style with ktlint for this project" + main = "com.pinterest.ktlint.Main" + classpath = ktlint + args = listOf("--apply-to-idea-project", "--experimental", "-y") + } + } + + afterEvaluate { + withConvention(JavaPluginConvention::class) { + tasks { + for (sourceSet in sourceSets) { + val sourceSetName = + if (sourceSet.name == "main") "" + else sourceSet.name.capitalize() + + val baseArgs = listOf("--experimental") + + val files = + sourceSet.allSource.sourceDirectories.files + .map { it.path + "/**/*.kt" } + + val checkTaskName = "ktlintCheck$sourceSetName" + + register(checkTaskName) { + group = "verification" + description = "Check Kotlin code style" + main = "com.pinterest.ktlint.Main" + classpath = ktlint + args = baseArgs + files + } + + named("check") { + dependsOn(checkTaskName) + } + + val formatTaskName = "ktlintFormat$sourceSetName" + + register("ktlintFormat$sourceSetName") { + group = "verification" + description = "Fix Kotlin code style deviations" + main = "com.pinterest.ktlint.Main" + classpath = ktlint + args = baseArgs + listOf("-F") + files + } + + named("compile${sourceSetName}Kotlin") { + dependsOn(formatTaskName) + } + } + } + } + } + } + } +} diff --git a/buildSrc/src/main/kotlin/ProjectDefaultsPlugin.kt b/buildSrc/src/main/kotlin/ProjectDefaultsPlugin.kt index 92af6ae..abe5f6d 100644 --- a/buildSrc/src/main/kotlin/ProjectDefaultsPlugin.kt +++ b/buildSrc/src/main/kotlin/ProjectDefaultsPlugin.kt @@ -20,6 +20,8 @@ class ProjectDefaultsPlugin : Plugin { private fun Project.configurePlugins() { plugins.apply("java-library") + plugins.apply("ktlint") + plugins.apply("org.jetbrains.kotlin.jvm") } From 4764c42ff96ac75704195d31d47e4b22c3ac0079 Mon Sep 17 00:00:00 2001 From: Joel McCance Date: Mon, 4 May 2020 10:12:32 -0500 Subject: [PATCH 2/2] Run formatter --- .../kotlin/org/coepi/api/v4/TCNCloudAPIHandler.kt | 12 +++++++----- .../src/main/kotlin/org/coepi/api/v4/TCNReport.kt | 2 +- core/src/main/kotlin/org/coepi/api/Exceptions.kt | 2 +- .../org/coepi/api/common/ByteBufferExtensions.kt | 2 +- .../src/main/kotlin/org/coepi/api/v4/Intervals.kt | 2 +- .../org/coepi/api/v4/dao/TCNReportRecord.kt | 2 +- .../kotlin/org/coepi/api/v4/dao/TCNReportsDao.kt | 14 ++++++++------ .../org/coepi/api/v4/http/TCNHttpHandler.kt | 15 ++++++++------- .../org/coepi/api/v4/reports/TCNReportService.kt | 2 +- core/src/test/kotlin/org/coepi/api/Fixtures.kt | 9 ++++----- .../kotlin/org/coepi/api/base/LocalDynamoDB.kt | 10 +++++----- .../org/coepi/api/v4/dao/TCNReportsDaoTest.kt | 8 ++++---- .../org/coepi/api/v4/http/TCNHttpHandlerTest.kt | 5 ++--- 13 files changed, 44 insertions(+), 41 deletions(-) diff --git a/api-aws-lambda/src/main/kotlin/org/coepi/api/v4/TCNCloudAPIHandler.kt b/api-aws-lambda/src/main/kotlin/org/coepi/api/v4/TCNCloudAPIHandler.kt index 5ae272d..0f08b01 100644 --- a/api-aws-lambda/src/main/kotlin/org/coepi/api/v4/TCNCloudAPIHandler.kt +++ b/api-aws-lambda/src/main/kotlin/org/coepi/api/v4/TCNCloudAPIHandler.kt @@ -33,9 +33,11 @@ class TCNCloudAPIHandler( ) override fun handleRequest(input: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent { - logger.info("Processing request: ${context.awsRequestId}. " + + logger.info( + "Processing request: ${context.awsRequestId}. " + "Query params: ${input.queryStringParameters}. " + - "Body: ${input.body}") + "Body: ${input.body}" + ) try { if (input.httpMethod == "GET") { logger.info("Handling GET Request for :${input.path}. ReqId: ${context.awsRequestId}") @@ -46,8 +48,8 @@ class TCNCloudAPIHandler( } catch (ex: Exception) { logger.info("Failed to serve request: ${context.awsRequestId}. Cause: ${ex.message}") return APIGatewayProxyResponseEvent() - .withStatusCode(500) - .withBody("CoEpi Service Internal Failure") + .withStatusCode(500) + .withBody("CoEpi Service Internal Failure") } } @@ -65,4 +67,4 @@ class TCNCloudAPIHandler( private fun HttpResponse.toAPIGatewayProxyResponseEvent(): APIGatewayProxyResponseEvent = APIGatewayProxyResponseEvent() .withStatusCode(status) - .withBody(body?.decodeToString()) \ No newline at end of file + .withBody(body?.decodeToString()) diff --git a/api-aws-lambda/src/main/kotlin/org/coepi/api/v4/TCNReport.kt b/api-aws-lambda/src/main/kotlin/org/coepi/api/v4/TCNReport.kt index 3e288f1..99715b2 100644 --- a/api-aws-lambda/src/main/kotlin/org/coepi/api/v4/TCNReport.kt +++ b/api-aws-lambda/src/main/kotlin/org/coepi/api/v4/TCNReport.kt @@ -11,4 +11,4 @@ class TCNReport { // TODO: Do stuff with the ByteBuffer and validate signature } } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/org/coepi/api/Exceptions.kt b/core/src/main/kotlin/org/coepi/api/Exceptions.kt index fe5d13f..6cbdfa8 100644 --- a/core/src/main/kotlin/org/coepi/api/Exceptions.kt +++ b/core/src/main/kotlin/org/coepi/api/Exceptions.kt @@ -13,4 +13,4 @@ open class InvalidTCNSignatureException : RuntimeException { open class UnexpectedIntervalLengthException : RuntimeException { constructor(message: String?) : super(message) constructor(message: String?, cause: Throwable?) : super(message, cause) -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/org/coepi/api/common/ByteBufferExtensions.kt b/core/src/main/kotlin/org/coepi/api/common/ByteBufferExtensions.kt index 9d4926b..8e7ddc4 100644 --- a/core/src/main/kotlin/org/coepi/api/common/ByteBufferExtensions.kt +++ b/core/src/main/kotlin/org/coepi/api/common/ByteBufferExtensions.kt @@ -11,4 +11,4 @@ fun ByteBuffer.decodeToString(): String = String(array()) fun String.toByteBuffer(): ByteBuffer = ByteBuffer.wrap(toByteArray()) -fun ByteArray.toByteBuffer(): ByteBuffer = ByteBuffer.wrap(this) \ No newline at end of file +fun ByteArray.toByteBuffer(): ByteBuffer = ByteBuffer.wrap(this) diff --git a/core/src/main/kotlin/org/coepi/api/v4/Intervals.kt b/core/src/main/kotlin/org/coepi/api/v4/Intervals.kt index 7040372..7fdd505 100644 --- a/core/src/main/kotlin/org/coepi/api/v4/Intervals.kt +++ b/core/src/main/kotlin/org/coepi/api/v4/Intervals.kt @@ -9,4 +9,4 @@ object Intervals { fun Instant.toInterval(): Long = toEpochMilli() / Intervals.INTERVAL_LENGTH_MS fun generateIntervalForTimestamp(timestamp: Long): Long = - timestamp / Intervals.INTERVAL_LENGTH_MS \ No newline at end of file + timestamp / Intervals.INTERVAL_LENGTH_MS diff --git a/core/src/main/kotlin/org/coepi/api/v4/dao/TCNReportRecord.kt b/core/src/main/kotlin/org/coepi/api/v4/dao/TCNReportRecord.kt index 8c7c9a8..e7d7058 100644 --- a/core/src/main/kotlin/org/coepi/api/v4/dao/TCNReportRecord.kt +++ b/core/src/main/kotlin/org/coepi/api/v4/dao/TCNReportRecord.kt @@ -18,4 +18,4 @@ data class TCNReportRecord( @DynamoDBAttribute var report: ByteArray = byteArrayOf() -) \ No newline at end of file +) diff --git a/core/src/main/kotlin/org/coepi/api/v4/dao/TCNReportsDao.kt b/core/src/main/kotlin/org/coepi/api/v4/dao/TCNReportsDao.kt index d1c22ce..134c723 100644 --- a/core/src/main/kotlin/org/coepi/api/v4/dao/TCNReportsDao.kt +++ b/core/src/main/kotlin/org/coepi/api/v4/dao/TCNReportsDao.kt @@ -4,9 +4,9 @@ import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBQueryExpression import com.amazonaws.services.dynamodbv2.model.AttributeValue -import org.apache.commons.lang3.Validate import java.time.LocalDate import java.util.* +import org.apache.commons.lang3.Validate class TCNReportsDao { private val dynamoMapper: DynamoDBMapper @@ -22,10 +22,12 @@ class TCNReportsDao { this.dynamoMapper = DynamoDBMapper(ddbClient) } - fun addReport(reportData: ByteArray, - date: LocalDate, - intervalNumber: Long, - timestamp: Long): TCNReportRecord { + fun addReport( + reportData: ByteArray, + date: LocalDate, + intervalNumber: Long, + timestamp: Long + ): TCNReportRecord { Validate.isTrue(reportData.isNotEmpty(), "reportData cannot be empty") Validate.isTrue(intervalNumber > 0, "intervalNumber should be positive") Validate.isTrue(timestamp > 0, "timestamp needs to be positive") @@ -58,4 +60,4 @@ class TCNReportsDao { return outputList } -} \ No newline at end of file +} diff --git a/core/src/main/kotlin/org/coepi/api/v4/http/TCNHttpHandler.kt b/core/src/main/kotlin/org/coepi/api/v4/http/TCNHttpHandler.kt index 1286fee..5547d5f 100644 --- a/core/src/main/kotlin/org/coepi/api/v4/http/TCNHttpHandler.kt +++ b/core/src/main/kotlin/org/coepi/api/v4/http/TCNHttpHandler.kt @@ -1,6 +1,10 @@ package org.coepi.api.v4.http import com.fasterxml.jackson.databind.ObjectMapper +import java.nio.ByteBuffer +import java.time.LocalDate +import java.time.format.DateTimeParseException +import java.util.* import org.coepi.api.InvalidTCNSignatureException import org.coepi.api.TCNClientException import org.coepi.api.UnexpectedIntervalLengthException @@ -10,10 +14,6 @@ import org.coepi.api.common.toByteBuffer import org.coepi.api.v4.Intervals import org.coepi.api.v4.reports.TCNReportService import org.slf4j.LoggerFactory -import java.nio.ByteBuffer -import java.time.LocalDate -import java.time.format.DateTimeParseException -import java.util.* class TCNHttpHandler( private val objectMapper: ObjectMapper, @@ -84,7 +84,7 @@ private fun parseQueryParameters( if (!parameters.containsKey(INTERVAL_LENGTH_MS_KEY)) { throw TCNClientException( "$INTERVAL_LENGTH_MS_KEY query parameter is required if " + - " $INTERVAL_LENGTH_MS_KEY is provided" + " $INTERVAL_LENGTH_MS_KEY is provided" ) } val intervalLengthMs = parameters[INTERVAL_LENGTH_MS_KEY]?.toLong() @@ -92,7 +92,7 @@ private fun parseQueryParameters( if (intervalLengthMs != Intervals.INTERVAL_LENGTH_MS) { throw UnexpectedIntervalLengthException( "$intervalLengthMs is invalid for the date " + - "$DATE_KEY. Please use ${Intervals.INTERVAL_LENGTH_MS} to calculate $INTERVAL_NUMBER_KEY" + "$DATE_KEY. Please use ${Intervals.INTERVAL_LENGTH_MS} to calculate $INTERVAL_NUMBER_KEY" ) } } @@ -101,7 +101,8 @@ private fun parseQueryParameters( } catch (ex: NumberFormatException) { throw TCNClientException( "$INTERVAL_NUMBER_KEY or $INTERVAL_LENGTH_MS_KEY in " + - "illegal number format.", ex + "illegal number format.", + ex ) } diff --git a/core/src/main/kotlin/org/coepi/api/v4/reports/TCNReportService.kt b/core/src/main/kotlin/org/coepi/api/v4/reports/TCNReportService.kt index 0888e18..08325d2 100644 --- a/core/src/main/kotlin/org/coepi/api/v4/reports/TCNReportService.kt +++ b/core/src/main/kotlin/org/coepi/api/v4/reports/TCNReportService.kt @@ -1,12 +1,12 @@ package org.coepi.api.v4.reports +import java.nio.ByteBuffer import java.time.Clock import java.time.LocalDate import org.coepi.api.common.time.toUtcLocalDate import org.coepi.api.v4.dao.TCNReportRecord import org.coepi.api.v4.dao.TCNReportsDao import org.coepi.api.v4.toInterval -import java.nio.ByteBuffer class TCNReportService( private val clock: Clock, diff --git a/core/src/test/kotlin/org/coepi/api/Fixtures.kt b/core/src/test/kotlin/org/coepi/api/Fixtures.kt index 1e962ec..2793be0 100644 --- a/core/src/test/kotlin/org/coepi/api/Fixtures.kt +++ b/core/src/test/kotlin/org/coepi/api/Fixtures.kt @@ -2,13 +2,12 @@ package org.coepi.api import io.mockk.every import io.mockk.mockk -import org.assertj.core.api.ObjectAssert import org.coepi.api.v4.dao.TCNReportRecord object Fixtures { - fun someBytes() = ByteArray(42) { it.toByte() } + fun someBytes() = ByteArray(42) { it.toByte() } - fun mockSavedReport(): TCNReportRecord = mockk { - every { reportId } returns "" - } + fun mockSavedReport(): TCNReportRecord = mockk { + every { reportId } returns "" + } } diff --git a/core/src/test/kotlin/org/coepi/api/base/LocalDynamoDB.kt b/core/src/test/kotlin/org/coepi/api/base/LocalDynamoDB.kt index 61f7dda..27873d3 100644 --- a/core/src/test/kotlin/org/coepi/api/base/LocalDynamoDB.kt +++ b/core/src/test/kotlin/org/coepi/api/base/LocalDynamoDB.kt @@ -7,8 +7,8 @@ import com.amazonaws.services.dynamodbv2.local.main.ServerRunner class LocalDynamoDB { - fun startDynamoDb(){ - val localUrl= "http://localhost:9000" + fun startDynamoDb() { + val localUrl = "http://localhost:9000" val region = "us-west-2" println("Trying to start dynamo db at $localUrl") @@ -17,8 +17,8 @@ class LocalDynamoDB { server.start() val ddb = AmazonDynamoDBClientBuilder.standard() - .withEndpointConfiguration(AwsClientBuilder.EndpointConfiguration(localUrl, region)) - .build() + .withEndpointConfiguration(AwsClientBuilder.EndpointConfiguration(localUrl, region)) + .build() var ddbMapper = DynamoDBMapper(ddb) } -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/org/coepi/api/v4/dao/TCNReportsDaoTest.kt b/core/src/test/kotlin/org/coepi/api/v4/dao/TCNReportsDaoTest.kt index 99f184d..2ebdbd8 100644 --- a/core/src/test/kotlin/org/coepi/api/v4/dao/TCNReportsDaoTest.kt +++ b/core/src/test/kotlin/org/coepi/api/v4/dao/TCNReportsDaoTest.kt @@ -1,13 +1,13 @@ package org.coepi.api.v4.dao -import org.coepi.api.v4.generateIntervalForTimestamp -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test import java.nio.charset.Charset import java.time.Instant import java.time.LocalDate import java.time.ZoneId +import org.coepi.api.v4.generateIntervalForTimestamp +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test @Disabled class TCNReportsDaoTest { diff --git a/core/src/test/kotlin/org/coepi/api/v4/http/TCNHttpHandlerTest.kt b/core/src/test/kotlin/org/coepi/api/v4/http/TCNHttpHandlerTest.kt index 0880ec6..4bc903c 100644 --- a/core/src/test/kotlin/org/coepi/api/v4/http/TCNHttpHandlerTest.kt +++ b/core/src/test/kotlin/org/coepi/api/v4/http/TCNHttpHandlerTest.kt @@ -4,13 +4,13 @@ import com.fasterxml.jackson.databind.ObjectMapper import io.mockk.every import io.mockk.mockk import io.mockk.verify +import java.time.LocalDate +import java.util.* import org.assertj.core.api.Assertions.assertThat import org.coepi.api.Fixtures import org.coepi.api.common.toByteBuffer import org.coepi.api.v4.reports.TCNReportService import org.junit.jupiter.api.Test -import java.time.LocalDate -import java.util.* class TCNHttpHandlerTest { @@ -52,4 +52,3 @@ class TCNHttpHandlerTest { assertThat(response).isInstanceOf(Ok::class.java) } } -