Skip to content

Commit

Permalink
Merge IntelliJ version parsing.
Browse files Browse the repository at this point in the history
  • Loading branch information
rhdunn committed May 25, 2023
2 parents 207d8ee + 4b236a1 commit dff41fc
Show file tree
Hide file tree
Showing 4 changed files with 273 additions and 0 deletions.
9 changes: 9 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,12 @@ repositories {
mavenLocal()
mavenCentral()
}

dependencies {
testImplementation(kotlin("test"))
testImplementation("org.junit.jupiter:junit-jupiter:5.9.2")
}

tasks.test {
useJUnitPlatform()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright (C) 2023 Reece H. Dunn. SPDX-License-Identifier: Apache-2.0
package io.github.rhdunn.intellij

/**
* The IntelliJ product type.
*
* @param productName The name of the product.
*
* @see <a href="https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#intellij-extension-type">Gradle IntelliJ Plugin type property</a>
*/
enum class IntellijProductType(val productName: String) {
/**
* IntelliJ IDEA Community Edition
*/
IC("IntelliJ IDEA Community Edition"),

/**
* IntelliJ IDEA Ultimate Edition
*/
IU("IntelliJ IDEA Ultimate Edition"),

/**
* CLion
*/
CL("CLion"),

/**
* PyCharm Professional Edition
*/
PY("PyCharm Professional Edition"),

/**
* PyCharm Community Edition
*/
PC("PyCharm Community Edition"),

/**
* PhpStorm
*/
PS("PhpStorm"),

/**
* Rider
*/
RD("Rider"),

/**
* GoLand
*/
GO("GoLand"),

/**
* Android Studio
*/
AI("Android Studio"),

/**
* JPS-only
*/
JPS("JPS-only"),

/**
* Gateway
*/
GW("Gateway"),
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (C) 2023 Reece H. Dunn. SPDX-License-Identifier: Apache-2.0
package io.github.rhdunn.intellij

import org.gradle.api.GradleException
import java.io.File
import java.net.URL

/**
* An IntelliJ version number.
*
* @see <a href="https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#intellij-extension-version">Gradle IntelliJ Plugin version property</a>
*/
data class IntellijVersion(
/**
* The product type.
*/
val productType: IntellijProductType?,

/**
* The major version in the YYR (Y=Year, R=Release) format.
*/
val majorVersion: Int,

/**
* The full version number string.
*/
val version: String
) {
companion object {
private const val REPOSITORY_PATH =
"https://www.jetbrains.com/intellij-repository/snapshots/com/jetbrains/intellij/idea/BUILD"

/**
* Download and extract the build from an IntelliJ snapshot build file.
*
* @param version the version name corresponding to a build file
*/
fun build(version: String): IntellijVersion {
val build = File("build/BUILD-$version.txt")
if (!build.exists()) {
build.parentFile.mkdirs()

val downloadUrl = URL("$REPOSITORY_PATH/$version/BUILD-$version.txt")
println("Downloading build version file '$downloadUrl' to '${build.absolutePath}'")

downloadUrl.openStream().use { input ->
build.outputStream().use { output ->
input.copyTo(output)
}
}
}
return IntellijVersion(build.readLines()[0], version)
}
}
}

private val VERSION_NUMBER = Regex("(([A-Z]+)-)?20([0-9][0-9]).([1-3])(.[0-9]+)?")
private val BUILD_NUMBER = Regex("(([A-Z]+)-)?([0-9][0-9][0-9]).[0-9]+(.[0-9]+)?")
private val EAP_SNAPSHOT = Regex("([0-9][0-9][0-9]|LATEST)-EAP-SNAPSHOT")

/**
* An IntelliJ version number.
*
* @param version the full version number string
* @param versionAlias the version alias, e.g. EAP version string
*
* @see <a href="https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#intellij-extension-version">Gradle IntelliJ Plugin version property</a>
*/
fun IntellijVersion(version: String, versionAlias: String? = null): IntellijVersion {
VERSION_NUMBER.matchEntire(version)?.let { match ->
val productType = when (val type = match.groupValues[2]) {
"" -> null
else -> IntellijProductType.valueOf(type)
}
val majorVersion = "${match.groupValues[3]}${match.groupValues[4]}"
return IntellijVersion(productType, majorVersion.toInt(), versionAlias ?: version)
}

BUILD_NUMBER.matchEntire(version)?.let { match ->
val productType = when (val type = match.groupValues[2]) {
"" -> null
else -> IntellijProductType.valueOf(type)
}
val majorVersion = match.groupValues[3]
return IntellijVersion(productType, majorVersion.toInt(), versionAlias ?: version)
}

EAP_SNAPSHOT.matchEntire(version)?.let { match ->
return when (val majorVersion = match.groupValues[1]) {
"LATEST" -> IntellijVersion.build(version)
else -> IntellijVersion(null, majorVersion.toInt(), versionAlias ?: version)
}
}

throw GradleException("Unsupported IntelliJ version: $version")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (C) 2023 Reece H. Dunn. SPDX-License-Identifier: Apache-2.0
package io.github.rhdunn.test.intellij

import io.github.rhdunn.intellij.IntellijProductType
import io.github.rhdunn.intellij.IntellijVersion
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertTrue

@DisplayName("The IntellijVersion class")
class IntellijVersionTest {
@Test
fun `should parse version number strings without product types`() {
assertEquals(
IntellijVersion(null, 213, "2021.3"),
IntellijVersion("2021.3")
)
assertEquals(
IntellijVersion(null, 173, "2017.3.4"),
IntellijVersion("2017.3.4")
)
}

@Test
fun `should parse version number strings with product types`() {
assertEquals(
IntellijVersion(IntellijProductType.IC, 213, "IC-2021.3"),
IntellijVersion("IC-2021.3")
)
assertEquals(
IntellijVersion(IntellijProductType.IC, 173, "IC-2017.3.4"),
IntellijVersion("IC-2017.3.4")
)

assertEquals(
IntellijVersion(IntellijProductType.IU, 213, "IU-2021.3"),
IntellijVersion("IU-2021.3")
)
assertEquals(
IntellijVersion(IntellijProductType.IU, 173, "IU-2017.3.4"),
IntellijVersion("IU-2017.3.4")
)
}

@Test
fun `should parse build number strings without product types`() {
assertEquals(
IntellijVersion(null, 213, "213.53"),
IntellijVersion("213.53")
)
assertEquals(
IntellijVersion(null, 173, "173.4.5"),
IntellijVersion("173.4.5")
)
}

@Test
fun `should parse build number strings with product types`() {
assertEquals(
IntellijVersion(IntellijProductType.IC, 213, "IC-213.57"),
IntellijVersion("IC-213.57")
)
assertEquals(
IntellijVersion(IntellijProductType.IC, 173, "IC-173.4.5"),
IntellijVersion("IC-173.4.5")
)

assertEquals(
IntellijVersion(IntellijProductType.IU, 213, "IU-213.45"),
IntellijVersion("IU-213.45")
)
assertEquals(
IntellijVersion(IntellijProductType.IU, 173, "IU-173.4.5"),
IntellijVersion("IU-173.4.5")
)
}

@Test
fun `should parse snapshot strings with build numbers`() {
assertEquals(
IntellijVersion(null, 193, "193-EAP-SNAPSHOT"),
IntellijVersion("193-EAP-SNAPSHOT")
)
}

@Test
fun `should parse snapshot string LATEST-EAP-SNAPSHOT`() {
val build = File("build/BUILD-LATEST-EAP-SNAPSHOT.txt")
val version = IntellijVersion("LATEST-EAP-SNAPSHOT")

assertTrue(build.exists(), "The ${build.path} file exists.")

val buildNumber = build.readLines()[0].split('.')[0].toInt()

assertEquals(
IntellijVersion(null, buildNumber, "LATEST-EAP-SNAPSHOT"),
version
)
}
}

0 comments on commit dff41fc

Please sign in to comment.