Skip to content

Commit 829b357

Browse files
committed
feat: allow to exclude ABI by source path
1 parent 88a3ea5 commit 829b357

File tree

6 files changed

+43
-11
lines changed

6 files changed

+43
-11
lines changed

src/main/kotlin/com/autonomousapps/extension/AbiHandler.kt

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ abstract class ExclusionsHandler @Inject constructor(objects: ObjectFactory) {
7474
annotationExclusions.addAll(*annotationRegexes)
7575
}
7676

77-
// TODO Excluded for now but left as a toe-hold for future use
78-
// fun excludePaths(@Language("RegExp") vararg pathRegexes: String) {
79-
// pathExclusions.addAll(*pathRegexes)
80-
// }
77+
fun excludePaths(@Language("RegExp") vararg pathRegexes: String) {
78+
pathExclusions.addAll(*pathRegexes)
79+
}
8180
}

src/main/kotlin/com/autonomousapps/internal/analyzer/AndroidProjectAnalyzer.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ internal class AndroidLibAnalyzer(
181181
if (!hasAbi) return null
182182

183183
return project.tasks.register<AbiAnalysisTask>("abiAnalysis$taskNameSuffix") {
184+
sourceFiles.setFrom(javaSourceFiles)
185+
sourceFiles.setFrom(kotlinSourceFiles)
186+
sourceFiles.setFrom(groovySourceFiles)
187+
sourceFiles.setFrom(scalaSourceFiles)
184188
exclusions.set(abiExclusions)
185189
output.set(outputPaths.abiAnalysisPath)
186190
abiDump.set(outputPaths.abiDumpPath)

src/main/kotlin/com/autonomousapps/internal/analyzer/JvmProjectAnalyzer.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ internal abstract class JvmAnalyzer(
6060
if (!hasAbi) return null
6161

6262
return project.tasks.register<AbiAnalysisTask>("abiAnalysis$variantNameCapitalized") {
63+
sourceFiles.setFrom(sourceSet.sourceCode)
6364
classes.setFrom(sourceSet.classesDirs)
6465
exclusions.set(abiExclusions)
6566
output.set(outputPaths.abiAnalysisPath)

src/main/kotlin/com/autonomousapps/internal/kotlin/PublicApiDump.kt

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ internal fun JarFile.classEntries() = Sequence { entries().iterator() }.filter {
3434
}
3535

3636
internal fun getBinaryAPI(jar: JarFile, visibilityFilter: (String) -> Boolean = { true }): List<ClassBinarySignature> =
37-
getBinaryAPI(jar.classEntries().map { entry -> jar.getInputStream(entry) }, visibilityFilter)
37+
getBinaryAPI(jar.classEntries().map { entry -> jar.getInputStream(entry) }, visibilityFilter = visibilityFilter)
3838

39-
internal fun getBinaryAPI(classes: Set<File>, visibilityFilter: (String) -> Boolean = { true }): List<ClassBinarySignature> =
40-
getBinaryAPI(classes.asSequence().map { it.inputStream() }, visibilityFilter)
39+
internal fun getBinaryAPI(classes: Set<File>, sourceFiles: Set<File>, visibilityFilter: (String) -> Boolean = { true }): List<ClassBinarySignature> =
40+
getBinaryAPI(classes.asSequence().map { it.inputStream() }, sourceFiles, visibilityFilter)
4141

42-
internal fun getBinaryAPI(classStreams: Sequence<InputStream>, visibilityFilter: (String) -> Boolean = { true }): List<ClassBinarySignature> {
42+
internal fun getBinaryAPI(classStreams: Sequence<InputStream>, sourceFiles: Set<File> = emptySet(), visibilityFilter: (String) -> Boolean = { true }): List<ClassBinarySignature> {
4343
val classNodes = classStreams.map {
4444
it.use { stream ->
4545
val classNode = ClassNode()
@@ -53,6 +53,10 @@ internal fun getBinaryAPI(classStreams: Sequence<InputStream>, visibilityFilter:
5353

5454
val visibilityMapNew = classNodes.readKotlinVisibilities().filterKeys(visibilityFilter)
5555

56+
val sourceFilePackageReversedBySourceFile = sourceFiles.associateWith {
57+
it.parentFile.invariantSeparatorsPath.split('/').reversed()
58+
}
59+
5660
return classNodes
5761
.filter { it != moduleInfo }
5862
.map { clazz ->
@@ -112,6 +116,21 @@ internal fun getBinaryAPI(classStreams: Sequence<InputStream>, visibilityFilter:
112116
// Strip out JDK classes
113117
.filterNotToSet { it.startsWith("Ljava/lang") }
114118

119+
val sourceFileName = clazz.sourceFile ?: "${clazz.name.substringAfterLast('/')}."
120+
val clazzPackageReversed = clazz.name.substringBeforeLast('/').split('/').reversed()
121+
val sourceFile = sourceFilePackageReversedBySourceFile
122+
.filterKeys { it.name.startsWith(sourceFileName) }
123+
.maxByOrNull { (_, sourceFilePackageReversed) ->
124+
sourceFilePackageReversed
125+
.asSequence()
126+
.zip(clazzPackageReversed.asSequence())
127+
.takeWhile { (sourceFilePart, clazzPart) -> sourceFilePart == clazzPart }
128+
.count()
129+
}
130+
?.key
131+
?.invariantSeparatorsPath
132+
?: sourceFileName
133+
115134
ClassBinarySignature(
116135
name = name,
117136
superName = superName,
@@ -124,7 +143,7 @@ internal fun getBinaryAPI(classStreams: Sequence<InputStream>, visibilityFilter:
124143
isNotUsedWhenEmpty = metadata.isFileOrMultipartFacade() || isDefaultImpls(metadata),
125144
annotations = visibleAnnotations.annotationTypes(),
126145
invisibleAnnotations = invisibleAnnotations.annotationTypes(),
127-
sourceFile = clazz.sourceFile
146+
sourceFile = sourceFile
128147
)
129148
}
130149
}

src/main/kotlin/com/autonomousapps/internal/kotlin/abiDependencies.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@ import java.util.jar.JarFile
1313

1414
internal fun computeAbi(
1515
classFiles: Set<File>,
16+
sourceFiles: Set<File>,
1617
exclusions: AbiExclusions,
1718
abiDumpFile: File? = null
18-
): Set<ExplodingAbi> = getBinaryAPI(classFiles).explodedAbi(exclusions, abiDumpFile)
19+
): Set<ExplodingAbi> = getBinaryAPI(classFiles, sourceFiles).explodedAbi(exclusions, abiDumpFile)
1920

2021
private fun List<ClassBinarySignature>.explodedAbi(
2122
exclusions: AbiExclusions,

src/main/kotlin/com/autonomousapps/tasks/AbiAnalysisTask.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,11 @@ abstract class AbiAnalysisTask @Inject constructor(
3030
description = "Produces a report of the ABI of this project"
3131
}
3232

33+
/** Source files from which the class files were generated. May be empty. */
34+
@get:InputFiles
35+
@get:PathSensitive(PathSensitivity.RELATIVE)
36+
abstract val sourceFiles: ConfigurableFileCollection
37+
3338
/** Class files generated by any JVM source (Java, Kotlin, Groovy, etc.). May be empty. */
3439
@get:Classpath
3540
@get:InputFiles
@@ -48,6 +53,7 @@ abstract class AbiAnalysisTask @Inject constructor(
4853
@TaskAction
4954
fun action() {
5055
workerExecutor.noIsolation().submit(AbiAnalysisWorkAction::class.java) {
56+
sourceFiles.setFrom(this@AbiAnalysisTask.sourceFiles.asFileTree)
5157
// JVM projects
5258
classFiles.setFrom(classes.asFileTree.filterToClassFiles().files)
5359
// Android projects
@@ -60,6 +66,7 @@ abstract class AbiAnalysisTask @Inject constructor(
6066
}
6167

6268
interface AbiAnalysisParameters : WorkParameters {
69+
val sourceFiles: ConfigurableFileCollection
6370
val classFiles: ConfigurableFileCollection
6471
val exclusions: Property<String>
6572
val output: RegularFileProperty
@@ -72,10 +79,11 @@ abstract class AbiAnalysisTask @Inject constructor(
7279
val output = parameters.output.getAndDelete()
7380
val outputAbiDump = parameters.abiDump.getAndDelete()
7481

82+
val sourceFiles = parameters.sourceFiles.files
7583
val classFiles = parameters.classFiles.files
7684
val exclusions = parameters.exclusions.orNull?.fromJson<AbiExclusions>() ?: AbiExclusions.NONE
7785

78-
val explodingAbi = computeAbi(classFiles, exclusions, outputAbiDump)
86+
val explodingAbi = computeAbi(classFiles, sourceFiles, exclusions, outputAbiDump)
7987

8088
output.bufferWriteJsonSet(explodingAbi)
8189
}

0 commit comments

Comments
 (0)