All files cache-key.ts

94.11% Statements 16/17
88.88% Branches 8/9
100% Functions 2/2
94.11% Lines 16/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 471x                                                     1x 20x 20x   20x 20x 15x 15x 7x 1x 1x 4x 4x 4x 7x       20x  
/**
 * Java cacheKey implementation.
 *
 * Produces `java-${buildFileHash || 'no-config'}`.
 *
 * Java has no canonical resolved-dependency lock file like Cargo.lock
 * or go.sum. Maven's `pom.xml` and Gradle's `build.gradle` /
 * `build.gradle.kts` are the build-config sources of truth, so we
 * fingerprint those. Gradle does emit `gradle.lockfile` when locking
 * is enabled but it's opt-in; we treat it as preferred when present
 * since it captures the resolved versions.
 *
 * Precedence (most-resolved first):
 *   1. `gradle.lockfile`  — resolved deps when Gradle locking is on
 *   2. `pom.xml`          — Maven's source of truth
 *   3. `build.gradle.kts` — Gradle Kotlin DSL build config
 *   4. `build.gradle`     — Gradle Groovy DSL build config
 *
 * Per contract invariant I-6: pure function of `(config content)`.
 * Per I-8: emits `java-`, distinct from `rs-`, `py-`, `go-`.
 */
 
import { createHash } from 'node:crypto';
import { existsSync, readFileSync } from 'node:fs';
 
import type { CacheKeyInput } from '@opensip-tools/graph';
 
export function cacheKey(input: CacheKeyInput): string {
  return `java-${hashConfig(input.configPathAbs)}`;
}
 
function hashConfig(configPathAbs: string | undefined): string {
  if (configPathAbs === undefined || configPathAbs.length === 0) {
    return 'no-config';
  }
  if (!existsSync(configPathAbs)) {
    return `missing:${configPathAbs}`;
  }
  try {
    const content = readFileSync(configPathAbs, 'utf8');
    return createHash('sha256').update(content).digest('hex').slice(0, 16);
  } catch {
    /* v8 ignore next */
    return `unreadable:${configPathAbs}`;
  }
}