Skip to content

Commit

Permalink
ci: 1411 implement version (#1412)
Browse files Browse the repository at this point in the history
Fixes #1411 

Implement `Version` class (and related logic) to handle dependencies versioning

## Test Plan
> How do we know the code works?

1. run 
   ```
    git checkout master &&\
      ./gradlew clean assemble &&\
      ./gradlew dependencyUpdates -DoutputFormatter=json -DoutputDir=. &&\
      java -jar ./flank-scripts/build/libs/flank-scripts.jar  dependencies update &&\
      git diff >> dep_master
   ```
1. run
    ```
    git checkout . &&\
      git checkout 1411-implement-version &&\
      ./gradlew clean assemble &&\
      ./gradlew dependencyUpdates -DoutputFormatter=json -DoutputDir=. &&\
      java -jar ./flank-scripts/build/libs/flank-scripts.jar  dependencies update &&\
      git diff >> dep_version
    ```
1. compare dep files
    ```
    diff dep_master dep_version
    ```
1. there should be no differences (nothing is printed to the console, exit code = 0)

## Checklist

- [x] Unit tested
  • Loading branch information
pawelpasterz authored Dec 18, 2020
1 parent 2b84392 commit 5bb6870
Show file tree
Hide file tree
Showing 15 changed files with 294 additions and 85 deletions.
2 changes: 1 addition & 1 deletion flank-scripts/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ shadowJar.apply {
}
}
// <breaking change>.<feature added>.<fix/minor change>
version = "1.2.1"
version = "1.2.2"
group = "com.github.flank"

