Support prefix notation in the MultiMessage

Error messages look better when prefixed like this:
    idea: Could not read from remote repository.
Instead of the standard mechanism which looks like this:
    Could not read from remote repository in idea
Because wordy error message text hides the repository name a bit.
This commit is contained in:
Kirill Likhodedov
2018-09-26 14:38:00 +03:00
parent 26537b6658
commit e5ebc2b5b5
4 changed files with 30 additions and 11 deletions
@@ -22,12 +22,13 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.containers.ContainerUtil
import com.intellij.vcsUtil.VcsImplUtil.getShortVcsRootName
class MultiRootMessage(project: Project, allValues: Collection<VirtualFile>, html: Boolean = true) :
MultiMessage<VirtualFile>(allValues, VirtualFile::getPath, { getShortVcsRootName(project, it) }, html)
class MultiRootMessage(project: Project, allValues: Collection<VirtualFile>, rootInPrefix: Boolean = false, html: Boolean = true) :
MultiMessage<VirtualFile>(allValues, VirtualFile::getPath, { getShortVcsRootName(project, it) }, rootInPrefix, html)
open class MultiMessage<Aspect>(private val allValues: Collection<Aspect>,
private val logPresentation: (Aspect) -> String,
private val shortPresentation: (Aspect) -> String,
private val aspectInPrefix: Boolean,
html: Boolean = true) {
private val LOG = Logger.getInstance(MultiMessage::class.java)
private val messages = ContainerUtil.newLinkedHashMap<Aspect, String>()
@@ -50,13 +51,15 @@ open class MultiMessage<Aspect>(private val allValues: Collection<Aspect>,
if (allValues.size == 1) return messages.values.first()
if (messages.size == 1) {
val (aspect, message) = messages.entries.first()
return "$message in ${shortPresentation(aspect)}"
return if (aspectInPrefix) "${shortPresentation(aspect)}: $message" else "$message in ${shortPresentation(aspect)}"
}
val grouped = messages.keys.groupBy { messages[it]!!.trim() }
if (grouped.size == 1 && allValues.size == messages.size) return messages.values.first()
return grouped.keys.joinToString(lineSeparator) {
val presentableNames = grouped[it]!!.map { shortPresentation(it) }
"$it in ${joinWithAnd(presentableNames, 5)}" }
val names = joinWithAnd(presentableNames, 5)
if (aspectInPrefix) "$names: $it" else "$it in $names"
}
}
override fun toString(): String {
@@ -87,6 +87,21 @@ class MultiMessageTest {
""".trimIndent(), multiRootMessage.asString())
}
@Test
fun `test two roots with different messages and prefix notation`() {
val idea = project.baseDir
val community = createSubDir(idea, "community")
val multiRootMessage = MultiRootMessage(project, listOf(idea, community), true, false)
multiRootMessage.append(idea, "Could not read from remote repository.")
multiRootMessage.append(community, "Authentication failed for 'https://login@bitbucket.org/login/repo.git/'")
assertEquals(
"""
idea: Could not read from remote repository.
community: Authentication failed for 'https://login@bitbucket.org/login/repo.git/'
""".trimIndent(), multiRootMessage.asString())
}
@Test
fun `test html message for three roots with same message, and one root with another`() {
val idea = project.baseDir
@@ -94,7 +109,7 @@ class MultiMessageTest {
val contrib = createSubDir(idea, "contrib")
val android = createSubDir(community, "android")
val multiRootMessage = MultiRootMessage(project, setOf(idea, community, contrib, android), true)
val multiRootMessage = MultiRootMessage(project, setOf(idea, community, contrib, android), false, true)
multiRootMessage.append(idea, "Pruned obsolete remote references: origin/fix1, origin/fix2")
multiRootMessage.append(community, "Pruned obsolete remote references: origin/fix3")
multiRootMessage.append(contrib, "Pruned obsolete remote references: origin/fix3")
@@ -106,7 +121,7 @@ class MultiMessageTest {
""".trimIndent(), multiRootMessage.asString())
}
private fun multiRootMessage(vararg roots : VirtualFile) = MultiRootMessage(project, roots.asList(), false)
private fun multiRootMessage(vararg roots : VirtualFile) = MultiRootMessage(project, roots.asList(), false, false)
private fun createSubDir(parent: VirtualFile, name: String): VirtualFile {
val vf = MockVirtualFile(true, name)
@@ -203,7 +203,7 @@ internal class GitFetchSupportImpl(val project: Project) : GitFetchSupport {
override fun totallySuccessful() = results.values.all { it.success() }
override fun error(): String? {
val errorMessage = multiRemoteMessage()
val errorMessage = multiRemoteMessage(true)
for ((remote, result) in results) {
if (result.error != null) errorMessage.append(remote, result.error)
}
@@ -211,14 +211,15 @@ internal class GitFetchSupportImpl(val project: Project) : GitFetchSupport {
}
override fun prunedRefs(): String {
val prunedRefs = multiRemoteMessage()
val prunedRefs = multiRemoteMessage(false)
for ((remote, result) in results) {
if (result.prunedRefs.isNotEmpty()) prunedRefs.append(remote, result.prunedRefs.joinToString("\n"))
}
return prunedRefs.asString()
}
private fun multiRemoteMessage() = MultiMessage(results.keys, GitRemote::getName, GitRemote::getName)
private fun multiRemoteMessage(remoteInPrefix: Boolean) =
MultiMessage(results.keys, GitRemote::getName, GitRemote::getName, remoteInPrefix)
}
private class SingleRemoteResult(val error: String?, val prunedRefs: List<String>) {
@@ -245,7 +246,7 @@ internal class GitFetchSupportImpl(val project: Project) : GitFetchSupport {
private fun doShowNotification(failureTitle: String = "Fetch Failed") {
val roots = results.keys.map { it.root }
val errorMessage = MultiRootMessage(project, roots, true)
val prunedRefs = MultiRootMessage(project, roots, true)
val prunedRefs = MultiRootMessage(project, roots)
val failed = results.filterValues { !it.totallySuccessful() }
@@ -270,7 +270,7 @@ public class GitFetcher {
@Deprecated
public boolean fetchRootsAndNotify(@NotNull Collection<GitRepository> roots,
@Nullable String errorNotificationTitle, boolean notifySuccess) {
MultiRootMessage additionalInfo = new MultiRootMessage(myProject, GitUtil.getRootsFromRepositories(roots), true);
MultiRootMessage additionalInfo = new MultiRootMessage(myProject, GitUtil.getRootsFromRepositories(roots), false, true);
for (GitRepository repository : roots) {
LOG.info("fetching " + repository);
GitFetchResult result = fetch(repository);