What does the `-x` / `--exclude-task` flag do, and how does excluding a task interact with the task dependency graph?
answer
- -x / --exclude-task prunes from the graph
- build -x test = build without tests
- orphaned-only deps also pruned
- shared deps still run
- exclude arg is itself a selector
basics
~10 s-x <task> (or --exclude-task) removes a task from the execution graph for this run. The excluded task and any task that would run only as its dependency are skipped, while requested tasks still run.
solid answer
~50 s`-x`/`--exclude-task` tells Gradle to **prune a task from the computed task graph** for the current invocation. A classic use is `./gradlew build -x test` to build without running tests. Key behavior: - Gradle first builds the full graph for the requested tasks, then **removes the excluded task and any task that is reachable only through it**. A task that is also a dependency of something *not* excluded still runs. - The exclude argument is itself a **task name selector** and follows the same matching rules (it can be a name or a qualified path; abbreviation applies). So `-x test` excludes `test` in every matching project, while `-x :app:test` excludes only that one. - Order of `-x` relative to the task name doesn't matter; multiple `-x` flags are allowed. Exclusion is a graph operation, not a "skip if encountered" flag, so it deterministically guarantees the task and its now-orphaned dependencies will not execute, while preserving everything else the requested tasks legitimately need.
code
bash · 3 lines./gradlew build -x test
./gradlew check -x integrationTest -x checkstyleMain
./gradlew build -x :app:test # only :app's testgo deeper
Know -x test builds without running tests.
Explain that it is a graph prune that also drops orphaned dependencies while keeping shared ones.
Note the exclude arg follows full selector semantics (fan-out vs qualified) and discuss when to prefer onlyIf.
Discourage -x as a standing policy; encode skip logic in build config so behavior is reproducible across all invocations.
## The flag `-x <selector>` (long form `--exclude-task <selector>`) removes a task — and the dependencies that exist **only** to support it — from the execution plan for a single run. ```bash ./gradlew build -x test # build, skip the test task ./gradlew check -x integrationTest # run check but skip integrationTest ./gradlew build -x :app:test # exclude only :app's test ``` ## How Gradle applies it Gradle computes the directed acyclic **task graph** for your requested tasks. The excluded selector is matched (same rules as any selector: name vs qualified path, camelCase abbreviation, fan-out across subprojects). Each matched task is then pruned. Crucially, pruning also drops tasks that were pulled in **solely** as transitive dependencies of the excluded task. But a task that is *also* needed by a non-excluded task is retained — Gradle does not break the requirements of tasks you still asked for. ### Worked example Suppose `build` → `check` → `test` → `compileTestJava` → `compileJava`, and `jar` → `compileJava`. - `./gradlew build -x test` prunes `test`. - `compileTestJava` is now reachable only through `test`, so it is **also pruned**. - `compileJava` is **kept** because `jar` (still in the graph) depends on it. ## Selector semantics still apply Because the exclude argument is a selector, `-x test` from the root excludes `test` in **all** matching subprojects, whereas `-x :app:test` is surgical. Multiple excludes combine: `./gradlew build -x test -x checkstyleMain`. ## When to use it - Fast local feedback (`build -x test`). - Skipping slow or flaky verification tasks during iteration. - Working around an environment-specific task you can't run locally. Use it tactically — long-term suppression belongs in the build script (e.g. `onlyIf {}`, conditional configuration), not as a permanent CLI habit.
- In `./gradlew build -x test`, why does `compileJava` still run but `compileTestJava` does not?`compileTestJava` is reachable only through `test`, so it is pruned with it; `compileJava` is also required by `jar`/`build`, so it is retained.
- Does `-x test` exclude tests in every subproject?Yes — the exclude argument is a name selector, so it matches `test` across the current project and its subprojects unless you qualify it like `-x :app:test`.
- Is `-x` a good long-term way to permanently skip a task?No. For permanent behavior, gate the task in the build script (e.g. `onlyIf { ... }`) rather than relying on every caller to pass `-x`.
saying these in an interview costs you the question
- Saying `-x` skips the task but still runs its now-unneeded dependencies — orphaned-only deps are pruned too.
- Claiming `-x` can remove a dependency that another requested task still needs — shared deps are retained.