-
Notifications
You must be signed in to change notification settings - Fork 54
/
KotlinApiBuildTask.kt
111 lines (92 loc) · 3.49 KB
/
KotlinApiBuildTask.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
* Copyright 2016-2020 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/
package kotlinx.validation
import kotlinx.validation.api.*
import org.gradle.api.*
import org.gradle.api.file.*
import org.gradle.api.tasks.*
import java.io.*
import java.util.jar.JarFile
import javax.inject.Inject
open class KotlinApiBuildTask @Inject constructor(
) : DefaultTask() {
private val extension = project.apiValidationExtensionOrNull
@InputFiles
@Optional
@PathSensitive(PathSensitivity.RELATIVE)
var inputClassesDirs: FileCollection? = null
@InputFile
@Optional
@PathSensitive(PathSensitivity.RELATIVE)
val inputJar: RegularFileProperty = this.project.objects.fileProperty()
@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)
lateinit var inputDependencies: FileCollection
@OutputDirectory
lateinit var outputApiDir: File
private var _ignoredPackages: Set<String>? = null
@get:Input
var ignoredPackages : Set<String>
get() = _ignoredPackages ?: extension?.ignoredPackages ?: emptySet()
set(value) { _ignoredPackages = value }
private var _nonPublicMarkes: Set<String>? = null
@get:Input
var nonPublicMarkers : Set<String>
get() = _nonPublicMarkes ?: extension?.nonPublicMarkers ?: emptySet()
set(value) { _nonPublicMarkes = value }
private var _ignoredClasses: Set<String>? = null
@get:Input
var ignoredClasses : Set<String>
get() = _ignoredClasses ?: extension?.ignoredClasses ?: emptySet()
set(value) { _ignoredClasses = value }
@get:Internal
internal val projectName = project.name
@TaskAction
fun generate() {
cleanup(outputApiDir)
outputApiDir.mkdirs()
val inputClassesDirs = inputClassesDirs
val signatures = when {
// inputJar takes precedence if specified
inputJar.isPresent ->
JarFile(inputJar.get().asFile)
.loadApiFromJvmClasses()
inputClassesDirs != null ->
inputClassesDirs.asFileTree.asSequence()
.filter {
!it.isDirectory && it.name.endsWith(".class") && !it.name.startsWith("META-INF/")
}
.map { it.inputStream() }
.loadApiFromJvmClasses()
else ->
throw GradleException("KotlinApiBuildTask should have either inputClassesDirs, or inputJar property set")
}
val filteredSignatures = signatures
.filterOutNonPublic(ignoredPackages, ignoredClasses)
.filterOutAnnotated(nonPublicMarkers.map { it.replace(".", "/") }.toSet())
outputApiDir.resolve("$projectName.api").bufferedWriter().use { writer ->
filteredSignatures
.sortedBy { it.name }
.forEach { api ->
writer.append(api.signature).appendLine(" {")
api.memberSignatures
.sortedWith(MEMBER_SORT_ORDER)
.forEach { writer.append("\t").appendLine(it.signature) }
writer.appendLine("}\n")
}
}
}
private fun cleanup(file: File) {
if (file.exists()) {
val listing = file.listFiles()
if (listing != null) {
for (sub in listing) {
cleanup(sub)
}
}
file.delete()
}
}
}