Compare RELATIVE, NAME_ONLY, and NONE path sensitivity. How do you choose the right one for a given file input?
answer
- RELATIVE keeps in-tree path
- NAME_ONLY keeps just the name
- NONE keeps only content
- move test → RELATIVE; rename test → NAME_ONLY
- loosest correct mode wins
basics
~20 sRELATIVE keys on the path relative to the input root; NAME_ONLY keys only on the file name; NONE keys only on content. Pick the loosest one where renaming or moving a file would NOT change the task's correct output.
solid answer
~50 sAll three relax beyond ABSOLUTE to improve reuse, but they discard different information. **RELATIVE** keeps the relative directory structure — right when a file's in-tree location is semantically meaningful (Java sources, where package path matters). **NAME_ONLY** discards the directory and keeps only the file name — right when only the name carries meaning, e.g. a properties file whose basename is the key but whose containing folder is irrelevant. **NONE** discards path entirely — right when the task only consumes bytes and is wholly indifferent to identity, e.g. a tool that concatenates a set of inputs regardless of names. The decision test: imagine moving or renaming an input without changing its bytes. If that *should* change the output, you need the sensitivity level that captures that change; if it shouldn't, you can relax further. Always pick the loosest correct mode to maximize hits, never looser.
code
kotlin · 9 linesabstract class RenderTask : DefaultTask() {
// package path matters → RELATIVE
@get:InputFiles @get:PathSensitive(PathSensitivity.RELATIVE)
abstract val sources: ConfigurableFileCollection
// resolved by basename, folders incidental → NAME_ONLY
@get:InputFiles @get:PathSensitive(PathSensitivity.NAME_ONLY)
abstract val templates: ConfigurableFileCollection
}go deeper
Recognize the three modes and that they discard increasingly more path info.
Map each mode to a concrete input type and state what changing it would break.
Apply the move-and-rename test to choose the loosest correct mode and articulate the silent-wrong-reuse risk of over-relaxing.
Set conventions/lint for which modes are allowed on which input categories so teams don't introduce unsafe relaxations at scale.
## What each mode discards Gradle's fingerprint of a file input is conceptually `(pathView, contentHash)`. The three relaxed modes differ purely in `pathView`: - `RELATIVE` → `pathView` = path **relative to the input root**. `src/a/X.txt` and `src/b/X.txt` fingerprint **differently** even with equal content. Moving the whole tree to a new checkout location does **not** change the fingerprint. - `NAME_ONLY` → `pathView` = **file name only**. `a/X.txt` and `b/X.txt` fingerprint **identically** if content is equal. Renaming `X.txt`→`Y.txt` **does** change it. - `NONE` → `pathView` is empty. Only content matters. Renaming or moving never changes the fingerprint; only editing bytes does. ## Choosing: the move-and-rename thought experiment For a candidate input, ask two questions: 1. **If I move this file to a different directory (same name, same bytes), should the task output change?** If yes → you need at least RELATIVE. If no → NAME_ONLY or NONE are candidates. 2. **If I rename this file (same directory, same bytes), should the output change?** If yes → you need at least NAME_ONLY. If no → NONE is a candidate. The loosest mode that answers "no" to the relevant questions is the optimal one: it admits the most cache/up-to-date hits without ever reusing an output that should have differed. ## Typical mappings - **Compiled sources** (package = directory) → RELATIVE. Location encodes the package, which is part of compiler output. - **Resource bundles keyed by filename** → often NAME_ONLY, when the loader resolves by basename and folder layout is incidental. - **Content-only transforms** (minify, checksum a set, concatenate) → NONE, when the tool truly ignores names. ## Cost of over-relaxing Every relaxation increases the chance two genuinely-different inputs collide to the same key, producing **incorrect reuse** (stale or wrong outputs marked UP-TO-DATE or restored from cache). This is a silent correctness bug, strictly worse than a missed hit. So the discipline is: relax only when you can prove the discarded path information cannot affect the output. ```kotlin @get:InputFiles @get:PathSensitive(PathSensitivity.NAME_ONLY) abstract val templates: ConfigurableFileCollection // safe only because the renderer resolves templates by file name, ignoring folders ``` ## Empty directories and the path view Separately from these modes, `@IgnoreEmptyDirectories` controls whether empty directories participate in the fingerprint at all — orthogonal to which path portion is kept, but another lever for stabilizing fingerprints across environments that create stray empty folders.
- Give an input where NONE is correct and one where it would be a bug.Correct: a task that concatenates a set of fragments where only the bytes matter. Bug: a task generating code whose package is derived from the file's directory — NONE would ignore the location and reuse wrong output.
- Two files with the same name in different folders, same content — do they collide under NAME_ONLY?Yes, their fingerprints are identical under NAME_ONLY, which is exactly why you only use it when folder location is irrelevant to the task.
saying these in an interview costs you the question
- Recommending NONE 'to get more hits' without checking the task is path-indifferent.
- Believing RELATIVE is relative to the project root rather than the specific input root.
- Treating the choice as a pure performance knob rather than a correctness constraint.