Compare PREFER_PROJECT, PREFER_SETTINGS, and FAIL_ON_PROJECT_REPOS. When would you choose each during a migration?
answer
- PREFER_PROJECT = project wins (default)
- PREFER_SETTINGS = central wins, project ignored + warning
- FAIL_ON_PROJECT_REPOS = build fails
- migrate: add central -> PREFER_SETTINGS -> delete -> FAIL_ON
- strict mode guards CI against regressions
basics
~10 sPREFER_PROJECT (default) lets project repos override central; PREFER_SETTINGS uses central and ignores project repos; FAIL_ON_PROJECT_REPOS fails if any project declares repos. Use PREFER_SETTINGS mid-migration, then FAIL_ON_PROJECT_REPOS once clean.
solid answer
~50 sThe three `RepositoriesMode` values trade strictness for safety. `PREFER_PROJECT` (default) keeps backward compatibility — a project's own `repositories {}` wins, so legacy builds keep working. `PREFER_SETTINGS` flips precedence: the central settings list is authoritative and project-level repos are silently ignored (with a warning) — useful as a transitional step where you want central repos to take effect even before every module is cleaned up. `FAIL_ON_PROJECT_REPOS` is the end state: any lingering project `repositories {}` breaks the build, so the central list is provably the only source. A pragmatic migration: start at PREFER_PROJECT, add the central block, switch to PREFER_SETTINGS to make central repos effective and surface warnings, delete the now-redundant project blocks, then lock it down with FAIL_ON_PROJECT_REPOS to prevent regressions. The strict mode is what you want in CI for a governed, audited build.
code
kotlin · 9 lines// settings.gradle.kts
dependencyResolutionManagement {
// Step toward strictness; flip to FAIL_ON_PROJECT_REPOS when modules are clean
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
mavenCentral()
google()
}
}go deeper
Name the three modes and which one is the default.
Explain each mode's behavior on conflict and that PREFER_SETTINGS warns while FAIL fails.
Lay out a staged migration (add central → PREFER_SETTINGS → delete → FAIL) and justify each step.
Frame mode selection as a governance/rollout decision across many teams, with CI gating and a deprecation timeline for project repos.
## The three modes, precisely `org.gradle.api.initialization.resolve.RepositoriesMode`: - **PREFER_PROJECT** — *default*. When a project declares its own repositories, those are used and the settings-level repositories are ignored *for that project*. Maximally backward-compatible; no enforcement. - **PREFER_SETTINGS** — the settings-level repositories are always used; any project-level `repositories {}` is **ignored** and Gradle emits a warning naming the offending project. Effective but non-fatal. - **FAIL_ON_PROJECT_REPOS** — if any project declares repositories, the build **fails immediately** with an error. Zero tolerance. ## Migration strategy For a large existing multi-module build you rarely flip straight to strict mode: 1. **Add the central block** in `settings.gradle.kts` with all repositories the build currently uses (union across modules). 2. **Set PREFER_SETTINGS.** Now central repos are authoritative and you get a warning for every module still carrying its own `repositories {}`. Resolution behavior is now driven centrally, so you can validate nothing broke. 3. **Delete the redundant project blocks** module by module, using the warnings as a checklist. 4. **Switch to FAIL_ON_PROJECT_REPOS.** With the project blocks gone, the strict mode passes — and now it *guards* the build: any future copy-paste of a project repo fails CI. ## Choosing in steady state - New/greenfield builds → start directly at `FAIL_ON_PROJECT_REPOS` so the discipline is baked in. - Legacy builds you can't fully clean yet → `PREFER_SETTINGS` to centralize effective behavior without breaking the build. - You can't change anything → `PREFER_PROJECT`, but you lose enforcement and most of the benefit. ## Important caveats - All three modes are scoped to **regular dependency** repositories; `pluginManagement` repos are independent. - PREFER_SETTINGS doesn't error on plugins that inject project repos — it just ignores them, which can mask a misconfiguration that FAIL_ON_PROJECT_REPOS would expose. - The warning from PREFER_SETTINGS is your migration to-do list; treat each one as a task. ```kotlin // settings.gradle.kts — transitional dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS) // later: FAIL_ON_PROJECT_REPOS repositories { mavenCentral(); google() } } ```
- Why use PREFER_SETTINGS as an intermediate step instead of jumping straight to FAIL_ON_PROJECT_REPOS?PREFER_SETTINGS makes the central repos take effect without breaking the build, and emits a warning per offending module — giving you a non-fatal migration checklist. FAIL_ON_PROJECT_REPOS would block the build before you've cleaned the modules.
- Does PREFER_SETTINGS error if a project still declares repositories?No — it ignores the project repositories and logs a warning. Only FAIL_ON_PROJECT_REPOS turns that into a hard error.
saying these in an interview costs you the question
- Saying PREFER_SETTINGS fails the build — it only warns and ignores project repos.
- Treating the three modes as merge strategies — Gradle picks one side, it never merges repository lists.
- Recommending an immediate flip to strict mode on a large legacy build without a migration path.