KT-13478 Error creating Maven project by archetype: The desired archetype does not exist

don't filter versions in internal mode or if all were filtered out
This commit is contained in:
Sergey Mashkov
2016-08-26 20:57:25 +03:00
parent 297248dc4f
commit 17137f1c4f
2 changed files with 102 additions and 23 deletions
@@ -23,28 +23,35 @@ import org.jetbrains.idea.maven.dom.MavenVersionComparable
import org.jetbrains.idea.maven.indices.MavenArchetypesProvider
import org.jetbrains.idea.maven.model.MavenArchetype
import org.jetbrains.kotlin.idea.KotlinPluginUtil
import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode
import org.jetbrains.kotlin.utils.ifEmpty
import java.net.HttpURLConnection
import java.net.URLEncoder
import java.util.concurrent.TimeUnit
class KotlinMavenArchetypesProvider(val kotlinPluginVersion: String) : MavenArchetypesProvider {
constructor() : this(KotlinPluginUtil.getPluginVersion())
class KotlinMavenArchetypesProvider(val kotlinPluginVersion: String, val predefinedInternalMode: Boolean?) : MavenArchetypesProvider {
constructor() : this(KotlinPluginUtil.getPluginVersion(), null)
val VERSIONS_LIST_URL = mavenSearchUrl("org.jetbrains.kotlin", packaging = "maven-archetype", rowsLimit = 1000)
private val versionPrefix by lazy { """^\d+\.\d+\.""".toRegex().find(kotlinPluginVersion)?.value ?: "1.0." }
private val versionPrefix by lazy { versionPrefix(kotlinPluginVersion) }
private val fallbackVersion = "1.0.3"
private val internalMode: Boolean
get() = predefinedInternalMode ?: KotlinInternalMode.enabled
private val archetypesBlocking by lazy {
try {
loadVersions().ifEmpty { defaultArchetypes() }
} catch (t: Throwable) {
defaultArchetypes()
loadVersions().ifEmpty { fallbackArchetypes() }
}
catch (t: Throwable) {
fallbackArchetypes()
}
}
override fun getArchetypes() = archetypesBlocking.toMutableList()
private fun defaultArchetypes() = listOf(MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-jvm", "1.0.0", null, null))
private fun fallbackArchetypes() =
listOf("kotlin-archetype-jvm", "kotlin-archetype-js")
.map { MavenArchetype("org.jetbrains.kotlin", it, fallbackVersion, null, null) }
private fun loadVersions(): List<MavenArchetype> {
return connectAndApply(VERSIONS_LIST_URL) { urlConnection ->
@@ -56,14 +63,21 @@ class KotlinMavenArchetypesProvider(val kotlinPluginVersion: String) : MavenArch
internal fun extractVersions(root: JsonElement) =
root.asJsonObject.get("response")
.asJsonObject.get("docs")
.asJsonArray
.map { it.asJsonObject }
.map { MavenArchetype(it.get("g").asString, it.get("a").asString, it.get("v").asString, null, null) }
.filter { it.version?.startsWith(versionPrefix) ?: false }
.groupBy { it.groupId + ":" + it.artifactId }
.mapValues { chooseVersion(it.value) }
.mapNotNull { it.value }
.asJsonObject.get("docs")
.asJsonArray
.map { it.asJsonObject }
.map { MavenArchetype(it.get("g").asString, it.get("a").asString, it.get("v").asString, null, null) }
.let { versions ->
val prefix = versionPrefix
when {
internalMode || prefix == null -> versions
else -> versions.filter { it.version?.startsWith(prefix) ?: false }.ifEmpty { versions }
}
.groupBy { it.groupId + ":" + it.artifactId + ":" + versionPrefix(it.version) }
.mapValues { chooseVersion(it.value) }
.mapNotNull { it.value }
}
private fun chooseVersion(versions: List<MavenArchetype>): MavenArchetype? {
return versions.maxBy { MavenVersionComparable(it.version) }
@@ -95,12 +109,14 @@ class KotlinMavenArchetypesProvider(val kotlinPluginVersion: String) : MavenArch
}
private fun <R> HttpURLConnection.use(block: (HttpURLConnection) -> R): R =
try {
block(this)
}
finally {
disconnect()
}
try {
block(this)
}
finally {
disconnect()
}
private fun String.encodeURL() = URLEncoder.encode(this, "UTF-8")
private fun versionPrefix(version: String) = """^\d+\.\d+\.""".toRegex().find(version)?.value
}
@@ -35,7 +35,7 @@ class KotlinMavenArchetypesProviderTest {
JsonParser().parse(it)
}
val versions = KotlinMavenArchetypesProvider("1.0.0-Release-Something-1886").extractVersions(json)
val versions = KotlinMavenArchetypesProvider("1.0.0-Release-Something-1886", false).extractVersions(json)
assertEquals(
listOf(
@@ -55,7 +55,7 @@ class KotlinMavenArchetypesProviderTest {
JsonParser().parse(it)
}
val versions = KotlinMavenArchetypesProvider("1.1.0-Next-Release-Something-9999").extractVersions(json)
val versions = KotlinMavenArchetypesProvider("1.1.0-Next-Release-Something-9999", false).extractVersions(json)
assertEquals(
listOf(
@@ -64,4 +64,67 @@ class KotlinMavenArchetypesProviderTest {
versions.sortedBy { it.artifactId + "." + it.version }
)
}
@Test
fun extractVersionsInternalMode() {
val file = File(BASE_PATH, "extractVersions/maven-central-response.json")
assertTrue("Test data is missing", file.exists())
val json = file.bufferedReader().use {
JsonParser().parse(it)
}
val versions = KotlinMavenArchetypesProvider("1.0.0-Release-Something-1886", true).extractVersions(json)
assertEquals(
listOf(
MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-jvm", "1.0.1-2", null, null),
MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-jvm", "1.1.2", null, null),
MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-js", "1.0.0", null, null)
).sortedBy { it.artifactId + "." + it.version },
versions.sortedBy { it.artifactId + "." + it.version }
)
}
@Test
fun extractVersionsTooDifferentPluginVersion() {
val file = File(BASE_PATH, "extractVersions/maven-central-response.json")
assertTrue("Test data is missing", file.exists())
val json = file.bufferedReader().use {
JsonParser().parse(it)
}
val versions = KotlinMavenArchetypesProvider("1.9.0-Missing-Release-Something-1886", false).extractVersions(json)
assertEquals(
listOf(
MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-jvm", "1.0.1-2", null, null),
MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-jvm", "1.1.2", null, null),
MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-js", "1.0.0", null, null)
).sortedBy { it.artifactId + "." + it.version },
versions.sortedBy { it.artifactId + "." + it.version }
)
}
@Test
fun extractVersionsSnapshotPlugin() {
val file = File(BASE_PATH, "extractVersions/maven-central-response.json")
assertTrue("Test data is missing", file.exists())
val json = file.bufferedReader().use {
JsonParser().parse(it)
}
val versions = KotlinMavenArchetypesProvider("@snapshot@", false).extractVersions(json)
assertEquals(
listOf(
MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-jvm", "1.0.1-2", null, null),
MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-jvm", "1.1.2", null, null),
MavenArchetype("org.jetbrains.kotlin", "kotlin-archetype-js", "1.0.0", null, null)
).sortedBy { it.artifactId + "." + it.version },
versions.sortedBy { it.artifactId + "." + it.version }
)
}
}