From fd23de2e3d254d1dcbd4498c4aa581fb85d5dbce Mon Sep 17 00:00:00 2001 From: SettingDust Date: Sun, 6 Oct 2024 11:00:02 +0800 Subject: [PATCH 1/7] feat: add project aliases config fix #33 fix #12 --- .../teksturepako/pakku/api/data/ConfigFile.kt | 17 ++++++++++------- .../kotlin/teksturepako/pakku/api/data/Json.kt | 6 ++++++ .../teksturepako/pakku/api/data/LockFile.kt | 5 +++-- .../kotlin/teksturepako/pakku/io/ReadFile.kt | 5 +++-- .../kotlin/teksturepako/pakku/io/WriteToFile.kt | 3 ++- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt b/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt index 02d40664..dc691d58 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt @@ -2,9 +2,9 @@ package teksturepako.pakku.api.data -import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import teksturepako.pakku.api.overrides.filterOverrides +import teksturepako.pakku.api.projects.Project import teksturepako.pakku.api.projects.ProjectSide import teksturepako.pakku.api.projects.ProjectType import teksturepako.pakku.api.projects.UpdateStrategy @@ -34,16 +34,19 @@ data class ConfigFile( private val overrides: MutableList = mutableListOf(), /** A mutable list of server overrides packed up with the modpack. */ - @SerialName("server_overrides") private val serverOverrides: MutableList = mutableListOf(), + private val serverOverrides: MutableList = mutableListOf(), /** A mutable list of client overrides packed up with the modpack. */ - @SerialName("client_overrides") private val clientOverrides: MutableList = mutableListOf(), + private val clientOverrides: MutableList = mutableListOf(), /** A map of project types to their respective paths. */ val paths: MutableMap = mutableMapOf(), /** A mutable map of _project slugs, names, IDs or filenames_ to _project configs_. */ - val projects: MutableMap = mutableMapOf() + val projects: MutableMap = mutableMapOf(), + + /** A mutable map of project aliases to their respective project slugs. */ + val projectAliases: MutableMap = mutableMapOf() ) { // -- PACK -- @@ -110,8 +113,8 @@ data class ConfigFile( data class ProjectConfig( var type: ProjectType? = null, var side: ProjectSide? = null, - @SerialName("update_strategy") var updateStrategy: UpdateStrategy? = null, - @SerialName("redistributable") var redistributable: Boolean? = null, + var updateStrategy: UpdateStrategy? = null, + var redistributable: Boolean? = null, var subpath: String? = null ) @@ -136,5 +139,5 @@ data class ConfigFile( fun readToResultFrom(path: String): Result = decodeToResult(path) } - suspend fun write() = writeToFile(this, "$workingPath/$FILE_NAME", overrideText = true, format = json) + suspend fun write() = writeToFile(this, "$workingPath/$FILE_NAME", overrideText = true, format = jsonSnakeCase) } \ No newline at end of file diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt b/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt index 7d933d45..37cb50c8 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt @@ -2,6 +2,7 @@ package teksturepako.pakku.api.data import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonNamingStrategy @OptIn(ExperimentalSerializationApi::class) val json = Json { @@ -18,3 +19,8 @@ val jsonEncodeDefaults = Json { encodeDefaults = true } +@OptIn(ExperimentalSerializationApi::class) +val jsonSnakeCase = Json(json) { + namingStrategy = JsonNamingStrategy.SnakeCase +} + diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/data/LockFile.kt b/src/commonMain/kotlin/teksturepako/pakku/api/data/LockFile.kt index 082ec999..4dc74aa2 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/data/LockFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/data/LockFile.kt @@ -205,8 +205,9 @@ data class LockFile( return removed } - fun getProject(input: String): Project? = this.projects - .find { project -> input in project || project.files.any { input in it.fileName } } + fun getProject(input: String): Project? = (ConfigFile.readOrNull()?.projectAliases?.get(input) ?: input).let { transformedInput -> + this.projects.find { project -> transformedInput in project || project.files.any { transformedInput in it.fileName } } + } fun getProject(project: Project): Project? = this.projects.find { it isAlmostTheSameAs project } diff --git a/src/commonMain/kotlin/teksturepako/pakku/io/ReadFile.kt b/src/commonMain/kotlin/teksturepako/pakku/io/ReadFile.kt index dc53b9ad..c64ad8a0 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/io/ReadFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/io/ReadFile.kt @@ -4,6 +4,7 @@ import kotlinx.serialization.StringFormat import kotlinx.serialization.serializer import teksturepako.pakku.api.data.PakkuException import teksturepako.pakku.api.data.json +import teksturepako.pakku.api.data.jsonSnakeCase import kotlin.io.path.Path import kotlin.io.path.readBytes import kotlin.io.path.readText @@ -19,13 +20,13 @@ fun readPathBytesOrNull(path: String): ByteArray? } inline fun decodeOrNew( - value: T, path: String, format: StringFormat = json + value: T, path: String, format: StringFormat = jsonSnakeCase ): T = readPathTextOrNull(path)?.let { runCatching { format.decodeFromString(format.serializersModule.serializer(), it) }.getOrElse { value } } ?: value inline fun decodeToResult( - path: String, format: StringFormat = json + path: String, format: StringFormat = jsonSnakeCase ): Result = readPathTextOrNull(path)?.let { runCatching { Result.success(format.decodeFromString(format.serializersModule.serializer(), it)) }.getOrElse { exception -> Result.failure(PakkuException("Error occurred while reading '$path': ${exception.message}")) diff --git a/src/commonMain/kotlin/teksturepako/pakku/io/WriteToFile.kt b/src/commonMain/kotlin/teksturepako/pakku/io/WriteToFile.kt index e9ab660b..0c9a0803 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/io/WriteToFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/io/WriteToFile.kt @@ -6,13 +6,14 @@ import kotlinx.serialization.StringFormat import kotlinx.serialization.encodeToString import teksturepako.pakku.api.actions.ActionError import teksturepako.pakku.api.data.json +import teksturepako.pakku.api.data.jsonSnakeCase import kotlin.io.path.* suspend inline fun writeToFile( value: T, path: String, overrideText: Boolean = false, - format: StringFormat = json + format: StringFormat = jsonSnakeCase ): ActionError? { val file = Path(path) From b2bf4e06c40971a11dac250050362fe254abb2cd Mon Sep 17 00:00:00 2001 From: SettingDust Date: Sun, 6 Oct 2024 11:19:17 +0800 Subject: [PATCH 2/7] feat: add project aliases to `cfg` command --- .../kotlin/teksturepako/pakku/cli/cmd/Cfg.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Cfg.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Cfg.kt index da9b98b0..02afb941 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Cfg.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Cfg.kt @@ -4,6 +4,7 @@ import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.Context import com.github.ajalt.clikt.core.subcommands import com.github.ajalt.clikt.core.terminal +import com.github.ajalt.clikt.parameters.options.associate import com.github.ajalt.clikt.parameters.options.help import com.github.ajalt.clikt.parameters.options.option import kotlinx.coroutines.runBlocking @@ -56,6 +57,12 @@ class Cfg : CliktCommand() private val shadersPathOpt by option("--shaders-path", metavar = "path") .help("Change the path for the `${ProjectType.SHADER}` project type") + private val projectAliasesOpts: Map? by option( + "-pa", "--project-alias", + help = "Add alias for project", + metavar = "=" + ).associate() + override fun run(): Unit = runBlocking { val configFile = ConfigFile.readOrNew() @@ -128,6 +135,15 @@ class Cfg : CliktCommand() echo() } + projectAliasesOpts?.let { opt -> + for ((alias, project) in opt) + { + configFile.projectAliases[alias] = project + terminal.pSuccess("'project_aliases.$alias' set to '$project'.") + echo() + } + } + configFile.write()?.let { terminal.pError(it) echo() From 638a5da268161fc415069725b9b37fe6af196530 Mon Sep 17 00:00:00 2001 From: SettingDust Date: Sun, 6 Oct 2024 11:32:53 +0800 Subject: [PATCH 3/7] feat: resolve alias when resolving dependencies --- .../pakku/cli/ResolveDependencies.kt | 11 ++++++++--- .../kotlin/teksturepako/pakku/cli/cmd/Add.kt | 16 +++++++++++++++- .../kotlin/teksturepako/pakku/cli/cmd/AddPrj.kt | 16 +++++++++++++++- .../kotlin/teksturepako/pakku/cli/cmd/Import.kt | 16 +++++++++++++++- 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/ResolveDependencies.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/ResolveDependencies.kt index 15c5d0f8..aef57c88 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/ResolveDependencies.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/ResolveDependencies.kt @@ -4,6 +4,7 @@ import com.github.ajalt.mordant.terminal.Terminal import com.github.ajalt.mordant.terminal.info import teksturepako.pakku.api.actions.RequestHandlers import teksturepako.pakku.api.actions.createAdditionRequest +import teksturepako.pakku.api.data.ConfigFile import teksturepako.pakku.api.data.LockFile import teksturepako.pakku.api.platforms.Platform import teksturepako.pakku.api.platforms.Provider @@ -17,6 +18,7 @@ suspend fun Project.resolveDependencies( terminal: Terminal, reqHandlers: RequestHandlers, lockFile: LockFile, + configFile: ConfigFile, projectProvider: Provider, platforms: List, addAsProjects: Boolean = true @@ -29,10 +31,13 @@ suspend fun Project.resolveDependencies( for (dependencyIn in dependencies) { - if (lockFile.isProjectAdded(dependencyIn)) + val alias = configFile.projectAliases.keys.find { it in dependencyIn } + + if (lockFile.isProjectAdded(dependencyIn) || alias != null) { // Link project to dependency if the dependency is already added - lockFile.getProject(dependencyIn)?.pakkuId?.let { pakkuId -> + val project = if (alias != null) lockFile.getProject(alias) else lockFile.getProject(dependencyIn) + project?.pakkuId?.let { pakkuId -> lockFile.addPakkuLink(pakkuId, this) } } @@ -50,7 +55,7 @@ suspend fun Project.resolveDependencies( lockFile.addPakkuLink(dependency.pakkuId!!, this@resolveDependencies) // Resolve dependencies for dependency - dependency.resolveDependencies(terminal, depReqHandlers, lockFile, projectProvider, platforms) + dependency.resolveDependencies(terminal, depReqHandlers, lockFile, configFile, projectProvider, platforms) terminal.pInfo("${dependency.getFlavoredSlug()} added") }, lockFile, platforms diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Add.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Add.kt index e1833fb5..8bee7b46 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Add.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Add.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.runBlocking import teksturepako.pakku.api.actions.ActionError.NotFoundOn import teksturepako.pakku.api.actions.ActionError.ProjNotFound import teksturepako.pakku.api.actions.createAdditionRequest +import teksturepako.pakku.api.data.ConfigFile import teksturepako.pakku.api.data.LockFile import teksturepako.pakku.api.platforms.GitHub import teksturepako.pakku.api.platforms.Platform @@ -59,6 +60,12 @@ class Add : CliktCommand() return@runBlocking } + val configFile = ConfigFile.readToResult().getOrElse { + terminal.danger(it.message) + echo() + return@runBlocking + } + val platforms: List = lockFile.getPlatforms().getOrElse { terminal.danger(it.message) echo() @@ -110,7 +117,14 @@ class Add : CliktCommand() if (!noDepsFlag) { - project.resolveDependencies(terminal, reqHandlers, lockFile, projectProvider, platforms) + project.resolveDependencies( + terminal, + reqHandlers, + lockFile, + configFile, + projectProvider, + platforms + ) } terminal.pSuccess("$projMsg added") diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/AddPrj.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/AddPrj.kt index ca5b5089..ac912d15 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/AddPrj.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/AddPrj.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.runBlocking import teksturepako.pakku.api.actions.ActionError.NotFoundOn import teksturepako.pakku.api.actions.ActionError.ProjNotFound import teksturepako.pakku.api.actions.createAdditionRequest +import teksturepako.pakku.api.data.ConfigFile import teksturepako.pakku.api.data.LockFile import teksturepako.pakku.api.platforms.CurseForge import teksturepako.pakku.api.platforms.GitHub @@ -76,6 +77,12 @@ class AddPrj : CliktCommand("prj") return@runBlocking } + val configFile = ConfigFile.readToResult().getOrElse { + terminal.danger(it.message) + echo() + return@runBlocking + } + val platforms: List = lockFile.getPlatforms().getOrElse { terminal.danger(it.message) echo() @@ -127,7 +134,14 @@ class AddPrj : CliktCommand("prj") if (!noDepsFlag) { - project.resolveDependencies(terminal, reqHandlers, lockFile, projectProvider, platforms) + project.resolveDependencies( + terminal, + reqHandlers, + lockFile, + configFile, + projectProvider, + platforms + ) } terminal.pSuccess("$projMsg added") diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Import.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Import.kt index 2082ef76..9921bb4e 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Import.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Import.kt @@ -15,6 +15,7 @@ import kotlinx.coroutines.runBlocking import teksturepako.pakku.api.actions.ActionError.AlreadyAdded import teksturepako.pakku.api.actions.createAdditionRequest import teksturepako.pakku.api.actions.import.importModpackModel +import teksturepako.pakku.api.data.ConfigFile import teksturepako.pakku.api.data.LockFile import teksturepako.pakku.api.platforms.Modrinth import teksturepako.pakku.api.platforms.Platform @@ -41,6 +42,12 @@ class Import : CliktCommand() val lockFile = LockFile.readToResult().getOrNull() ?: modpackModel.toLockFile() + val configFile = ConfigFile.readToResult().getOrElse { + terminal.danger(it.message) + echo() + return@runBlocking + } + val platforms: List = lockFile.getPlatforms().getOrElse { terminal.danger(it.message) echo() @@ -67,7 +74,14 @@ class Import : CliktCommand() if (depsFlag) { - project.resolveDependencies(terminal, reqHandlers, lockFile, projectProvider, platforms) + project.resolveDependencies( + terminal, + reqHandlers, + lockFile, + configFile, + projectProvider, + platforms + ) } terminal.pSuccess("${project.getFullMsg()} added") From 4280400843a1c3e620cf712a9f8ee85937e8f166 Mon Sep 17 00:00:00 2001 From: SettingDust Date: Tue, 8 Oct 2024 10:10:50 +0800 Subject: [PATCH 4/7] refactor: make the alias as a property for project --- build.gradle.kts | 1 + .../teksturepako/pakku/api/data/ConfigFile.kt | 2 +- .../teksturepako/pakku/api/data/Json.kt | 6 --- .../teksturepako/pakku/api/data/LockFile.kt | 5 +-- .../pakku/api/projects/Project.kt | 11 +++++- .../pakku/cli/ResolveDependencies.kt | 11 ++---- .../kotlin/teksturepako/pakku/cli/cmd/Add.kt | 17 +------- .../teksturepako/pakku/cli/cmd/AddPrj.kt | 16 +------- .../teksturepako/pakku/cli/cmd/Import.kt | 16 +------- .../kotlin/teksturepako/pakku/io/ReadFile.kt | 5 +-- .../teksturepako/pakku/io/WriteToFile.kt | 3 +- .../pakku/api/projects/ProjectTest.kt | 39 +++++++++++++++++++ 12 files changed, 62 insertions(+), 70 deletions(-) create mode 100644 src/commonTest/kotlin/teksturepako/pakku/api/projects/ProjectTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index 9ce3d74e..93fb8182 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -99,6 +99,7 @@ kotlin { val commonTest by getting { dependencies { implementation(kotlin("test")) + implementation("io.mockk:mockk:1.13.12") } } diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt b/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt index dc691d58..3b89f18a 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt @@ -139,5 +139,5 @@ data class ConfigFile( fun readToResultFrom(path: String): Result = decodeToResult(path) } - suspend fun write() = writeToFile(this, "$workingPath/$FILE_NAME", overrideText = true, format = jsonSnakeCase) + suspend fun write() = writeToFile(this, "$workingPath/$FILE_NAME", overrideText = true, format = json) } \ No newline at end of file diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt b/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt index 37cb50c8..ab5ae3b6 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt @@ -18,9 +18,3 @@ val jsonEncodeDefaults = Json { classDiscriminator = "_internal" encodeDefaults = true } - -@OptIn(ExperimentalSerializationApi::class) -val jsonSnakeCase = Json(json) { - namingStrategy = JsonNamingStrategy.SnakeCase -} - diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/data/LockFile.kt b/src/commonMain/kotlin/teksturepako/pakku/api/data/LockFile.kt index 4dc74aa2..082ec999 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/data/LockFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/data/LockFile.kt @@ -205,9 +205,8 @@ data class LockFile( return removed } - fun getProject(input: String): Project? = (ConfigFile.readOrNull()?.projectAliases?.get(input) ?: input).let { transformedInput -> - this.projects.find { project -> transformedInput in project || project.files.any { transformedInput in it.fileName } } - } + fun getProject(input: String): Project? = this.projects + .find { project -> input in project || project.files.any { input in it.fileName } } fun getProject(project: Project): Project? = this.projects.find { it isAlmostTheSameAs project } diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt b/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt index 79dce8c5..4022f767 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt @@ -43,6 +43,7 @@ data class Project( @SerialName("redistributable") var redistributable: Boolean = true, private var subpath: String? = null, + var aliases: MutableSet = mutableSetOf(), var files: MutableSet ) @@ -91,14 +92,22 @@ data class Project( return this.id.values.any { it in other.id.values } || this.name.values.any { it in other.name.values } || this.slug.values.any { it in other.slug.values } + || hasAliasOf(other) } - /** Checks if the current project contains the specified string in its slugs, names or IDs. */ + /** Check if the current project has an alias of the specified project. */ + infix fun hasAliasOf(other: Project): Boolean + { + return this.aliases.any { it in other.id.values || it in other.name.values || it in other.slug.values } + } + + /** Checks if the current project contains the specified string in its slugs, names, IDs or aliases. */ operator fun contains(input: String): Boolean { return input in this.slug.values || input in this.name.values || input in this.id.values + || input in this.aliases } /** Checks if the project has any files. */ diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/ResolveDependencies.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/ResolveDependencies.kt index aef57c88..15c5d0f8 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/ResolveDependencies.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/ResolveDependencies.kt @@ -4,7 +4,6 @@ import com.github.ajalt.mordant.terminal.Terminal import com.github.ajalt.mordant.terminal.info import teksturepako.pakku.api.actions.RequestHandlers import teksturepako.pakku.api.actions.createAdditionRequest -import teksturepako.pakku.api.data.ConfigFile import teksturepako.pakku.api.data.LockFile import teksturepako.pakku.api.platforms.Platform import teksturepako.pakku.api.platforms.Provider @@ -18,7 +17,6 @@ suspend fun Project.resolveDependencies( terminal: Terminal, reqHandlers: RequestHandlers, lockFile: LockFile, - configFile: ConfigFile, projectProvider: Provider, platforms: List, addAsProjects: Boolean = true @@ -31,13 +29,10 @@ suspend fun Project.resolveDependencies( for (dependencyIn in dependencies) { - val alias = configFile.projectAliases.keys.find { it in dependencyIn } - - if (lockFile.isProjectAdded(dependencyIn) || alias != null) + if (lockFile.isProjectAdded(dependencyIn)) { // Link project to dependency if the dependency is already added - val project = if (alias != null) lockFile.getProject(alias) else lockFile.getProject(dependencyIn) - project?.pakkuId?.let { pakkuId -> + lockFile.getProject(dependencyIn)?.pakkuId?.let { pakkuId -> lockFile.addPakkuLink(pakkuId, this) } } @@ -55,7 +50,7 @@ suspend fun Project.resolveDependencies( lockFile.addPakkuLink(dependency.pakkuId!!, this@resolveDependencies) // Resolve dependencies for dependency - dependency.resolveDependencies(terminal, depReqHandlers, lockFile, configFile, projectProvider, platforms) + dependency.resolveDependencies(terminal, depReqHandlers, lockFile, projectProvider, platforms) terminal.pInfo("${dependency.getFlavoredSlug()} added") }, lockFile, platforms diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Add.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Add.kt index 8bee7b46..2e523361 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Add.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Add.kt @@ -14,7 +14,6 @@ import kotlinx.coroutines.runBlocking import teksturepako.pakku.api.actions.ActionError.NotFoundOn import teksturepako.pakku.api.actions.ActionError.ProjNotFound import teksturepako.pakku.api.actions.createAdditionRequest -import teksturepako.pakku.api.data.ConfigFile import teksturepako.pakku.api.data.LockFile import teksturepako.pakku.api.platforms.GitHub import teksturepako.pakku.api.platforms.Platform @@ -59,13 +58,6 @@ class Add : CliktCommand() echo() return@runBlocking } - - val configFile = ConfigFile.readToResult().getOrElse { - terminal.danger(it.message) - echo() - return@runBlocking - } - val platforms: List = lockFile.getPlatforms().getOrElse { terminal.danger(it.message) echo() @@ -117,14 +109,7 @@ class Add : CliktCommand() if (!noDepsFlag) { - project.resolveDependencies( - terminal, - reqHandlers, - lockFile, - configFile, - projectProvider, - platforms - ) + project.resolveDependencies(terminal, reqHandlers, lockFile, projectProvider, platforms) } terminal.pSuccess("$projMsg added") diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/AddPrj.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/AddPrj.kt index ac912d15..ca5b5089 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/AddPrj.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/AddPrj.kt @@ -14,7 +14,6 @@ import kotlinx.coroutines.runBlocking import teksturepako.pakku.api.actions.ActionError.NotFoundOn import teksturepako.pakku.api.actions.ActionError.ProjNotFound import teksturepako.pakku.api.actions.createAdditionRequest -import teksturepako.pakku.api.data.ConfigFile import teksturepako.pakku.api.data.LockFile import teksturepako.pakku.api.platforms.CurseForge import teksturepako.pakku.api.platforms.GitHub @@ -77,12 +76,6 @@ class AddPrj : CliktCommand("prj") return@runBlocking } - val configFile = ConfigFile.readToResult().getOrElse { - terminal.danger(it.message) - echo() - return@runBlocking - } - val platforms: List = lockFile.getPlatforms().getOrElse { terminal.danger(it.message) echo() @@ -134,14 +127,7 @@ class AddPrj : CliktCommand("prj") if (!noDepsFlag) { - project.resolveDependencies( - terminal, - reqHandlers, - lockFile, - configFile, - projectProvider, - platforms - ) + project.resolveDependencies(terminal, reqHandlers, lockFile, projectProvider, platforms) } terminal.pSuccess("$projMsg added") diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Import.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Import.kt index 9921bb4e..2082ef76 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Import.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Import.kt @@ -15,7 +15,6 @@ import kotlinx.coroutines.runBlocking import teksturepako.pakku.api.actions.ActionError.AlreadyAdded import teksturepako.pakku.api.actions.createAdditionRequest import teksturepako.pakku.api.actions.import.importModpackModel -import teksturepako.pakku.api.data.ConfigFile import teksturepako.pakku.api.data.LockFile import teksturepako.pakku.api.platforms.Modrinth import teksturepako.pakku.api.platforms.Platform @@ -42,12 +41,6 @@ class Import : CliktCommand() val lockFile = LockFile.readToResult().getOrNull() ?: modpackModel.toLockFile() - val configFile = ConfigFile.readToResult().getOrElse { - terminal.danger(it.message) - echo() - return@runBlocking - } - val platforms: List = lockFile.getPlatforms().getOrElse { terminal.danger(it.message) echo() @@ -74,14 +67,7 @@ class Import : CliktCommand() if (depsFlag) { - project.resolveDependencies( - terminal, - reqHandlers, - lockFile, - configFile, - projectProvider, - platforms - ) + project.resolveDependencies(terminal, reqHandlers, lockFile, projectProvider, platforms) } terminal.pSuccess("${project.getFullMsg()} added") diff --git a/src/commonMain/kotlin/teksturepako/pakku/io/ReadFile.kt b/src/commonMain/kotlin/teksturepako/pakku/io/ReadFile.kt index c64ad8a0..dc53b9ad 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/io/ReadFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/io/ReadFile.kt @@ -4,7 +4,6 @@ import kotlinx.serialization.StringFormat import kotlinx.serialization.serializer import teksturepako.pakku.api.data.PakkuException import teksturepako.pakku.api.data.json -import teksturepako.pakku.api.data.jsonSnakeCase import kotlin.io.path.Path import kotlin.io.path.readBytes import kotlin.io.path.readText @@ -20,13 +19,13 @@ fun readPathBytesOrNull(path: String): ByteArray? } inline fun decodeOrNew( - value: T, path: String, format: StringFormat = jsonSnakeCase + value: T, path: String, format: StringFormat = json ): T = readPathTextOrNull(path)?.let { runCatching { format.decodeFromString(format.serializersModule.serializer(), it) }.getOrElse { value } } ?: value inline fun decodeToResult( - path: String, format: StringFormat = jsonSnakeCase + path: String, format: StringFormat = json ): Result = readPathTextOrNull(path)?.let { runCatching { Result.success(format.decodeFromString(format.serializersModule.serializer(), it)) }.getOrElse { exception -> Result.failure(PakkuException("Error occurred while reading '$path': ${exception.message}")) diff --git a/src/commonMain/kotlin/teksturepako/pakku/io/WriteToFile.kt b/src/commonMain/kotlin/teksturepako/pakku/io/WriteToFile.kt index 0c9a0803..e9ab660b 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/io/WriteToFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/io/WriteToFile.kt @@ -6,14 +6,13 @@ import kotlinx.serialization.StringFormat import kotlinx.serialization.encodeToString import teksturepako.pakku.api.actions.ActionError import teksturepako.pakku.api.data.json -import teksturepako.pakku.api.data.jsonSnakeCase import kotlin.io.path.* suspend inline fun writeToFile( value: T, path: String, overrideText: Boolean = false, - format: StringFormat = jsonSnakeCase + format: StringFormat = json ): ActionError? { val file = Path(path) diff --git a/src/commonTest/kotlin/teksturepako/pakku/api/projects/ProjectTest.kt b/src/commonTest/kotlin/teksturepako/pakku/api/projects/ProjectTest.kt new file mode 100644 index 00000000..bb5723ff --- /dev/null +++ b/src/commonTest/kotlin/teksturepako/pakku/api/projects/ProjectTest.kt @@ -0,0 +1,39 @@ +package teksturepako.pakku.api.projects + +import io.mockk.every +import io.mockk.mockk +import kotlin.test.Test +import kotlin.test.assertTrue + +class ProjectTest +{ + @Test + fun hasAliasOf_whenProjectHasAlias_returnsTrue() + { + val project1 = mockk() { + every { id } returns mutableMapOf("id1" to "id1") + every { name } returns mutableMapOf("name1" to "name1") + every { slug } returns mutableMapOf("slug1" to "slug1") + every { aliases } returns mutableSetOf("id3") + every { hasAliasOf(any()) } answers { callOriginal() } + } + val project2 = mockk() { + every { id } returns mutableMapOf("id2" to "id2") + every { name } returns mutableMapOf("name2" to "name2") + every { slug } returns mutableMapOf("slug2" to "slug2") + every { aliases } returns mutableSetOf("name1") + every { hasAliasOf(any()) } answers { callOriginal() } + } + val project3 = mockk() { + every { id } returns mutableMapOf("id3" to "id3") + every { name } returns mutableMapOf("name3" to "name3") + every { slug } returns mutableMapOf("slug3" to "slug3") + every { aliases } returns mutableSetOf("slug2") + every { hasAliasOf(any()) } answers { callOriginal() } + } + + assertTrue(project1 hasAliasOf project3) + assertTrue(project2 hasAliasOf project1) + assertTrue(project3 hasAliasOf project2) + } +} \ No newline at end of file From e7912776118398b8f27d3d7d1885747cbc70345f Mon Sep 17 00:00:00 2001 From: SettingDust Date: Tue, 8 Oct 2024 10:16:40 +0800 Subject: [PATCH 5/7] feat: add `alias` option to `cfg prj` command --- .../teksturepako/pakku/api/data/ConfigFile.kt | 3 ++- .../teksturepako/pakku/api/projects/Project.kt | 1 + .../kotlin/teksturepako/pakku/cli/cmd/Cfg.kt | 15 --------------- .../kotlin/teksturepako/pakku/cli/cmd/CfgPrj.kt | 10 ++++++++++ 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt b/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt index 3b89f18a..c2223416 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt @@ -115,7 +115,8 @@ data class ConfigFile( var side: ProjectSide? = null, var updateStrategy: UpdateStrategy? = null, var redistributable: Boolean? = null, - var subpath: String? = null + var subpath: String? = null, + var aliases :MutableSet? = null ) // -- FILE I/O -- diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt b/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt index 4022f767..f3042fbe 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt @@ -200,6 +200,7 @@ data class Project( config.updateStrategy?.let { this.updateStrategy = it } config.redistributable?.let { this.redistributable = it } config.subpath?.let { this.subpath = it } + config.aliases?.let { this.aliases = it } } } diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Cfg.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Cfg.kt index 02afb941..e4e1ef62 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Cfg.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/Cfg.kt @@ -57,12 +57,6 @@ class Cfg : CliktCommand() private val shadersPathOpt by option("--shaders-path", metavar = "path") .help("Change the path for the `${ProjectType.SHADER}` project type") - private val projectAliasesOpts: Map? by option( - "-pa", "--project-alias", - help = "Add alias for project", - metavar = "=" - ).associate() - override fun run(): Unit = runBlocking { val configFile = ConfigFile.readOrNew() @@ -135,15 +129,6 @@ class Cfg : CliktCommand() echo() } - projectAliasesOpts?.let { opt -> - for ((alias, project) in opt) - { - configFile.projectAliases[alias] = project - terminal.pSuccess("'project_aliases.$alias' set to '$project'.") - echo() - } - } - configFile.write()?.let { terminal.pError(it) echo() diff --git a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/CfgPrj.kt b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/CfgPrj.kt index bc456924..51394d2b 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/CfgPrj.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/cli/cmd/CfgPrj.kt @@ -58,6 +58,9 @@ class CfgPrj : CliktCommand("prj") private val subpathOpt: String? by option("-p", "--subpath", metavar = "path") .help("Change the subpath of the project") + private val aliasOpt: String? by option("-a", "--alias", metavar = "alias") + .help("Add alias to the project") + override fun run(): Unit = runBlocking { val lockFile = LockFile.readToResult().getOrElse { terminal.danger(it.message) @@ -106,6 +109,13 @@ class CfgPrj : CliktCommand("prj") terminal.pSuccess("'projects.$arg.subpath' set to '$opt'.") echo() } + + aliasOpt?.let { opt -> + if (aliases == null) aliases = mutableSetOf() + aliases!!.add(opt) + terminal.pSuccess("'projects.$arg.aliases' add '$opt'.") + echo() + } } } From 99d45fde28f63fbe87a7b49dd8c9896a5b16224a Mon Sep 17 00:00:00 2001 From: SettingDust Date: Tue, 8 Oct 2024 13:01:20 +0800 Subject: [PATCH 6/7] fix: plus the `aliases` when plus project --- .../kotlin/teksturepako/pakku/api/projects/Project.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt b/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt index f3042fbe..2b26ba73 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt @@ -81,6 +81,8 @@ data class Project( updateStrategy = this.updateStrategy, redistributable = this.redistributable && other.redistributable, + aliases = (this.aliases + other.aliases).toMutableSet(), + files = (this.files + other.files).toMutableSet(), ) ) From 4ac63ffb95eba1a8a8e2cdd6b52aac1dbdf5aa4a Mon Sep 17 00:00:00 2001 From: SettingDust Date: Tue, 8 Oct 2024 15:47:10 +0800 Subject: [PATCH 7/7] chore: make project aliases nullable --- .../teksturepako/pakku/api/data/ConfigFile.kt | 18 +++++++----------- .../kotlin/teksturepako/pakku/api/data/Json.kt | 1 - .../teksturepako/pakku/api/projects/Project.kt | 8 ++++---- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt b/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt index c2223416..cb4e51f2 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/data/ConfigFile.kt @@ -2,9 +2,9 @@ package teksturepako.pakku.api.data +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import teksturepako.pakku.api.overrides.filterOverrides -import teksturepako.pakku.api.projects.Project import teksturepako.pakku.api.projects.ProjectSide import teksturepako.pakku.api.projects.ProjectType import teksturepako.pakku.api.projects.UpdateStrategy @@ -34,19 +34,15 @@ data class ConfigFile( private val overrides: MutableList = mutableListOf(), /** A mutable list of server overrides packed up with the modpack. */ - private val serverOverrides: MutableList = mutableListOf(), + @SerialName("server_overrides") private val serverOverrides: MutableList = mutableListOf(), /** A mutable list of client overrides packed up with the modpack. */ - private val clientOverrides: MutableList = mutableListOf(), - + @SerialName("client_overrides") private val clientOverrides: MutableList = mutableListOf(), /** A map of project types to their respective paths. */ val paths: MutableMap = mutableMapOf(), /** A mutable map of _project slugs, names, IDs or filenames_ to _project configs_. */ - val projects: MutableMap = mutableMapOf(), - - /** A mutable map of project aliases to their respective project slugs. */ - val projectAliases: MutableMap = mutableMapOf() + val projects: MutableMap = mutableMapOf() ) { // -- PACK -- @@ -113,10 +109,10 @@ data class ConfigFile( data class ProjectConfig( var type: ProjectType? = null, var side: ProjectSide? = null, - var updateStrategy: UpdateStrategy? = null, - var redistributable: Boolean? = null, + @SerialName("update_strategy") var updateStrategy: UpdateStrategy? = null, + @SerialName("redistributable") var redistributable: Boolean? = null, var subpath: String? = null, - var aliases :MutableSet? = null + var aliases: MutableSet? = null ) // -- FILE I/O -- diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt b/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt index ab5ae3b6..6e4c547b 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/data/Json.kt @@ -2,7 +2,6 @@ package teksturepako.pakku.api.data import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json -import kotlinx.serialization.json.JsonNamingStrategy @OptIn(ExperimentalSerializationApi::class) val json = Json { diff --git a/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt b/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt index 2b26ba73..575877eb 100644 --- a/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt +++ b/src/commonMain/kotlin/teksturepako/pakku/api/projects/Project.kt @@ -43,7 +43,7 @@ data class Project( @SerialName("redistributable") var redistributable: Boolean = true, private var subpath: String? = null, - var aliases: MutableSet = mutableSetOf(), + var aliases: MutableSet? = null, var files: MutableSet ) @@ -81,7 +81,7 @@ data class Project( updateStrategy = this.updateStrategy, redistributable = this.redistributable && other.redistributable, - aliases = (this.aliases + other.aliases).toMutableSet(), + aliases = this.aliases?.plus(other.aliases ?: emptySet())?.toMutableSet() ?: other.aliases, files = (this.files + other.files).toMutableSet(), ) @@ -100,7 +100,7 @@ data class Project( /** Check if the current project has an alias of the specified project. */ infix fun hasAliasOf(other: Project): Boolean { - return this.aliases.any { it in other.id.values || it in other.name.values || it in other.slug.values } + return this.aliases?.any { it in other.id.values || it in other.name.values || it in other.slug.values } ?: false } /** Checks if the current project contains the specified string in its slugs, names, IDs or aliases. */ @@ -109,7 +109,7 @@ data class Project( return input in this.slug.values || input in this.name.values || input in this.id.values - || input in this.aliases + || this.aliases?.contains(input) == true } /** Checks if the project has any files. */