diff --git a/platform/build-scripts/icons/src/org/jetbrains/intellij/build/images/IconsClassGenerator.kt b/platform/build-scripts/icons/src/org/jetbrains/intellij/build/images/IconsClassGenerator.kt index 4d9409d9be3a..444e494bcfae 100644 --- a/platform/build-scripts/icons/src/org/jetbrains/intellij/build/images/IconsClassGenerator.kt +++ b/platform/build-scripts/icons/src/org/jetbrains/intellij/build/images/IconsClassGenerator.kt @@ -18,6 +18,7 @@ package org.jetbrains.intellij.build.images import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.text.StringUtil import com.intellij.util.containers.ContainerUtil +import com.intellij.util.diff.Diff import org.jetbrains.jps.model.JpsSimpleElement import org.jetbrains.jps.model.java.JavaSourceRootProperties import org.jetbrains.jps.model.java.JavaSourceRootType @@ -29,7 +30,7 @@ import java.util.* class IconsClassGenerator(val projectHome: File, val util: JpsModule, val writeChangesToDisk: Boolean = true) { private var processedClasses = 0 private var processedIcons = 0 - private var modifiedClasses = ArrayList>() + private var modifiedClasses = ArrayList>() fun processModule(module: JpsModule) { val customLoad: Boolean @@ -81,13 +82,30 @@ class IconsClassGenerator(val projectHome: File, val util: JpsModule, val writeC processedClasses++ if (!outFile.exists() || outFile.readText().lines() != text.lines()) { - modifiedClasses.add(Pair(module, outFile)) - if (writeChangesToDisk) { outFile.parentFile.mkdirs() outFile.writeText(text) println("Updated icons class: ${outFile.name}") } + else { + val oldLines = outFile.readText().lines() + val newLines = text.lines() + + val sb = StringBuilder() + var ch = Diff.buildChanges(oldLines.toTypedArray(), newLines.toTypedArray()) + while (ch != null) { + val deleted = oldLines.subList(ch.line0, ch.line0 + ch.deleted) + val inserted = newLines.subList(ch.line1, ch.line1 + ch.inserted) + + if (sb.isNotEmpty()) sb.append("=".repeat(20)).append("\n") + deleted.forEach { sb.append("-").append(it).append("\n") } + inserted.forEach { sb.append("+").append(it).append("\n") } + + ch = ch.link + } + + modifiedClasses.add(Triple(module, outFile, sb.toString())) + } } } } diff --git a/platform/build-scripts/icons/tests/org/jetbrains/intellij/build/images/ImageResourcesTest.kt b/platform/build-scripts/icons/tests/org/jetbrains/intellij/build/images/ImageResourcesTest.kt index efa424df9287..022169d910ce 100644 --- a/platform/build-scripts/icons/tests/org/jetbrains/intellij/build/images/ImageResourcesTest.kt +++ b/platform/build-scripts/icons/tests/org/jetbrains/intellij/build/images/ImageResourcesTest.kt @@ -220,22 +220,22 @@ private class MyIconClassFileChecker(val projectHome: File, val util: JpsModule) val generator = IconsClassGenerator(projectHome, util, false) generator.processModule(module) - generator.getModifiedClasses().forEach { (module, file) -> - failures.add(FailedTest(module, "image class file should be regenerated", file)) + generator.getModifiedClasses().forEach { (module, file, details) -> + failures.add(FailedTest(module, "image class file should be regenerated", file, details)) } } } -class FailedTest internal constructor(val module: String, val message: String, val id: String, val paths: List) { +class FailedTest internal constructor(val module: String, val message: String, val id: String, val details: String) { internal constructor(module: JpsModule, message: String, image: ImagePaths, file: File) : - this(module.name, message, image.id, listOf(file.absolutePath)) + this(module.name, message, image.id, file.absolutePath) internal constructor(module: JpsModule, message: String, image: ImagePaths) : - this(module.name, message, image.id, image.files.map { it.absolutePath }.toList()) + this(module.name, message, image.id, image.files.map { it.absolutePath }.joinToString("\n")) - internal constructor(module: JpsModule, message: String, file: File) : - this(module.name, message, file.name, listOf(file.path)) + internal constructor(module: JpsModule, message: String, file: File, details: String) : + this(module.name, message, file.name, "${file.path}\n\n$details") fun getTestName(): String = "'${module}' - $id - $message" - fun getException(): Throwable = Exception("${message}\n\n${paths.joinToString("\n")}") + fun getException(): Throwable = Exception("${message}\n\n$details".trim()) } \ No newline at end of file