Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: logger class #27

Merged
merged 3 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import minecraftAssetProviders.curseForge.models.CurseForgeModFileDownloadUrlRes
import minecraftAssetProviders.curseForge.models.CurseForgeModFileResponse
import services.HttpClient
import services.HttpResponse
import utils.Logger

class RemoteCurseForgeDataSource : CurseForgeDataSource {
companion object {
Expand All @@ -28,7 +29,7 @@ class RemoteCurseForgeDataSource : CurseForgeDataSource {
)
) {
is HttpResponse.Success -> {
println("ℹ\uFE0F Curse Forge Mod ($modId) File ($fileId) Json Response: ${response.body}")
Logger.info { "ℹ\uFE0F Curse Forge Mod ($modId) File ($fileId) Json Response: ${response.body}" }
Result.success(response.decodeJson<CurseForgeModFileResponse>())
}

Expand All @@ -52,7 +53,7 @@ class RemoteCurseForgeDataSource : CurseForgeDataSource {
)
return when (response) {
is HttpResponse.Success -> {
println("ℹ\uFE0F Curse Forge Mod ($modId) File ($fileId) Download URL Json Response: ${response.body}")
Logger.info { "ℹ\uFE0F Curse Forge Mod ($modId) File ($fileId) Download URL Json Response: ${response.body}" }
Result.success(response.decodeJson<CurseForgeModFileDownloadUrlResponse>())
}

Expand Down
2 changes: 2 additions & 0 deletions common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ val generateBuildConfig =
tasks.register<GenerateBuildConfigTask>("generateBuildConfig") {
// To allow overriding the current project version
val projectVersion: String? by project
val developmentMode: String? by project

val buildConfigDirectory = project.layout.buildDirectory.dir("generated")

classFullyQualifiedName.set("generated.BuildConfig")
generatedOutputDirectory.set(buildConfigDirectory)
fieldsToGenerate.put("PROJECT_VERSION", projectVersion ?: libs.versions.project.get())
fieldsToGenerate.put("DEVELOPMENT_MODE", developmentMode?.toBooleanStrictOrNull() ?: false)
}

sourceSets.main.configure {
Expand Down
13 changes: 7 additions & 6 deletions common/src/main/kotlin/gui/utils/GuiUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.formdev.flatlaf.themes.FlatMacLightLaf
import constants.SharedAssetConstants
import gui.theme.Theme
import gui.theme.ThemeMode
import utils.Logger
import utils.getResourceAsURLOrThrow
import utils.os.OperatingSystem
import java.awt.Component
Expand Down Expand Up @@ -152,14 +153,14 @@ object GuiUtils {
e.printStackTrace()

if (e is UnsupportedLookAndFeelException) {
println(
"⚠️ Couldn't switch to the selected theme \uD83C\uDFA8. It looks like this theme is not supported on your system.",
)
Logger.error {
"⚠️ Couldn't switch to the selected theme \uD83C\uDFA8. It looks like this theme is not supported on your system."
}
return
}
println(
"❌ Failed to switch to the selected theme \uD83C\uDFA8: ${e.message}",
)
Logger.error {
"❌ Failed to switch to the selected theme \uD83C\uDFA8: ${e.message}"
}
}
}

Expand Down
11 changes: 6 additions & 5 deletions common/src/main/kotlin/gui/utils/ThemeDetector.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gui.utils

import utils.Logger
import utils.SystemInfoProvider
import utils.commandLine
import utils.os.LinuxDesktopEnvironment
Expand Down Expand Up @@ -48,20 +49,20 @@ object ThemeDetector {
SystemInfoProvider.getUserHomeDirectoryPath(),
".config/kdeglobals",
)
println(
Logger.info {
"\uD83D\uDCC4 Reading the following file to check if the KDE Plasma desktop environment " +
"is in dark mode: ${kdeGlobalsFile.pathString}",
)
"is in dark mode: ${kdeGlobalsFile.pathString}"
}
return try {
val lookAndFeelPackageName =
kdeGlobalsFile.bufferedReader().useLines { line ->
line.firstOrNull { it.startsWith("LookAndFeelPackage=") }?.substringAfter('=')
}
println("✨ The KDE Plasma look and feel package name: 🎨 $lookAndFeelPackageName")
Logger.info { "✨ The KDE Plasma look and feel package name: 🎨 $lookAndFeelPackageName" }
Result.success(lookAndFeelPackageName)
} catch (e: Exception) {
e.printStackTrace()
println("❌ Error while reading the file ${kdeGlobalsFile.name}: ${e.message}")
Logger.error { "❌ Error while reading the file ${kdeGlobalsFile.name}: ${e.message}" }
Result.failure(e)
}
}
Expand Down
12 changes: 8 additions & 4 deletions common/src/main/kotlin/utils/CommandLine.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ fun commandLine(
}
append(": ${args.joinToString(" ")}")
}
println(message)
Logger.info { message }
}
return try {
val process =
Expand All @@ -39,18 +39,22 @@ fun commandLine(
process.destroy()
val errorMessage = "⏰ Process timed out for the command: ${args.joinToString(" ")}"
if (isLoggingEnabled) {
println("❌ $errorMessage")
Logger.error { "❌ $errorMessage" }
}
return Result.failure(RuntimeException(errorMessage))
}
val result = process.inputStream.bufferedReader().use { it.readText() }
if (isLoggingEnabled) {
println("✅ Command executed successfully: '${args.joinToString(" ")}'. " + "📜 Output: ${result.trim()}")
Logger.info {
"✅ Command executed successfully: '${args.joinToString(" ")}'. " + "📜 Output: ${result.trim()}"
}
}
Result.success(result)
} catch (e: Exception) {
if (isLoggingEnabled) {
println("❌ Error executing command `${args.joinToString(" ")}`: ${e.message}")
Logger.error {
"❌ Error executing command `${args.joinToString(" ")}`: ${e.message}"
}
}
e.printStackTrace()
Result.failure(e)
Expand Down
60 changes: 60 additions & 0 deletions common/src/main/kotlin/utils/Logger.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package utils

import generated.BuildConfig

/**
* A simple logger that doesn't require additional dependencies and is not compatible
* with known logging solutions. Most of the messages will be shown to the user
* in case they run the application in CLI mode either in command-line or using the launcher,
* which is why don't use something like `[main] INFO Main - The log message` in production mode.
* */
object Logger {
fun error(lazyMessage: () -> String) {
logMessage(lazyMessage = lazyMessage, logLevel = "Error")
}

fun debug(lazyMessage: () -> String) {
if (!BuildConfig.DEVELOPMENT_MODE) return
logMessage(lazyMessage = lazyMessage, logLevel = "Debug")
}

fun info(
extraLine: Boolean = false,
lazyMessage: () -> String,
) {
logMessage(
extraLine = extraLine,
lazyMessage = lazyMessage,
logLevel = "Info",
)
}

fun warning(lazyMessage: () -> String) {
logMessage(lazyMessage = lazyMessage, logLevel = "Warning")
}

fun trace(lazyMessage: () -> String) {
logMessage(lazyMessage = lazyMessage, logLevel = "Trace")
}

private fun logMessage(
/**
* Add an extra new line before printing the message
* */
extraLine: Boolean = false,
lazyMessage: () -> String,
logLevel: String,
) {
val message =
buildString {
if (extraLine) {
append("\n")
}
if (BuildConfig.DEVELOPMENT_MODE) {
append("$logLevel - ")
}
append(lazyMessage())
}
println(message)
}
}
41 changes: 22 additions & 19 deletions sync-script/src/main/kotlin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import syncService.ResourcePacksSyncService
import syncService.ServersSyncService
import syncService.SyncService
import utils.ExecutionTimer
import utils.Logger
import utils.SystemInfoProvider
import utils.createFileWithParentDirectoriesOrTerminate
import utils.deleteRecursivelyWithLegacyJavaIo
Expand All @@ -49,8 +50,8 @@ suspend fun main(args: Array<String>) {

passedArgs = args

println("📋 Current project version: ${BuildConfig.PROJECT_VERSION}")
println("\uD83D\uDCC1 Current working directory: ${SystemInfoProvider.getCurrentWorkingDirectoryPath()}")
Logger.info { "📋 Current project version: ${BuildConfig.PROJECT_VERSION}" }
Logger.info { "\uD83D\uDCC1 Current working directory: ${SystemInfoProvider.getCurrentWorkingDirectoryPath()}" }

logSystemInfo()
handleTemporaryDirectory(isStart = true)
Expand Down Expand Up @@ -79,7 +80,7 @@ suspend fun main(args: Array<String>) {

GuiState.updateIsGuiEnabled()

println("ℹ\uFE0F Script Configuration: ${ScriptConfig.instance}")
Logger.info { "ℹ\uFE0F Script Configuration: ${ScriptConfig.instance}" }

// Switch to the themes specified by config
if (GuiState.isGuiEnabled) {
Expand Down Expand Up @@ -108,28 +109,28 @@ private fun logSystemInfo() {
OperatingSystem.MacOS -> "\uD83C\uDF4F You are using macOS \uF8FF. Welcome to the world of Apple \uD83C\uDF4E."
OperatingSystem.Windows -> "\uD83E\uDE9F You are using Windows. Be safe!"
OperatingSystem.Unknown -> "❓Your operating system couldn't be identified. Let's hope everything works smoothly."
}.also { println(it) }
}.also { Logger.info { it } }

if (!GraphicsEnvironment.isHeadless()) {
if (GuiUtils.isSystemInDarkMode) {
"🌙 Welcome to the dark side! Your system is in dark mode. Enjoy the soothing darkness! 🌃"
} else {
"☀️ Brighten up your day! Your system is in the light mode. Embrace the light! 🌅"
}.also { println(it) }
}.also { Logger.info { it } }
}
}

private fun handleTemporaryDirectory(isStart: Boolean) {
SyncScriptDotMinecraftFiles.SyncScriptData.Temp.path.apply {
if (exists()) {
println(
Logger.info {
if (isStart) {
"ℹ\uFE0F The temporary folder: $pathString exist. " +
"The script might not finished last time. Removing the folder."
} else {
"\uD83D\uDEAB Deleting the temporary folder: '$pathString' (no longer needed)."
},
)
}
}
deleteRecursivelyWithLegacyJavaIo()
}
}
Expand All @@ -139,10 +140,10 @@ private suspend fun loadScriptConfig(): ScriptConfig {
val scriptConfigFile = SyncScriptDotMinecraftFiles.SyncScriptData.ScriptConfig.path
if (!scriptConfigFile.exists()) {
if (GuiState.isGuiEnabled) {
println(
"Configuration Missing! ⚠\uFE0F. Since you're in GUI mode, we'll launch a quick " +
"dialog to gather the necessary information",
)
Logger.info {
"ℹ\uFE0F Configuration Missing. Since you're in GUI mode, we'll launch a quick " +
"dialog to gather the necessary information"
}

val scriptConfig = CreateScriptConfigDialog().showDialog()
runBlocking { scriptConfigDataSource.replaceConfig(scriptConfig) }
Expand Down Expand Up @@ -248,6 +249,8 @@ private suspend fun fetchSyncInfo() {
return
}

Logger.debug { "\uD83D\uDC1E Sync Info: ${SyncInfo.instance}" }

LoadingIndicatorDialog.instance?.updateComponentProperties(
title = "Synchronization",
infoText = "Performing initial checks and configurations...",
Expand Down Expand Up @@ -275,10 +278,10 @@ private suspend fun handleAdminTrustCheck() {
// If the user doesn't say he/she trusts the admin yet, then we will ask him
val doesUserTrustThisSource = TrustAdminDialog.showDialog()
if (!doesUserTrustThisSource) {
println(
Logger.info {
"\uD83D\uDD12 Script is closing because trust in the administration is lacking. " +
"Feel free to reach out if you have any concerns.",
)
"Feel free to reach out if you have any concerns."
}
terminateWithOrWithoutError()
}
runBlocking {
Expand Down Expand Up @@ -315,9 +318,9 @@ private fun finalize(applicationExecutionTimer: ExecutionTimer) {
// after finish syncing the contents successfully, we don't need it anymore.
handleTemporaryDirectory(isStart = false)

println(
"\n\uD83C\uDF89 The script has successfully completed in " +
"(${applicationExecutionTimer.getRunningUntilNowDuration().inWholeMilliseconds}ms)! \uD83D\uDE80",
)
Logger.info(extraLine = true) {
"\uD83C\uDF89 The script has successfully completed in " +
"(${applicationExecutionTimer.getRunningUntilNowDuration().inWholeMilliseconds}ms)! \uD83D\uDE80"
}
exitProcess(0)
}
Loading