10 Commits

Author SHA1 Message Date
ac0a398afc release: 发布 0.3.1 版本. 2022-06-07 00:27:20 +08:00
145e5a2141 build: 暂时将发布仓库迁移到 Kuku 的仓库.
由于私有仓库所在的服务器出现问题, 所以暂时将仓库改到 Kuku 的那边.
在此感谢 Kuku 提供仓库!
2022-06-07 00:25:50 +08:00
b5c85e213b test: 完善序列化器的单元测试.
目前经测试, 已完善到 100% 覆盖率.
2022-05-19 23:54:27 +08:00
746221a085 feat(config): 简化凭证配置过程.
由于先前的配置过程较为麻烦, 故将凭证配置简化为只有用户名和密码.
2022-05-19 23:53:25 +08:00
24f34aa27f refactor: 调整 checkJsonKey 的所在类, 以便于编写测试用例.
通过调整所在类, 可更好的在单元测试中获取方法对象, 进行测试调用.
2022-05-19 18:20:46 +08:00
31366575a9 test: 补充部分序列化单元测试.
补充一部分测试内容.
2022-05-19 17:55:36 +08:00
37c3275bb6 fix(config): 修复因 Maven 仓库配置中未包括 layout 属性导致解析错误的问题.
当 Maven 仓库采用 JsonObject 形式配置, 且未配置 "layout" 属性时, 将会引发 NPE,
该改动已修复该问题.
2022-05-19 16:54:47 +08:00
72e26bd677 fix(config): 更改 MavenRepositoryConfig.proxy 的默认值.
防止因默认值导致出现错误的代理配置, 故将默认值更改为无代理(null).
2022-05-19 16:43:25 +08:00
9aab3c2a24 feat(config): 将代理类型为 null 的情况视为不使用代理.
为简化用户配置难度, 关闭代理可选择将 type 设为 null, 来表示不需要使用代理.
2022-05-19 15:46:18 +08:00
cac055bb08 test: 完善 AppPaths 中对 BOT_DATA_PATH 环境变量的测试流程.
通过使用 System-Lambda 库, 补充 AppPaths 中对环境变量使用的测试.
2022-05-19 15:01:16 +08:00
9 changed files with 415 additions and 77 deletions

View File

@ -7,5 +7,5 @@ allprojects {
} }
group = "net.lamgc" group = "net.lamgc"
version = "0.3.0" version = "0.3.1"
} }

View File

