How do reporting tasks decide where to write their output, and how would you relocate all reports for a project?
answer
- ReportingExtension / reporting {}
- baseDirectory DirectoryProperty
- default build/reports
- lazy Provider wiring
- per-task reports container override
basics
~10 sReporting plugins honor the ReportingExtension (reporting { baseDirectory }), which defaults to build/reports. Setting reporting.baseDirectory relocates the base under which report tasks (project-report, build-dashboard, tests, coverage) write.
solid answer
~40 sGradle's reporting plugins resolve their output relative to a shared `ReportingExtension`, exposed as the `reporting { }` block. Its `baseDirectory` is a `DirectoryProperty` defaulting to `build/reports`. Tasks contributed by `project-report` (e.g. `htmlDependencyReport` → `dependencies/`) and the `buildDashboard` task derive their destinations from this base, as do `test` and `jacocoTestReport`. To move every report for a project you set `reporting.baseDirectory` once — because the property is lazy (a Provider), tasks pick up the change wherever it is finalized. This centralizes report locations, which is handy for CI archival paths or for keeping reports outside `build/` if you want them to survive a `clean` differently. Per-task overrides are still possible via each task's `reports` container.
code
kotlin · 4 linesreporting {
baseDirectory.set(layout.buildDirectory.dir("ci-reports"))
}
// htmlDependencyReport, buildDashboard, test, jacoco all relocate under build/ci-reportsgo deeper
Know reports default to build/reports.
Name the reporting { baseDirectory } block and that setting it moves report output.
Explain lazy Provider wiring, how tasks derive subpaths, and per-task reports-container overrides.
Standardize report locations via convention plugins across repos and align with CI artifact conventions and configuration cache.
## The shared base: ReportingExtension When any reporting-capable plugin is applied (including the `reporting-base` plugin that others apply transitively), Gradle adds the `ReportingExtension` to the project, accessible via the `reporting { }` DSL block. Its central property is: ```kotlin reporting { baseDirectory.set(layout.buildDirectory.dir("all-reports")) } ``` `baseDirectory` is a `DirectoryProperty` (a lazy `Provider`), defaulting to `build/reports`. ## How tasks consume it Report-producing tasks don't hardcode paths; they wire their destination from `reporting.baseDirectory` at configuration time. For example: - `htmlDependencyReport` → `<base>/project/dependencies` - `buildDashboard` → `<base>/buildDashboard` - `test` → `<base>/tests/test` - `jacocoTestReport` → `<base>/jacoco/test` Because the wiring is through lazy providers, setting `baseDirectory` propagates to all of them regardless of evaluation order. ## Relocating all reports Set the base once, typically in a convention/build script: ```kotlin plugins { id("project-report") id("build-dashboard") } reporting { baseDirectory.set(layout.buildDirectory.dir("ci-reports")) } ``` Now `htmlDependencyReport`, `buildDashboard`, and downstream report tasks all land under `build/ci-reports`. ## Lazy configuration matters The property is part of Gradle's lazy configuration API (`Property`/`Provider`). That means you should `set` it rather than read it eagerly, and downstream tasks resolve it only when needed — avoiding ordering bugs and supporting the configuration cache. ## Per-task overrides Reporting tasks also expose a `reports` container (the `Reporting` interface) where you can override individual outputs, formats, or enable/disable a report: ```kotlin tasks.named<Test>("test") { reports { html.required.set(true) junitXml.outputLocation.set(layout.buildDirectory.dir("test-xml")) } } ``` Use `reporting.baseDirectory` for whole-project relocation; use the per-task `reports` container for fine-grained control. ## Why it matters Centralizing report locations simplifies CI publishing globs, keeps a multi-module build's reports consistent, and lets convention plugins enforce one standard across many repos.
- Why is baseDirectory a Provider/DirectoryProperty rather than a plain File?Lazy configuration: downstream tasks wire from it and resolve only when needed, which avoids evaluation-ordering bugs and is compatible with the configuration cache.
- How do you change just one task's report location without affecting others?Use that task's `reports` container (from the Reporting interface) to set the specific report's outputLocation, leaving reporting.baseDirectory untouched.
saying these in an interview costs you the question
- Hardcoding absolute report paths instead of using reporting.baseDirectory.
- Reading the property eagerly with .get() at configuration time, breaking laziness.
- Assuming each plugin has an independent, unrelated output dir — they share the ReportingExtension base.