diff --git a/gradle-plugin/build.gradle.kts b/gradle-plugin/build.gradle.kts index 6e461b6..1c5e6ae 100644 --- a/gradle-plugin/build.gradle.kts +++ b/gradle-plugin/build.gradle.kts @@ -37,6 +37,7 @@ testing { dependencies { implementation(libs.junit.jupiter.api) + implementation(libs.junit.jupiter.params) implementation(libs.truth) } } diff --git a/gradle-plugin/src/functionalTest/kotlin/schwarz/it/lightsaber/gradle/LightsaberPluginIntegrationTest.kt b/gradle-plugin/src/functionalTest/kotlin/schwarz/it/lightsaber/gradle/LightsaberPluginIntegrationTest.kt index 1895c51..a5b762c 100644 --- a/gradle-plugin/src/functionalTest/kotlin/schwarz/it/lightsaber/gradle/LightsaberPluginIntegrationTest.kt +++ b/gradle-plugin/src/functionalTest/kotlin/schwarz/it/lightsaber/gradle/LightsaberPluginIntegrationTest.kt @@ -189,7 +189,7 @@ class LightsaberPluginIntegrationTest { * Copy project files from `resources` to temporary directories for isolation. * This helps with the incremental build (up-to-date checks). */ -private fun GradleRunner.withProjectDirFromResources(resourcePath: String) = apply { +internal fun GradleRunner.withProjectDirFromResources(resourcePath: String) = apply { val resourceDir = File(javaClass.classLoader.getResource("testProjects/$resourcePath")!!.file) val projectDir = Files.createTempDirectory(resourcePath).toFile() resourceDir.copyRecursively(projectDir) diff --git a/gradle-plugin/src/functionalTest/kotlin/schwarz/it/lightsaber/gradle/LightsaberPluginOtherTasksTest.kt b/gradle-plugin/src/functionalTest/kotlin/schwarz/it/lightsaber/gradle/LightsaberPluginOtherTasksTest.kt new file mode 100644 index 0000000..8597100 --- /dev/null +++ b/gradle-plugin/src/functionalTest/kotlin/schwarz/it/lightsaber/gradle/LightsaberPluginOtherTasksTest.kt @@ -0,0 +1,23 @@ +package schwarz.it.lightsaber.gradle + +import org.gradle.testkit.runner.GradleRunner +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource +import java.io.File + +class LightsaberPluginOtherTasksTest { + + @ParameterizedTest + @ValueSource(strings = ["annotationProcessor", "kapt", "ksp", "androidAnnotationProcessor", "androidKapt", "androidKsp"]) + fun `Execute test task correctly`(resourcePath: String) { + val dir: File + GradleRunner.create() + .withProjectDirFromResources(resourcePath) + .also { dir = it.projectDir } + .withPluginClasspath() + .withArguments("test") + .build() + + check(dir.walkBottomUp().none { it.extension == "lightsaber" }) + } +} diff --git a/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberDaggerProcessor.kt b/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberDaggerProcessor.kt index 4e458eb..b3098c5 100644 --- a/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberDaggerProcessor.kt +++ b/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberDaggerProcessor.kt @@ -26,8 +26,10 @@ public class LightsaberDaggerProcessor : BindingGraphPlugin { private lateinit var daggerProcessingEnv: DaggerProcessingEnv private lateinit var fileGenerator: FileGenerator private lateinit var config: DaggerConfig + private var enabled: Boolean = false override fun visitGraph(bindingGraph: BindingGraph, diagnosticReporter: DiagnosticReporter) { + if (!enabled) return val issues = listOf( runRule(config.checkEmptyComponents, "EmptyComponents") { checkEmptyComponents(bindingGraph, daggerProcessingEnv) @@ -58,6 +60,8 @@ public class LightsaberDaggerProcessor : BindingGraphPlugin { } override fun init(processingEnv: DaggerProcessingEnv, options: MutableMap) { + val path = options["Lightsaber.path"] ?: return + enabled = true this.config = DaggerConfig( checkEmptyComponents = options["Lightsaber.CheckEmptyComponents"] != "false", checkUnusedBindsInstances = options["Lightsaber.CheckUnusedBindsInstances"] != "false", @@ -68,7 +72,6 @@ public class LightsaberDaggerProcessor : BindingGraphPlugin { checkUnusedScopes = options["Lightsaber.CheckUnusedScopes"] != "false", ) this.daggerProcessingEnv = processingEnv - val path = checkNotNull(options["Lightsaber.path"]) { "Lightsaber.path argument not provided" } this.fileGenerator = FileGenerator(Path(path)) } diff --git a/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberJavacProcessor.kt b/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberJavacProcessor.kt index 1d9f95c..9a2a593 100644 --- a/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberJavacProcessor.kt +++ b/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberJavacProcessor.kt @@ -14,9 +14,11 @@ import kotlin.io.path.Path class LightsaberJavacProcessor : AbstractProcessor() { private lateinit var fileGenerator: FileGenerator private lateinit var rules: Set> + private var enabled: Boolean = false override fun init(processingEnv: ProcessingEnvironment) { - val path = checkNotNull(processingEnv.options["Lightsaber.path"]) { "Lightsaber.path argument not provided" } + val path = processingEnv.options["Lightsaber.path"] ?: return + enabled = true fileGenerator = FileGenerator(Path(path)) val elements = processingEnv.elementUtils rules = buildSet { @@ -30,6 +32,7 @@ class LightsaberJavacProcessor : AbstractProcessor() { } override fun process(annotations: Set, roundEnv: RoundEnvironment): Boolean { + if (!enabled) return false rules.forEach { (_, rule) -> rule.process(roundEnv) } if (roundEnv.processingOver()) { diff --git a/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberKspProcessor.kt b/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberKspProcessor.kt index 2a7fd0e..87ba572 100644 --- a/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberKspProcessor.kt +++ b/lightsaber/src/main/java/schwarz/it/lightsaber/LightsaberKspProcessor.kt @@ -52,15 +52,21 @@ interface LightsaberKspRule { class LightsaberKspProcessorProvider : SymbolProcessorProvider { override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { + val path = environment.options["Lightsaber.path"] ?: return NoOpSymbolProcessor val config = AnnotationProcessorConfig( checkUnusedInject = environment.options["Lightsaber.CheckUnusedInject"] != "false", checkUnusedScopes = environment.options["Lightsaber.CheckUnusedScopes"] != "false", ) - val path = checkNotNull(environment.options["Lightsaber.path"]) { "Lightsaber.path argument not provided" } return LightsaberKspProcessor(FileGenerator(Path(path)), config) } } +private object NoOpSymbolProcessor : SymbolProcessor { + override fun process(resolver: Resolver): List { + return emptyList() + } +} + internal data class AnnotationProcessorConfig( val checkUnusedInject: Boolean, val checkUnusedScopes: Boolean,