import java.net.HttpURLConnection import java.net.URI rootProject.name = "LoveLiveMusicPlayerKMP" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") val nexusBaseUrl = "http://192.168.123.100:18081" /** * Probe a URL: returns HTTP status, or -1 on connection failure. * Consumes/closes the body so connections are not leaked during settings eval. */ fun httpStatus(url: String, timeoutMs: Int = 2000): Int = try { val conn = URI.create(url).toURL().openConnection() as HttpURLConnection conn.connectTimeout = timeoutMs conn.readTimeout = timeoutMs conn.requestMethod = "GET" conn.instanceFollowRedirects = true val code = conn.responseCode (if (code in 200 until 400) conn.inputStream else conn.errorStream)?.close() conn.disconnect() code } catch (_: Throwable) { -1 } fun probeNexusStatus(baseUrl: String): Boolean = httpStatus("$baseUrl/service/rest/v1/status") in 200 until 400 /** * Nexus may serve a cached POM while the matching JAR is "Remote Auto Blocked". * Gradle then treats the module as found at Nexus and never falls back to google(). * Probe a known Google Maven JAR; only use Nexus google if that JAR is actually there. */ fun probeNexusGoogleProxy(baseUrl: String): Boolean { val canaryJar = "$baseUrl/repository/google/com/android/tools/build/jetifier/" + "jetifier-core/1.0.0-beta10/jetifier-core-1.0.0-beta10.jar" return httpStatus(canaryJar, timeoutMs = 3000) == 200 } val forcedNexus = startParameter.projectProperties["useNexus"] val (useNexusRepos, useNexusGoogle) = when { forcedNexus != null -> { val on = forcedNexus.toBoolean() on to on } !probeNexusStatus(nexusBaseUrl) -> false to false else -> true to probeNexusGoogleProxy(nexusBaseUrl) } gradle.extra["useNexusRepos"] = useNexusRepos gradle.extra["useNexusGoogle"] = useNexusGoogle gradle.extra["nexusBaseUrl"] = nexusBaseUrl logger.lifecycle( when { !useNexusRepos -> "[repos] Nexus unreachable, using public repositories only" !useNexusGoogle -> "[repos] Nexus up but google proxy incomplete/blocked — " + "skip Nexus google, use public google() (Nexus still used for other repos)" else -> "[repos] Nexus reachable — prefer $nexusBaseUrl, public repos as fallback" }, ) /** * Prefer local Nexus (fast) then fall back to public mirrors so missing * proxy artifacts (e.g. AGP / jetifier) still resolve. * * Never list a Nexus google repo that can return POM-without-JAR: that * blocks Gradle fallback to the real Google Maven repository. */ fun RepositoryHandler.addLlmpRepositories(includeGradlePortal: Boolean) { if (useNexusRepos) { maven { url = uri("$nexusBaseUrl/repository/maven-public/") isAllowInsecureProtocol = true } if (useNexusGoogle) { maven { url = uri("$nexusBaseUrl/repository/google/") isAllowInsecureProtocol = true } } maven { url = uri("$nexusBaseUrl/repository/mob/") isAllowInsecureProtocol = true } if (includeGradlePortal) { maven { url = uri("$nexusBaseUrl/repository/gradle/") isAllowInsecureProtocol = true } } maven { url = uri("$nexusBaseUrl/repository/jitpack/") isAllowInsecureProtocol = true } } google() mavenCentral() if (includeGradlePortal) gradlePluginPortal() maven { url = uri("https://mvn.mob.com/android") } maven { url = uri("https://jitpack.io") } } pluginManagement { val base = "http://192.168.123.100:18081" val forced = settings.startParameter.projectProperties["useNexus"] // pluginManagement is isolated from the rest of settings.gradle.kts — keep probes inline. fun status(url: String, timeoutMs: Int = 2000): Int = try { val conn = java.net.URI.create(url).toURL() .openConnection() as java.net.HttpURLConnection conn.connectTimeout = timeoutMs conn.readTimeout = timeoutMs conn.requestMethod = "GET" conn.instanceFollowRedirects = true val code = conn.responseCode (if (code in 200 until 400) conn.inputStream else conn.errorStream)?.close() conn.disconnect() code } catch (_: Throwable) { -1 } val (useNexus, useNexusGoogle) = when { forced != null -> { val on = forced.toBoolean() on to on } status("$base/service/rest/v1/status") !in 200 until 400 -> false to false else -> { val canary = "$base/repository/google/com/android/tools/build/jetifier/" + "jetifier-core/1.0.0-beta10/jetifier-core-1.0.0-beta10.jar" true to (status(canary, timeoutMs = 3000) == 200) } } repositories { if (useNexus) { maven { url = uri("$base/repository/maven-public/") isAllowInsecureProtocol = true } if (useNexusGoogle) { maven { url = uri("$base/repository/google/") isAllowInsecureProtocol = true } } maven { url = uri("$base/repository/mob/") isAllowInsecureProtocol = true } maven { url = uri("$base/repository/gradle/") isAllowInsecureProtocol = true } maven { url = uri("$base/repository/jitpack/") isAllowInsecureProtocol = true } } google() mavenCentral() gradlePluginPortal() maven { url = uri("https://mvn.mob.com/android") } maven { url = uri("https://jitpack.io") } } } plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" } dependencyResolutionManagement { repositories { addLlmpRepositories(includeGradlePortal = false) } } include(":shared") include(":composeApp") include(":androidApp")