From 059a9d5b7a99840574ac96ff0db419f29dae8968 Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 9 Dec 2022 01:01:08 +0200 Subject: [PATCH 1/8] chore: rename version property --- src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt | 6 +++--- .../coder/gateway/views/steps/CoderWorkspacesStepView.kt | 2 +- .../resources/version/CoderSupportedVersions.properties | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt b/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt index 5fa4c928..a767f9ca 100644 --- a/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt +++ b/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt @@ -9,9 +9,9 @@ import org.jetbrains.annotations.PropertyKey private const val BUNDLE = "version.CoderSupportedVersions" object CoderSupportedVersions : DynamicBundle(BUNDLE) { - val lastTestedVersion = CoderSemVer.parse(message("lastTestedCoderVersion")) + val maxCompatibleCoderVersion = CoderSemVer.parse(message("maxCompatibleCoderVersion")) - @Suppress("SpreadOperator") @JvmStatic + @Suppress("SpreadOperator") private fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) = getMessage(key, *params) -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt index fd6a5874..6426b2ff 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt @@ -325,7 +325,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : } } else { val coderVersion = CoderSemVer.parse(coderClient.buildVersion) - val testedCoderVersion = CoderSupportedVersions.lastTestedVersion + val testedCoderVersion = CoderSupportedVersions.maxCompatibleCoderVersion if (!testedCoderVersion.isCompatibleWith(coderVersion)) { notificationBanner.apply { diff --git a/src/main/resources/version/CoderSupportedVersions.properties b/src/main/resources/version/CoderSupportedVersions.properties index 9c25eeda..93f3fd1b 100644 --- a/src/main/resources/version/CoderSupportedVersions.properties +++ b/src/main/resources/version/CoderSupportedVersions.properties @@ -1 +1 @@ -lastTestedCoderVersion=0.13.0 +maxCompatibleCoderVersion=0.13.0 From 6ce1d6fcab457757f9dd9ed5d5bffbca9cf38b61 Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 9 Dec 2022 01:02:07 +0200 Subject: [PATCH 2/8] chore: increase max compatible Coder version to 0.13.1 --- src/main/resources/version/CoderSupportedVersions.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/version/CoderSupportedVersions.properties b/src/main/resources/version/CoderSupportedVersions.properties index 93f3fd1b..4e54607f 100644 --- a/src/main/resources/version/CoderSupportedVersions.properties +++ b/src/main/resources/version/CoderSupportedVersions.properties @@ -1 +1 @@ -maxCompatibleCoderVersion=0.13.0 +maxCompatibleCoderVersion=0.13.1 From e3fec1cca4d3115c314dfb81a12da163eebb6b21 Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 9 Dec 2022 01:24:23 +0200 Subject: [PATCH 3/8] Impl: parse the patch number from semver - update equals&hashCode - implement comparator --- .../com/coder/gateway/sdk/CoderSemVer.kt | 23 ++- src/test/groovy/CoderSemVerTest.groovy | 132 ++++++++++-------- 2 files changed, 89 insertions(+), 66 deletions(-) diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt index a7e64acc..a1ddc8c4 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt @@ -1,11 +1,12 @@ package com.coder.gateway.sdk -class CoderSemVer(private val major: Long = 0, private val minor: Long = 0) { +class CoderSemVer(private val major: Long = 0, private val minor: Long = 0, private val patch: Long = 0) : Comparable { init { require(major >= 0) { "Coder major version must be a positive number" } require(minor >= 0) { "Coder minor version must be a positive number" } + require(patch >= 0) { "Coder minor version must be a positive number" } } fun isCompatibleWith(other: CoderSemVer): Boolean { @@ -17,6 +18,11 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0) { return this.major <= other.major } + + override fun toString(): String { + return "CoderSemVer(major=$major, minor=$minor)" + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false @@ -25,6 +31,7 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0) { if (major != other.major) return false if (minor != other.minor) return false + if (patch != other.patch) return false return true } @@ -32,13 +39,20 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0) { override fun hashCode(): Int { var result = major.hashCode() result = 31 * result + minor.hashCode() + result = 31 * result + patch.hashCode() return result } - override fun toString(): String { - return "CoderSemVer(major=$major, minor=$minor)" - } + override fun compareTo(other: CoderSemVer): Int { + if (major > other.major) return 1 + if (major < other.major) return -1 + if (minor > other.minor) return 1 + if (minor < other.minor) return -1 + if (patch > other.patch) return 1 + if (patch < other.patch) return -1 + return 0 + } companion object { private val pattern = """^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$""".toRegex() @@ -52,6 +66,7 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0) { return CoderSemVer( if (matchResult.groupValues[1].isNotEmpty()) matchResult.groupValues[1].toLong() else 0, if (matchResult.groupValues[2].isNotEmpty()) matchResult.groupValues[2].toLong() else 0, + if (matchResult.groupValues[3].isNotEmpty()) matchResult.groupValues[3].toLong() else 0, ) } } diff --git a/src/test/groovy/CoderSemVerTest.groovy b/src/test/groovy/CoderSemVerTest.groovy index 1cf62366..a021f09b 100644 --- a/src/test/groovy/CoderSemVerTest.groovy +++ b/src/test/groovy/CoderSemVerTest.groovy @@ -1,5 +1,7 @@ package com.coder.gateway.sdk +import spock.lang.Ignore + class CoderSemVerTest extends spock.lang.Specification { def 'semver versions are valid'() { @@ -46,37 +48,37 @@ class CoderSemVerTest extends spock.lang.Specification { where: semver || expectedCoderSemVer - '0.0.4' || new CoderSemVer(0L, 0L) - '1.2.3' || new CoderSemVer(1L, 2L) - '10.20.30' || new CoderSemVer(10L, 20L) - '1.1.2-prerelease+meta' || new CoderSemVer(1L, 1L) - '1.1.2+meta' || new CoderSemVer(1L, 1L) - '1.1.2+meta-valid' || new CoderSemVer(1L, 1L) - '1.0.0-alpha' || new CoderSemVer(1L, 0L) - '1.0.0-beta' || new CoderSemVer(1L, 0L) - '1.0.0-alpha.beta' || new CoderSemVer(1L, 0L) - '1.0.0-alpha.beta.1' || new CoderSemVer(1L, 0L) - '1.0.0-alpha.1' || new CoderSemVer(1L, 0L) - '1.0.0-alpha0.valid' || new CoderSemVer(1L, 0L) - '1.0.0-alpha.0valid' || new CoderSemVer(1L, 0L) - '1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay' || new CoderSemVer(1L, 0L) - '1.0.0-rc.1+build.1' || new CoderSemVer(1L, 0L) - '2.0.0-rc.1+build.123' || new CoderSemVer(2L, 0L) - '1.2.3-beta' || new CoderSemVer(1L, 2L) - '10.2.3-DEV-SNAPSHOT' || new CoderSemVer(10L, 2L) - '1.2.3-SNAPSHOT-123' || new CoderSemVer(1L, 2L) - '1.0.0' || new CoderSemVer(1L, 0L) - '2.0.0' || new CoderSemVer(2L, 0L) - '1.1.7' || new CoderSemVer(1L, 1L) - '2.0.0+build.1848' || new CoderSemVer(2L, 0L) - '2.0.1-alpha.1227' || new CoderSemVer(2L, 0L) - '1.0.0-alpha+beta' || new CoderSemVer(1L, 0L) - '1.2.3----RC-SNAPSHOT.12.9.1--.12+788' || new CoderSemVer(1L, 2L) - '1.2.3----R-S.12.9.1--.12+meta' || new CoderSemVer(1L, 2L) - '1.2.3----RC-SNAPSHOT.12.9.1--.12' || new CoderSemVer(1L, 2L) - '1.0.0+0.build.1-rc.10000aaa-kk-0.1' || new CoderSemVer(1L, 0L) - '2147483647.2147483647.2147483647' || new CoderSemVer(2147483647L, 2147483647L) - '1.0.0-0A.is.legal' || new CoderSemVer(1L, 0L) + '0.0.4' || new CoderSemVer(0L, 0L, 4L) + '1.2.3' || new CoderSemVer(1L, 2L, 3L) + '10.20.30' || new CoderSemVer(10L, 20L, 30L) + '1.1.2-prerelease+meta' || new CoderSemVer(1L, 1L, 2L) + '1.1.2+meta' || new CoderSemVer(1L, 1L, 2L) + '1.1.2+meta-valid' || new CoderSemVer(1L, 1L, 2L) + '1.0.0-alpha' || new CoderSemVer(1L, 0L, 0L) + '1.0.0-beta' || new CoderSemVer(1L, 0L, 0L) + '1.0.0-alpha.beta' || new CoderSemVer(1L, 0L, 0L) + '1.0.0-alpha.beta.1' || new CoderSemVer(1L, 0L, 0L) + '1.0.0-alpha.1' || new CoderSemVer(1L, 0L, 0L) + '1.0.0-alpha0.valid' || new CoderSemVer(1L, 0L, 0L) + '1.0.0-alpha.0valid' || new CoderSemVer(1L, 0L, 0L) + '1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay' || new CoderSemVer(1L, 0L, 0L) + '1.0.0-rc.1+build.1' || new CoderSemVer(1L, 0L, 0L) + '2.0.0-rc.1+build.123' || new CoderSemVer(2L, 0L, 0L) + '1.2.3-beta' || new CoderSemVer(1L, 2L, 3L) + '10.2.3-DEV-SNAPSHOT' || new CoderSemVer(10L, 2L, 3L) + '1.2.3-SNAPSHOT-123' || new CoderSemVer(1L, 2L, 3L) + '1.0.0' || new CoderSemVer(1L, 0L, 0L) + '2.0.0' || new CoderSemVer(2L, 0L, 0L) + '1.1.7' || new CoderSemVer(1L, 1L, 7L) + '2.0.0+build.1848' || new CoderSemVer(2L, 0L, 0L) + '2.0.1-alpha.1227' || new CoderSemVer(2L, 0L, 1L) + '1.0.0-alpha+beta' || new CoderSemVer(1L, 0L, 0L) + '1.2.3----RC-SNAPSHOT.12.9.1--.12+788' || new CoderSemVer(1L, 2L, 3L) + '1.2.3----R-S.12.9.1--.12+meta' || new CoderSemVer(1L, 2L, 3L) + '1.2.3----RC-SNAPSHOT.12.9.1--.12' || new CoderSemVer(1L, 2L, 3L) + '1.0.0+0.build.1-rc.10000aaa-kk-0.1' || new CoderSemVer(1L, 0L, 0L) + '2147483647.2147483647.2147483647' || new CoderSemVer(2147483647L, 2147483647L, 2147483647L) + '1.0.0-0A.is.legal' || new CoderSemVer(1L, 0L, 0L) } def 'semver like versions that start with a `v` are considered valid'() { @@ -123,54 +125,58 @@ class CoderSemVerTest extends spock.lang.Specification { where: semver || expectedCoderSemVer - 'v0.0.4' || new CoderSemVer(0L, 0L) - 'v1.2.3' || new CoderSemVer(1L, 2L) - 'v10.20.30' || new CoderSemVer(10L, 20L) - 'v1.1.2-prerelease+meta' || new CoderSemVer(1L, 1L) - 'v1.1.2+meta' || new CoderSemVer(1L, 1L) - 'v1.1.2+meta-valid' || new CoderSemVer(1L, 1L) - 'v1.0.0-alpha' || new CoderSemVer(1L, 0L) - 'v1.0.0-beta' || new CoderSemVer(1L, 0L) - 'v1.0.0-alpha.beta' || new CoderSemVer(1L, 0L) - 'v1.0.0-alpha.beta.1' || new CoderSemVer(1L, 0L) - 'v1.0.0-alpha.1' || new CoderSemVer(1L, 0L) - 'v1.0.0-alpha0.valid' || new CoderSemVer(1L, 0L) - 'v1.0.0-alpha.0valid' || new CoderSemVer(1L, 0L) - 'v1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay' || new CoderSemVer(1L, 0L) - 'v1.0.0-rc.1+build.1' || new CoderSemVer(1L, 0L) - 'v2.0.0-rc.1+build.123' || new CoderSemVer(2L, 0L) - 'v1.2.3-beta' || new CoderSemVer(1L, 2L) - 'v10.2.3-DEV-SNAPSHOT' || new CoderSemVer(10L, 2L) - 'v1.2.3-SNAPSHOT-123' || new CoderSemVer(1L, 2L) - 'v1.0.0' || new CoderSemVer(1L, 0L) - 'v2.0.0' || new CoderSemVer(2L, 0L) - 'v1.1.7' || new CoderSemVer(1L, 1L) - 'v2.0.0+build.1848' || new CoderSemVer(2L, 0L) - 'v2.0.1-alpha.1227' || new CoderSemVer(2L, 0L) - 'v1.0.0-alpha+beta' || new CoderSemVer(1L, 0L) - 'v1.2.3----RC-SNAPSHOT.12.9.1--.12+788' || new CoderSemVer(1L, 2L) - 'v1.2.3----R-S.12.9.1--.12+meta' || new CoderSemVer(1L, 2L) - 'v1.2.3----RC-SNAPSHOT.12.9.1--.12' || new CoderSemVer(1L, 2L) - 'v1.0.0+0.build.1-rc.10000aaa-kk-0.1' || new CoderSemVer(1L, 0L) - 'v2147483647.2147483647.2147483647' || new CoderSemVer(2147483647L, 2147483647L) - 'v1.0.0-0A.is.legal' || new CoderSemVer(1L, 0L) + 'v0.0.4' || new CoderSemVer(0L, 0L, 4L) + 'v1.2.3' || new CoderSemVer(1L, 2L, 3L) + 'v10.20.30' || new CoderSemVer(10L, 20L, 30L) + 'v1.1.2-prerelease+meta' || new CoderSemVer(1L, 1L, 2L) + 'v1.1.2+meta' || new CoderSemVer(1L, 1L, 2L) + 'v1.1.2+meta-valid' || new CoderSemVer(1L, 1L, 2L) + 'v1.0.0-alpha' || new CoderSemVer(1L, 0L, 0L) + 'v1.0.0-beta' || new CoderSemVer(1L, 0L, 0L) + 'v1.0.0-alpha.beta' || new CoderSemVer(1L, 0L, 0L) + 'v1.0.0-alpha.beta.1' || new CoderSemVer(1L, 0L, 0L) + 'v1.0.0-alpha.1' || new CoderSemVer(1L, 0L, 0L) + 'v1.0.0-alpha0.valid' || new CoderSemVer(1L, 0L, 0L) + 'v1.0.0-alpha.0valid' || new CoderSemVer(1L, 0L, 0L) + 'v1.0.0-alpha-a.b-c-somethinglong+build.1-aef.1-its-okay' || new CoderSemVer(1L, 0L, 0L) + 'v1.0.0-rc.1+build.1' || new CoderSemVer(1L, 0L, 0L) + 'v2.0.0-rc.1+build.123' || new CoderSemVer(2L, 0L, 0L) + 'v1.2.3-beta' || new CoderSemVer(1L, 2L, 3L) + 'v10.2.3-DEV-SNAPSHOT' || new CoderSemVer(10L, 2L, 3L) + 'v1.2.3-SNAPSHOT-123' || new CoderSemVer(1L, 2L, 3L) + 'v1.0.0' || new CoderSemVer(1L, 0L, 0L) + 'v2.0.0' || new CoderSemVer(2L, 0L, 0L) + 'v1.1.7' || new CoderSemVer(1L, 1L, 7L) + 'v2.0.0+build.1848' || new CoderSemVer(2L, 0L, 0L) + 'v2.0.1-alpha.1227' || new CoderSemVer(2L, 0L, 1L) + 'v1.0.0-alpha+beta' || new CoderSemVer(1L, 0L, 0L) + 'v1.2.3----RC-SNAPSHOT.12.9.1--.12+788' || new CoderSemVer(1L, 2L, 3L) + 'v1.2.3----R-S.12.9.1--.12+meta' || new CoderSemVer(1L, 2L, 3L) + 'v1.2.3----RC-SNAPSHOT.12.9.1--.12' || new CoderSemVer(1L, 2L, 3L) + 'v1.0.0+0.build.1-rc.10000aaa-kk-0.1' || new CoderSemVer(1L, 0L, 0L) + 'v2147483647.2147483647.2147483647' || new CoderSemVer(2147483647L, 2147483647L, 2147483647L) + 'v1.0.0-0A.is.legal' || new CoderSemVer(1L, 0L, 0L) } + @Ignore def 'two initial development versions are compatible when first minor is equal to the second minor'() { expect: new CoderSemVer(0, 1).isCompatibleWith(new CoderSemVer(0, 1)) } + @Ignore def 'two initial development versions are not compatible when first minor is less than the second minor'() { expect: !new CoderSemVer(0, 1).isCompatibleWith(new CoderSemVer(0, 2)) } + @Ignore def 'two initial development versions are not compatible when first minor is bigger than the second minor'() { expect: !new CoderSemVer(0, 2).isCompatibleWith(new CoderSemVer(0, 1)) } + @Ignore def 'versions are not compatible when one version is initial phase of development and the other is not, even though the minor is the same'() { expect: !new CoderSemVer(0, 2).isCompatibleWith(new CoderSemVer(1, 2)) @@ -179,6 +185,7 @@ class CoderSemVerTest extends spock.lang.Specification { !new CoderSemVer(1, 2).isCompatibleWith(new CoderSemVer(0, 2)) } + @Ignore def 'two versions which are not in development phase are compatible when first major is less or equal to the other, regardless of the minor'() { expect: 'versions compatible when same major and same minor' new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(1, 1)) @@ -193,6 +200,7 @@ class CoderSemVerTest extends spock.lang.Specification { new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(2, 2)) } + @Ignore def 'two versions which are not in development phase are not compatible when first major is greater than the second major, regardless of the minor'() { expect: 'versions are not compatible when first major is bigger than the second but with same minor' !new CoderSemVer(2, 1).isCompatibleWith(new CoderSemVer(1, 1)) From 91ce5514e317a3290f4c7024e0ce06cffefd9b3c Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 9 Dec 2022 22:43:17 +0200 Subject: [PATCH 4/8] impl: check if Coder version is in range - compare if version is in between min&max supported versions of Coder --- src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt | 1 + src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt | 1 + .../com/coder/gateway/views/steps/CoderWorkspacesStepView.kt | 4 +--- src/main/resources/version/CoderSupportedVersions.properties | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt b/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt index a767f9ca..43464325 100644 --- a/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt +++ b/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt @@ -9,6 +9,7 @@ import org.jetbrains.annotations.PropertyKey private const val BUNDLE = "version.CoderSupportedVersions" object CoderSupportedVersions : DynamicBundle(BUNDLE) { + val minCompatibleCoderVersion = CoderSemVer.parse(message("minCompatibleCoderVersion")) val maxCompatibleCoderVersion = CoderSemVer.parse(message("maxCompatibleCoderVersion")) @JvmStatic diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt index a1ddc8c4..9acd4468 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt @@ -9,6 +9,7 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0, priv require(patch >= 0) { "Coder minor version must be a positive number" } } + fun isInClosedRange(start: CoderSemVer, endInclusive: CoderSemVer) = this in start..endInclusive fun isCompatibleWith(other: CoderSemVer): Boolean { // in the initial development phase minor changes when there are API incompatibilities if (this.major == 0L) { diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt index 6426b2ff..167f8f06 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt @@ -325,9 +325,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : } } else { val coderVersion = CoderSemVer.parse(coderClient.buildVersion) - val testedCoderVersion = CoderSupportedVersions.maxCompatibleCoderVersion - - if (!testedCoderVersion.isCompatibleWith(coderVersion)) { + if (!coderVersion.isInClosedRange(CoderSupportedVersions.minCompatibleCoderVersion, CoderSupportedVersions.maxCompatibleCoderVersion)) { notificationBanner.apply { component.isVisible = true showWarning(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.unsupported.coder.version", coderClient.buildVersion)) diff --git a/src/main/resources/version/CoderSupportedVersions.properties b/src/main/resources/version/CoderSupportedVersions.properties index 4e54607f..12ba1ee3 100644 --- a/src/main/resources/version/CoderSupportedVersions.properties +++ b/src/main/resources/version/CoderSupportedVersions.properties @@ -1 +1,2 @@ +minCompatibleCoderVersion=0.12.9 maxCompatibleCoderVersion=0.13.1 From 566b8e5e54c70de4051acbc2c8bb9763fcd491f3 Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 9 Dec 2022 22:44:10 +0200 Subject: [PATCH 5/8] chore: remove unused code --- .../com/coder/gateway/sdk/CoderSemVer.kt | 8 --- src/test/groovy/CoderSemVerTest.groovy | 56 ------------------- 2 files changed, 64 deletions(-) diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt index 9acd4468..1df22547 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt @@ -10,14 +10,6 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0, priv } fun isInClosedRange(start: CoderSemVer, endInclusive: CoderSemVer) = this in start..endInclusive - fun isCompatibleWith(other: CoderSemVer): Boolean { - // in the initial development phase minor changes when there are API incompatibilities - if (this.major == 0L) { - if (other.major > 0) return false - return this.minor == other.minor - } - return this.major <= other.major - } override fun toString(): String { diff --git a/src/test/groovy/CoderSemVerTest.groovy b/src/test/groovy/CoderSemVerTest.groovy index a021f09b..5a3960ae 100644 --- a/src/test/groovy/CoderSemVerTest.groovy +++ b/src/test/groovy/CoderSemVerTest.groovy @@ -1,7 +1,5 @@ package com.coder.gateway.sdk -import spock.lang.Ignore - class CoderSemVerTest extends spock.lang.Specification { def 'semver versions are valid'() { @@ -157,58 +155,4 @@ class CoderSemVerTest extends spock.lang.Specification { 'v2147483647.2147483647.2147483647' || new CoderSemVer(2147483647L, 2147483647L, 2147483647L) 'v1.0.0-0A.is.legal' || new CoderSemVer(1L, 0L, 0L) } - - @Ignore - def 'two initial development versions are compatible when first minor is equal to the second minor'() { - expect: - new CoderSemVer(0, 1).isCompatibleWith(new CoderSemVer(0, 1)) - } - - @Ignore - def 'two initial development versions are not compatible when first minor is less than the second minor'() { - expect: - !new CoderSemVer(0, 1).isCompatibleWith(new CoderSemVer(0, 2)) - } - - @Ignore - def 'two initial development versions are not compatible when first minor is bigger than the second minor'() { - expect: - !new CoderSemVer(0, 2).isCompatibleWith(new CoderSemVer(0, 1)) - } - - @Ignore - def 'versions are not compatible when one version is initial phase of development and the other is not, even though the minor is the same'() { - expect: - !new CoderSemVer(0, 2).isCompatibleWith(new CoderSemVer(1, 2)) - - and: - !new CoderSemVer(1, 2).isCompatibleWith(new CoderSemVer(0, 2)) - } - - @Ignore - def 'two versions which are not in development phase are compatible when first major is less or equal to the other, regardless of the minor'() { - expect: 'versions compatible when same major and same minor' - new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(1, 1)) - - and: 'they are also compatible when major is the same but minor is different' - new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(1, 2)) - - and: 'they are also compatible when first major is less than the second major but with same minor' - new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(2, 1)) - - and: 'they are also compatible when first major is less than the second major and also with a different minor' - new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(2, 2)) - } - - @Ignore - def 'two versions which are not in development phase are not compatible when first major is greater than the second major, regardless of the minor'() { - expect: 'versions are not compatible when first major is bigger than the second but with same minor' - !new CoderSemVer(2, 1).isCompatibleWith(new CoderSemVer(1, 1)) - - and: 'they are also not compatible when minor first minor is less than the second minor' - !new CoderSemVer(2, 1).isCompatibleWith(new CoderSemVer(1, 2)) - - and: 'also also not compatible when minor first minor is bigger than the second minor' - !new CoderSemVer(2, 3).isCompatibleWith(new CoderSemVer(1, 2)) - } } From 1e77f43b549fa33c2ffa6fd843d5c4e6d82c8805 Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 9 Dec 2022 22:43:17 +0200 Subject: [PATCH 6/8] impl: check if Coder version is in range - compare if version is in between min&max supported versions of Coder - resolves #113 --- src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt | 1 + src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt | 1 + .../com/coder/gateway/views/steps/CoderWorkspacesStepView.kt | 4 +--- src/main/resources/version/CoderSupportedVersions.properties | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt b/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt index a767f9ca..43464325 100644 --- a/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt +++ b/src/main/kotlin/com/coder/gateway/CoderSupportedVersions.kt @@ -9,6 +9,7 @@ import org.jetbrains.annotations.PropertyKey private const val BUNDLE = "version.CoderSupportedVersions" object CoderSupportedVersions : DynamicBundle(BUNDLE) { + val minCompatibleCoderVersion = CoderSemVer.parse(message("minCompatibleCoderVersion")) val maxCompatibleCoderVersion = CoderSemVer.parse(message("maxCompatibleCoderVersion")) @JvmStatic diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt index a1ddc8c4..9acd4468 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt @@ -9,6 +9,7 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0, priv require(patch >= 0) { "Coder minor version must be a positive number" } } + fun isInClosedRange(start: CoderSemVer, endInclusive: CoderSemVer) = this in start..endInclusive fun isCompatibleWith(other: CoderSemVer): Boolean { // in the initial development phase minor changes when there are API incompatibilities if (this.major == 0L) { diff --git a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt index 6426b2ff..167f8f06 100644 --- a/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt +++ b/src/main/kotlin/com/coder/gateway/views/steps/CoderWorkspacesStepView.kt @@ -325,9 +325,7 @@ class CoderWorkspacesStepView(val enableNextButtonCallback: (Boolean) -> Unit) : } } else { val coderVersion = CoderSemVer.parse(coderClient.buildVersion) - val testedCoderVersion = CoderSupportedVersions.maxCompatibleCoderVersion - - if (!testedCoderVersion.isCompatibleWith(coderVersion)) { + if (!coderVersion.isInClosedRange(CoderSupportedVersions.minCompatibleCoderVersion, CoderSupportedVersions.maxCompatibleCoderVersion)) { notificationBanner.apply { component.isVisible = true showWarning(CoderGatewayBundle.message("gateway.connector.view.coder.workspaces.unsupported.coder.version", coderClient.buildVersion)) diff --git a/src/main/resources/version/CoderSupportedVersions.properties b/src/main/resources/version/CoderSupportedVersions.properties index 4e54607f..12ba1ee3 100644 --- a/src/main/resources/version/CoderSupportedVersions.properties +++ b/src/main/resources/version/CoderSupportedVersions.properties @@ -1 +1,2 @@ +minCompatibleCoderVersion=0.12.9 maxCompatibleCoderVersion=0.13.1 From cf20457d74919864300edd3b9a864f860d2bdd12 Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 9 Dec 2022 22:44:10 +0200 Subject: [PATCH 7/8] chore: remove unused code --- .../com/coder/gateway/sdk/CoderSemVer.kt | 8 --- src/test/groovy/CoderSemVerTest.groovy | 56 ------------------- 2 files changed, 64 deletions(-) diff --git a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt index 9acd4468..1df22547 100644 --- a/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt +++ b/src/main/kotlin/com/coder/gateway/sdk/CoderSemVer.kt @@ -10,14 +10,6 @@ class CoderSemVer(private val major: Long = 0, private val minor: Long = 0, priv } fun isInClosedRange(start: CoderSemVer, endInclusive: CoderSemVer) = this in start..endInclusive - fun isCompatibleWith(other: CoderSemVer): Boolean { - // in the initial development phase minor changes when there are API incompatibilities - if (this.major == 0L) { - if (other.major > 0) return false - return this.minor == other.minor - } - return this.major <= other.major - } override fun toString(): String { diff --git a/src/test/groovy/CoderSemVerTest.groovy b/src/test/groovy/CoderSemVerTest.groovy index a021f09b..5a3960ae 100644 --- a/src/test/groovy/CoderSemVerTest.groovy +++ b/src/test/groovy/CoderSemVerTest.groovy @@ -1,7 +1,5 @@ package com.coder.gateway.sdk -import spock.lang.Ignore - class CoderSemVerTest extends spock.lang.Specification { def 'semver versions are valid'() { @@ -157,58 +155,4 @@ class CoderSemVerTest extends spock.lang.Specification { 'v2147483647.2147483647.2147483647' || new CoderSemVer(2147483647L, 2147483647L, 2147483647L) 'v1.0.0-0A.is.legal' || new CoderSemVer(1L, 0L, 0L) } - - @Ignore - def 'two initial development versions are compatible when first minor is equal to the second minor'() { - expect: - new CoderSemVer(0, 1).isCompatibleWith(new CoderSemVer(0, 1)) - } - - @Ignore - def 'two initial development versions are not compatible when first minor is less than the second minor'() { - expect: - !new CoderSemVer(0, 1).isCompatibleWith(new CoderSemVer(0, 2)) - } - - @Ignore - def 'two initial development versions are not compatible when first minor is bigger than the second minor'() { - expect: - !new CoderSemVer(0, 2).isCompatibleWith(new CoderSemVer(0, 1)) - } - - @Ignore - def 'versions are not compatible when one version is initial phase of development and the other is not, even though the minor is the same'() { - expect: - !new CoderSemVer(0, 2).isCompatibleWith(new CoderSemVer(1, 2)) - - and: - !new CoderSemVer(1, 2).isCompatibleWith(new CoderSemVer(0, 2)) - } - - @Ignore - def 'two versions which are not in development phase are compatible when first major is less or equal to the other, regardless of the minor'() { - expect: 'versions compatible when same major and same minor' - new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(1, 1)) - - and: 'they are also compatible when major is the same but minor is different' - new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(1, 2)) - - and: 'they are also compatible when first major is less than the second major but with same minor' - new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(2, 1)) - - and: 'they are also compatible when first major is less than the second major and also with a different minor' - new CoderSemVer(1, 1).isCompatibleWith(new CoderSemVer(2, 2)) - } - - @Ignore - def 'two versions which are not in development phase are not compatible when first major is greater than the second major, regardless of the minor'() { - expect: 'versions are not compatible when first major is bigger than the second but with same minor' - !new CoderSemVer(2, 1).isCompatibleWith(new CoderSemVer(1, 1)) - - and: 'they are also not compatible when minor first minor is less than the second minor' - !new CoderSemVer(2, 1).isCompatibleWith(new CoderSemVer(1, 2)) - - and: 'also also not compatible when minor first minor is bigger than the second minor' - !new CoderSemVer(2, 3).isCompatibleWith(new CoderSemVer(1, 2)) - } } From 24b00beff2a360626aaf3df28718792742733a9e Mon Sep 17 00:00:00 2001 From: Faur Ioan-Aurel Date: Fri, 9 Dec 2022 23:31:27 +0200 Subject: [PATCH 8/8] impl: add UTs --- src/test/groovy/CoderSemVerTest.groovy | 131 ++++++++++++++++++++++++- 1 file changed, 127 insertions(+), 4 deletions(-) diff --git a/src/test/groovy/CoderSemVerTest.groovy b/src/test/groovy/CoderSemVerTest.groovy index 5a3960ae..e20dbec1 100644 --- a/src/test/groovy/CoderSemVerTest.groovy +++ b/src/test/groovy/CoderSemVerTest.groovy @@ -1,8 +1,11 @@ package com.coder.gateway.sdk +import spock.lang.Unroll + +@Unroll class CoderSemVerTest extends spock.lang.Specification { - def 'semver versions are valid'() { + def "#semver is valid"() { expect: CoderSemVer.isValidVersion(semver) @@ -40,7 +43,7 @@ class CoderSemVerTest extends spock.lang.Specification { '1.0.0-0A.is.legal'] } - def 'semver versions are parsed and correct major and minor values are extracted'() { + def "#semver version is parsed and correct major, minor and patch values are extracted"() { expect: CoderSemVer.parse(semver) == expectedCoderSemVer @@ -79,7 +82,7 @@ class CoderSemVerTest extends spock.lang.Specification { '1.0.0-0A.is.legal' || new CoderSemVer(1L, 0L, 0L) } - def 'semver like versions that start with a `v` are considered valid'() { + def "#semver is considered valid even when it starts with `v`"() { expect: CoderSemVer.isValidVersion(semver) @@ -117,7 +120,7 @@ class CoderSemVerTest extends spock.lang.Specification { 'v1.0.0-0A.is.legal'] } - def 'semver like versions that start with a `v` are parsed and correct major and minor values are extracted'() { + def "#semver is parsed and correct major, minor and patch values are extracted even though the version starts with a `v`"() { expect: CoderSemVer.parse(semver) == expectedCoderSemVer @@ -155,4 +158,124 @@ class CoderSemVerTest extends spock.lang.Specification { 'v2147483647.2147483647.2147483647' || new CoderSemVer(2147483647L, 2147483647L, 2147483647L) 'v1.0.0-0A.is.legal' || new CoderSemVer(1L, 0L, 0L) } + + def "#firstVersion is > than #secondVersion"() { + expect: + firstVersion <=> secondVersion == 1 + + where: + firstVersion | secondVersion + new CoderSemVer(1, 0, 0) | new CoderSemVer(0, 0, 0) + new CoderSemVer(1, 0, 0) | new CoderSemVer(0, 0, 1) + new CoderSemVer(1, 0, 0) | new CoderSemVer(0, 1, 0) + new CoderSemVer(1, 0, 0) | new CoderSemVer(0, 1, 1) + + new CoderSemVer(2, 0, 0) | new CoderSemVer(1, 0, 0) + new CoderSemVer(2, 0, 0) | new CoderSemVer(1, 3, 0) + new CoderSemVer(2, 0, 0) | new CoderSemVer(1, 0, 3) + new CoderSemVer(2, 0, 0) | new CoderSemVer(1, 3, 3) + + + new CoderSemVer(0, 1, 0) | new CoderSemVer(0, 0, 1) + new CoderSemVer(0, 2, 0) | new CoderSemVer(0, 1, 0) + new CoderSemVer(0, 2, 0) | new CoderSemVer(0, 1, 2) + + new CoderSemVer(0, 0, 2) | new CoderSemVer(0, 0, 1) + } + + def "#firstVersion is == #secondVersion"() { + expect: + firstVersion <=> secondVersion == 0 + + where: + firstVersion | secondVersion + new CoderSemVer(0, 0, 0) | new CoderSemVer(0, 0, 0) + new CoderSemVer(1, 0, 0) | new CoderSemVer(1, 0, 0) + new CoderSemVer(1, 1, 0) | new CoderSemVer(1, 1, 0) + new CoderSemVer(1, 1, 1) | new CoderSemVer(1, 1, 1) + new CoderSemVer(0, 1, 0) | new CoderSemVer(0, 1, 0) + new CoderSemVer(0, 1, 1) | new CoderSemVer(0, 1, 1) + new CoderSemVer(0, 0, 1) | new CoderSemVer(0, 0, 1) + + } + + def "#firstVersion is < than #secondVersion"() { + expect: + firstVersion <=> secondVersion == -1 + + where: + firstVersion | secondVersion + new CoderSemVer(0, 0, 0) | new CoderSemVer(1, 0, 0) + new CoderSemVer(0, 0, 1) | new CoderSemVer(1, 0, 0) + new CoderSemVer(0, 1, 0) | new CoderSemVer(1, 0, 0) + new CoderSemVer(0, 1, 1) | new CoderSemVer(1, 0, 0) + + new CoderSemVer(1, 0, 0) | new CoderSemVer(2, 0, 0) + new CoderSemVer(1, 3, 0) | new CoderSemVer(2, 0, 0) + new CoderSemVer(1, 0, 3) | new CoderSemVer(2, 0, 0) + new CoderSemVer(1, 3, 3) | new CoderSemVer(2, 0, 0) + + + new CoderSemVer(0, 0, 1) | new CoderSemVer(0, 1, 0) + new CoderSemVer(0, 1, 0) | new CoderSemVer(0, 2, 0) + new CoderSemVer(0, 1, 2) | new CoderSemVer(0, 2, 0) + + new CoderSemVer(0, 0, 1) | new CoderSemVer(0, 0, 2) + } + + def 'in closed range comparison returns true when the version is equal to the left side of the range'() { + expect: + new CoderSemVer(1, 2, 3).isInClosedRange(new CoderSemVer(1, 2, 3), new CoderSemVer(7, 8, 9)) + } + + def 'in closed range comparison returns true when the version is equal to the right side of the range'() { + expect: + new CoderSemVer(7, 8, 9).isInClosedRange(new CoderSemVer(1, 2, 3), new CoderSemVer(7, 8, 9)) + } + + def "in closed range comparison returns false when #buildVersion is lower than the left side of the range"() { + expect: + buildVersion.isInClosedRange(new CoderSemVer(1, 2, 3), new CoderSemVer(7, 8, 9)) == false + + where: + buildVersion << [ + new CoderSemVer(0, 0, 0), + new CoderSemVer(0, 0, 1), + new CoderSemVer(0, 1, 0), + new CoderSemVer(1, 0, 0), + new CoderSemVer(0, 1, 1), + new CoderSemVer(1, 1, 1), + new CoderSemVer(1, 2, 1), + new CoderSemVer(0, 2, 3), + ] + } + + def "in closed range comparison returns false when #buildVersion is higher than the right side of the range"() { + expect: + buildVersion.isInClosedRange(new CoderSemVer(1, 2, 3), new CoderSemVer(7, 8, 9)) == false + + where: + buildVersion << [ + new CoderSemVer(7, 8, 10), + new CoderSemVer(7, 9, 0), + new CoderSemVer(8, 0, 0), + new CoderSemVer(8, 8, 9), + ] + } + + def "in closed range comparison returns true when #buildVersion is higher than the left side of the range but lower then the right side"() { + expect: + buildVersion.isInClosedRange(new CoderSemVer(1, 2, 3), new CoderSemVer(7, 8, 9)) == true + + where: + buildVersion << [ + new CoderSemVer(1, 2, 4), + new CoderSemVer(1, 3, 0), + new CoderSemVer(2, 0, 0), + new CoderSemVer(7, 8, 8), + new CoderSemVer(7, 7, 10), + new CoderSemVer(6, 9, 10), + + ] + } }