build.gradle.kts 11 KB

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