skip to content

When would you choose @PathSensitive(NAME_ONLY) or NONE over RELATIVE for a task input? Give a concrete correctness consideration.

level: seniorimportance: should knowfreq 28%

answer

  1. ABSOLUTE>RELATIVE>NAME_ONLY>NONE
  2. looser = more hits, risk false up-to-date
  3. NONE = content blob
  4. NAME_ONLY = name matters, dir doesn't
  5. ask: does move/rename change output?

basics

~20 s

Use NONE when only file content matters and location is irrelevant (e.g. a config blob). Use NAME_ONLY when the filename is significant but its directory isn't. Both are looser than RELATIVE, giving more cache hits — but only if the tool truly ignores the dropped path info.

solid answer

~50 s

The four `@PathSensitive` modes form a spectrum from strict to loose: `ABSOLUTE > RELATIVE > NAME_ONLY > NONE`. Looser modes hash less path information, so more inputs fingerprint equal and you get more up-to-date/cache hits — at the risk of *false up-to-date* if the tool actually depends on the discarded path detail. Choose `NONE` when the task consumes a file purely by content and never by where it sits or what it's called (a single template read as bytes). Choose `NAME_ONLY` when the filename carries meaning the tool uses — for example a code generator that derives an output class name from the input filename — but the containing directories are irrelevant. Choose `RELATIVE` (the safe default) when the relative directory structure is part of the semantics, e.g. resource packaging that preserves folder layout. The discipline is: pick the loosest mode that can't make Gradle wrongly skip the task.

code

kotlin · 3 lines
kotlin
@get:InputFiles
@get:PathSensitive(PathSensitivity.NAME_ONLY)
abstract val protos: ConfigurableFileCollection  // output class name derives from file name

go deeper

for a junior

Know that NONE and NAME_ONLY exist and are looser than RELATIVE.

for a middle

Explain the strict-to-loose spectrum and that looser means more cache hits with correctness risk.

for a senior

Apply the move/rename decision rule and articulate concrete false-up-to-date scenarios for over-loosening.

for a principal

Encode the decision rule into plugin review guidance so teams don't silently introduce stale-output bugs by loosening sensitivity.

## The sensitivity spectrum `@PathSensitive` accepts a `PathSensitivity` enum. From most to least path information: 1. `ABSOLUTE` — full path. Worst for caching; almost never correct to choose deliberately. 2. `RELATIVE` — path relative to the input root + content. The portable default. 3. `NAME_ONLY` — only the file's *name* (last segment) + content; directories dropped. 4. `NONE` — only content; the path is entirely ignored. Looser = fewer distinctions = more fingerprints collide as equal = more hits. The danger is a **false up-to-date**: Gradle believes nothing relevant changed and reuses stale outputs, because you told it to ignore a path aspect the tool actually used. ## NONE — content is everything Pick `NONE` when the task reads the file as an opaque blob and produces output determined solely by bytes. Example: a task that base64-encodes a single resource file into an output. Moving or renaming the file changes nothing about the result, so `NONE` is both correct and maximally cacheable. ## NAME_ONLY — the name carries meaning Pick `NAME_ONLY` when the filename influences output but the directory does not. Classic case: a stub/codegen task that turns `Foo.proto` into `FooOuter.java`, deriving the class name from the filename. Two files named `Foo.proto` in different directories *should* be treated the same for fingerprinting only if your build genuinely doesn't distinguish them — be careful here, because name collisions across directories can be a correctness trap. ## RELATIVE — structure matters Pick `RELATIVE` when the relative folder layout is part of the contract, e.g. copying `src/main/resources/**` into a jar where `com/acme/x.properties` must keep its package directory. Dropping to `NAME_ONLY` would let two same-named resources in different packages collide. ```kotlin abstract class Encode : DefaultTask() { // content-only: location/name irrelevant @get:InputFiles @get:PathSensitive(PathSensitivity.NONE) abstract val payload: ConfigurableFileCollection } ``` ## Decision rule Ask: "If I move this file to another directory / rename it, would the task's output legitimately change?" If neither move nor rename matters → `NONE`. If rename matters but move doesn't → `NAME_ONLY`. If the relative directory matters → `RELATIVE`. Choosing too loose risks stale outputs; too strict just wastes cache hits.

  • What is a 'false up-to-date' and how can over-loosening path sensitivity cause it?
    It's when Gradle skips a task believing inputs are unchanged, but they actually changed in a path aspect you told it to ignore. If you pick NONE but the tool embeds the relative path in its output, a move would change the real output while the fingerprint stays equal — stale results.
  • Why is NAME_ONLY risky when two inputs share a filename in different directories?
    NAME_ONLY collapses directories, so two distinct files named identically can fingerprint as the same input. If the build actually needs to distinguish them by directory, that's incorrect.

saying these in an interview costs you the question

  • Recommending the loosest mode universally to maximize cache hits, ignoring correctness.
  • Saying NONE and NAME_ONLY are interchangeable — NAME_ONLY keeps the filename, NONE drops everything but content.
  • Treating ABSOLUTE as a reasonable default.

context