Skip to content

Instantly share code, notes, and snippets.

@Romain-P
Last active February 3, 2022 17:57
Show Gist options
  • Save Romain-P/f0859987c8b2ef0b8676e8705bd57ed2 to your computer and use it in GitHub Desktop.
Save Romain-P/f0859987c8b2ef0b8676e8705bd57ed2 to your computer and use it in GitHub Desktop.
Maven POM - Dependency versions hard values to properties using a script
import java.io.File
import java.util.regex.Pattern
object Main {
val propertyPattern = Pattern.compile("<dependency>\\r\\n\\s+<groupId>.+<\\/groupId>\\r\\n\\s+<artifactId>(.+)<\\/artifactId>\\r\\n\\s+<version>([0-9].+)<\\/version>", Pattern.MULTILINE).toRegex()
val duplicatePattern = Regex("<([^>]+)>([0-9.A-Za-z]+)<\\/[^>]+>")
@JvmStatic
fun main(args: Array<String>) {
mergeDuplicates()
//findDuplicates()
//generateProperties()
}
data class Version(val version: String, val artifact: String, val payload: String)
fun mergeDuplicates() {
val duplicates = findDuplicates(false)
var bom = File("bom.xml").readText()
val toMerge = mapOf(
"cxf.tools.common.version" to "cxf.version",
"weld.se.core.version" to "weld.version",
"spring.security.web.version" to "spring.version",
"narayana.jts.integration.version" to "narayana.jts.version",
"ironjacamar.jdbc.version" to "ironjacamar.version",
"hibernate.entitymanager.version" to "hibernate.version",
"jackson.mapper.asl.version" to "jackson.asl.version",
"groovy.all.version" to "groovy.version",
"activiti.engine.version" to "activiti.version",
"querydsl.jpa.version" to "querydsl.version",
"jackson.dataformat.xml.version" to "jackson.version"
)
val found = duplicates.filter { it.value.any { toMerge.containsKey(it.artifact) } }
println("${found.size} groups of properties will be merged")
found.forEach {
val properties = it.value
val version = properties.first().version
val mergePropertyName = toMerge[it.value.find { toMerge.containsKey(it.artifact) }!!.artifact]
val mergeProperty = "<$mergePropertyName>$version</$mergePropertyName>"
//remove all properties & rename references
properties.forEach {
bom = bom.replace(it.payload, "")
bom = bom.replace("\${${it.artifact}}", "\${${mergePropertyName}}")
}
//add new property
bom = bom.replace("<properties>\r\n ", "<properties>\r\n $mergeProperty\r\n ")
}
val newBom = File("bom-patched.xml").also { it.createNewFile() }
newBom.writeText(bom)
println("patched")
}
fun findDuplicates(showTrace: Boolean = true): Map<String, List<Version>> {
//load only properties
val bom = File("bom.xml").readText().split("<properties>")[1].split("</properties>")[0]
val matches = duplicatePattern.findAll(bom)
val versions = mutableMapOf<String, MutableList<Version>>()
matches.forEach {
val match = it.groups[0]!!.value
val version = it.groups[2]!!.value
val artifact = it.groups[1]!!.value
val data = Version(version, artifact, match)
if (versions.containsKey(version))
versions.get(version)!!.add(data)
else
versions.put(version, mutableListOf(data))
}
val duplicates = versions
.filter { it.value.size >= 2 }
.map { it.value.joinToString(", ", "Duplicate versions for [", "]") { it.artifact } }
if (showTrace)
println("Duplicates: ${duplicates.joinToString("\n")}")
return versions.filter { it.value.size >= 2 }
}
fun generateProperties() {
val bom = File("bom.xml").readText()
var patch = bom //cpy
val matches = propertyPattern.findAll(bom)
println("${matches.count()} properties to generate & patch")
matches.forEach {
val version = it.groups[2]!!.value
val artifact = it.groups[1]!!.value.replace("-", ".") + ".version"
val property = "<$artifact>$version</$artifact>"
val dependencyBlock = it.groups[0]!!.value
val dependencyBlockPatch = dependencyBlock.replace(version, "\${$artifact}")
patch = patch.replace(dependencyBlock, dependencyBlockPatch)
patch = patch.replace("<properties>\r\n ", "<properties>\r\n $property\r\n ")
}
val newBom = File("bom-patched.xml").also { it.createNewFile() }
newBom.writeText(patch)
println("patched")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment