From 672169f3bea96ddae63229c441b35e0db410b1e7 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 11 Apr 2018 12:59:56 +0300 Subject: [PATCH] Forgotten bunch file commit reminder --- .../kotlin/idea/vcs/BunchCheckinHandler.kt | 125 ++++++++++++++++++ idea/src/META-INF/plugin.xml | 2 + idea/src/META-INF/plugin.xml.172 | 2 + idea/src/META-INF/plugin.xml.181 | 2 + idea/src/META-INF/plugin.xml.182 | 2 + idea/src/META-INF/plugin.xml.as31 | 2 + idea/src/META-INF/plugin.xml.as32 | 2 + 7 files changed, 137 insertions(+) create mode 100644 idea/idea-jvm/src/org/jetbrains/kotlin/idea/vcs/BunchCheckinHandler.kt diff --git a/idea/idea-jvm/src/org/jetbrains/kotlin/idea/vcs/BunchCheckinHandler.kt b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/vcs/BunchCheckinHandler.kt new file mode 100644 index 00000000000..94f39165e97 --- /dev/null +++ b/idea/idea-jvm/src/org/jetbrains/kotlin/idea/vcs/BunchCheckinHandler.kt @@ -0,0 +1,125 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.vcs + +import com.intellij.BundleBase.replaceMnemonicAmpersand +import com.intellij.CommonBundle +import com.intellij.openapi.project.Project +import com.intellij.openapi.ui.Messages +import com.intellij.openapi.ui.Messages.NO +import com.intellij.openapi.ui.Messages.YES +import com.intellij.openapi.util.Key +import com.intellij.openapi.vcs.CheckinProjectPanel +import com.intellij.openapi.vcs.changes.CommitContext +import com.intellij.openapi.vcs.changes.CommitExecutor +import com.intellij.openapi.vcs.checkin.CheckinHandler +import com.intellij.openapi.vcs.checkin.CheckinHandlerFactory +import com.intellij.openapi.vcs.ui.RefreshableOnComponent +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.ui.NonFocusableCheckBox +import com.intellij.util.PairConsumer +import org.jetbrains.kotlin.psi.NotNullableUserDataProperty +import java.awt.GridLayout +import java.io.File +import javax.swing.JComponent +import javax.swing.JPanel + +private var Project.bunchFileCheckEnabled: Boolean by NotNullableUserDataProperty(Key.create("IS_BUNCH_FILE_CHECK_ENABLED"), true) + +class BunchFileCheckInHandlerFactory : CheckinHandlerFactory() { + override fun createHandler(panel: CheckinProjectPanel, commitContext: CommitContext): CheckinHandler { + return BunchCheckInHandler(panel) + } + + class BunchCheckInHandler(private val checkInProjectPanel: CheckinProjectPanel) : CheckinHandler() { + private val project get() = checkInProjectPanel.project + + override fun getBeforeCheckinConfigurationPanel(): RefreshableOnComponent? { + BunchFileUtils.bunchFile(project) ?: return null + + val bunchFilesCheckBox = NonFocusableCheckBox(replaceMnemonicAmpersand("Check &bunch files")) + return object : RefreshableOnComponent { + override fun getComponent(): JComponent { + val panel = JPanel(GridLayout(1, 0)) + panel.add(bunchFilesCheckBox) + return panel + } + + override fun refresh() {} + override fun saveState() { + project.bunchFileCheckEnabled = bunchFilesCheckBox.isSelected + } + + override fun restoreState() { + bunchFilesCheckBox.isSelected = project.bunchFileCheckEnabled + } + } + } + + override fun beforeCheckin( + executor: CommitExecutor?, + additionalDataConsumer: PairConsumer? + ): CheckinHandler.ReturnResult { + if (!project.bunchFileCheckEnabled) return CheckinHandler.ReturnResult.COMMIT + + val extensions = BunchFileUtils.bunchExtension(project)?.toSet() ?: return CheckinHandler.ReturnResult.COMMIT + + val forgottenFiles = HashSet() + val commitFiles = checkInProjectPanel.files.filter { it.isFile }.toSet() + for (file in commitFiles) { + if (file.extension in extensions) continue + + val parent = file.parent ?: continue + val name = file.name + for (extension in extensions) { + val bunchFile = File(parent, "$name.$extension") + if (bunchFile !in commitFiles && bunchFile.exists()) { + forgottenFiles.add(bunchFile) + } + } + } + + if (forgottenFiles.isEmpty()) return CheckinHandler.ReturnResult.COMMIT + + val projectBaseFile = File(project.basePath) + var filePaths = forgottenFiles.map { it.relativeTo(projectBaseFile).path }.sorted() + if (filePaths.size > 15) { + filePaths = filePaths.take(15) + "..." + } + + when (Messages.showYesNoCancelDialog( + project, + "Several bunch files haven't been updated:\n\n${filePaths.joinToString("\n")}\n\nDo you want to review them before commit?", + "Forgotten Bunch Files", "Review", "Commit", CommonBundle.getCancelButtonText(), Messages.getWarningIcon() + )) { + YES -> { + return CheckinHandler.ReturnResult.CLOSE_WINDOW + } + NO -> return CheckinHandler.ReturnResult.COMMIT + } + + return CheckinHandler.ReturnResult.CANCEL + } + } +} + +object BunchFileUtils { + fun bunchFile(project: Project): VirtualFile? { + val baseDir = project.baseDir ?: return null + return baseDir.findChild(".bunch") + } + + fun bunchExtension(project: Project): List? { + val bunchFile: VirtualFile = bunchFile(project) ?: return null + val file = File(bunchFile.path) + if (!file.exists()) return null + + val lines = file.readLines().map { it.trim() }.filter { !it.isEmpty() } + if (lines.size <= 1) return null + + return lines.drop(1).map { it.split('_').first() } + } +} diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 6d93620712d..cf0e224b50f 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -2800,6 +2800,8 @@ + + diff --git a/idea/src/META-INF/plugin.xml.172 b/idea/src/META-INF/plugin.xml.172 index 84fc15c617a..22e2ff459ef 100644 --- a/idea/src/META-INF/plugin.xml.172 +++ b/idea/src/META-INF/plugin.xml.172 @@ -2793,6 +2793,8 @@ + + diff --git a/idea/src/META-INF/plugin.xml.181 b/idea/src/META-INF/plugin.xml.181 index f46d35344b7..77e843a9e3c 100644 --- a/idea/src/META-INF/plugin.xml.181 +++ b/idea/src/META-INF/plugin.xml.181 @@ -2791,6 +2791,8 @@ + + diff --git a/idea/src/META-INF/plugin.xml.182 b/idea/src/META-INF/plugin.xml.182 index dbb88c0185b..406780c45a3 100644 --- a/idea/src/META-INF/plugin.xml.182 +++ b/idea/src/META-INF/plugin.xml.182 @@ -2792,6 +2792,8 @@ + + diff --git a/idea/src/META-INF/plugin.xml.as31 b/idea/src/META-INF/plugin.xml.as31 index fa023b316f3..a881ee86d03 100644 --- a/idea/src/META-INF/plugin.xml.as31 +++ b/idea/src/META-INF/plugin.xml.as31 @@ -2792,6 +2792,8 @@ + + diff --git a/idea/src/META-INF/plugin.xml.as32 b/idea/src/META-INF/plugin.xml.as32 index c6bc38a39f3..45a1d2dcd7a 100644 --- a/idea/src/META-INF/plugin.xml.as32 +++ b/idea/src/META-INF/plugin.xml.as32 @@ -2792,6 +2792,8 @@ + +