fun doStepByStepSwitch()

in bunch-cli/src/main/kotlin/org/jetbrains/bunches/switch.kt [136:234]


fun doStepByStepSwitch(suffixes: List<String>, repoPath: String, commitTitle: String) {
    val originBranchExtension = suffixes.first()
    val donorExtensionsInStepByStepOrder = suffixes.subList(1, suffixes.size).toSet()

    val root = File(repoPath)

    if (!isGitRoot(root)) {
        exitWithError(NO_GIT_EXCEPTION_TEXT)
    }

    val gitIgnoreParseResult = parseGitIgnore(root)

    val filesWithDonorExtensions = getFilesWithExtensions(root, gitIgnoreParseResult, donorExtensionsInStepByStepOrder)

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

    run {
        val backupChanges = HashSet<FileChange>()
        for (originFile in affectedOriginFiles) {
            val baseCopiedFile = originFile.toBunchFile(originBranchExtension)
            if (baseCopiedFile.exists()) {
                exitWithError("$SAVED_VALUE_EXISTS $baseCopiedFile")
            }

            if (originFile.exists()) {
                if (originFile.isDirectory) {
                    exitWithError("$NO_DIRECTORIES_SUPPORT $originFile")
                }

                originFile.copyTo(baseCopiedFile)
                backupChanges.add(
                    FileChange(
                        ChangeType.ADD,
                        baseCopiedFile
                    )
                )
            } else {
                // File was absent and going to be introduced.
                // Create empty bunch files to show it's going to be removed in old branch.
                baseCopiedFile.createNewFile()
                backupChanges.add(
                    FileChange(
                        ChangeType.ADD,
                        baseCopiedFile
                    )
                )
            }
        }

        if (backupChanges.isEmpty()) {
            exitWithError("No bunch files for switch found")
        }

        commitChanges(
            repoPath,
            backupChanges,
            RESTORE_BACKUP_COMMIT_TITLE
        )
    }

    for (extension in donorExtensionsInStepByStepOrder) {
        val branchChanges = HashSet<FileChange>()
        for (originFile in affectedOriginFiles) {
            val targetFile = originFile.toBunchFile(extension)
            if (!targetFile.exists()) {
                continue
            }

            if (targetFile.isDirectory) {
                exitWithError("$NO_DIRECTORIES_SUPPORT $targetFile")
            }

            val isOriginExist = originFile.exists()

            val isTargetRemoved = targetFile.readText().trim().isEmpty()
            if (!isTargetRemoved) {
                targetFile.copyTo(originFile, true)
                branchChanges.add(FileChange(if (isOriginExist) ChangeType.MODIFY else ChangeType.ADD, originFile))
            } else {
                if (isOriginExist) {
                    originFile.delete()
                    branchChanges.add(FileChange(ChangeType.REMOVE, originFile))
                } else {
                    // That mean the bunch file is redundant, but do nothing
                }
            }
        }

        if (branchChanges.isNotEmpty()) {
            commitChanges(
                repoPath,
                branchChanges,
                commitTitle.replace("{target}", extension),
                noVerify = true
            )
        }
    }
}