mirror of
https://github.com/LamGC/ScalaBot.git
synced 2025-04-30 06:37:29 +00:00
refactor(config): 重构 AppPaths 的构造方法, 应对将来 Kotlin 更新中的特性.
先前的方法是利用了初始化与调用的顺序, 来实现的 Supplier 互补(虽然在代码中, 确实存在未初始化调用的情况, 但实际运行的时候, 会先初始化, 再调用 Supplier), 但是未来 Kotlin 的更新中,编译器会把这个操作视为未初始化错误, 所以在这次改动中修复掉这个 bug 操作.
This commit is contained in:
parent
dce28be9c7
commit
255a02c93c
@ -17,7 +17,8 @@ import java.io.File
|
|||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.function.Supplier
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
private val log = KotlinLogging.logger { }
|
private val log = KotlinLogging.logger { }
|
||||||
|
|
||||||
@ -102,9 +103,9 @@ private fun createDefaultRepositoryId(): String {
|
|||||||
* 必须提供 `pathSupplier` 或 `fileSupplier` 其中一个, 才能正常提供路径.
|
* 必须提供 `pathSupplier` 或 `fileSupplier` 其中一个, 才能正常提供路径.
|
||||||
*/
|
*/
|
||||||
internal enum class AppPaths(
|
internal enum class AppPaths(
|
||||||
private val pathSupplier: () -> String = { fileSupplier.invoke().canonicalPath },
|
private val pathSupplier: PathSupplier,
|
||||||
private val initializer: AppPaths.() -> Unit = AppPaths::defaultInitializer,
|
private val initializer: AppPaths.() -> Unit = AppPaths::defaultInitializer,
|
||||||
private val fileSupplier: () -> File = { File(pathSupplier()) }
|
private val fileSupplier: FileSupplier,
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* 数据根目录.
|
* 数据根目录.
|
||||||
@ -113,7 +114,7 @@ internal enum class AppPaths(
|
|||||||
*
|
*
|
||||||
* 提示: 结尾不带 `/`.
|
* 提示: 结尾不带 `/`.
|
||||||
*/
|
*/
|
||||||
DATA_ROOT(fileSupplier = {
|
DATA_ROOT(fileSupplier = FileSupplier {
|
||||||
File(
|
File(
|
||||||
System.getProperty(PathConst.PROP_DATA_PATH) ?: System.getenv(PathConst.ENV_DATA_PATH)
|
System.getProperty(PathConst.PROP_DATA_PATH) ?: System.getenv(PathConst.ENV_DATA_PATH)
|
||||||
?: System.getProperty("user.dir") ?: "."
|
?: System.getProperty("user.dir") ?: "."
|
||||||
@ -125,7 +126,7 @@ internal enum class AppPaths(
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
CONFIG_APPLICATION({ "$DATA_ROOT/config.json" }, {
|
CONFIG_APPLICATION(PathSupplier { "$DATA_ROOT/config.json" }, {
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
file.bufferedWriter(StandardCharsets.UTF_8).use {
|
file.bufferedWriter(StandardCharsets.UTF_8).use {
|
||||||
GsonConst.appConfigGson.toJson(
|
GsonConst.appConfigGson.toJson(
|
||||||
@ -141,7 +142,7 @@ internal enum class AppPaths(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
CONFIG_BOT({ "$DATA_ROOT/bot.json" }, {
|
CONFIG_BOT(PathSupplier { "$DATA_ROOT/bot.json" }, {
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
file.bufferedWriter(StandardCharsets.UTF_8).use {
|
file.bufferedWriter(StandardCharsets.UTF_8).use {
|
||||||
GsonConst.botConfigGson.toJson(
|
GsonConst.botConfigGson.toJson(
|
||||||
@ -167,10 +168,25 @@ internal enum class AppPaths(
|
|||||||
TEMP({ "$DATA_ROOT/tmp/" })
|
TEMP({ "$DATA_ROOT/tmp/" })
|
||||||
;
|
;
|
||||||
|
|
||||||
val file: File
|
constructor(pathSupplier: PathSupplier, initializer: AppPaths.() -> Unit = AppPaths::defaultInitializer) : this(
|
||||||
get() = fileSupplier.invoke()
|
fileSupplier = FileSupplier { File(pathSupplier.path).canonicalFile },
|
||||||
val path: String
|
pathSupplier = pathSupplier,
|
||||||
get() = pathSupplier.invoke()
|
initializer = initializer
|
||||||
|
)
|
||||||
|
|
||||||
|
constructor(fileSupplier: FileSupplier, initializer: AppPaths.() -> Unit = AppPaths::defaultInitializer) : this(
|
||||||
|
fileSupplier = fileSupplier,
|
||||||
|
pathSupplier = PathSupplier { fileSupplier.file.canonicalPath },
|
||||||
|
initializer = initializer
|
||||||
|
)
|
||||||
|
|
||||||
|
constructor(pathSupplier: () -> String) : this(
|
||||||
|
fileSupplier = FileSupplier { File(pathSupplier.invoke()).canonicalFile },
|
||||||
|
pathSupplier = PathSupplier { pathSupplier.invoke() }
|
||||||
|
)
|
||||||
|
|
||||||
|
val file: File by fileSupplier
|
||||||
|
val path: String by pathSupplier
|
||||||
|
|
||||||
private val initialized = AtomicBoolean(false)
|
private val initialized = AtomicBoolean(false)
|
||||||
|
|
||||||
@ -206,6 +222,20 @@ internal enum class AppPaths(
|
|||||||
const val ENV_DATA_PATH = "BOT_DATA_PATH"
|
const val ENV_DATA_PATH = "BOT_DATA_PATH"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class FileSupplier(private val supplier: Supplier<File>) {
|
||||||
|
operator fun getValue(appPaths: AppPaths, property: KProperty<*>): File = supplier.get()
|
||||||
|
|
||||||
|
val file: File
|
||||||
|
get() = supplier.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PathSupplier(private val supplier: Supplier<String>) {
|
||||||
|
operator fun getValue(appPaths: AppPaths, property: KProperty<*>): String = supplier.get()
|
||||||
|
|
||||||
|
val path: String
|
||||||
|
get() = supplier.get()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,6 +21,17 @@ import kotlin.test.*
|
|||||||
|
|
||||||
internal class AppPathsTest {
|
internal class AppPathsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `Consistency check`() {
|
||||||
|
for (path in AppPaths.values()) {
|
||||||
|
assertEquals(
|
||||||
|
File(path.path).canonicalPath,
|
||||||
|
path.file.canonicalPath,
|
||||||
|
"路径 File 与 Path 不一致: ${path.name}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `Data root path priority`() {
|
fun `Data root path priority`() {
|
||||||
System.setProperty(AppPaths.PathConst.PROP_DATA_PATH, "fromSystemProperties")
|
System.setProperty(AppPaths.PathConst.PROP_DATA_PATH, "fromSystemProperties")
|
||||||
|
Loading…
Reference in New Issue
Block a user