diff --git a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenArchetypesProvider.kt b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenArchetypesProvider.kt index cda9789e852..ed8b27a2fde 100644 --- a/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenArchetypesProvider.kt +++ b/idea/idea-maven/src/org/jetbrains/kotlin/idea/maven/KotlinMavenArchetypesProvider.kt @@ -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 { 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? { return versions.maxBy { MavenVersionComparable(it.version) } @@ -95,12 +109,14 @@ class KotlinMavenArchetypesProvider(val kotlinPluginVersion: String) : MavenArch } private fun 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 } diff --git a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenArchetypesProviderTest.kt b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenArchetypesProviderTest.kt index 7d485175572..e746598e31e 100644 --- a/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenArchetypesProviderTest.kt +++ b/idea/idea-maven/test/org/jetbrains/kotlin/idea/maven/KotlinMavenArchetypesProviderTest.kt @@ -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 } + ) + } } \ No newline at end of file