diff --git a/common/src/main/kotlin/utils/CommandLine.kt b/common/src/main/kotlin/utils/CommandLine.kt index 822283f..7d3a1ea 100644 --- a/common/src/main/kotlin/utils/CommandLine.kt +++ b/common/src/main/kotlin/utils/CommandLine.kt @@ -9,8 +9,8 @@ import kotlin.io.path.absolutePathString * Run a command in the command line of the system * @param args The arguments that is used to run the command, the reason this is not a String to * prevent some issues and bugs with the paths or the arguments that have spacing - * @param reasonOfRunningTheCommand This is used to tell the user why we're running this command on the system - * should be something like `to check if the system in dark mode` + * @param reasonOfRunningTheCommand This is used to tell the user why we're running this command on the system. + * Should be something like `to check if the system in dark mode` * @param isLoggingEnabled Should we print the result, output and errors to the log? * */ fun commandLine( @@ -57,6 +57,16 @@ fun commandLine( } } +/** + * Similar to [commandLine] without logging and waiting for the result. + * It doesn't handle the output or specific error to the output of the command. + * */ +fun commandLineNonBlocking(vararg args: String): Result = + runCatching { + ProcessBuilder(listOf(*args)) + .start() + } + /** * Has the similar functionality as [commandLine] specifically for using powershell commands in Windows * */ diff --git a/common/src/test/kotlin/utils/CommandLineTest.kt b/common/src/test/kotlin/utils/CommandLineTest.kt index 279a9b5..c4a1a82 100644 --- a/common/src/test/kotlin/utils/CommandLineTest.kt +++ b/common/src/test/kotlin/utils/CommandLineTest.kt @@ -13,6 +13,9 @@ class CommandLineTest { assertThrows { commandLine("java-incorrect", "--version", reasonOfRunningTheCommand = null).getOrThrow() } + assertThrows { + commandLineNonBlocking("java-incorrect", "--version").getOrThrow() + } } @Test @@ -20,6 +23,9 @@ class CommandLineTest { assertDoesNotThrow { commandLine("java", "--version", reasonOfRunningTheCommand = null).getOrThrow() } + assertDoesNotThrow { + commandLineNonBlocking("java", "--version").getOrThrow() + } } @Test diff --git a/sync-script/src/main/kotlin/services/updater/JarAutoUpdater.kt b/sync-script/src/main/kotlin/services/updater/JarAutoUpdater.kt index 5203370..777519a 100644 --- a/sync-script/src/main/kotlin/services/updater/JarAutoUpdater.kt +++ b/sync-script/src/main/kotlin/services/updater/JarAutoUpdater.kt @@ -11,12 +11,14 @@ import services.HttpResponse import utils.FileDownloader import utils.SystemInfoProvider import utils.buildHtml +import utils.commandLineNonBlocking import utils.convertBytesToReadableMegabytesAsString import utils.createFileWithParentDirectoriesOrTerminate import utils.deleteExistingOrTerminate import utils.executeBatchScriptInSeparateWindow import utils.getRunningJarFilePath import utils.moveToOrTerminate +import utils.os.LinuxDesktopEnvironment import utils.os.OperatingSystem import utils.terminateWithOrWithoutError import utils.version.SemanticVersion @@ -89,6 +91,7 @@ object JarAutoUpdater { ?.value Result.success(projectVersion) } + is HttpResponse.HttpFailure -> Result.failure(response.exception()) is HttpResponse.UnknownError -> Result.failure(response.exception) } @@ -185,6 +188,44 @@ object JarAutoUpdater { overwrite = true, fileEntityType = "JAR", ) + + // The Application has been updated without automatically relaunching it, showing a message + val (windowTitle, message) = buildUpdateSuccessMessage() + val commandArgs: Array = + when (OperatingSystem.current) { + OperatingSystem.Linux -> + when (LinuxDesktopEnvironment.current) { + LinuxDesktopEnvironment.KdePlasma -> + arrayOf( + "kdialog", + "--title", + windowTitle, + "--msgbox", + message, + ) + else -> + arrayOf( + "zenity", + "--info", + "--title", + windowTitle, + "--text", + message, + ) + } + + OperatingSystem.MacOS -> + arrayOf( + "osascript", + "-e", + "display dialog \"$message\" with title \"$windowTitle\" buttons {\"OK\"} default button \"OK\"", + ) + + else -> error("The operating system is expected to be either Linux or macOS in the current check.") + } + commandLineNonBlocking( + *commandArgs, + ).getOrThrow() }, ) } @@ -204,8 +245,7 @@ object JarAutoUpdater { } val secondsToWait = 1 - val windowTitle = "Update Complete" - val message = "${ProjectInfoConstants.DISPLAY_NAME} has been updated. Relaunch to use the new version." + val (windowTitle, message) = buildUpdateSuccessMessage() val messageVbsFilePath = SyncScriptDotMinecraftFiles.SyncScriptData.Temp.path @@ -239,4 +279,10 @@ object JarAutoUpdater { // Will require the user to launch once again after the update. terminateWithOrWithoutError() } + + private fun buildUpdateSuccessMessage(): Pair = + Pair( + "Update Complete", + "${ProjectInfoConstants.DISPLAY_NAME} has been updated. Relaunch to use the new version.", + ) }