import org.gradle.api.GradleException plugins { java } repositories { google() mavenCentral() } val agpVersion: String = providers.gradleProperty("agpVersion").orElse("8.11.0").get() configurations { create("agp") create("androidDeps") create("buildPlugins") } dependencies { add("agp", "com.android.tools.build:gradle:$agpVersion") add("buildPlugins", "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.25") add("buildPlugins", "org.jetbrains.kotlin:kotlin-stdlib:1.9.25") add("androidDeps", "androidx.webkit:webkit:1.14.0") add("androidDeps", "androidx.appcompat:appcompat:1.7.1") add("androidDeps", "androidx.activity:activity-ktx:1.10.1") add("androidDeps", "com.google.android.material:material:1.12.0") add("androidDeps", "androidx.lifecycle:lifecycle-process:2.10.0") add("androidDeps", "androidx.core:core-ktx:1.9.0") add("androidDeps", "androidx.browser:browser:1.8.0") add("androidDeps", "androidx.core:core:1.13.0") } fun installArtifact( root: File, group: String, name: String, version: String, ext: String, src: File, ) { val dir = root.resolve("${group.replace('.', '/')}/$name/$version") dir.mkdirs() src.copyTo(dir.resolve("$name-$version.$ext"), overwrite = true) } fun ensurePom(root: File, group: String, name: String, version: String) { val dir = root.resolve("${group.replace('.', '/')}/$name/$version") dir.mkdirs() val pom = dir.resolve("$name-$version.pom") if (pom.exists() && pom.length() > 0L) { return } val groupPath = group.replace('.', '/') val bases = when { group.startsWith("com.android") || group.startsWith("androidx") || group.startsWith("com.google.android") -> listOf( "https://dl.google.com/dl/android/maven2", "https://dl.google.com/android/maven2", "https://maven.google.com", ) else -> listOf( "https://repo.maven.apache.org/maven2", "https://dl.google.com/dl/android/maven2", "https://maven.google.com", ) } for (base in bases) { val url = "$base/$groupPath/$name/$version/$name-$version.pom" try { exec { commandLine("curl", "-fsSL", url, "-o", pom.absolutePath) } if (pom.exists() && pom.length() > 0L) { return } } catch (_: Exception) { pom.delete() } } throw GradleException("POM not found: $group:$name:$version") } fun exportConfiguration(configName: String, offlineRoot: File): Int { val configuration = configurations.getByName(configName) val modules = linkedSetOf>() configuration.resolvedConfiguration.resolvedArtifacts.forEach { artifact -> val id = artifact.moduleVersion.id modules.add(Triple(id.group, id.name, id.version)) installArtifact( offlineRoot, id.group, id.name, id.version, artifact.extension ?: "jar", artifact.file, ) } modules.forEach { (group, name, version) -> ensurePom(offlineRoot, group, name, version) } println("Exported ${modules.size} modules from configuration ${configName}") return modules.size } tasks.register("exportOfflineMaven") { dependsOn(configurations.named("agp")) doLast { val offlineRoot = file("${rootProject.projectDir}/../offline-maven").apply { mkdirs() } val modules = exportConfiguration("agp", offlineRoot) file("${offlineRoot.absolutePath}/.agp-offline-complete").writeText( "agpVersion=$agpVersion\nmodules=$modules\n", ) } } tasks.register("exportAllOfflineMaven") { dependsOn(configurations.named("agp"), configurations.named("androidDeps"), configurations.named("buildPlugins")) doLast { val offlineRoot = file("${rootProject.projectDir}/../offline-maven").apply { mkdirs() } val modules = exportConfiguration("agp", offlineRoot) + exportConfiguration("androidDeps", offlineRoot) + exportConfiguration("buildPlugins", offlineRoot) file("${offlineRoot.absolutePath}/.agp-offline-complete").writeText( "agpVersion=$agpVersion\nmodules=$modules\n", ) file("${offlineRoot.absolutePath}/.android-deps-offline-complete").writeText( "modules=$modules\n", ) println("Exported ${modules} total modules to ${offlineRoot.absolutePath}") } }