build.gradle.kts 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. @file:Suppress("UnstableApiUsage", "UNUSED_VARIABLE")
  2. import org.jetbrains.dokka.gradle.DokkaTask
  3. import java.time.Duration
  4. import kotlin.math.pow
  5. buildscript {
  6. repositories {
  7. mavenLocal()
  8. // maven(url = "https://mirrors.huaweicloud.com/repository/maven")
  9. maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
  10. maven(url = "https://kotlin.bintray.com/kotlinx")
  11. jcenter()
  12. google()
  13. mavenCentral()
  14. }
  15. dependencies {
  16. classpath("com.github.jengelman.gradle.plugins:shadow:5.2.0")
  17. classpath("com.android.tools.build:gradle:${Versions.Android.androidGradlePlugin}")
  18. classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.Kotlin.compiler}")
  19. classpath("org.jetbrains.kotlin:kotlin-serialization:${Versions.Kotlin.compiler}")
  20. classpath("org.jetbrains.kotlinx:atomicfu-gradle-plugin:${Versions.Kotlin.atomicFU}")
  21. classpath("org.jetbrains.kotlinx:binary-compatibility-validator:${Versions.Kotlin.binaryValidator}")
  22. }
  23. }
  24. plugins {
  25. id("org.jetbrains.dokka") version Versions.Kotlin.dokka apply false
  26. id("net.mamoe.kotlin-jvm-blocking-bridge") version Versions.blockingBridge apply false
  27. // id("com.jfrog.bintray") version Versions.Publishing.bintray apply false
  28. }
  29. // https://github.com/kotlin/binary-compatibility-validator
  30. //apply(plugin = "binary-compatibility-validator")
  31. project.ext.set("isAndroidSDKAvailable", false)
  32. // until
  33. // https://youtrack.jetbrains.com/issue/KT-37152,
  34. // are fixed.
  35. /*
  36. runCatching {
  37. val keyProps = Properties().apply {
  38. file("local.properties").takeIf { it.exists() }?.inputStream()?.use { load(it) }
  39. }
  40. if (keyProps.getProperty("sdk.dir", "").isNotEmpty()) {
  41. project.ext.set("isAndroidSDKAvailable", true)
  42. } else {
  43. project.ext.set("isAndroidSDKAvailable", false)
  44. }
  45. }.exceptionOrNull()?.run {
  46. project.ext.set("isAndroidSDKAvailable", false)
  47. }*/
  48. allprojects {
  49. group = "net.mamoe"
  50. version = Versions.Mirai.version
  51. repositories {
  52. mavenLocal()
  53. // maven(url = "https://mirrors.huaweicloud.com/repository/maven")
  54. maven(url = "https://dl.bintray.com/kotlin/kotlin-eap")
  55. maven(url = "https://kotlin.bintray.com/kotlinx")
  56. jcenter()
  57. google()
  58. mavenCentral()
  59. }
  60. }
  61. subprojects {
  62. if ([email protected] == "java-test") {
  63. return@subprojects
  64. }
  65. afterEvaluate {
  66. apply(plugin = "com.github.johnrengelman.shadow")
  67. val kotlin =
  68. runCatching {
  69. (this as ExtensionAware).extensions.getByName("kotlin") as? org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
  70. }.getOrNull() ?: return@afterEvaluate
  71. val shadowJvmJar by tasks.creating(com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar::class) {
  72. group = "mirai"
  73. val compilations =
  74. kotlin.targets.filter { it.platformType == org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType.jvm }
  75. .map { it.compilations["main"] }
  76. compilations.forEach {
  77. dependsOn(it.compileKotlinTask)
  78. }
  79. compilations.forEach {
  80. from(it.output)
  81. }
  82. configurations = compilations.map { it.compileDependencyFiles as Configuration }
  83. this.exclude { file ->
  84. file.name.endsWith(".sf", ignoreCase = true)
  85. .also { if (it) println("excluded ${file.name}") }
  86. }
  87. this.manifest {
  88. this.attributes(
  89. "Manifest-Version" to 1,
  90. "Implementation-Vendor" to "Mamoe Technologies",
  91. "Implementation-Title" to [email protected](),
  92. "Implementation-Version" to [email protected]()
  93. )
  94. }
  95. }
  96. val githubUpload by tasks.creating {
  97. group = "mirai"
  98. dependsOn(shadowJvmJar)
  99. doFirst {
  100. timeout.set(Duration.ofHours(3))
  101. findLatestFile().let { (_, file) ->
  102. val filename = file.name
  103. println("Uploading file $filename")
  104. runCatching {
  105. upload.GitHub.upload(
  106. file,
  107. project,
  108. "mirai-repo",
  109. "shadow/${project.name}/$filename"
  110. )
  111. }.exceptionOrNull()?.let {
  112. System.err.println("GitHub Upload failed")
  113. it.printStackTrace() // force show stacktrace
  114. throw it
  115. }
  116. }
  117. }
  118. }
  119. apply(plugin = "org.jetbrains.dokka")
  120. this.tasks {
  121. val dokka by getting(DokkaTask::class) {
  122. outputFormat = "html"
  123. outputDirectory = "$buildDir/dokka"
  124. }
  125. val dokkaMarkdown by creating(DokkaTask::class) {
  126. outputFormat = "markdown"
  127. outputDirectory = "$buildDir/dokka-markdown"
  128. }
  129. val dokkaGfm by creating(DokkaTask::class) {
  130. outputFormat = "gfm"
  131. outputDirectory = "$buildDir/dokka-gfm"
  132. }
  133. }
  134. val dokkaGitHubUpload by tasks.creating {
  135. group = "mirai"
  136. val dokkaTaskName = "dokka"
  137. dependsOn(tasks.getByName(dokkaTaskName))
  138. doFirst {
  139. val baseDir = file("./build/$dokkaTaskName/${project.name}")
  140. timeout.set(Duration.ofHours(6))
  141. file("build/$dokkaTaskName/").walk()
  142. .filter { it.isFile }
  143. .map { old ->
  144. if (old.name == "index.md") File(old.parentFile, "README.md").also { new -> old.renameTo(new) }
  145. else old
  146. }
  147. // optimize md
  148. .forEach { file ->
  149. if (file.endsWith(".md")) {
  150. file.writeText(
  151. file.readText().replace("index.md", "README.md", ignoreCase = true)
  152. .replace(Regex("""```\n([\s\S]*?)```""")) {
  153. "\n" + """
  154. ```kotlin
  155. $it
  156. ```
  157. """.trimIndent()
  158. })
  159. } /* else if (file.name == "README.md") {
  160. file.writeText(file.readText().replace(Regex("""(\n\n\|\s)""")) {
  161. "\n\n" + """"
  162. |||
  163. |:----------------------------------------------------------------------------------------|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
  164. |
  165. """.trimIndent()
  166. })
  167. }*/
  168. val filename = file.toRelativeString(baseDir)
  169. println("Uploading file $filename")
  170. runCatching {
  171. upload.GitHub.upload(
  172. file,
  173. project,
  174. "mirai-doc",
  175. "${project.name}/${project.version}/$filename"
  176. )
  177. }.exceptionOrNull()?.let {
  178. System.err.println("GitHub Upload failed")
  179. it.printStackTrace() // force show stacktrace
  180. throw it
  181. }
  182. }
  183. }
  184. }
  185. val cuiCloudUpload by tasks.creating {
  186. group = "mirai"
  187. dependsOn(shadowJvmJar)
  188. doFirst {
  189. timeout.set(Duration.ofHours(3))
  190. findLatestFile().let { (_, file) ->
  191. val filename = file.name
  192. println("Uploading file $filename")
  193. runCatching {
  194. upload.CuiCloud.upload(
  195. file,
  196. project
  197. )
  198. }.exceptionOrNull()?.let {
  199. System.err.println("CuiCloud Upload failed")
  200. it.printStackTrace() // force show stacktrace
  201. throw it
  202. }
  203. }
  204. }
  205. }
  206. }
  207. afterEvaluate {
  208. tasks.filterIsInstance<DokkaTask>().forEach { task ->
  209. with(task) {
  210. configuration {
  211. perPackageOption {
  212. prefix = "net.mamoe.mirai"
  213. skipDeprecated = true
  214. }
  215. perPackageOption {
  216. prefix = "net.mamoe.mirai.internal"
  217. suppress = true
  218. }
  219. perPackageOption {
  220. prefix = "net.mamoe.mirai.event.internal"
  221. suppress = true
  222. }
  223. perPackageOption {
  224. prefix = "net.mamoe.mirai.utils.internal"
  225. suppress = true
  226. }
  227. perPackageOption {
  228. prefix = "net.mamoe.mirai.qqandroid.utils"
  229. suppress = true
  230. }
  231. perPackageOption {
  232. prefix = "net.mamoe.mirai.qqandroid.contact"
  233. suppress = true
  234. }
  235. perPackageOption {
  236. prefix = "net.mamoe.mirai.qqandroid.message"
  237. suppress = true
  238. }
  239. perPackageOption {
  240. prefix = "net.mamoe.mirai.qqandroid.network"
  241. suppress = true
  242. }
  243. }
  244. }
  245. }
  246. }
  247. }
  248. fun Project.findLatestFile(): Map.Entry<String, File> {
  249. return File(projectDir, "build/libs").walk()
  250. .filter { it.isFile }
  251. .onEach { println("all files=$it") }
  252. .filter { it.name.matches(Regex("""${project.name}-[0-9][0-9]*(\.[0-9]*)*.*\.jar""")) }
  253. .onEach { println("matched file: ${it.name}") }
  254. .associateBy { it.nameWithoutExtension.substringAfterLast('-') }
  255. .onEach { println("versions: $it") }
  256. .maxBy { (version, _) ->
  257. version.split('.').let {
  258. if (it.size == 2) it + "0"
  259. else it
  260. }.reversed().foldIndexed(0) { index: Int, acc: Int, s: String ->
  261. acc + 100.0.pow(index).toInt() * (s.toIntOrNull() ?: 0)
  262. }
  263. } ?: error("cannot find any file to upload")
  264. }