@ -36,6 +36,7 @@ dependencies {
testImplementation(kotlin("test")) testImplementation(kotlin("test"))
testImplementation("io.mockk:mockk:1.12.3") testImplementation("io.mockk:mockk:1.12.3")
testImplementation("com.github.stefanbirkner:system-lambda:1.2.1")
} }
tasks.test { tasks.test {

View File

@ -104,7 +104,7 @@ internal data class MetricsConfig(
internal data class MavenRepositoryConfig( internal data class MavenRepositoryConfig(
val id: String? = null, val id: String? = null,
val url: URL, val url: URL,
val proxy: Proxy? = Proxy("http", "127.0.0.1", 1080), val proxy: Proxy? = null,
val layout: String = "default", val layout: String = "default",
val enableReleases: Boolean = true, val enableReleases: Boolean = true,
val enableSnapshots: Boolean = true, val enableSnapshots: Boolean = true,

View File

@ -1,7 +1,6 @@
package net.lamgc.scalabot.util package net.lamgc.scalabot.util
import com.google.gson.* import com.google.gson.*
import mu.KotlinLogging
import net.lamgc.scalabot.MavenRepositoryConfig import net.lamgc.scalabot.MavenRepositoryConfig
import org.eclipse.aether.artifact.Artifact import org.eclipse.aether.artifact.Artifact
import org.eclipse.aether.artifact.DefaultArtifact import org.eclipse.aether.artifact.DefaultArtifact
@ -20,6 +19,9 @@ internal object ProxyTypeSerializer : JsonDeserializer<DefaultBotOptions.ProxyTy
typeOfT: Type?, typeOfT: Type?,
context: JsonDeserializationContext? context: JsonDeserializationContext?
): DefaultBotOptions.ProxyType { ): DefaultBotOptions.ProxyType {
if (json.isJsonNull) {
return DefaultBotOptions.ProxyType.NO_PROXY
}
if (!json.isJsonPrimitive) { if (!json.isJsonPrimitive) {
throw JsonParseException("Wrong configuration value type.") throw JsonParseException("Wrong configuration value type.")
} }
@ -52,8 +54,8 @@ internal object ArtifactSerializer : JsonSerializer<Artifact>, JsonDeserializer<
return JsonPrimitive(gavBuilder.append(':').append(src.version).toString()) return JsonPrimitive(gavBuilder.append(':').append(src.version).toString())
} }
override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Artifact { override fun deserialize(json: JsonElement, typeOfT: Type?, context: JsonDeserializationContext?): Artifact {
if (!json!!.isJsonPrimitive) { if (!json.isJsonPrimitive) {
throw JsonParseException("Wrong configuration value type.") throw JsonParseException("Wrong configuration value type.")
} }
return DefaultArtifact(json.asString.trim()) return DefaultArtifact(json.asString.trim())
@ -63,72 +65,29 @@ internal object ArtifactSerializer : JsonSerializer<Artifact>, JsonDeserializer<
internal object AuthenticationSerializer : JsonDeserializer<Authentication> { internal object AuthenticationSerializer : JsonDeserializer<Authentication> {
private val log = KotlinLogging.logger { } override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Authentication {
if (json !is JsonObject) {
override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Authentication? { throw JsonParseException("Unsupported JSON type.")
val builder = AuthenticationBuilder()
when (json) {
is JsonArray -> {
for (element in json) {
if (element is JsonArray) {
builder.addCustom(jsonArrayToAuthentication(element))
} else if (element is JsonObject) {
jsonToAuthentication(element, builder)
}
}
}
is JsonObject -> {
jsonToAuthentication(json, builder)
}
else -> {
throw JsonParseException("Unsupported JSON data type: ${json::class.java}")
}
} }
val username = SerializerUtils.checkJsonKey(json, "username")
val password = SerializerUtils.checkJsonKey(json, "password")
val builder = AuthenticationBuilder()
builder.addUsername(username)
builder.addPassword(password)
return builder.build() return builder.build()
} }
private fun jsonArrayToAuthentication(jsonArray: JsonArray): Authentication {
val builder = AuthenticationBuilder()
for (element in jsonArray) {
when (element) {
is JsonObject -> jsonToAuthentication(element, builder)
is JsonArray -> builder.addCustom(jsonArrayToAuthentication(element))
else -> log.warn { "不支持的 Json 类型: ${element::class.java}" }
}
}
return builder.build()
}
private const val KEY_TYPE = "type"
private fun jsonToAuthentication(json: JsonObject, builder: AuthenticationBuilder) {
if (!json.has(KEY_TYPE)) {
log.warn { "缺少 type 字段, 无法判断 Maven 认证信息类型." }
return
} else if (!json.get(KEY_TYPE).isJsonPrimitive) {
log.warn { "type 字段类型错误(应为 Primitive 类型), 无法判断 Maven 认证信息类型.(实际类型: `${json::class.java}`)" }
return
}
when (json.get(KEY_TYPE).asString.trim().lowercase()) {
"string" -> {
builder.addString(checkJsonKey(json, "key"), checkJsonKey(json, "value"))
}
"secret" -> {
builder.addSecret(checkJsonKey(json, "key"), checkJsonKey(json, "value"))
}
}
}
} }
private fun checkJsonKey(json: JsonObject, key: String): String { private object SerializerUtils {
if (!json.has(key)) { fun checkJsonKey(json: JsonObject, key: String): String {
throw JsonParseException("Required field does not exist: $key") if (!json.has(key)) {
} else if (!json.get(key).isJsonPrimitive) { throw JsonParseException("Required field does not exist: $key")
throw JsonParseException("Wrong field `$key` type: ${json.get(key)::class.java}") } else if (!json.get(key).isJsonPrimitive) {
throw JsonParseException("Wrong field `$key` type: ${json.get(key)::class.java}")
}
return json.get(key).asString
} }
return json.get(key).asString
} }
internal object MavenRepositoryConfigSerializer internal object MavenRepositoryConfigSerializer
@ -143,12 +102,12 @@ internal object MavenRepositoryConfigSerializer
is JsonObject -> { is JsonObject -> {
MavenRepositoryConfig( MavenRepositoryConfig(
id = json.get("id")?.asString, id = json.get("id")?.asString,
url = URL(checkJsonKey(json, "url")), url = URL(SerializerUtils.checkJsonKey(json, "url")),
proxy = if (json.has("proxy") && json.get("proxy").isJsonObject) proxy = if (json.has("proxy") && json.get("proxy").isJsonObject)
context.deserialize<Proxy>( context.deserialize<Proxy>(
json.getAsJsonObject("proxy"), Proxy::class.java json.getAsJsonObject("proxy"), Proxy::class.java
) else null, ) else null,
layout = json.get("layout").asString ?: "default", layout = json.get("layout")?.asString ?: "default",
enableReleases = json.get("enableReleases")?.asBoolean ?: true, enableReleases = json.get("enableReleases")?.asBoolean ?: true,
enableSnapshots = json.get("enableSnapshots")?.asBoolean ?: true, enableSnapshots = json.get("enableSnapshots")?.asBoolean ?: true,
authentication = if (json.has("authentication") && json.get("authentication").isJsonObject) authentication = if (json.has("authentication") && json.get("authentication").isJsonObject)

View File

@ -1,5 +1,6 @@
package net.lamgc.scalabot package net.lamgc.scalabot
import com.github.stefanbirkner.systemlambda.SystemLambda
import com.google.gson.Gson import com.google.gson.Gson
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
@ -40,23 +41,27 @@ internal class AppPathsTest {
@Test @Test
fun `Data root path priority`() { fun `Data root path priority`() {
System.setProperty("bot.path.data", "A") System.setProperty("bot.path.data", "fromSystemProperties")
assertEquals("A", AppPaths.DATA_ROOT.file.path, "`DATA_ROOT`没有优先返回 Property 的值.") assertEquals("fromSystemProperties", AppPaths.DATA_ROOT.file.path, "`DATA_ROOT`没有优先返回 Property 的值.")
System.getProperties().remove("bot.path.data") System.getProperties().remove("bot.path.data")
if (System.getenv("BOT_DATA_PATH") != null) {
val expectEnvValue = "fromEnvironmentVariable"
SystemLambda.withEnvironmentVariable("BOT_DATA_PATH", expectEnvValue).execute {
assertEquals( assertEquals(
System.getenv("BOT_DATA_PATH"), AppPaths.DATA_ROOT.file.path, expectEnvValue, AppPaths.DATA_ROOT.file.path,
"`DATA_ROOT`没有返回 env 的值." "`DATA_ROOT`没有优先返回 env 的值."
) )
} else { }
SystemLambda.withEnvironmentVariable("BOT_DATA_PATH", null).execute {
assertEquals( assertEquals(
System.getProperty("user.dir"), AppPaths.DATA_ROOT.file.path, System.getProperty("user.dir"), AppPaths.DATA_ROOT.file.path,
"`DATA_ROOT`没有返回 `user.dir` 的值." "`DATA_ROOT`没有返回 System.properties `user.dir` 的值."
) )
val userDir = System.getProperty("user.dir") val userDir = System.getProperty("user.dir")
System.getProperties().remove("user.dir") System.getProperties().remove("user.dir")
assertEquals(".", AppPaths.DATA_ROOT.file.path, "`DATA_ROOT`没有返回 `.`(当前目录).") assertEquals(".", AppPaths.DATA_ROOT.file.path, "`DATA_ROOT`没有返回替补值 `.`(当前目录).")
System.setProperty("user.dir", userDir) System.setProperty("user.dir", userDir)
assertNotNull(System.getProperty("user.dir"), "环境还原失败!") assertNotNull(System.getProperty("user.dir"), "环境还原失败!")
} }

View File

@ -18,13 +18,21 @@ internal class ArtifactSerializerTest {
} }
@Test @Test
fun serialize() { fun `Basic format serialization`() {
val gav = "org.example.software:test:1.0.0-SNAPSHOT" val gav = "org.example.software:test:1.0.0-SNAPSHOT"
val expectArtifact = DefaultArtifact(gav) val expectArtifact = DefaultArtifact(gav)
val actualArtifact = DefaultArtifact(ArtifactSerializer.serialize(expectArtifact, null, null).asString) val actualArtifact = DefaultArtifact(ArtifactSerializer.serialize(expectArtifact, null, null).asString)
assertEquals(expectArtifact, actualArtifact) assertEquals(expectArtifact, actualArtifact)
} }
@Test
fun `Full format serialization`() {
val gav = "org.example.software:test:war:javadoc:1.0.0-SNAPSHOT"
val expectArtifact = DefaultArtifact(gav)
val actualArtifact = DefaultArtifact(ArtifactSerializer.serialize(expectArtifact, null, null).asString)
assertEquals(expectArtifact, actualArtifact)
}
@Test @Test
fun deserialize() { fun deserialize() {
val gav = "org.example.software:test:1.0.0-SNAPSHOT" val gav = "org.example.software:test:1.0.0-SNAPSHOT"

View File

@ -0,0 +1,325 @@
package util
import com.google.gson.*
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import net.lamgc.scalabot.MavenRepositoryConfig
import net.lamgc.scalabot.util.AuthenticationSerializer
import net.lamgc.scalabot.util.MavenRepositoryConfigSerializer
import net.lamgc.scalabot.util.ProxyTypeSerializer
import org.eclipse.aether.repository.Authentication
import org.eclipse.aether.repository.AuthenticationContext
import org.eclipse.aether.repository.Proxy
import org.intellij.lang.annotations.Language
import org.junit.jupiter.api.Assertions.assertThrows
import org.telegram.telegrambots.bots.DefaultBotOptions
import java.lang.reflect.InvocationTargetException
import java.lang.reflect.Method
import java.lang.reflect.Type
import java.net.URL
import kotlin.test.*
internal class SerializersKtTest {
private val instance: Any
private val method: Method
init {
val clazz = Class.forName("net.lamgc.scalabot.util.SerializerUtils")
method = clazz.getDeclaredMethod("checkJsonKey", JsonObject::class.java, String::class.java)
method.isAccessible = true
instance = clazz.getDeclaredField("INSTANCE").apply {
isAccessible = true
}.get(null)
}
private fun invoke(json: JsonObject, key: String): String {
try {
return method.invoke(instance, json, key) as String
} catch (e: InvocationTargetException) {
throw e.targetException
}
}
@Test
fun `Json key checker test`() {
assertThrows(JsonParseException::class.java) {
invoke(JsonObject(), "NOT_EXIST_KEY")
}
assertThrows(JsonParseException::class.java) {
invoke(JsonObject().apply { add("NULL_KEY", JsonNull.INSTANCE) }, "NULL_KEY")
}
assertThrows(JsonParseException::class.java) {
invoke(JsonObject().apply { add("ARRAY_KEY", JsonArray()) }, "ARRAY_KEY")
}
assertThrows(JsonParseException::class.java) {
invoke(JsonObject().apply { add("OBJECT_KEY", JsonObject()) }, "OBJECT_KEY")
}
val expectKey = "TEST"
val expectString = "testString"
val json = JsonObject().apply { addProperty(expectKey, expectString) }
assertEquals(expectString, invoke(json, expectKey))
}
}
internal class ProxyTypeSerializerTest {
@Test
fun `serialize test`() {
for (type in DefaultBotOptions.ProxyType.values()) {
assertEquals(
JsonPrimitive(type.name), ProxyTypeSerializer.serialize(type, null, null),
"ProxyType 序列化结果与预期不符."
)
}
}
@Test
fun `deserialize test`() {
assertThrows(JsonParseException::class.java) {
ProxyTypeSerializer.deserialize(JsonObject(), null, null)
}
assertThrows(JsonParseException::class.java) {
ProxyTypeSerializer.deserialize(JsonArray(), null, null)
}
assertThrows(JsonParseException::class.java) {
ProxyTypeSerializer.deserialize(JsonPrimitive("NOT_IN_ENUM_VALUE"), null, null)
}
assertEquals(
DefaultBotOptions.ProxyType.NO_PROXY,
ProxyTypeSerializer.deserialize(JsonNull.INSTANCE, null, null)
)
for (type in DefaultBotOptions.ProxyType.values()) {
assertEquals(
type, ProxyTypeSerializer.deserialize(JsonPrimitive(type.name), null, null),
"ProxyType 反序列化结果与预期不符."
)
assertEquals(
type, ProxyTypeSerializer.deserialize(JsonPrimitive(" ${type.name} "), null, null),
"ProxyType 反序列化时未对 Json 字符串进行修剪(trim)."
)
}
}
}
internal class MavenRepositoryConfigSerializerTest {
@Test
fun `unsupported json type deserialize test`() {
assertThrows(JsonParseException::class.java) {
MavenRepositoryConfigSerializer.deserialize(
JsonArray(),
MavenRepositoryConfig::class.java,
TestJsonDeserializationContext
)
}
assertThrows(JsonParseException::class.java) {
MavenRepositoryConfigSerializer.deserialize(
JsonNull.INSTANCE,
MavenRepositoryConfig::class.java,
TestJsonDeserializationContext
)
}
}
@Test
fun `json primitive deserialize test`() {
val expectRepoUrl = "https://repo.example.org/maven"
val config = MavenRepositoryConfigSerializer.deserialize(
JsonPrimitive(expectRepoUrl),
MavenRepositoryConfig::class.java,
TestJsonDeserializationContext
)
assertNull(config.id)
assertEquals(URL(expectRepoUrl), config.url)
assertNull(config.proxy, "Proxy 默认值不为 null.")
assertEquals("default", config.layout)
assertTrue(config.enableReleases)
assertTrue(config.enableSnapshots)
assertNull(config.authentication)
}
@Test
fun `json object default deserialize test`() {
val expectRepoUrl = "https://repo.example.org/maven"
val jsonObject = JsonObject()
jsonObject.addProperty("url", expectRepoUrl)
val config = MavenRepositoryConfigSerializer.deserialize(
jsonObject,
MavenRepositoryConfig::class.java,
TestJsonDeserializationContext
)
assertNull(config.id)
assertEquals(URL(expectRepoUrl), config.url)
assertNull(config.proxy, "Proxy 默认值不为 null.")
assertEquals("default", config.layout)
assertTrue(config.enableReleases)
assertTrue(config.enableSnapshots)
assertNull(config.authentication)
}
@Test
fun `json object deserialize test`() {
@Language("JSON5")
val looksGoodJsonString = """
{
"id": "test-repository",
"url": "https://repo.example.org/maven",
"proxy": {
"type": "http",
"host": "127.0.1.1",
"port": 10800
},
"layout": "default",
"enableReleases": false,
"enableSnapshots": true
}
""".trimIndent()
val jsonObject = Gson().fromJson(looksGoodJsonString, JsonObject::class.java)
var config = MavenRepositoryConfigSerializer.deserialize(
jsonObject,
MavenRepositoryConfig::class.java,
TestJsonDeserializationContext
)
assertEquals(jsonObject["id"].asString, config.id)
assertEquals(URL(jsonObject["url"].asString), config.url)
assertEquals(Proxy("http", "127.0.1.1", 10800), config.proxy)
assertEquals(jsonObject["layout"].asString, config.layout)
assertEquals(jsonObject["enableReleases"].asBoolean, config.enableReleases)
assertEquals(jsonObject["enableSnapshots"].asBoolean, config.enableSnapshots)
// ------------------------------------
jsonObject.add("proxy", JsonNull.INSTANCE)
jsonObject.remove("layout")
config = MavenRepositoryConfigSerializer.deserialize(
jsonObject,
MavenRepositoryConfig::class.java,
TestJsonDeserializationContext
)
assertEquals(jsonObject["id"].asString, config.id)
assertEquals(URL(jsonObject["url"].asString), config.url)
assertNull(config.proxy)
assertEquals("default", config.layout)
assertEquals(jsonObject["enableReleases"].asBoolean, config.enableReleases)
assertEquals(jsonObject["enableSnapshots"].asBoolean, config.enableSnapshots)
// ------------------------------------
jsonObject.add("authentication", JsonArray())
jsonObject.add("layout", mockk<JsonPrimitive> {
every { asString }.returns(null)
})
config = MavenRepositoryConfigSerializer.deserialize(
jsonObject,
MavenRepositoryConfig::class.java,
TestJsonDeserializationContext
)
assertEquals(jsonObject["id"].asString, config.id)
assertEquals(URL(jsonObject["url"].asString), config.url)
assertNull(config.proxy)
assertEquals("default", config.layout)
assertEquals(jsonObject["enableReleases"].asBoolean, config.enableReleases)
assertEquals(jsonObject["enableSnapshots"].asBoolean, config.enableSnapshots)
assertNull(config.authentication)
// ------------------------------------
jsonObject.add("authentication", JsonObject().apply {
addProperty("username", "testUsername")
addProperty("password", "testPassword")
})
config = MavenRepositoryConfigSerializer.deserialize(
jsonObject,
MavenRepositoryConfig::class.java,
TestJsonDeserializationContext
)
assertEquals(jsonObject["id"].asString, config.id)
assertEquals(URL(jsonObject["url"].asString), config.url)
assertNull(config.proxy)
assertEquals("default", config.layout)
assertEquals(jsonObject["enableReleases"].asBoolean, config.enableReleases)
assertEquals(jsonObject["enableSnapshots"].asBoolean, config.enableSnapshots)
assertNotNull(config.authentication)
}
}
private object TestJsonDeserializationContext : JsonDeserializationContext {
private val gson = GsonBuilder()
.registerTypeAdapter(Authentication::class.java, AuthenticationSerializer)
.create()
override fun <T : Any?> deserialize(json: JsonElement, typeOfT: Type): T {
return gson.fromJson(json, typeOfT)
}
}
internal class AuthenticationSerializerTest {
@Test
fun `deserialize test`() {
assertThrows(JsonParseException::class.java) {
AuthenticationSerializer.deserialize(
JsonNull.INSTANCE,
Authentication::class.java, TestJsonDeserializationContext
)
}
assertThrows(JsonParseException::class.java) {
AuthenticationSerializer.deserialize(
JsonArray(),
Authentication::class.java, TestJsonDeserializationContext
)
}
assertThrows(JsonParseException::class.java) {
AuthenticationSerializer.deserialize(
JsonPrimitive("A STRING"),
Authentication::class.java, TestJsonDeserializationContext
)
}
val expectJsonObject = JsonObject().apply {
addProperty("username", "testUsername")
addProperty("password", "testPassword")
}
val mockContext = mockk<AuthenticationContext> {
every { put(any(), any()) }.answers { }
}
val result = AuthenticationSerializer.deserialize(
expectJsonObject,
Authentication::class.java, TestJsonDeserializationContext
)
assertNotNull(result)
result.fill(mockContext, "username", null)
result.fill(mockContext, "password", null)
verify {
mockContext.put("username", "testUsername")
mockContext.put("password", "testPassword".toCharArray())
}
}
}

View File

@ -0,0 +1,40 @@
package net.lamgc.scalabot.util
import ch.qos.logback.classic.Level
import ch.qos.logback.classic.spi.LoggingEvent
import ch.qos.logback.core.spi.FilterReply
import io.mockk.every
import io.mockk.mockk
import kotlin.test.Test
import kotlin.test.assertEquals
class StdOutFilterTest {
@Test
fun filterTest() {
val filter = StdOutFilter()
for (level in listOf(
Level.ALL,
Level.TRACE,
Level.DEBUG,
Level.INFO
)) {
val loggingEvent = mockk<LoggingEvent> {
every { this@mockk.level }.returns(level)
}
assertEquals(FilterReply.ACCEPT, filter.decide(loggingEvent))
}
for (level in listOf(
Level.WARN,
Level.ERROR
)) {
val loggingEvent = mockk<LoggingEvent> {
every { this@mockk.level }.returns(level)
}
assertEquals(FilterReply.DENY, filter.decide(loggingEvent))
}
}
}

View File

@ -40,14 +40,14 @@ tasks.withType<KotlinCompile> {
publishing { publishing {
repositories { repositories {
if (project.version.toString().endsWith("-SNAPSHOT")) { if (project.version.toString().endsWith("-SNAPSHOT")) {
maven("https://repo.lamgc.moe/repository/maven-snapshots/") { maven("https://nexus.kuku.me/repository/maven-snapshots/") {
credentials { credentials {
username = project.properties["repo.credentials.private.username"].toString() username = project.properties["repo.credentials.private.username"].toString()
password = project.properties["repo.credentials.private.password"].toString() password = project.properties["repo.credentials.private.password"].toString()
} }
} }
} else { } else {
maven("https://repo.lamgc.moe/repository/maven-releases/") { maven("https://nexus.kuku.me/repository/maven-releases/") {
credentials { credentials {
username = project.properties["repo.credentials.private.username"].toString() username = project.properties["repo.credentials.private.username"].toString()
password = project.properties["repo.credentials.private.password"].toString() password = project.properties["repo.credentials.private.password"].toString()