From 53a4dd0c2b50499272193649a3e9832f51db7b2d Mon Sep 17 00:00:00 2001 From: Wojtek Zieba Date: Tue, 20 Feb 2024 18:52:18 +0100 Subject: [PATCH 1/9] build: bump kotlin to 1.9.22, introduce ksp in libs:processors --- WordPress/build.gradle | 1 + build.gradle | 3 ++- libs/processors/build.gradle | 5 ++--- settings.gradle | 4 +++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 36e0ad7a0637..26d2218b3db4 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -12,6 +12,7 @@ plugins { id "com.google.gms.google-services" id "com.google.dagger.hilt.android" id "org.jetbrains.kotlinx.kover" + id "com.google.devtools.ksp" } sentry { diff --git a/build.gradle b/build.gradle index eba5484f157b..40434f7d0e0f 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ plugins { id "com.android.library" apply false id 'com.google.gms.google-services' apply false id "org.jetbrains.kotlin.plugin.parcelize" apply false + id "com.google.devtools.ksp" apply false } ext { @@ -43,7 +44,7 @@ ext { androidxArchCoreVersion = '2.2.0' androidxCameraVersion = '1.2.3' androidxComposeBomVersion = '2023.10.00' - androidxComposeCompilerVersion = '1.5.3' + androidxComposeCompilerVersion = '1.5.9' androidxComposeNavigationVersion = '2.7.6' androidxCardviewVersion = '1.0.0' androidxConstraintlayoutVersion = '2.1.4' diff --git a/libs/processors/build.gradle b/libs/processors/build.gradle index 8e338bd2ea76..513a05e9be1f 100644 --- a/libs/processors/build.gradle +++ b/libs/processors/build.gradle @@ -1,6 +1,5 @@ plugins { id "org.jetbrains.kotlin.jvm" - id "org.jetbrains.kotlin.kapt" id "org.jetbrains.kotlinx.kover" } @@ -10,9 +9,9 @@ targetCompatibility = JavaVersion.VERSION_1_8 dependencies { implementation project(":libs:annotations") - implementation "com.google.auto.service:auto-service:$googleAutoServiceVersion" - kapt "com.google.auto.service:auto-service:$googleAutoServiceVersion" implementation "com.squareup:kotlinpoet:$squareupKotlinPoetVersion" + implementation "com.squareup:kotlinpoet-ksp:$squareupKotlinPoetVersion" + implementation "com.google.devtools.ksp:symbol-processing-api:$gradle.ext.kspVersion" testImplementation "junit:junit:$junitVersion" testImplementation "org.assertj:assertj-core:$assertjVersion" diff --git a/settings.gradle b/settings.gradle index a092afee5eb6..342adb055c3f 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,6 @@ pluginManagement { - gradle.ext.kotlinVersion = '1.9.10' + gradle.ext.kotlinVersion = '1.9.22' + gradle.ext.kspVersion = '1.9.22-1.0.17' gradle.ext.agpVersion = '8.1.0' gradle.ext.googleServicesVersion = '4.3.15' gradle.ext.navigationVersion = '2.5.3' @@ -27,6 +28,7 @@ pluginManagement { id 'com.automattic.android.measure-builds' version gradle.ext.measureBuildsVersion id "org.jetbrains.kotlinx.kover" version gradle.ext.koverVersion id "com.google.dagger.hilt.android" version gradle.ext.daggerVersion + id "com.google.devtools.ksp" version gradle.ext.kspVersion } repositories { maven { From 5490e4ece010c549ea527272a8e40039039484e7 Mon Sep 17 00:00:00 2001 From: Wojtek Zieba Date: Tue, 20 Feb 2024 18:52:40 +0100 Subject: [PATCH 2/9] refactor: rewrite `RemoteConfigProcessor` to ksp --- WordPress/build.gradle | 2 +- .../processor/RemoteConfigProcessor.kt | 203 ++++++++---------- .../RemoteConfigProcessorProvider.kt | 13 ++ ...ols.ksp.processing.SymbolProcessorProvider | 1 + 4 files changed, 109 insertions(+), 110 deletions(-) create mode 100644 libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessorProvider.kt create mode 100644 libs/processors/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 26d2218b3db4..00a222bcd866 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -346,7 +346,7 @@ dependencies { implementation 'androidx.webkit:webkit:1.10.0' implementation "androidx.navigation:navigation-compose:$androidxComposeNavigationVersion" compileOnly project(path: ':libs:annotations') - kapt project(':libs:processors') + ksp project(':libs:processors') implementation (project(path:':libs:networking')) { exclude group: "com.android.volley" exclude group: 'org.wordpress', module: 'utils' diff --git a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt index a8217dd7084f..3a325a1b6b3e 100644 --- a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt +++ b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt @@ -1,128 +1,113 @@ +@file:OptIn(KspExperimental::class) + + package org.wordpress.android.processor -import com.google.auto.service.AutoService -import com.squareup.kotlinpoet.DelicateKotlinPoetApi -import com.squareup.kotlinpoet.TypeName -import com.squareup.kotlinpoet.asTypeName +import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.getAnnotationsByType +import com.google.devtools.ksp.processing.CodeGenerator +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.squareup.kotlinpoet.ksp.toTypeName +import com.squareup.kotlinpoet.ksp.writeTo import org.wordpress.android.annotation.Experiment import org.wordpress.android.annotation.Feature -import org.wordpress.android.annotation.FeatureInDevelopment import org.wordpress.android.annotation.RemoteFieldDefaultGenerater -import java.io.File -import javax.annotation.processing.AbstractProcessor -import javax.annotation.processing.Processor -import javax.annotation.processing.RoundEnvironment -import javax.annotation.processing.SupportedAnnotationTypes -import javax.annotation.processing.SupportedSourceVersion -import javax.lang.model.SourceVersion -import javax.lang.model.element.TypeElement -import javax.tools.Diagnostic.Kind - -@AutoService(Processor::class) // For registering the service -@SupportedSourceVersion(SourceVersion.RELEASE_8) // to support Java 8 -@SupportedAnnotationTypes( - "org.wordpress.android.annotation.Experiment", - "org.wordpress.android.annotation.Feature", - "org.wordpress.android.annotation.FeatureInDevelopment", - "org.wordpress.android.annotation.RemoteFieldDefaultGenerater" -) -class RemoteConfigProcessor : AbstractProcessor() { - @OptIn(DelicateKotlinPoetApi::class) - @Suppress("DEPRECATION") - override fun process(p0: MutableSet?, roundEnvironment: RoundEnvironment?): Boolean { - val experiments = roundEnvironment?.getElementsAnnotatedWith(Experiment::class.java)?.map { element -> - val annotation = element.getAnnotation(Experiment::class.java) - annotation.remoteField to annotation.defaultVariant - } ?: listOf() - val remoteFeatureNames = mutableListOf() - val features = roundEnvironment?.getElementsAnnotatedWith(Feature::class.java)?.map { element -> - val annotation = element.getAnnotation(Feature::class.java) - remoteFeatureNames.add(element.asType().asTypeName()) - annotation.remoteField to annotation.defaultValue.toString() - } ?: listOf() - val remoteFields = roundEnvironment?.getElementsAnnotatedWith(RemoteFieldDefaultGenerater::class.java) - ?.map { element -> - val annotation = element.getAnnotation(RemoteFieldDefaultGenerater::class.java) - annotation.remoteField to annotation.defaultValue - } ?: listOf() - val featuresInDevelopment = roundEnvironment?.getElementsAnnotatedWith(FeatureInDevelopment::class.java) - ?.map { element -> - element.asType().toString() - } ?: listOf() - return if (experiments.isNotEmpty() || features.isNotEmpty()) { - generateRemoteFieldConfigDefaults(remoteFields.toMap()) - generateRemoteFeatureConfigDefaults((experiments + features).toMap()) - generateRemoteFeatureConfigCheck(remoteFeatureNames) - generateFeaturesInDevelopment(featuresInDevelopment) - true - } else { - false - } - } - @Suppress("TooGenericExceptionCaught", "SwallowedException") - private fun generateRemoteFeatureConfigDefaults( - remoteConfigDefaults: Map - ) { - try { - val fileContent = RemoteFeatureConfigDefaultsBuilder(remoteConfigDefaults).getContent() - - val kaptKotlinGeneratedDir = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME] - fileContent.writeTo(File(kaptKotlinGeneratedDir)) - } catch (e: Exception) { - processingEnv.messager.printMessage(Kind.ERROR, "Failed to generate remote feature config defaults") +@OptIn(KspExperimental::class) +class RemoteConfigProcessor( + private val codeGenerator: CodeGenerator, +) : SymbolProcessor { + /** + * See: https://github.com/google/ksp/issues/797#issuecomment-1041127747 + * Also: https://github.com/google/ksp/blob/a0cd7774a7f65cec45a50ecc8960ef5e4d47fc21/examples/playground/test-processor/src/main/kotlin/TestProcessor.kt#L20 + */ + private var invoked = false + + override fun process(resolver: Resolver): List { + if (invoked) { + return emptyList() } + + val remoteFeatures = resolver.getSymbolsWithAnnotation("org.wordpress.android.annotation.Feature") + .toList() + + generateRemoteFeatureConfigDefaults(resolver, remoteFeatures) + generateRemoteFieldsConfigDefaults(resolver) + generateFeaturesInDevelopment(resolver) + generateRemoteFeatureConfigCheck(remoteFeatures) + + invoked = true + return emptyList() } - @Suppress("TooGenericExceptionCaught", "SwallowedException") - private fun generateRemoteFieldConfigDefaults( - remoteConfigDefaults: Map - ) { - try { - val fileContent = RemoteFieldConfigDefaultsBuilder(remoteConfigDefaults).getContent() - - val kaptKotlinGeneratedDir = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME] - fileContent.writeTo(File(kaptKotlinGeneratedDir)) - } catch (e: Exception) { - processingEnv.messager.printMessage(Kind.ERROR, "Failed to generate remote feature config defaults") - } + private fun generateRemoteFeatureConfigDefaults(resolver: Resolver, remoteFeatures: List) { + val experiments = resolver.getSymbolsWithAnnotation("org.wordpress.android.annotation.Experiment") + .toList() + + val defaults = (remoteFeatures + experiments) + .map { element: KSAnnotated -> + val featuresDefaults = element.getAnnotationsByType(Feature::class) + .toList().associate { annotation -> + annotation.remoteField to annotation.defaultValue.toString() + } + val experimentsDefaults = element.getAnnotationsByType(Experiment::class).toList() + .toList().associate { annotation -> + annotation.remoteField to annotation.defaultVariant + } + featuresDefaults + experimentsDefaults + }.flatMap { it.toList() } + .toMap() + + RemoteFeatureConfigDefaultsBuilder(defaults).getContent() + .writeTo( + codeGenerator, + aggregating = true, + ) } - @Suppress("TooGenericExceptionCaught") - private fun generateRemoteFeatureConfigCheck( - remoteFeatureNames: List - ) { - try { - val fileContent = RemoteFeatureConfigCheckBuilder(remoteFeatureNames).getContent() - - val kaptKotlinGeneratedDir = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME] - fileContent.writeTo(File(kaptKotlinGeneratedDir)) - } catch (e: Exception) { - processingEnv.messager.printMessage( - Kind.ERROR, - "Failed to generate remote feature config check: $e" + private fun generateRemoteFieldsConfigDefaults(resolver: Resolver) { + val remoteFieldDefaults = + resolver.getSymbolsWithAnnotation("org.wordpress.android.annotation.RemoteFieldDefaultGenerater") + .toList() + .associate { element: KSAnnotated -> + element.getAnnotationsByType(RemoteFieldDefaultGenerater::class) + .toList() + .first() + .let { annotation -> + annotation.remoteField to annotation.defaultValue + } + } + + RemoteFieldConfigDefaultsBuilder(remoteFieldDefaults).getContent() + .writeTo( + codeGenerator, + aggregating = true, ) - } } - @Suppress("TooGenericExceptionCaught") - private fun generateFeaturesInDevelopment( - remoteFeatureNames: List - ) { - try { - val fileContent = FeaturesInDevelopmentDefaultsBuilder(remoteFeatureNames).getContent() - - val kaptKotlinGeneratedDir = processingEnv.options[KAPT_KOTLIN_GENERATED_OPTION_NAME] - fileContent.writeTo(File(kaptKotlinGeneratedDir)) - } catch (e: Exception) { - processingEnv.messager.printMessage( - Kind.ERROR, - "Failed to generate remote config check: $e" + private fun generateFeaturesInDevelopment(resolver: Resolver) { + val featuresInDevelopmentDefaults = + resolver.getSymbolsWithAnnotation("org.wordpress.android.annotation.FeatureInDevelopment") + .filterIsInstance() + .toList() + .map { it.simpleName.asString() } + + FeaturesInDevelopmentDefaultsBuilder(featuresInDevelopmentDefaults).getContent() + .writeTo( + codeGenerator, + aggregating = true, ) - } } - companion object { - const val KAPT_KOTLIN_GENERATED_OPTION_NAME = "kapt.kotlin.generated" + private fun generateRemoteFeatureConfigCheck(remoteFeatures: List) { + RemoteFeatureConfigCheckBuilder( + remoteFeatures.filterIsInstance().map { it.asType(emptyList()).toTypeName() } + ).getContent().writeTo( + codeGenerator, + aggregating = true, + ) } } diff --git a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessorProvider.kt b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessorProvider.kt new file mode 100644 index 000000000000..81c317430a8b --- /dev/null +++ b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessorProvider.kt @@ -0,0 +1,13 @@ +package org.wordpress.android.processor + +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.processing.SymbolProcessorProvider + +class RemoteConfigProcessorProvider : SymbolProcessorProvider { + override fun create( + environment: SymbolProcessorEnvironment + ): SymbolProcessor { + return RemoteConfigProcessor(environment.codeGenerator) + } +} diff --git a/libs/processors/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/libs/processors/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider new file mode 100644 index 000000000000..1f997f654fad --- /dev/null +++ b/libs/processors/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -0,0 +1 @@ +org.wordpress.android.processor.RemoteConfigProcessorProvider From 80a80aa61c01a2c8a1e84fccd9a3ead307be8b7f Mon Sep 17 00:00:00 2001 From: Wojtek Zieba Date: Tue, 20 Feb 2024 19:38:11 +0100 Subject: [PATCH 3/9] feat: specify correct `originatingFiles` to optimize ksp output invalidation --- .../processor/RemoteConfigProcessor.kt | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt index 3a325a1b6b3e..cbc88987ce91 100644 --- a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt +++ b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt @@ -4,6 +4,7 @@ package org.wordpress.android.processor import com.google.devtools.ksp.KspExperimental +import com.google.devtools.ksp.containingFile import com.google.devtools.ksp.getAnnotationsByType import com.google.devtools.ksp.processing.CodeGenerator import com.google.devtools.ksp.processing.Resolver @@ -65,40 +66,45 @@ class RemoteConfigProcessor( .writeTo( codeGenerator, aggregating = true, + originatingKSFiles = remoteFeatures.map { it.containingFile!! } ) } private fun generateRemoteFieldsConfigDefaults(resolver: Resolver) { - val remoteFieldDefaults = + val remoteFields = resolver.getSymbolsWithAnnotation("org.wordpress.android.annotation.RemoteFieldDefaultGenerater") .toList() - .associate { element: KSAnnotated -> - element.getAnnotationsByType(RemoteFieldDefaultGenerater::class) - .toList() - .first() - .let { annotation -> - annotation.remoteField to annotation.defaultValue - } - } + val remoteFieldDefaults = remoteFields + .associate { element: KSAnnotated -> + element.getAnnotationsByType(RemoteFieldDefaultGenerater::class) + .toList() + .first() + .let { annotation -> + annotation.remoteField to annotation.defaultValue + } + } RemoteFieldConfigDefaultsBuilder(remoteFieldDefaults).getContent() .writeTo( codeGenerator, aggregating = true, + originatingKSFiles = remoteFields.map { it.containingFile!! } ) } private fun generateFeaturesInDevelopment(resolver: Resolver) { - val featuresInDevelopmentDefaults = + val featuresInDevelopment = resolver.getSymbolsWithAnnotation("org.wordpress.android.annotation.FeatureInDevelopment") .filterIsInstance() .toList() - .map { it.simpleName.asString() } + val featuresInDevelopmentDefaults = featuresInDevelopment + .map { it.simpleName.asString() } FeaturesInDevelopmentDefaultsBuilder(featuresInDevelopmentDefaults).getContent() .writeTo( codeGenerator, aggregating = true, + originatingKSFiles = featuresInDevelopment.map { it.containingFile!! } ) } @@ -108,6 +114,7 @@ class RemoteConfigProcessor( ).getContent().writeTo( codeGenerator, aggregating = true, + originatingKSFiles = remoteFeatures.map { it.containingFile!! } ) } } From 55199e2344e932ec3dc85f99202bd95c3b7f4199 Mon Sep 17 00:00:00 2001 From: Wojtek Zieba Date: Wed, 21 Feb 2024 11:12:53 +0100 Subject: [PATCH 4/9] fix: do not generate classes if inputs are empty This commit brings back behaviour from previous, kapt implementation, of not generating classes if inputs for them are empty. This solves the problem of generating classes with empty content in different sourceset, e.g. `androidTest`. You can reproduce such problem in 80a80aa61c01a2c8a1e84fccd9a3ead307be8b7f --- .../processor/RemoteConfigProcessor.kt | 58 +++++++++++-------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt index cbc88987ce91..72e549fb59fd 100644 --- a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt +++ b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt @@ -62,12 +62,14 @@ class RemoteConfigProcessor( }.flatMap { it.toList() } .toMap() - RemoteFeatureConfigDefaultsBuilder(defaults).getContent() - .writeTo( - codeGenerator, - aggregating = true, - originatingKSFiles = remoteFeatures.map { it.containingFile!! } - ) + if (defaults.isNotEmpty()) { + RemoteFeatureConfigDefaultsBuilder(defaults).getContent() + .writeTo( + codeGenerator, + aggregating = true, + originatingKSFiles = remoteFeatures.map { it.containingFile!! } + ) + } } private fun generateRemoteFieldsConfigDefaults(resolver: Resolver) { @@ -84,12 +86,14 @@ class RemoteConfigProcessor( } } - RemoteFieldConfigDefaultsBuilder(remoteFieldDefaults).getContent() - .writeTo( - codeGenerator, - aggregating = true, - originatingKSFiles = remoteFields.map { it.containingFile!! } - ) + if(remoteFieldDefaults.isNotEmpty()) { + RemoteFieldConfigDefaultsBuilder(remoteFieldDefaults).getContent() + .writeTo( + codeGenerator, + aggregating = true, + originatingKSFiles = remoteFields.map { it.containingFile!! } + ) + } } private fun generateFeaturesInDevelopment(resolver: Resolver) { @@ -100,21 +104,25 @@ class RemoteConfigProcessor( val featuresInDevelopmentDefaults = featuresInDevelopment .map { it.simpleName.asString() } - FeaturesInDevelopmentDefaultsBuilder(featuresInDevelopmentDefaults).getContent() - .writeTo( - codeGenerator, - aggregating = true, - originatingKSFiles = featuresInDevelopment.map { it.containingFile!! } - ) + if(featuresInDevelopmentDefaults.isNotEmpty()) { + FeaturesInDevelopmentDefaultsBuilder(featuresInDevelopmentDefaults).getContent() + .writeTo( + codeGenerator, + aggregating = true, + originatingKSFiles = featuresInDevelopment.map { it.containingFile!! } + ) + } } private fun generateRemoteFeatureConfigCheck(remoteFeatures: List) { - RemoteFeatureConfigCheckBuilder( - remoteFeatures.filterIsInstance().map { it.asType(emptyList()).toTypeName() } - ).getContent().writeTo( - codeGenerator, - aggregating = true, - originatingKSFiles = remoteFeatures.map { it.containingFile!! } - ) + if(remoteFeatures.isNotEmpty()) { + RemoteFeatureConfigCheckBuilder( + remoteFeatures.filterIsInstance().map { it.asType(emptyList()).toTypeName() } + ).getContent().writeTo( + codeGenerator, + aggregating = true, + originatingKSFiles = remoteFeatures.map { it.containingFile!! } + ) + } } } From 95da243006bfbd22cab61fb9cc533ca5a9d59fd5 Mon Sep 17 00:00:00 2001 From: Wojtek Zieba Date: Wed, 21 Feb 2024 12:26:01 +0100 Subject: [PATCH 5/9] build: replace kapt with ksp --- WordPress/build.gradle | 13 ++++--------- config/lint/lint.xml | 4 ++-- settings.gradle | 1 - 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/WordPress/build.gradle b/WordPress/build.gradle index 00a222bcd866..799850435354 100644 --- a/WordPress/build.gradle +++ b/WordPress/build.gradle @@ -4,7 +4,6 @@ import se.bjurr.violations.lib.model.SEVERITY plugins { id "com.android.application" id "org.jetbrains.kotlin.android" - id "org.jetbrains.kotlin.kapt" id "org.jetbrains.kotlin.plugin.parcelize" id "org.jetbrains.kotlin.plugin.allopen" id "io.sentry.android.gradle" @@ -337,10 +336,6 @@ static def addBuildConfigFieldsFromPrefixedProperties(variant, properties, prefi variant.buildConfigField "String", it.key.toUpperCase(), "\"${it.value}\"" } } -kapt { - // Enable to infer error types in stubs (see: https://kotlinlang.org/docs/kapt.html#non-existent-type-correction) - correctErrorTypes true -} dependencies { implementation 'androidx.webkit:webkit:1.10.0' @@ -453,7 +448,7 @@ dependencies { exclude group: 'androidx.appcompat', module: 'appcompat' } implementation "com.github.bumptech.glide:glide:$glideVersion" - kapt "com.github.bumptech.glide:compiler:$glideVersion" + ksp "com.github.bumptech.glide:ksp:$glideVersion" implementation "com.github.bumptech.glide:volley-integration:$glideVersion" implementation "com.github.indexos.media-for-mobile:domain:$indexosMediaForMobileVersion" implementation "com.github.indexos.media-for-mobile:android:$indexosMediaForMobileVersion" @@ -467,9 +462,9 @@ dependencies { exclude group: 'com.android.support', module: 'support-annotations' } implementation "com.google.dagger:dagger-android-support:$gradle.ext.daggerVersion" - kapt "com.google.dagger:dagger-android-processor:$gradle.ext.daggerVersion" + ksp "com.google.dagger:dagger-android-processor:$gradle.ext.daggerVersion" implementation "com.google.dagger:hilt-android:$gradle.ext.daggerVersion" - kapt "com.google.dagger:hilt-compiler:$gradle.ext.daggerVersion" + ksp "com.google.dagger:hilt-compiler:$gradle.ext.daggerVersion" testImplementation "$gradle.ext.storiesAndroidPhotoEditorPath:$automatticStoriesVersion" @@ -526,7 +521,7 @@ dependencies { androidTestImplementation (name:'cloudtestingscreenshotter_lib', ext:'aar') // Screenshots on Firebase Cloud Testing androidTestImplementation "androidx.work:work-testing:$androidxWorkManagerVersion" androidTestImplementation "com.google.dagger:hilt-android-testing:$gradle.ext.daggerVersion" - kaptAndroidTest "com.google.dagger:hilt-android-compiler:$gradle.ext.daggerVersion" + kspAndroidTest "com.google.dagger:hilt-android-compiler:$gradle.ext.daggerVersion" // Enables Java 8+ API desugaring support coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:$androidDesugarVersion" lintChecks "org.wordpress:lint:$wordPressLintVersion" diff --git a/config/lint/lint.xml b/config/lint/lint.xml index e779334f1bba..3985b167379f 100644 --- a/config/lint/lint.xml +++ b/config/lint/lint.xml @@ -19,7 +19,7 @@ - + @@ -63,7 +63,7 @@ - + diff --git a/settings.gradle b/settings.gradle index 342adb055c3f..d9c81086d9d9 100644 --- a/settings.gradle +++ b/settings.gradle @@ -14,7 +14,6 @@ pluginManagement { plugins { id "org.jetbrains.kotlin.android" version gradle.ext.kotlinVersion id "org.jetbrains.kotlin.jvm" version gradle.ext.kotlinVersion - id "org.jetbrains.kotlin.kapt" version gradle.ext.kotlinVersion id "org.jetbrains.kotlin.plugin.serialization" version gradle.ext.kotlinVersion id "org.jetbrains.kotlin.plugin.parcelize" version gradle.ext.kotlinVersion id "org.jetbrains.kotlin.plugin.allopen" version gradle.ext.kotlinVersion From 29409bc2f9d633427a3335fd71962af0c19834ca Mon Sep 17 00:00:00 2001 From: Wojtek Zieba Date: Wed, 21 Feb 2024 18:27:54 +0100 Subject: [PATCH 6/9] test: adjust test setup for ksp usage --- libs/processors/build.gradle | 4 +++- .../wordpress/android/processor/RemoteConfigProcessorTest.kt | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libs/processors/build.gradle b/libs/processors/build.gradle index 78bc9b3cc134..6baeb1bb411d 100644 --- a/libs/processors/build.gradle +++ b/libs/processors/build.gradle @@ -13,7 +13,9 @@ dependencies { implementation "com.squareup:kotlinpoet-ksp:$squareupKotlinPoetVersion" implementation "com.google.devtools.ksp:symbol-processing-api:$gradle.ext.kspVersion" - testImplementation "com.github.tschuchortdev:kotlin-compile-testing:1.5.0" + def kctVersion = "1.5.0" + testImplementation "com.github.tschuchortdev:kotlin-compile-testing:$kctVersion" + testImplementation "com.github.tschuchortdev:kotlin-compile-testing-ksp:$kctVersion" testImplementation "junit:junit:$junitVersion" testImplementation "org.assertj:assertj-core:$assertjVersion" testImplementation "org.jetbrains.kotlin:kotlin-reflect:$gradle.ext.kotlinVersion" diff --git a/libs/processors/src/test/kotlin/org/wordpress/android/processor/RemoteConfigProcessorTest.kt b/libs/processors/src/test/kotlin/org/wordpress/android/processor/RemoteConfigProcessorTest.kt index b4ee3385c125..2f552b9374aa 100644 --- a/libs/processors/src/test/kotlin/org/wordpress/android/processor/RemoteConfigProcessorTest.kt +++ b/libs/processors/src/test/kotlin/org/wordpress/android/processor/RemoteConfigProcessorTest.kt @@ -2,6 +2,8 @@ package org.wordpress.android.processor import com.tschuchort.compiletesting.KotlinCompilation import com.tschuchort.compiletesting.SourceFile +import com.tschuchort.compiletesting.kspWithCompilation +import com.tschuchort.compiletesting.symbolProcessorProviders import org.assertj.core.api.Assertions.assertThat import org.jetbrains.kotlin.utils.addToStdlib.cast import org.junit.Test @@ -124,7 +126,8 @@ class RemoteConfigProcessorTest { private fun compile(src: List) = KotlinCompilation().apply { sources = src + fakeAppConfig - annotationProcessors = listOf(RemoteConfigProcessor()) + symbolProcessorProviders = listOf(RemoteConfigProcessorProvider()) + kspWithCompilation = true inheritClassPath = true messageOutputStream = System.out }.compile() From dfcf76188804623a26d90298884fc12cbea94378 Mon Sep 17 00:00:00 2001 From: Wojtek Zieba Date: Thu, 22 Feb 2024 12:05:45 +0100 Subject: [PATCH 7/9] tests: simplify RemoteConfigProcessorTest Remove the, now not necessairy, feature in every test. It's unnecessary now as condition was updated in RemoteConfigProcessor --- .../android/processor/RemoteConfigProcessorTest.kt | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/libs/processors/src/test/kotlin/org/wordpress/android/processor/RemoteConfigProcessorTest.kt b/libs/processors/src/test/kotlin/org/wordpress/android/processor/RemoteConfigProcessorTest.kt index 2f552b9374aa..aa99781c26ac 100644 --- a/libs/processors/src/test/kotlin/org/wordpress/android/processor/RemoteConfigProcessorTest.kt +++ b/libs/processors/src/test/kotlin/org/wordpress/android/processor/RemoteConfigProcessorTest.kt @@ -34,12 +34,7 @@ class RemoteConfigProcessorTest { ) // when - val result = compile( - listOf( - remoteFieldA, - featureA, /* adding a feature, as without it, annotation processor won't start */ - ) - ) + val result = compile(listOf(remoteFieldA)) // then assertThat(result.exitCode).isEqualTo(KotlinCompilation.ExitCode.OK) @@ -104,12 +99,7 @@ class RemoteConfigProcessorTest { ) // when - val result = compile( - listOf( - experiment, - featureA, /* adding a feature, as without it, annotation processor won't start */ - ) - ) + val result = compile(listOf(experiment)) // then From 0292847e39d9e704b117c6f3c53fb494881ad6a1 Mon Sep 17 00:00:00 2001 From: Wojtek Zieba Date: Fri, 23 Feb 2024 11:04:24 +0100 Subject: [PATCH 8/9] docs: add single-round processor comment --- .../org/wordpress/android/processor/RemoteConfigProcessor.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt index 72e549fb59fd..515774603317 100644 --- a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt +++ b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt @@ -22,6 +22,7 @@ class RemoteConfigProcessor( private val codeGenerator: CodeGenerator, ) : SymbolProcessor { /** + * In the case of this processor, we only one need round - generated files do not depend on each other or any other processor. * See: https://github.com/google/ksp/issues/797#issuecomment-1041127747 * Also: https://github.com/google/ksp/blob/a0cd7774a7f65cec45a50ecc8960ef5e4d47fc21/examples/playground/test-processor/src/main/kotlin/TestProcessor.kt#L20 */ From 3df71cfb3c7b68a29c4f2d141f9e8ba4b427e0e0 Mon Sep 17 00:00:00 2001 From: Wojtek Zieba Date: Fri, 23 Feb 2024 11:13:42 +0100 Subject: [PATCH 9/9] style: fix checkstyle --- .../org/wordpress/android/processor/RemoteConfigProcessor.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt index 515774603317..2c5c57acd01b 100644 --- a/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt +++ b/libs/processors/src/main/java/org/wordpress/android/processor/RemoteConfigProcessor.kt @@ -22,7 +22,9 @@ class RemoteConfigProcessor( private val codeGenerator: CodeGenerator, ) : SymbolProcessor { /** - * In the case of this processor, we only one need round - generated files do not depend on each other or any other processor. + * In the case of this processor, we only one need round. Generated files do not depend on each other + * or any other processor. + * * See: https://github.com/google/ksp/issues/797#issuecomment-1041127747 * Also: https://github.com/google/ksp/blob/a0cd7774a7f65cec45a50ecc8960ef5e4d47fc21/examples/playground/test-processor/src/main/kotlin/TestProcessor.kt#L20 */