From 31cb1898638067cacebba080fb9bfc6b8091638d Mon Sep 17 00:00:00 2001 From: Sergey Mashkov Date: Wed, 11 Nov 2015 00:55:16 +0300 Subject: [PATCH] Upgrade to latest Kotlin --- github-release-plugin/pom.xml | 4 +- .../src/main/kotlin/gh-upload.kt | 85 +++++++++---------- .../src/test/kotlin/utils.kt | 6 +- github-release-shared/pom.xml | 2 +- .../src/main/kotlin/github-api.kt | 56 ++++++------ .../src/main/kotlin/rfc6570.kt | 34 ++++---- github-release-shared/src/main/kotlin/util.kt | 15 ++-- pom.xml | 6 +- 8 files changed, 100 insertions(+), 108 deletions(-) diff --git a/github-release-plugin/pom.xml b/github-release-plugin/pom.xml index 195c33f..59d1904 100755 --- a/github-release-plugin/pom.xml +++ b/github-release-plugin/pom.xml @@ -5,12 +5,12 @@ github-release-parent cy.github - 0.1-SNAPSHOT + 0.2.1 cy.github github-release-plugin - 0.1-SNAPSHOT + 0.2.1 maven-plugin github-release-plugin Maven Plugin diff --git a/github-release-plugin/src/main/kotlin/gh-upload.kt b/github-release-plugin/src/main/kotlin/gh-upload.kt index 0b298b1..65dadf5 100755 --- a/github-release-plugin/src/main/kotlin/gh-upload.kt +++ b/github-release-plugin/src/main/kotlin/gh-upload.kt @@ -1,112 +1,107 @@ package cy.github -import org.apache.maven.plugin.AbstractMojo -import org.apache.maven.plugin.MojoFailureException -import org.apache.maven.plugins.annotations.Component -import org.apache.maven.plugins.annotations.LifecyclePhase +import org.apache.maven.plugin.* +import org.apache.maven.plugins.annotations.* import org.apache.maven.plugins.annotations.Mojo -import org.apache.maven.plugins.annotations.Parameter -import org.apache.maven.project.MavenProject -import org.apache.maven.settings.Server -import org.apache.maven.settings.Settings -import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher -import kotlin.properties.Delegates - -Mojo(name = "gh-upload", defaultPhase = LifecyclePhase.DEPLOY, requiresOnline = true, threadSafe = true) +import org.apache.maven.project.* +import org.apache.maven.settings.* +import org.sonatype.plexus.components.sec.dispatcher.* + +@Mojo(name = "gh-upload", defaultPhase = LifecyclePhase.DEPLOY, requiresOnline = true, threadSafe = true) public class GitHubUpload : AbstractMojo() { - Component + @Component var security: SecDispatcher? = null - Parameter(defaultValue = "\${project}", readonly = true, required = true) + @Parameter(defaultValue = "\${project}", readonly = true, required = true) var project: MavenProject? = null - Parameter(defaultValue = "\${reactorProjects}", required = true, readonly = true) + @Parameter(defaultValue = "\${reactorProjects}", required = true, readonly = true) var reactorProjects: List? = null - Parameter(property = "maven.deploy.skip", defaultValue = "false") + @Parameter(property = "maven.deploy.skip", defaultValue = "false") var skip: Boolean = false - Parameter(defaultValue = "\${settings}") + @Parameter(defaultValue = "\${settings}") var settings: Settings? = null - Parameter(defaultValue = "github", required = true, readonly = true) + @Parameter(defaultValue = "github", required = true, readonly = true) var serverId: String = "github" - Parameter(required = false) + @Parameter(required = false) var endpointURL: String? = null - Parameter(required = false) + @Parameter(required = false) var owner: String? = null - Parameter(required = false) + @Parameter(required = false) var repository: String? = null - Parameter(required = true, defaultValue = "\${project.version}") + @Parameter(required = true, defaultValue = "\${project.version}") var tagName: String = "" - Parameter(required = false) + @Parameter(required = false) var releaseTitle = tagName - Parameter(required = true, defaultValue = "false") + @Parameter(required = true, defaultValue = "false") var preRelease: Boolean = false override fun execute() { if (skip) { - getLog().warn("GitHubUpload mojo has been skipped because maven.deploy.skip=true") + log.warn("GitHubUpload mojo has been skipped because maven.deploy.skip=true") return } val repo = getRepo() val serverSettings = findServerSettings() ?: throw MojoFailureException("GitHub upload failed: no server configuration found for $serverId in settings.xml") val auth = Auth( - userName = serverSettings.getUsername() ?: throw MojoFailureException("No username configured for github server ${serverSettings.getId()}"), - personalAccessToken = serverSettings.getPassword()?.decryptIfNeeded() ?: throw MojoFailureException("No password/personal access token specified for github server ${serverSettings.getId()}") + userName = serverSettings.username ?: throw MojoFailureException("No username configured for github server ${serverSettings.id}"), + personalAccessToken = serverSettings.password?.decryptIfNeeded() ?: throw MojoFailureException("No password/personal access token specified for github server ${serverSettings.id}") ) - getLog().info("Contacting server ${serverSettings.getId()} @ ${repo.serverEndpoint}") + log.info("Contacting server ${serverSettings.id} @ ${repo.serverEndpoint}") val repositoryFormat = probeGitHubRepositoryFormat(repo.serverEndpoint, auth) val releasesFormat = probeGitHubReleasesFormat(repositoryFormat, repo, auth) - getLog().debug("Releases URL format is $releasesFormat") + log.debug("Releases URL format is $releasesFormat") - getLog().info("Lookup/create release for tag $tagName") + log.info("Lookup/create release for tag $tagName") val release = findRelease(releasesFormat, tagName, auth) ?: createRelease(auth, releasesFormat, tagName, releaseTitle, "", preRelease) ?: throw MojoFailureException("Failed to find/create release for tag $tagName") - getLog().debug("Found release $release") + log.debug("Found release $release") - if (settings?.isOffline() ?: false) { + if (settings?.isOffline ?: false) { throw MojoFailureException("Can't upload artifacts in offline mode") } - val defaultArtifact = project?.getArtifact() + val defaultArtifact = project?.artifact if (defaultArtifact != null) { - val file = defaultArtifact.getFile() + val file = defaultArtifact.file if (file != null) { - getLog().info("Uploading $file") + log.info("Uploading $file") upload(auth, release.uploadFormat, file) } } - val artifacts = project?.getAttachedArtifacts() ?: emptyList() - artifacts.map { it.getFile() }.forEach { file -> - getLog().info("Uploading $file") + val artifacts = project?.attachedArtifacts ?: emptyList() + artifacts.map { it.file }.forEach { file -> + log.info("Uploading $file") upload(auth, release.uploadFormat, file) } - getLog().info("Upload for project ${project!!.getArtifactId()} completed. See ${release.htmlPage}") + log.info("Upload for project ${project!!.artifactId} completed. See ${release.htmlPage}") } - private fun String.decryptIfNeeded() = "\\{.*\\}".toRegex().match(this)?.let { m -> + private fun String.decryptIfNeeded() = "\\{.*\\}".toRegex().find(this)?.let { m -> security?.decrypt(m.value) } ?: this private val interactiveMode: Boolean - get() = settings?.isInteractiveMode() ?: false + get() = settings?.isInteractiveMode ?: false private fun findServerSettings(): Server? = settings?.getServer(serverId) private fun getRepo(): Repo { - val repos = listOf(project?.getScm()?.getConnection(), project?.getScm()?.getDeveloperConnection()) + val repos = listOf(project?.scm?.connection, project?.scm?.developerConnection) .filterNotNull() .map { it.parseSCMUrl() } .filterNotNull() @@ -119,21 +114,21 @@ public class GitHubUpload : AbstractMojo() { val host = when { endpointURL != null -> endpointURL!! hosts.isEmpty() -> "https://api.github.com" - hosts.size() > 1 -> throw MojoFailureException("Ambiguous github host specification: please correct connection/developerConnection or specify plugin endpointURL configuration parameter") + hosts.size > 1 -> throw MojoFailureException("Ambiguous github host specification: please correct connection/developerConnection or specify plugin endpointURL configuration parameter") else -> hosts.single() } val owner = when { this.owner != null -> this.owner!! owners.isEmpty() -> throw MojoFailureException("Couldn't detect github username: please configure SCM connection/developerConnection or specify plugin's owner configuration parameter") - owners.size() > 1 -> throw MojoFailureException("Ambiguous github username: please fix SCM connection/developerConnection or specify plugin's owner configuration parameter") + owners.size > 1 -> throw MojoFailureException("Ambiguous github username: please fix SCM connection/developerConnection or specify plugin's owner configuration parameter") else -> owners.single() } val repoName = when { this.repository != null -> this.repository!! repositories.isEmpty() -> throw MojoFailureException("Couldn't detect github repository name: please configure SCM connection/developerConnection or specify plugin's repository configuration parameter") - repositories.size() > 1 -> throw MojoFailureException("Ambiguous github repository name: please fix SCM connection/developerConnection or specify plugin's repository configuration parameter") + repositories.size > 1 -> throw MojoFailureException("Ambiguous github repository name: please fix SCM connection/developerConnection or specify plugin's repository configuration parameter") else -> repositories.single() } diff --git a/github-release-plugin/src/test/kotlin/utils.kt b/github-release-plugin/src/test/kotlin/utils.kt index af7dee7..5958181 100644 --- a/github-release-plugin/src/test/kotlin/utils.kt +++ b/github-release-plugin/src/test/kotlin/utils.kt @@ -1,11 +1,11 @@ package cy.github.tests -import org.junit.Test as test import cy.github.* -import kotlin.test.assertEquals +import kotlin.test.* +import org.junit.Test as test class TestSCMParse { - test fun testSimple() { + @test fun testSimple() { assertEquals( Repo("https://api.github.com", "cy6erGn0m", "github-release-plugin"), "scm:git:git@github.com:cy6erGn0m/github-release-plugin.git".parseSCMUrl()) diff --git a/github-release-shared/pom.xml b/github-release-shared/pom.xml index e53f0c5..7623eae 100755 --- a/github-release-shared/pom.xml +++ b/github-release-shared/pom.xml @@ -5,7 +5,7 @@ github-release-parent cy.github - 0.1-SNAPSHOT + 0.2.1 4.0.0 diff --git a/github-release-shared/src/main/kotlin/github-api.kt b/github-release-shared/src/main/kotlin/github-api.kt index 56965a2..e296b6b 100755 --- a/github-release-shared/src/main/kotlin/github-api.kt +++ b/github-release-shared/src/main/kotlin/github-api.kt @@ -1,13 +1,11 @@ package cy.github -import cy.rfc6570.expandURLFormat -import org.json.simple.JSONObject -import java.io.File -import java.io.IOException -import java.net.HttpURLConnection -import java.net.URL -import java.util.Base64 -import javax.net.ssl.HttpsURLConnection +import cy.rfc6570.* +import org.json.simple.* +import java.io.* +import java.net.* +import java.util.* +import javax.net.ssl.* data class Auth(val userName: String, val personalAccessToken: String) @@ -20,11 +18,11 @@ fun connectionOf(url: String, method: String = "GET", auth: Auth? = null): HttpU val connection = URL(url).openConnection() as HttpURLConnection connection.setRequestProperty("User-Agent", "Kotlin") connection.setRequestProperty("Accept", "application/vnd.github.v3+json") - connection.setInstanceFollowRedirects(true) - connection.setAllowUserInteraction(false) - connection.setDefaultUseCaches(false) - connection.setDoInput(true) - connection.setRequestMethod(method) + connection.instanceFollowRedirects = true + connection.allowUserInteraction = false + connection.defaultUseCaches = false + connection.doInput = true + connection.requestMethod = method if (auth != null) { connection.setRequestProperty("Authorization", "Basic " + Base64.getEncoder().encodeToString("${auth.userName}:${auth.personalAccessToken}".toByteArray())) } @@ -40,21 +38,21 @@ fun connectionOf(url: String, method: String = "GET", auth: Auth? = null): HttpU fun createRelease(auth: Auth, releasesFormat: String, tagName: String, releaseTitle: String, description: String, preRelease: Boolean): Release? { val request = JSONObject() - request.set("tag_name", tagName) - request.set("target_commitish", null) - request.set("name", releaseTitle) - request.set("body", description) - request.set("draft", false) - request.set("prerelease", preRelease) + request["tag_name"] = tagName + request["target_commitish"] = null + request["name"] = releaseTitle + request["body"] = description + request["draft"] = false + request["prerelease"] = preRelease val connection = connectionOf(releasesFormat.expandURLFormat(emptyMap()), "POST", auth) - connection.setDoOutput(true) - connection.getOutputStream().bufferedWriter().use { + connection.doOutput = true + connection.outputStream.bufferedWriter().use { request.writeJSONString(it) } //println("${connection.getResponseCode()} ${connection.getResponseMessage()}") - connection.getErrorStream()?.let { error -> + connection.errorStream?.let { error -> error.use { it.copyTo(System.out) } @@ -77,7 +75,7 @@ fun JSONObject?.parseRelease(releasesFormat: String): Release? { return if (this == null || id == null) { null } else { - Release(this.get("tag_name")!!.toString(), this.getAsLong("id")!!, releasesFormat, this.get("upload_url")!!.toString(), this.get("html_url")!!.toString()) + Release(this.getRaw("tag_name")!!.toString(), this.getAsLong("id")!!, releasesFormat, this.getRaw("upload_url")!!.toString(), this.getRaw("html_url")!!.toString()) } } @@ -104,19 +102,19 @@ fun upload(auth: Auth, uploadFormat: String, source: File, name: String = source else -> "binary/octet-stream" }) - connection.setDoOutput(true) + connection.doOutput = true - connection.getOutputStream().use { out -> + connection.outputStream.use { out -> source.inputStream().use { ins -> ins.copyTo(out) } } - connection.getErrorStream()?.let { error -> + connection.errorStream?.let { error -> error.use { it.copyTo(System.out) } - throw IOException("${connection.getResponseCode()} ${connection.getResponseMessage()}") + throw IOException("${connection.responseCode} ${connection.responseMessage}") } connection.withReader { @@ -126,10 +124,10 @@ fun upload(auth: Auth, uploadFormat: String, source: File, name: String = source fun probeGitHubRepositoryFormat(base: String = "https://api.github.com", auth: Auth? = null): String = connectionOf(base, auth = auth).withReader { - it.toJSONObject()?.get("repository_url")?.toString() ?: throw IllegalArgumentException("No repository_url endpoint found for $base") + it.toJSONObject()?.getRaw("repository_url")?.toString() ?: throw IllegalArgumentException("No repository_url endpoint found for $base") } fun probeGitHubReleasesFormat(repositoryFormat: String, repo: Repo, auth: Auth? = null): String = connectionOf(repositoryFormat.expandURLFormat(mapOf("owner" to repo.user, "repo" to repo.repoName)), auth = auth).withReader { - it.toJSONObject()?.get("releases_url")?.toString() ?: throw IllegalArgumentException("No releases_url found for $repositoryFormat ($repo)") + it.toJSONObject()?.getRaw("releases_url")?.toString() ?: throw IllegalArgumentException("No releases_url found for $repositoryFormat ($repo)") } diff --git a/github-release-shared/src/main/kotlin/rfc6570.kt b/github-release-shared/src/main/kotlin/rfc6570.kt index e3278cf..a187110 100755 --- a/github-release-shared/src/main/kotlin/rfc6570.kt +++ b/github-release-shared/src/main/kotlin/rfc6570.kt @@ -1,6 +1,6 @@ package cy.rfc6570 -import cy.github.encodeURLComponent +import cy.github.* private interface Value { val key: String @@ -14,14 +14,14 @@ fun String.expandURLFormat(keys: Map): String = replace("""\{[^\}]+\} when { template.isEmpty() -> "" - template.startsWith("?") -> template.removePrefix("?").mapList(keys).flatMap { it.mapify { it.encodeURLComponent() }.map { "${it.first}=${it.second}" } }.join("&", "?").toEmptyIf("?") - template.startsWith("&") -> template.removePrefix("?").mapList(keys).flatMap { it.mapify { it.encodeURLComponent() }.map { "${it.first}=${it.second}" } }.join("&", "&").toEmptyIf("&") - template.startsWith("+") -> template.removePrefix("+").mapList(keys).flatMap { it.flatten { it } }.join(",") // TODO escape except slashes - template.startsWith("#") -> template.removePrefix("#").mapList(keys).flatMap { it.flatten { it } }.join(",", "#").toEmptyIf("#") // TODO escape except slashes - template.startsWith(".") -> template.removePrefix(".").mapList(keys).flatMap { it.flatten { it.encodeURLComponent() } }.join(".", ".").toEmptyIf(".") - template.startsWith(";") -> template.removePrefix(";").mapList(keys).flatMap { it.mapify { it.encodeURLComponent() }.map { "${it.first}=${it.second}" } }.join(";", ";").toEmptyIf(";") - template.startsWith("/") -> template.removePrefix("/").mapList(keys).flatMap { it.flatten { it } }.join("/", "/").toEmptyIf("/") - else -> template.mapList(keys).flatMap { it.flatten { it.encodeURLComponent() } }.join(",") + template.startsWith("?") -> template.removePrefix("?").mapList(keys).flatMap { it.mapify { it.encodeURLComponent() }.map { "${it.first}=${it.second}" } }.joinToString("&", "?").toEmptyIf("?") + template.startsWith("&") -> template.removePrefix("?").mapList(keys).flatMap { it.mapify { it.encodeURLComponent() }.map { "${it.first}=${it.second}" } }.joinToString("&", "&").toEmptyIf("&") + template.startsWith("+") -> template.removePrefix("+").mapList(keys).flatMap { it.flatten { it } }.joinToString(",") // TODO escape except slashes + template.startsWith("#") -> template.removePrefix("#").mapList(keys).flatMap { it.flatten { it } }.joinToString(",", "#").toEmptyIf("#") // TODO escape except slashes + template.startsWith(".") -> template.removePrefix(".").mapList(keys).flatMap { it.flatten { it.encodeURLComponent() } }.joinToString(".", ".").toEmptyIf(".") + template.startsWith(";") -> template.removePrefix(";").mapList(keys).flatMap { it.mapify { it.encodeURLComponent() }.map { "${it.first}=${it.second}" } }.joinToString(";", ";").toEmptyIf(";") + template.startsWith("/") -> template.removePrefix("/").mapList(keys).flatMap { it.flatten { it } }.joinToString("/", "/").toEmptyIf("/") + else -> template.mapList(keys).flatMap { it.flatten { it.encodeURLComponent() } }.joinToString(",") } } @@ -42,32 +42,32 @@ private fun Value.flatten(encoder: (String) -> String): List = when (thi is ListValue -> when { this.expand -> this.list.map(encoder) this.list.isEmpty() -> emptyList() - else -> listOf(this.list.map { encoder(it) }.join(",")) + else -> listOf(this.list.map { encoder(it) }.joinToString(",")) } is MapValue -> when { this.expand -> this.pairs.map { "${encoder(it.first)}=${encoder(it.second)}" } this.pairs.isEmpty() -> emptyList() - else -> listOf(this.pairs.map { "${encoder(it.first)}=${encoder(it.second)}" }.join(",")) + else -> listOf(this.pairs.map { "${encoder(it.first)}=${encoder(it.second)}" }.joinToString(",")) } - else -> throw UnsupportedOperationException(this.javaClass.getName()) + else -> throw UnsupportedOperationException(this.javaClass.name) } private fun Value.mapify(encoder: (String) -> String): List> = when (this) { is SingleValue -> listOf(encoder(this.key) to encoder(this.value)) is ListValue -> when { this.expand -> this.list.map { encoder(this.key) to encoder(it) } - else -> listOf(encoder(this.key) to this.list.map { encoder(it) }.join(",")) + else -> listOf(encoder(this.key) to this.list.map { encoder(it) }.joinToString(",")) } is MapValue -> when { this.expand -> this.pairs.map { encoder(it.first) to encoder(it.second) } - else -> listOf(encoder(this.key) to this.pairs.map { "${encoder(it.first)},${encoder(it.second)}" }.join(",")) + else -> listOf(encoder(this.key) to this.pairs.map { "${encoder(it.first)},${encoder(it.second)}" }.joinToString(",")) } - else -> throw UnsupportedOperationException(this.javaClass.getName()) + else -> throw UnsupportedOperationException(this.javaClass.name) } private fun String.mapList(keys: Map): List = trim().split("\\s*,\\s*".toRegex()).flatMap { key -> val expand = key.endsWith("*") - val slice = ":\\d+$".toRegex().match(key) + val slice = ":\\d+$".toRegex().find(key) val sliceIndex = slice?.value?.removePrefix(":")?.toInt() val clearedKey = key.removeSuffix("*").removeSuffix(slice?.value ?: "") @@ -75,7 +75,7 @@ private fun String.mapList(keys: Map): List = trim().split("\\ when (value) { null -> emptyList() - is Map<*, *> -> listOf(MapValue(clearedKey, expand, value.entrySet().filter { it.key != null && it.value != null}.map { it.key.toString() to it.value.toString()} )) + is Map<*, *> -> listOf(MapValue(clearedKey, expand, value.entries.filter { it.key != null && it.value != null}.map { it.key.toString() to it.value.toString()} )) is Iterable<*> -> listOf(ListValue(clearedKey, expand, value.filterNotNull().map { it.toString() })) else -> listOf(SingleValue(clearedKey, value.toString().subStringIfIndexNotNull(sliceIndex))) } diff --git a/github-release-shared/src/main/kotlin/util.kt b/github-release-shared/src/main/kotlin/util.kt index 26ba723..c095a8a 100755 --- a/github-release-shared/src/main/kotlin/util.kt +++ b/github-release-shared/src/main/kotlin/util.kt @@ -1,15 +1,14 @@ package cy.github -import org.json.simple.JSONObject -import org.json.simple.parser.JSONParser -import java.io.Reader -import java.net.URLConnection -import java.net.URLEncoder +import org.json.simple.* +import org.json.simple.parser.* +import java.io.* +import java.net.* fun String.encodeURLComponent() = URLEncoder.encode(this, "UTF-8") -private fun URLConnection.withReader(block: (Reader) -> T): T = getInputStream().reader().use(block) -private fun JSONObject.getAsLong(key: String) = (get(key) as? Number)?.toLong() -private fun Reader.toJSONObject(): JSONObject? = JSONParser().parse(this) as? JSONObject +internal fun URLConnection.withReader(block: (Reader) -> T): T = getInputStream().reader().use(block) +internal fun JSONObject.getAsLong(key: String) = (get(key) as? Number)?.toLong() +internal fun Reader.toJSONObject(): JSONObject? = JSONParser().parse(this) as? JSONObject fun String.parseSCMUrl(): Repo? = "^scm:git:([^\\@]+@)?(https?://)?([^:]+):([^/]+)/([^/]+)\\.git".toRegex().match(this)?.let { match -> diff --git a/pom.xml b/pom.xml index f4d9110..f119c02 100755 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ cy.github github-release-parent - 0.1-SNAPSHOT + 0.2.1 pom @@ -13,7 +13,7 @@ - 0.12.613 + 1.0.0-beta-1103 @@ -30,7 +30,7 @@ cy.github github-release-plugin - 0.1 + 0.2 github-release-parent-${project.version}