blob: ee99f22f26614a74dfcfeae3e40931438dc009ea [file] [log] [blame]
import java.io.InputStream
import java.util.jar.Manifest
import java.util.zip.ZipFile
val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
val distDir: String by rootProject.extra
val repoDir: String = "${rootProject.buildDir}/repo"
val kotlinVersion: String by rootProject.extra
val checkMavenArtifacts = tasks.register("checkMavenArtifacts") {
doLast {
fileTree(repoDir).checkArtifacts { zip ->
if (!zip.name.endsWith("-sources.jar"))
zip.checkCompilerVersion(kotlinVersion)
zip.checkManifest(kotlinVersion)
}
}
}
val checkDist = tasks.register("checkDistArtifacts") {
doLast {
fileTree(distDir).checkArtifacts { zip ->
zip.checkCompilerVersion(kotlinVersion)
zip.checkPluginXmlVersion(kotlinVersion)
}
}
}
tasks.register("checkArtifacts") {
dependsOn(checkDist)
dependsOn(checkMavenArtifacts)
}
fun FileTree.checkArtifacts(action: (zip: ZipFile) -> Unit) {
filter { it.extension == "jar" }.forEach { jar ->
val zip = ZipFile(jar)
if (isTeamcityBuild)
testStarted(zip.testName())
action(zip)
if (isTeamcityBuild)
testFinished(zip.testName())
}
}
fun ZipFile.checkManifest(version: String) = checkZipEntry("META-INF/MANIFEST.MF") { entryStream ->
val implementationVersion = Manifest(entryStream).mainAttributes.getValue("Implementation-Version")
"Manifest contains invalid 'Implementation-Version' value, expected: $version found: $implementationVersion".takeIf {
implementationVersion?.let { it != version } ?: false
}
}
fun ZipFile.checkCompilerVersion(version: String) = checkZipEntry("META-INF/compiler.version") {
val artifactVersion = it.bufferedReader().readLine()
"Invalid compiler.version content, expected: $version found: $artifactVersion"
.takeIf { artifactVersion != version }
}
fun ZipFile.checkPluginXmlVersion(version: String) = checkZipEntry("META-INF/plugin.xml") { inputStream ->
val pluginVersion = inputStream.bufferedReader()
.lineSequence()
.mapNotNull { Regex("""<version>([^<]+)</version>""").find(it) }
.firstOrNull()
?.groupValues
?.get(1) ?: return@checkZipEntry "Plugin version not found in plugin.xml"
"Invalid plugin version, expected version starting with '$version', actual: '$pluginVersion'"
.takeIf { !pluginVersion.startsWith(version) }
}
fun ZipFile.checkZipEntry(entryName: String, action: (entryStream: InputStream) -> String?) {
getEntry(entryName)
?.let { entry -> getInputStream(entry).use(action) }
?.let { reportProblem(testName(), it) }
}
fun ZipFile.testName() = file(name).relativeTo(file(rootDir)).invariantSeparatorsPath
fun reportProblem(artifact: String, message: String) {
if (isTeamcityBuild)
testFailed(artifact, "Artifact contains problems", message)
else
println("Artifact $artifact contains problems:\n$message")
}
fun escape(s: String): String {
return s.replace("[\\|'\\[\\]]".toRegex(), "\\|$0").replace("\n".toRegex(), "|n").replace("\r".toRegex(), "|r")
}
fun testStarted(testName: String) {
println("##teamcity[testStarted name='%s']".format(escape(testName)))
}
fun testFinished(testName: String) {
println("##teamcity[testFinished name='%s']".format(escape(testName)))
}
fun testFailed(name: String, message: String, details: String) {
println("##teamcity[testFailed name='%s' message='%s' details='%s']".format(escape(name), escape(message), escape(details)))
}