From 39b066e9997524036282b73783d252c533ab6cb1 Mon Sep 17 00:00:00 2001 From: Andreas Rossbacher Date: Mon, 20 Apr 2026 11:58:51 -0700 Subject: [PATCH] Manifest generation: fail on write errors, clean up logging - ManifestGenerator: throw DeepLinkProcessorException on IOException instead of swallowing as a diagnostic warning (a missing manifest would otherwise fail silently in a confusing downstream place). Catch scoped to IOException so processor bugs aren't hidden. - RelocateDeepLinkManifestTask: use orNull instead of get() on the @Optional kspManifestFile property (get() NPEs when unset), replace println with logger.warn, collapse empty else-if branch, fix typos. - GenerateManifestIntentFiltersForDeeplinkDispatchTask: replace println with logger.warn (respects --quiet) and switch error(...) calls to throw GradleException for idiomatic build-failure output. --- ...estIntentFiltersForDeeplinkDispatchTask.kt | 15 +++++------ .../RelocateDeepLinkManifestTask.kt | 25 ++++++++----------- .../metadata/ManifestGenerator.kt | 10 +++++--- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/deeplinkdispatch-gradle-plugin/src/main/java/com/airbnb/deeplinkdispatch/gradleplugin/GenerateManifestIntentFiltersForDeeplinkDispatchTask.kt b/deeplinkdispatch-gradle-plugin/src/main/java/com/airbnb/deeplinkdispatch/gradleplugin/GenerateManifestIntentFiltersForDeeplinkDispatchTask.kt index e037d0df..37b8072c 100644 --- a/deeplinkdispatch-gradle-plugin/src/main/java/com/airbnb/deeplinkdispatch/gradleplugin/GenerateManifestIntentFiltersForDeeplinkDispatchTask.kt +++ b/deeplinkdispatch-gradle-plugin/src/main/java/com/airbnb/deeplinkdispatch/gradleplugin/GenerateManifestIntentFiltersForDeeplinkDispatchTask.kt @@ -5,6 +5,7 @@ import com.android.manifmerger.ManifestMerger2 import com.android.manifmerger.MergingReport import com.android.utils.StdLogger import org.gradle.api.DefaultTask +import org.gradle.api.GradleException import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property @@ -82,12 +83,12 @@ abstract class GenerateManifestIntentFiltersForDeeplinkDispatchTask : DefaultTas generatedManifestFile.length() > 0 if (!hasGeneratedManifest) { - println( + logger.warn( "No DeepLinkDispatch generated manifest found or manifest is empty. Copying input" + - " manifest to output without modifications. You might have applied the" + - " deep link dispatch gradle plugin to a module that does not have deep" + - " links defined or you forgot the set the `activityClassFqn` on your deep" + - " links." + " manifest to output without modifications. You might have applied the" + + " deep link dispatch gradle plugin to a module that does not have deep" + + " links defined or you forgot to set the `activityClassFqn` on your deep" + + " links.", ) inputManifest.copyTo(outputManifest, overwrite = true) return @@ -112,7 +113,7 @@ abstract class GenerateManifestIntentFiltersForDeeplinkDispatchTask : DefaultTas val merge = invoker.merge() if (merge.result.isSuccess) { val mergedDocument = merge.getMergedDocument(MergingReport.MergedManifestKind.MERGED) - ?: error("Failed to get merged document") + ?: throw GradleException("DeepLinkDispatch: failed to get merged manifest document") outputManifest.writeText(mergedDocument) } else { val errorMessage = buildString { @@ -121,7 +122,7 @@ abstract class GenerateManifestIntentFiltersForDeeplinkDispatchTask : DefaultTas appendLine(" ${record.severity}: ${record.message}") } } - error(errorMessage) + throw GradleException(errorMessage) } } diff --git a/deeplinkdispatch-gradle-plugin/src/main/java/com/airbnb/deeplinkdispatch/gradleplugin/RelocateDeepLinkManifestTask.kt b/deeplinkdispatch-gradle-plugin/src/main/java/com/airbnb/deeplinkdispatch/gradleplugin/RelocateDeepLinkManifestTask.kt index 4d5c6ccf..6b18c37e 100644 --- a/deeplinkdispatch-gradle-plugin/src/main/java/com/airbnb/deeplinkdispatch/gradleplugin/RelocateDeepLinkManifestTask.kt +++ b/deeplinkdispatch-gradle-plugin/src/main/java/com/airbnb/deeplinkdispatch/gradleplugin/RelocateDeepLinkManifestTask.kt @@ -41,20 +41,18 @@ abstract class RelocateDeepLinkManifestTask : DefaultTask() { // 2. Gradle's up-to-date check only compares content, not file existence // 3. The task deletes the source file, which needs to happen every time outputs.upToDateWhen { - // Task is only up-to-date if source file doesn't exist - !kspManifestFile.get().asFile.exists() + val source = kspManifestFile.orNull?.asFile + source == null || !source.exists() } } @TaskAction fun taskAction() { - val sourceFile = kspManifestFile.get().asFile + val sourceFile = kspManifestFile.orNull?.asFile val destFile = safeManifestFile.get().asFile - if (sourceFile.exists()) { - // Ensure parent directory exists + if (sourceFile != null && sourceFile.exists()) { destFile.parentFile?.mkdirs() - // Copy to safe location sourceFile.copyTo(destFile, overwrite = true) // Delete from KSP resources to prevent Java resource merge conflict if (sourceFile.delete()) { @@ -70,14 +68,13 @@ abstract class RelocateDeepLinkManifestTask : DefaultTask() { parentDir = nextParent } } - } else if (destFile.exists()) { - // Source doesn't exist but dest does - this can happen on incremental builds - // where KSP was UP-TO-DATE and we already moved the file previously. - // The dest file is still valid, so nothing to do. - } else { - // Neither file exists - no manifest was generated - println("No DeepLinkDispatch manifest found to relocate in ${project.name}. If this module has no deep links, consider" + - "removing the DeepLinkDispatch gradle plugin from it's gradle file.") + } else if (!destFile.exists()) { + logger.warn( + "No DeepLinkDispatch manifest found to relocate in ${project.name}. " + + "If this module has no deep links, consider removing the DeepLinkDispatch " + + "gradle plugin from its gradle file.", + ) } + // If source is gone but dest exists, a previous run already relocated it — nothing to do. } } diff --git a/deeplinkdispatch-processor/src/main/java/com/airbnb/deeplinkdispatch/metadata/ManifestGenerator.kt b/deeplinkdispatch-processor/src/main/java/com/airbnb/deeplinkdispatch/metadata/ManifestGenerator.kt index 33073f1d..f4946696 100644 --- a/deeplinkdispatch-processor/src/main/java/com/airbnb/deeplinkdispatch/metadata/ManifestGenerator.kt +++ b/deeplinkdispatch-processor/src/main/java/com/airbnb/deeplinkdispatch/metadata/ManifestGenerator.kt @@ -5,9 +5,11 @@ import androidx.room.compiler.processing.XFiler import androidx.room.compiler.processing.XMessager import androidx.room.compiler.processing.XProcessingEnv import com.airbnb.deeplinkdispatch.DeepLinkAnnotatedElement +import com.airbnb.deeplinkdispatch.DeepLinkProcessorException import com.airbnb.deeplinkdispatch.base.ManifestGeneration import com.airbnb.deeplinkdispatch.metadata.writers.ManifestWriter import com.airbnb.deeplinkdispatch.metadata.writers.Writer +import java.io.IOException import java.io.PrintWriter import java.io.StringWriter import java.nio.file.Path @@ -108,10 +110,10 @@ internal class ManifestGenerator( Diagnostic.Kind.NOTE, "Manifest generation: Generated at KSP resource output: ${ManifestGeneration.MANIFEST_RESOURCE_PATH}", ) - } catch (e: Exception) { - messager.printMessage( - Diagnostic.Kind.ERROR, - "Manifest generation failed: ${e.message}", + } catch (e: IOException) { + throw DeepLinkProcessorException( + "Manifest generation failed: could not write " + + "${ManifestGeneration.MANIFEST_RESOURCE_PATH}: ${e.message}", ) } }