application {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package flank.scripts.dependencies.update

import flank.scripts.utils.Version
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

Expand All @@ -13,7 +14,7 @@ data class DependenciesResultCheck(
@Serializable
data class Dependency(
val group: String,
val version: String,
val version: Version,
val name: String? = null,
@SerialName("available") val availableVersion: AvailableVersion? = null
)
Expand All @@ -25,7 +26,7 @@ data class Dependencies(

@Serializable
data class AvailableVersion(
val release: String?,
val milestone: String?,
val integration: String?
val release: Version?,
val milestone: Version?,
val integration: Version?
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ val Dependency.versionToUpdate
?: availableVersion?.integration
?: version

fun GradleDependency.needsUpdate() = (running.version != current.version) || (running.version != releaseCandidate.version)
fun GradleDependency.needsUpdate() = running.version < current.version || running.version < releaseCandidate.version
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package flank.scripts.dependencies.update

import flank.scripts.utils.Version

data class DependencyUpdate(
val name: String,
val valName: String,
val oldVersion: String,
val newVersion: String
val oldVersion: Version,
val newVersion: Version
)
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package flank.scripts.dependencies.update

import flank.scripts.utils.Version
import kotlinx.serialization.Serializable

@Serializable
data class GradleDependency(
val current: GradleVersion,
val nightly: GradleVersion,
val releaseCandidate: GradleVersion,
val running: GradleVersion
val current: GradleReleaseChannel,
val nightly: GradleReleaseChannel,
val releaseCandidate: GradleReleaseChannel,
val running: GradleReleaseChannel
)

@Serializable
data class GradleVersion(
val version: String,
data class GradleReleaseChannel(
val version: Version,
val reason: String,
val isUpdateAvailable: Boolean,
val isFailure: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,9 @@ private fun updateGradleWrapper(gradleDependency: GradleDependency, gradleWrappe
findAllGradleWrapperPropertiesFiles(gradleWrapperPropertiesPath)
.forEach {
val from = gradleDependency.running.version
val to = if (gradleDependency.releaseCandidate.isUpdateAvailable)
gradleDependency.releaseCandidate.version
else
gradleDependency.current.version
val to = maxOf(gradleDependency.releaseCandidate.version, gradleDependency.current.version)
println("Update gradle wrapper $from to $to in file ${it.path}")
it.updateGradleWrapperPropertiesFile(from, to)
it.updateGradleWrapperPropertiesFile(from.toString(), to.toString())
}
}

Expand All @@ -28,8 +25,6 @@ private fun findAllGradleWrapperPropertiesFiles(gradleWrapperPropertiesPath: Str
.filter { it.fileName.toString() == GRADLE_WRAPPER_PROPERTIES_FILE }
.map { it.toFile() }

private fun File.updateGradleWrapperPropertiesFile(from: String, to: String) {
writeText(readText().replace(from, to))
}
private fun File.updateGradleWrapperPropertiesFile(from: String, to: String) = writeText(readText().replace(from, to))

private const val GRADLE_WRAPPER_PROPERTIES_FILE = "gradle-wrapper.properties"
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ private fun String.getInsertLine(
.find { containsValDeclaration(it) }
?.let {
println("Updated dependency ${it.name} from ${it.oldVersion} to ${it.newVersion}")
replaceFirst(it.oldVersion, it.newVersion)
replaceFirst(it.oldVersion.toString(), it.newVersion.toString())
}
?: this

Expand Down
52 changes: 52 additions & 0 deletions flank-scripts/src/main/kotlin/flank/scripts/utils/Version.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package flank.scripts.utils

import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

object VersionSerializer : KSerializer<Version> {
override val descriptor = PrimitiveSerialDescriptor("Version", PrimitiveKind.STRING)

override fun deserialize(decoder: Decoder): Version = parseToVersion(decoder.decodeString())

override fun serialize(encoder: Encoder, value: Version) = encoder.encodeString(value.toString())
}

@Serializable(with = VersionSerializer::class)
data class Version(
private val major: Int? = null,
private val minor: Int? = null,
private val micro: Int? = null,
private val patch: Int? = null,
private val qualifier: String? = null
) : Comparable<Version> {
private val hasSuffix = major != null && qualifier != null

override operator fun compareTo(other: Version): Int = when {
major differs other.major -> compareValuesBy(major, other.major, { it ?: 0 })
minor differs other.minor -> compareValuesBy(minor, other.minor, { it ?: 0 })
micro differs other.micro -> compareValuesBy(micro, other.micro, { it ?: 0 })
patch differs other.patch -> compareValuesBy(patch, other.patch, { it ?: 0 })
else -> nullsLast<String>().compare(qualifier, other.qualifier)
}

private infix fun Int?.differs(other: Int?) = (this ?: 0) != (other ?: 0)

override fun toString(): String = listOfNotNull(major, minor, micro, patch)
.joinToString(".") + "${if (hasSuffix) "-" else ""}${qualifier ?: ""}"
}

fun parseToVersion(versionString: String): Version {
val groups = "(\\d*)\\.?(\\d*)\\.?(\\d*)\\.?(\\d*)[-.]?([a-zA-Z0-9_.-]*)".toRegex().find(versionString)?.groupValues
return if (groups == null) Version(qualifier = versionString)
else Version(
major = groups[1].toIntOrNull(),
minor = groups[2].toIntOrNull(),
micro = groups[3].toIntOrNull(),
patch = groups[4].toIntOrNull(),
qualifier = if (groups[5].isNotBlank()) groups[5] else null
)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package flank.scripts.dependencies.update

import flank.scripts.utils.toAvailableVersion
import flank.scripts.utils.toDependency
import flank.scripts.utils.toGradleReleaseChannel
import org.junit.Test

import org.junit.Assert.assertEquals
Expand All @@ -11,7 +14,7 @@ class DependencyExtensionsTest {
@Test
fun `should return group with name`() {
// given
val dependency = Dependency(
val dependency = toDependency(
"group",
"1.0",
"name"
Expand All @@ -26,11 +29,11 @@ class DependencyExtensionsTest {

@Test
fun `should get version to update if release available`() {
val dependency = Dependency(
val dependency = toDependency(
"group",
"1.0",
"name",
AvailableVersion(
toAvailableVersion(
"1.1", null, null
)
)
Expand All @@ -44,11 +47,11 @@ class DependencyExtensionsTest {

@Test
fun `should get version to update if milestone available`() {
val dependency = Dependency(
val dependency = toDependency(
"group",
"1.0",
"name",
AvailableVersion(null, "1.1", null)
toAvailableVersion(null, "1.1", null)
)

// when
Expand All @@ -60,11 +63,11 @@ class DependencyExtensionsTest {

@Test
fun `should get version to update if integration available`() {
val dependency = Dependency(
val dependency = toDependency(
"group",
"1.0",
"name",
AvailableVersion(null, null, "1.1")
toAvailableVersion(null, null, "1.1")
)

// when
Expand All @@ -76,7 +79,7 @@ class DependencyExtensionsTest {

@Test
fun `should get current version to update if no update`() {
val dependency = Dependency(
val dependency = toDependency(
"group",
"1.0",
"name",
Expand All @@ -94,22 +97,22 @@ class DependencyExtensionsTest {
fun `should properly check if gradle needs update`() {
// given
val gradleWhichNeedsUpdate = GradleDependency(
current = GradleVersion("1.1", "test", false, false),
nightly = GradleVersion("1.3", "test", false, false),
releaseCandidate = GradleVersion("1.2rc", "test", false, false),
running = GradleVersion("1", "test", false, false),
current = toGradleReleaseChannel("1.1", "test", false, false),
nightly = toGradleReleaseChannel("1.3", "test", false, false),
releaseCandidate = toGradleReleaseChannel("1.2rc", "test", false, false),
running = toGradleReleaseChannel("1", "test", false, false),
)
val gradleWhichNeedsUpdateRc = GradleDependency(
current = GradleVersion("1.1", "test", false, false),
nightly = GradleVersion("1.3", "test", false, false),
releaseCandidate = GradleVersion("1.2rc", "test", false, false),
running = GradleVersion("1.1", "test", false, false),
current = toGradleReleaseChannel("1.1", "test", false, false),
nightly = toGradleReleaseChannel("1.3", "test", false, false),
releaseCandidate = toGradleReleaseChannel("1.2rc", "test", false, false),
running = toGradleReleaseChannel("1.1", "test", false, false),
)
val gradleWhichDoesNotNeedUpdate = GradleDependency(
current = GradleVersion("1.1", "test", false, false),
nightly = GradleVersion("1.3", "test", false, false),
releaseCandidate = GradleVersion("1.1", "test", false, false),
running = GradleVersion("1.1", "test", false, false),
current = toGradleReleaseChannel("1.1", "test", false, false),
nightly = toGradleReleaseChannel("1.3", "test", false, false),
releaseCandidate = toGradleReleaseChannel("1.1", "test", false, false),
running = toGradleReleaseChannel("1.1", "test", false, false),
)


Expand Down
Loading

0 comments on commit 5bb6870

Please sign in to comment.