fun getReducibleFiles()

in bunch-cli/src/main/kotlin/org/jetbrains/bunches/reduce.kt [79:131]


fun getReducibleFiles(repoPath: String, bunchPath: String): ArrayList<File> {
    val root = File(repoPath)
    if (!isGitRoot(root)) {
        exitWithError("Repository directory with branch is expected")
    }

    val gitignoreParseResult = parseGitIgnore(root)
    val (base, rules) = readUpdatePairsFromFile(bunchPath).resultWithExit()

    if (rules.isEmpty()) {
        exitWithError()
    }

    val extensions = rules.map { it.last() }.toSet() + base

    val filesWithDonorExtensions = root
        .walkTopDown()
        .onEnter { dir -> !shouldIgnoreDir(dir, root, gitignoreParseResult) }
        .filter { child -> child.extension in extensions }
        .toList()

    val affectedOriginFiles: Set<File> =
        filesWithDonorExtensions.mapTo(HashSet(), { child -> File(child.parentFile, child.nameWithoutExtension) })

    val reduceFiles = ArrayList<File>()
    for (affectedOriginFile in affectedOriginFiles) {
        val contentMap: Map<String, String?> = extensions.map { extension ->
            val file = if (extension == base) affectedOriginFile else affectedOriginFile.toBunchFile(extension)
            val content: String? =
                if (file.exists()) file.readText().replace(Regex("\\s*", RegexOption.MULTILINE), "") else null
            extension to content
        }.toMap()

        val checkedPairs = HashSet<UpdatePair>()
        for (rule in rules) {
            var fromExtension = rule.first()

            for (toExtension in rule.drop(1)) {
                val fromContent = contentMap[fromExtension] ?: continue
                val toContent = contentMap[toExtension] ?: continue

                if (checkedPairs.add(UpdatePair(fromExtension, toExtension))) {
                    if (toContent == fromContent) {
                        reduceFiles.add(affectedOriginFile.toBunchFile(toExtension))
                    }
                }

                fromExtension = toExtension
            }
        }
    }
    return reduceFiles
}