summaryrefslogtreecommitdiff
path: root/support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/DisplayUtils.kt
diff options
context:
space:
mode:
Diffstat (limited to 'support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/DisplayUtils.kt')
-rw-r--r--support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/DisplayUtils.kt415
1 files changed, 415 insertions, 0 deletions
diff --git a/support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/DisplayUtils.kt b/support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/DisplayUtils.kt
new file mode 100644
index 0000000000..213a9a21c3
--- /dev/null
+++ b/support/arara/source/src/main/kotlin/org/islandoftex/arara/utils/DisplayUtils.kt
@@ -0,0 +1,415 @@
+// SPDX-License-Identifier: BSD-3-Clause
+package org.islandoftex.arara.utils
+
+import org.islandoftex.arara.Arara
+import org.islandoftex.arara.configuration.AraraSpec
+import org.islandoftex.arara.configuration.ConfigurationUtils
+import org.islandoftex.arara.filehandling.FileHandlingUtils
+import org.islandoftex.arara.localization.LanguageController
+import org.islandoftex.arara.localization.Messages
+import org.islandoftex.arara.model.AraraException
+import org.islandoftex.arara.ruleset.Conditional
+import org.slf4j.LoggerFactory
+
+/**
+ * Implements display utilitary methods.
+ *
+ * @author Island of TeX
+ * @version 5.0
+ * @since 4.0
+ */
+object DisplayUtils {
+ // the application messages obtained from the
+ // language controller
+ private val messages = LanguageController
+
+ // get the logger context from a factory
+ private val logger = LoggerFactory.getLogger(DisplayUtils::class.java)
+
+ /**
+ * The length of the longest result match as integer.
+ */
+ private val longestMatch: Int = listOf(
+ messages.getMessage(Messages.INFO_LABEL_ON_SUCCESS),
+ messages.getMessage(Messages.INFO_LABEL_ON_FAILURE),
+ messages.getMessage(Messages.INFO_LABEL_ON_ERROR))
+ .map { it.length }.max()!!
+ /**
+ * If the longest match is longer than the width, then it will be truncated
+ * to this length.
+ */
+ private const val shortenedLongestMatch = 10
+
+ /**
+ * The default terminal width defined in the settings.
+ */
+ private val width: Int
+ get() = Arara.config[AraraSpec.Application.width]
+
+ /**
+ * Checks if the execution is in dry-run mode.
+ */
+ private val isDryRunMode: Boolean
+ get() = Arara.config[AraraSpec.Execution.dryrun]
+
+ /**
+ * Checks if the execution is in verbose mode.
+ */
+ private val isVerboseMode: Boolean
+ get() = Arara.config[AraraSpec.Execution.verbose]
+
+ /**
+ * The application path.
+ */
+ private val applicationPath: String
+ get() = try {
+ ConfigurationUtils.applicationPath.toString()
+ } catch (ae: AraraException) {
+ "[unknown application path]"
+ }
+
+ /**
+ * Displays the short version of the current entry in the terminal.
+ *
+ * @param name Rule name.
+ * @param task Task name.
+ */
+ private fun buildShortEntry(name: String, task: String) {
+ val result = if (longestMatch >= width)
+ shortenedLongestMatch
+ else
+ longestMatch
+ val space = width - result - 1
+ val line = "($name) $task ".abbreviate(space - "... ".length)
+ print(line.padEnd(space, '.') + " ")
+ }
+
+ /**
+ * Displays the short version of the current entry result in the terminal.
+ *
+ * @param value The boolean value to be displayed.
+ */
+ private fun buildShortResult(value: Boolean) {
+ val result = longestMatch
+ println(getResult(value).padStart(result))
+ }
+
+ /**
+ * Displays the current entry result in the terminal.
+ *
+ * @param value The boolean value to be displayed.
+ */
+ fun printEntryResult(value: Boolean) {
+ Arara.config[AraraSpec.UserInteraction.displayLine] = false
+ Arara.config[AraraSpec.UserInteraction.displayResult] = true
+ Arara.config[AraraSpec.Execution.status] = if (value) 0 else 1
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_TASK_RESULT
+ ) + " " + getResult(value)
+ )
+ if (!isDryRunMode) {
+ if (!isVerboseMode) {
+ buildShortResult(value)
+ } else {
+ buildLongResult(value)
+ }
+ }
+ }
+
+ /**
+ * Displays a long version of the current entry result in the terminal.
+ *
+ * @param value The boolean value to be displayed
+ */
+ private fun buildLongResult(value: Boolean) {
+ val width = width
+ println("\n" + (" " + getResult(value)).padStart(width, '-'))
+ }
+
+ /**
+ * Displays the current entry in the terminal.
+ *
+ * @param name The rule name.
+ * @param task The task name.
+ */
+ fun printEntry(name: String, task: String) {
+ logger.info(
+ messages.getMessage(
+ Messages.LOG_INFO_INTERPRET_TASK,
+ task,
+ name
+ )
+ )
+ Arara.config[AraraSpec.UserInteraction.displayLine] = true
+ Arara.config[AraraSpec.UserInteraction.displayResult] = false
+ if (!isDryRunMode) {
+ if (!isVerboseMode) {
+ buildShortEntry(name, task)
+ } else {
+ buildLongEntry(name, task)
+ }
+ } else {
+ buildDryRunEntry(name, task)
+ }
+ }
+
+ /**
+ * Displays a long version of the current entry in the terminal.
+ *
+ * @param name Rule name.
+ * @param task Task name.
+ */
+ private fun buildLongEntry(name: String, task: String) {
+ if (Arara.config[AraraSpec.UserInteraction.displayRolling]) {
+ addNewLine()
+ } else {
+ Arara.config[AraraSpec.UserInteraction.displayRolling] = true
+ }
+ println(displaySeparator())
+ println("($name) $task".abbreviate(width))
+ println(displaySeparator())
+ }
+
+ /**
+ * Displays a dry-run version of the current entry in the terminal.
+ *
+ * @param name The rule name.
+ * @param task The task name.
+ */
+ private fun buildDryRunEntry(name: String, task: String) {
+ if (Arara.config[AraraSpec.UserInteraction.displayRolling]) {
+ addNewLine()
+ } else {
+ Arara.config[AraraSpec.UserInteraction.displayRolling] = true
+ }
+ println("[DR] ($name) $task".abbreviate(width))
+ println(displaySeparator())
+ }
+
+ /**
+ * Displays the exception in the terminal.
+ *
+ * @param exception The exception object.
+ */
+ fun printException(exception: AraraException) {
+ Arara.config[AraraSpec.UserInteraction.displayException] = true
+ Arara.config[AraraSpec.Execution.status] = 2
+
+ val display = Arara.config[AraraSpec.UserInteraction.displayLine]
+ if (Arara.config[AraraSpec.UserInteraction.displayResult])
+ addNewLine()
+ if (display) {
+ if (!isDryRunMode) {
+ if (!isVerboseMode) {
+ buildShortError()
+ } else {
+ buildLongError()
+ }
+ addNewLine()
+ }
+ }
+ val text = (if (exception.hasException())
+ exception.message + " " + messages.getMessage(
+ Messages.INFO_DISPLAY_EXCEPTION_MORE_DETAILS)
+ else
+ exception.message) ?: "EXCEPTION PROVIDES NO MESSAGE"
+ // TODO: check null handling
+ logger.error(text)
+ wrapText(text)
+ if (exception.hasException()) {
+ addNewLine()
+ displayDetailsLine()
+ val details = exception.exception!!.message!!
+ logger.error(details)
+ wrapText(details)
+ }
+ }
+
+ /**
+ * Gets the string representation of the provided boolean value.
+ *
+ * @param value The boolean value.
+ * @return The string representation.
+ */
+ private fun getResult(value: Boolean): String {
+ return if (value)
+ messages.getMessage(
+ Messages.INFO_LABEL_ON_SUCCESS
+ )
+ else
+ messages.getMessage(Messages.INFO_LABEL_ON_FAILURE)
+ }
+
+ /**
+ * Displays the short version of an error in the terminal.
+ */
+ private fun buildShortError() {
+ val result = longestMatch
+ println(messages.getMessage(Messages.INFO_LABEL_ON_ERROR)
+ .padStart(result))
+ }
+
+ /**
+ * Displays the long version of an error in the terminal.
+ */
+ private fun buildLongError() {
+ println((" " + messages.getMessage(Messages.INFO_LABEL_ON_ERROR))
+ .padStart(width, '-'))
+ }
+
+ /**
+ * Displays the provided text wrapped nicely according to the default
+ * terminal width.
+ *
+ * @param text The text to be displayed.
+ */
+ fun wrapText(text: String) = println(text.wrap(width))
+
+ /**
+ * Displays the rule authors in the terminal.
+ *
+ * @param authors The list of authors.
+ */
+ fun printAuthors(authors: List<String>) {
+ val line = if (authors.size == 1)
+ messages.getMessage(Messages.INFO_LABEL_AUTHOR)
+ else
+ messages.getMessage(Messages.INFO_LABEL_AUTHORS)
+ val text = if (authors.isEmpty())
+ messages.getMessage(Messages.INFO_LABEL_NO_AUTHORS)
+ else
+ authors.joinToString(", ") { it.trim() }
+ wrapText("$line $text")
+ }
+
+ /**
+ * Displays the current conditional in the terminal.
+ *
+ * @param conditional The conditional object.
+ */
+ fun printConditional(conditional: Conditional) {
+ if (conditional.type !== Conditional.ConditionalType.NONE) {
+ wrapText(messages.getMessage(Messages.INFO_LABEL_CONDITIONAL) +
+ " (" + conditional.type + ") " +
+ conditional.condition)
+ }
+ }
+
+ /**
+ * Displays the file information in the terminal.
+ */
+ fun printFileInformation() {
+ val file = Arara.config[AraraSpec.Execution.reference]
+ val version = Arara.config[AraraSpec.Application.version]
+ val line = messages.getMessage(
+ Messages.INFO_DISPLAY_FILE_INFORMATION,
+ file.name,
+ CommonUtils.byteSizeToString(file.length()),
+ FileHandlingUtils.getLastModifiedInformation(file)
+ )
+ logger.info(messages.getMessage(
+ Messages.LOG_INFO_WELCOME_MESSAGE,
+ version
+ ))
+ logger.info(displaySeparator())
+ logger.debug("::: arara @ $applicationPath")
+ logger.debug("::: Java %s, %s".format(
+ CommonUtils.getSystemProperty("java.version",
+ "[unknown version]"),
+ CommonUtils.getSystemProperty("java.vendor",
+ "[unknown vendor]")
+ ))
+ logger.debug("::: %s".format(
+ CommonUtils.getSystemProperty("java.home",
+ "[unknown location]")
+ ))
+ logger.debug("::: %s, %s, %s".format(
+ CommonUtils.getSystemProperty("os.name",
+ "[unknown OS name]"),
+ CommonUtils.getSystemProperty("os.arch",
+ "[unknown OS arch]"),
+ CommonUtils.getSystemProperty("os.version",
+ "[unknown OS version]")
+ ))
+ logger.debug("::: user.home @ %s".format(
+ CommonUtils.getSystemProperty("user.home",
+ "[unknown user's home directory]")
+ ))
+ logger.debug("::: CF @ %s".format(Arara.config[AraraSpec.Execution
+ .configurationName]))
+ logger.debug(displaySeparator())
+ logger.info(line)
+ wrapText(line)
+ addNewLine()
+ }
+
+ /**
+ * Displays the elapsed time in the terminal.
+ *
+ * @param seconds The elapsed seconds.
+ */
+ fun printTime(seconds: Double) {
+ val language = Arara.config[AraraSpec.Execution.language]
+
+ if (Arara.config[AraraSpec.UserInteraction.displayTime]) {
+ if (Arara.config[AraraSpec.UserInteraction.displayLine] ||
+ Arara.config[AraraSpec.UserInteraction.displayException])
+ addNewLine()
+
+ val text = messages.getMessage(
+ Messages.INFO_DISPLAY_EXECUTION_TIME,
+ "%1.2f".format(language.locale, seconds))
+ logger.info(text)
+ wrapText(text)
+ }
+ }
+
+ /**
+ * Displays the application logo in the terminal.
+ */
+ fun printLogo() {
+ println("""
+ __ _ _ __ __ _ _ __ __ _
+ / _` | '__/ _` | '__/ _` |
+ | (_| | | | (_| | | | (_| |
+ \__,_|_| \__,_|_| \__,_|
+ """.trimIndent())
+ addNewLine()
+ }
+
+ /**
+ * Adds a new line in the terminal.
+ */
+ private fun addNewLine() {
+ println()
+ }
+
+ /**
+ * Displays a line containing details.
+ */
+ private fun displayDetailsLine() {
+ val line = messages.getMessage(
+ Messages.INFO_LABEL_ON_DETAILS) + " "
+ println(line.abbreviate(width).padEnd(width, '-'))
+ }
+
+ /**
+ * Gets the output separator with the provided text.
+ *
+ * @param message The provided text.
+ * @return A string containing the output separator with the provided text.
+ */
+ fun displayOutputSeparator(message: String): String {
+ return " $message ".center(width, '-')
+ }
+
+ /**
+ * Gets the line separator.
+ *
+ * @return A string containing the line separator.
+ */
+ fun displaySeparator(): String {
+ return "-".repeat(width)
+ }
+}