What does `--dry-run` do, and how is it useful for understanding the difference between requested and executed tasks?
answer
- -m short form
- configures, never executes actions
- prints scheduled tasks as SKIPPED
- shows executed set in order
- config-time side effects still happen
basics
~10 s--dry-run (or -m) makes Gradle resolve and print every task it would execute, each marked SKIPPED, without running any task actions. It shows the full executed set for a given request.
solid answer
~40 s`gradle <tasks> --dry-run` runs Gradle through initialization and configuration, builds the task graph, then prints each scheduled task with a `SKIPPED` marker and stops — no task actions execute. It's the fastest way to see the gap between *requested* and *executed*: type `gradle build --dry-run` and you'll see `compileJava`, `test`, `jar`, etc., even though you only requested `build`. It's invaluable for debugging unexpected task ordering, verifying a `dependsOn`/`finalizedBy` wiring, or confirming a plugin pulled in the tasks you expect — all without the cost or side effects of a real run. Note it still *configures* the build, so configuration-time logic and the configuration cache still apply.
code
bash · 4 lines# Preview what `build` would actually run, in order, without doing it
$ gradle build --dry-run
# or the short flag
$ gradle build -mgo deeper
Know -m/--dry-run lists the tasks that would run without running them.
Explain that configuration still runs and only task actions are skipped; use it to inspect the executed set vs the requested task.
Caveat configuration-time side effects and that it does not reflect up-to-date status; pair with build scans for dependency reasoning.
Recommend it as a safe preview practice in CI/onboarding, while noting its limits versus real execution and configuration-cache behavior.
## What --dry-run actually does `--dry-run` (short form `-m`) tells Gradle: *resolve everything, but execute nothing*. Concretely: 1. **Initialization** runs normally (settings evaluated, projects created). 2. **Configuration** runs normally — build scripts are evaluated, tasks registered/configured, the task graph is built. 3. **Execution** is replaced by a *print pass*: Gradle visits each task in the scheduled order and emits `:taskPath SKIPPED` instead of running its actions. Because configuration still happens, anything you do at configuration time (resolving the graph, `whenReady` callbacks, eager `tasks.create`) still executes. Only the *task actions* (`doFirst`/`doLast`/`@TaskAction` bodies) are skipped. ## Why it's the canonical 'requested vs executed' tool The output *is* the executed set, in order: ```bash $ gradle build -m :compileJava SKIPPED :processResources SKIPPED :classes SKIPPED :compileTestJava SKIPPED :processTestResources SKIPPED :testClasses SKIPPED :test SKIPPED :jar SKIPPED :assemble SKIPPED :check SKIPPED :build SKIPPED ``` You requested one task (`build`); the dry run reveals the eleven that would actually run, in dependency order. Compare this with `gradle.startParameter.taskNames`, which would contain only `["build"]`. ## Practical uses - **Debug ordering**: confirm a `mustRunAfter`/`shouldRunAfter`/`finalizedBy` produced the order you intended. - **Verify plugin wiring**: see which tasks a newly-applied plugin injects. - **Safe inspection on shared/CI builds**: preview the plan without mutating outputs, publishing, or hitting networks (within configuration-time limits). ## Limits / gotchas - It is **not** a sandbox: configuration-time side effects still happen (e.g. a build script that writes a file at configuration time, or a plugin that resolves dependencies during configuration). - It does **not** show up-to-date status — every task is simply `SKIPPED` regardless of whether it would have been `UP-TO-DATE` in a real run. - It doesn't tell you *why* a task is in the graph; for the dependency reasons use `--console=verbose` plus build scans or `getDependencies` introspection.
- Does --dry-run skip the configuration phase too?No. Initialization and configuration run normally; the task graph is built. Only execution of task actions is replaced by printing SKIPPED. Configuration-time side effects still occur.
- Will --dry-run show me which tasks are UP-TO-DATE?No. Every scheduled task is printed as SKIPPED regardless of up-to-date status, because no up-to-date checking or execution happens.
saying these in an interview costs you the question
- Claiming --dry-run skips configuration (it doesn't).
- Believing it is a fully side-effect-free sandbox.
- Thinking it reports UP-TO-DATE/FROM-CACHE outcomes.