From 574f8a8dc303fe3b535489a36ae21210d251ecf0 Mon Sep 17 00:00:00 2001 From: Justin Sadakhom Date: Wed, 5 Feb 2025 12:00:08 -0500 Subject: [PATCH 1/4] Add Spotless to build.gradle --- build.gradle.kts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 5f7d46c..7e0f118 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ plugins { kotlin("jvm") version "2.1.0" kotlin("plugin.serialization") version "1.9.10" id("com.apollographql.apollo3") version "3.8.2" + id("com.diffplug.spotless") version "7.0.2" } group = "com.ziro.engineering" @@ -60,6 +61,13 @@ apollo { } } +spotless { + kotlin { + ktfmt() + targetExclude("build/**") + } +} + tasks.test { useJUnitPlatform() } From 8c28a2c5e418cddf88cc6f627dbcd34a99766c49 Mon Sep 17 00:00:00 2001 From: Justin Sadakhom Date: Wed, 5 Feb 2025 12:04:36 -0500 Subject: [PATCH 2/4] Increase indents to 4 spaces --- build.gradle.kts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7e0f118..e66180b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -63,7 +63,10 @@ apollo { spotless { kotlin { - ktfmt() + ktfmt().configure { + it.setBlockIndent(4) + it.setContinuationIndent(4) + } targetExclude("build/**") } } From 4aca175a9d554679adfd5df59cfcce3847a20416 Mon Sep 17 00:00:00 2001 From: Justin Sadakhom Date: Wed, 5 Feb 2025 12:06:08 -0500 Subject: [PATCH 3/4] Configure Spotless to remove unused imports by default --- build.gradle.kts | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle.kts b/build.gradle.kts index e66180b..c0ab83b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -66,6 +66,7 @@ spotless { ktfmt().configure { it.setBlockIndent(4) it.setContinuationIndent(4) + it.setRemoveUnusedImports(true) } targetExclude("build/**") } From 626aa70d6617cdd158f12eba104dedb382b81de3 Mon Sep 17 00:00:00 2001 From: Justin Sadakhom Date: Wed, 5 Feb 2025 12:17:47 -0500 Subject: [PATCH 4/4] Apply formatting --- src/main/kotlin/github/GitHubClient.kt | 16 +-- .../kotlin/github/GitHubClientSmokeTest.kt | 1 - src/main/kotlin/zenhub/Pipeline.kt | 2 +- src/main/kotlin/zenhub/ZenHubClient.kt | 116 +++++++++++------- .../kotlin/zenhub/ZenHubClientSmokeTest.kt | 9 +- src/test/kotlin/github/GitHubClientTest.kt | 14 ++- src/test/kotlin/zenhub/ZenHubClientTest.kt | 6 +- 7 files changed, 98 insertions(+), 66 deletions(-) diff --git a/src/main/kotlin/github/GitHubClient.kt b/src/main/kotlin/github/GitHubClient.kt index b5f6579..3c7316e 100644 --- a/src/main/kotlin/github/GitHubClient.kt +++ b/src/main/kotlin/github/GitHubClient.kt @@ -5,11 +5,10 @@ import com.apollographql.apollo3.api.Optional import com.ziro.engineering.github.graphql.sdk.GetBranchLogHistoryQuery import com.ziro.engineering.github.graphql.sdk.GetFileFromBranchQuery import com.ziro.engineering.github.graphql.sdk.RepositoryQuery +import kotlin.math.min import kotlinx.coroutines.flow.single import kotlinx.coroutines.runBlocking import okhttp3.internal.closeQuietly -import kotlin.math.ceil -import kotlin.math.min const val MAX_COMMITS_IN_PAGE = 100 @@ -20,7 +19,8 @@ private const val GITHUB_GRAPHQL_URL = "https://api.github.com/graphql" class GitHubClient : AutoCloseable { private val apolloClient: ApolloClient = - ApolloClient.Builder().serverUrl(GITHUB_GRAPHQL_URL) + ApolloClient.Builder() + .serverUrl(GITHUB_GRAPHQL_URL) .addHttpHeader("Authorization", "Bearer ${System.getenv("GITHUB_API_TOKEN")}") .build() @@ -55,12 +55,14 @@ class GitHubClient : AutoCloseable { while (commitsLeft > 0 && hasNextPage) { val numCommitsInPage = min(MAX_COMMITS_IN_PAGE, commitsLeft) - val query = GetBranchLogHistoryQuery(repoOwner, repoName, branch, numCommitsInPage, cursor) + val query = + GetBranchLogHistoryQuery(repoOwner, repoName, branch, numCommitsInPage, cursor) val response = apolloClient.query(query).toFlow().single() - commits.addAll(response.data?.repository?.ref?.target?.onCommit?.history?.edges?.mapNotNull { - it?.node?.message - } ?: emptyList()) + commits.addAll( + response.data?.repository?.ref?.target?.onCommit?.history?.edges?.mapNotNull { + it?.node?.message + } ?: emptyList()) response.data?.repository?.ref?.target?.onCommit?.history?.pageInfo?.let { cursor = Optional.presentIfNotNull(it.endCursor) diff --git a/src/main/kotlin/github/GitHubClientSmokeTest.kt b/src/main/kotlin/github/GitHubClientSmokeTest.kt index 2c881fe..48366b6 100644 --- a/src/main/kotlin/github/GitHubClientSmokeTest.kt +++ b/src/main/kotlin/github/GitHubClientSmokeTest.kt @@ -9,4 +9,3 @@ fun main() { } } } - diff --git a/src/main/kotlin/zenhub/Pipeline.kt b/src/main/kotlin/zenhub/Pipeline.kt index 0263670..d288a38 100644 --- a/src/main/kotlin/zenhub/Pipeline.kt +++ b/src/main/kotlin/zenhub/Pipeline.kt @@ -3,4 +3,4 @@ package zenhub enum class Pipeline(val id: String) { MERGE_READY("Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzEwMTIwODA"), UAT_READY("Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzEwMTIxNzI") -} \ No newline at end of file +} diff --git a/src/main/kotlin/zenhub/ZenHubClient.kt b/src/main/kotlin/zenhub/ZenHubClient.kt index c085c6e..8367f1f 100644 --- a/src/main/kotlin/zenhub/ZenHubClient.kt +++ b/src/main/kotlin/zenhub/ZenHubClient.kt @@ -4,20 +4,16 @@ import com.apollographql.apollo3.ApolloClient import com.apollographql.apollo3.api.Optional import com.ziro.engineering.zenhub.graphql.sdk.* import com.ziro.engineering.zenhub.graphql.sdk.type.* +import java.time.Instant import kotlinx.coroutines.flow.single import kotlinx.coroutines.runBlocking import okhttp3.internal.closeQuietly -import java.time.Instant -/** - * Default GitHub Repository ID - references the SMACS repository. - */ +/** Default GitHub Repository ID - references the SMACS repository. */ const val DEFAULT_GITHUB_REPOSITORY_ID: Int = 15617306 const val DEFAULT_GIT_REPOSITORY_ID: String = "Z2lkOi8vcmFwdG9yL1JlcG9zaXRvcnkvMjEwNTg" -/** - * Default Workspace ID - references the "Engineering Team" workspace. - */ +/** Default Workspace ID - references the "Engineering Team" workspace. */ private const val DEFAULT_WORKSPACE_ID = "59c54eb49d9e774e473597f1" private const val ZENHUB_GRAPHQL_URL = "https://api.zenhub.com/public/graphql" @@ -27,14 +23,21 @@ class ZenHubClient( private val zenhubWorkspaceId: String = DEFAULT_WORKSPACE_ID ) : AutoCloseable { - private val apolloClient: ApolloClient = ApolloClient.Builder().serverUrl(ZENHUB_GRAPHQL_URL) - .addHttpHeader("Authorization", "Bearer ${System.getenv("ZENHUB_GRAPHQL_TOKEN")}").build() + private val apolloClient: ApolloClient = + ApolloClient.Builder() + .serverUrl(ZENHUB_GRAPHQL_URL) + .addHttpHeader("Authorization", "Bearer ${System.getenv("ZENHUB_GRAPHQL_TOKEN")}") + .build() - fun searchClosedIssuesBetween(startTime: Instant, endTime: Instant): List { + fun searchClosedIssuesBetween( + startTime: Instant, + endTime: Instant + ): List { val results = ArrayList() - val issueOnlyFilter = IssueSearchFiltersInput( - displayType = Optional.present(DisplayFilter.issues), - ) + val issueOnlyFilter = + IssueSearchFiltersInput( + displayType = Optional.present(DisplayFilter.issues), + ) var earliestClosedDate: Instant var cursor: String? = null @@ -49,11 +52,14 @@ class ZenHubClient( } fun getCurrentSprint(): GetSprintsByStateQuery.Node? = runBlocking { - val results = getSprintByState( - SprintFiltersInput(Optional.present(SprintStateInput(SprintState.OPEN)), Optional.absent()), - 1, - SprintOrderInput(Optional.present(OrderDirection.ASC), Optional.present(SprintOrderField.END_AT)) - ) + val results = + getSprintByState( + SprintFiltersInput( + Optional.present(SprintStateInput(SprintState.OPEN)), Optional.absent()), + 1, + SprintOrderInput( + Optional.present(OrderDirection.ASC), + Optional.present(SprintOrderField.END_AT))) if (results.isNullOrEmpty()) { null } else { @@ -62,11 +68,14 @@ class ZenHubClient( } fun getPreviousSprint(): GetSprintsByStateQuery.Node? = runBlocking { - val results = getSprintByState( - SprintFiltersInput(Optional.present(SprintStateInput(SprintState.CLOSED)), Optional.absent()), - 1, - SprintOrderInput(Optional.present(OrderDirection.DESC), Optional.present(SprintOrderField.END_AT)) - ) + val results = + getSprintByState( + SprintFiltersInput( + Optional.present(SprintStateInput(SprintState.CLOSED)), Optional.absent()), + 1, + SprintOrderInput( + Optional.present(OrderDirection.DESC), + Optional.present(SprintOrderField.END_AT))) if (results.isNullOrEmpty()) { null } else { @@ -74,7 +83,11 @@ class ZenHubClient( } } - fun issueByInfo(githubRepoId: Int, gitRepoId: String, issueNumber: Int): IssueByInfoQuery.IssueByInfo? = runBlocking { + fun issueByInfo( + githubRepoId: Int, + gitRepoId: String, + issueNumber: Int + ): IssueByInfoQuery.IssueByInfo? = runBlocking { val query = IssueByInfoQuery(githubRepoId, gitRepoId, issueNumber) apolloClient.query(query).toFlow().single().data?.issueByInfo } @@ -99,13 +112,21 @@ class ZenHubClient( fun getIssuesByPipeline(pipeline: Pipeline): List = runBlocking { val query = GetIssuesByPipelineQuery(pipeline.id) - apolloClient.query(query).toFlow().single().data?.searchIssuesByPipeline?.nodes ?: emptyList() + apolloClient.query(query).toFlow().single().data?.searchIssuesByPipeline?.nodes + ?: emptyList() } fun getReleases(githubRepoId: Int): List = runBlocking { val query = GetReleasesQuery(githubRepoId) - apolloClient.query(query).toFlow().single().data?.repositoriesByGhId?.get(0)?.releases?.nodes - ?: emptyList() + apolloClient + .query(query) + .toFlow() + .single() + .data + ?.repositoriesByGhId + ?.get(0) + ?.releases + ?.nodes ?: emptyList() } fun getSprints(workspaceId: String): List = runBlocking { @@ -113,14 +134,13 @@ class ZenHubClient( apolloClient.query(query).toFlow().single().data?.workspace?.sprints?.nodes ?: emptyList() } - /** - * Cannot move an issue to closed because closed is not a pipeline. - */ - fun moveIssueToPipeline(issueId: String, pipeline: Pipeline): MoveIssueMutation.MoveIssue? = runBlocking { - val input = MoveIssueInput(Optional.absent(), pipeline.id, issueId, Optional.present(0)) - val mutation = MoveIssueMutation(input, DEFAULT_WORKSPACE_ID) - apolloClient.mutation(mutation).toFlow().single().data?.moveIssue - } + /** Cannot move an issue to closed because closed is not a pipeline. */ + fun moveIssueToPipeline(issueId: String, pipeline: Pipeline): MoveIssueMutation.MoveIssue? = + runBlocking { + val input = MoveIssueInput(Optional.absent(), pipeline.id, issueId, Optional.present(0)) + val mutation = MoveIssueMutation(input, DEFAULT_WORKSPACE_ID) + apolloClient.mutation(mutation).toFlow().single().data?.moveIssue + } fun closeIssues(issueIds: List): CloseIssuesMutation.CloseIssues? = runBlocking { val mutation = CloseIssuesMutation(issueIds) @@ -136,12 +156,18 @@ class ZenHubClient( firstSprints: Int, orderSprintsBy: SprintOrderInput ): List? = runBlocking { - val query = GetSprintsByStateQuery(zenhubWorkspaceId, sprintFilters, firstSprints, orderSprintsBy) + val query = + GetSprintsByStateQuery(zenhubWorkspaceId, sprintFilters, firstSprints, orderSprintsBy) apolloClient.query(query).toFlow().single().data?.workspace?.sprints?.nodes } - private fun searchClosedIssues(filters: IssueSearchFiltersInput, after: String?): SearchClosedIssuesQuery.SearchClosedIssues? = runBlocking { - val query = SearchClosedIssuesQuery(zenhubWorkspaceId, filters, Optional.present(100), Optional.presentIfNotNull(after)) + private fun searchClosedIssues( + filters: IssueSearchFiltersInput, + after: String? + ): SearchClosedIssuesQuery.SearchClosedIssues? = runBlocking { + val query = + SearchClosedIssuesQuery( + zenhubWorkspaceId, filters, Optional.present(100), Optional.presentIfNotNull(after)) apolloClient.query(query).toFlow().single().data?.searchClosedIssues } @@ -155,15 +181,17 @@ class ZenHubClient( return results } - val indexOfEarliestIssue = results.indexOfFirst { issue -> - Instant.parse(issue.closedAt.toString()).isBefore(startDate) - } + val indexOfEarliestIssue = + results.indexOfFirst { issue -> + Instant.parse(issue.closedAt.toString()).isBefore(startDate) + } var indexOfLatestIssue = -1 if (Instant.parse(results[0].closedAt.toString()).isAfter(endDate)) { - indexOfLatestIssue = results.indexOfLast { issue -> - Instant.parse(issue.closedAt.toString()).isAfter(endDate) - } + indexOfLatestIssue = + results.indexOfLast { issue -> + Instant.parse(issue.closedAt.toString()).isAfter(endDate) + } } return results.subList(indexOfLatestIssue + 1, indexOfEarliestIssue) diff --git a/src/main/kotlin/zenhub/ZenHubClientSmokeTest.kt b/src/main/kotlin/zenhub/ZenHubClientSmokeTest.kt index 7131d69..f094249 100644 --- a/src/main/kotlin/zenhub/ZenHubClientSmokeTest.kt +++ b/src/main/kotlin/zenhub/ZenHubClientSmokeTest.kt @@ -5,15 +5,14 @@ import java.time.Instant fun main() { ZenHubClient().use { client -> - val issue = client.issueByInfo(DEFAULT_GITHUB_REPOSITORY_ID, DEFAULT_GIT_REPOSITORY_ID, 15675) + val issue = + client.issueByInfo(DEFAULT_GITHUB_REPOSITORY_ID, DEFAULT_GIT_REPOSITORY_ID, 15675) if (issue != null) { println("id: ${issue.id}") } val fourteenDays = Duration.ofDays(28) - val response = client.searchClosedIssuesBetween( - Instant.now().minus(fourteenDays), - Instant.now() - ) + val response = + client.searchClosedIssuesBetween(Instant.now().minus(fourteenDays), Instant.now()) println("Results Size: ${response.size}") response.forEach { node -> println(node) } diff --git a/src/test/kotlin/github/GitHubClientTest.kt b/src/test/kotlin/github/GitHubClientTest.kt index 97f8d4a..97b6149 100644 --- a/src/test/kotlin/github/GitHubClientTest.kt +++ b/src/test/kotlin/github/GitHubClientTest.kt @@ -1,7 +1,7 @@ package github -import org.junit.jupiter.api.Test import kotlin.test.assertEquals +import org.junit.jupiter.api.Test class GitHubClientTest { private val gitHubClient = GitHubClient() @@ -14,7 +14,8 @@ class GitHubClientTest { @Test fun whenGetCommitsWithLess1PageThenCorrectAmountIsReturned() { - val result = gitHubClient.getCommits(branch = "develop", numCommits = MAX_COMMITS_IN_PAGE / 10) + val result = + gitHubClient.getCommits(branch = "develop", numCommits = MAX_COMMITS_IN_PAGE / 10) assertEquals(MAX_COMMITS_IN_PAGE / 10, result.size) } @@ -26,19 +27,22 @@ class GitHubClientTest { @Test fun whenGetCommitsWithMoreThan1PageThenCorrectAmountIsReturned() { - val result = gitHubClient.getCommits(branch = "develop", numCommits = MAX_COMMITS_IN_PAGE * 2) + val result = + gitHubClient.getCommits(branch = "develop", numCommits = MAX_COMMITS_IN_PAGE * 2) assertEquals(MAX_COMMITS_IN_PAGE * 2, result.size) } @Test fun whenGetCommitsWith1PageAndLeftoverThenCorrectAmountIsReturned() { - val result = gitHubClient.getCommits(branch = "develop", numCommits = MAX_COMMITS_IN_PAGE * 2 - 1) + val result = + gitHubClient.getCommits(branch = "develop", numCommits = MAX_COMMITS_IN_PAGE * 2 - 1) assertEquals(MAX_COMMITS_IN_PAGE * 2 - 1, result.size) } @Test fun whenGetCommitsOnBadBranchThenThereAreNoCommits() { - val result = gitHubClient.getCommits(branch = "bad-branch", numCommits = MAX_COMMITS_IN_PAGE) + val result = + gitHubClient.getCommits(branch = "bad-branch", numCommits = MAX_COMMITS_IN_PAGE) assertEquals(0, result.size) } } diff --git a/src/test/kotlin/zenhub/ZenHubClientTest.kt b/src/test/kotlin/zenhub/ZenHubClientTest.kt index 1671944..09ff077 100644 --- a/src/test/kotlin/zenhub/ZenHubClientTest.kt +++ b/src/test/kotlin/zenhub/ZenHubClientTest.kt @@ -1,17 +1,17 @@ package zenhub -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertAll import kotlin.test.assertEquals import kotlin.test.assertNotNull import kotlin.test.assertTrue +import org.junit.jupiter.api.Test class ZenHubClientTest { private val zenHubClient = ZenHubClient() @Test fun whenIssueByInfoThenCorrectIssueIsReturned() { - val issue = zenHubClient.issueByInfo(DEFAULT_GITHUB_REPOSITORY_ID, DEFAULT_GIT_REPOSITORY_ID, 18004) + val issue = + zenHubClient.issueByInfo(DEFAULT_GITHUB_REPOSITORY_ID, DEFAULT_GIT_REPOSITORY_ID, 18004) assertEquals(18004, issue?.number) }