Class SnapshotScanner

java.lang.Object
network.ike.plugin.SnapshotScanner

public final class SnapshotScanner extends Object
Scan POM files for -SNAPSHOT references that would leak into a released artifact via Maven 4's consumer POM flattener.

Maven 4 resolves properties and promotes <pluginManagement> entries into <plugins> when it writes the consumer POM — the POM consumers download from the repository. If a <pluginManagement> entry references a property (e.g. <version>${ike-tooling.version}</version>) whose value ends in -SNAPSHOT, the flattener writes the literal SNAPSHOT string into the released artifact. Downstream consumers then see <version>117-SNAPSHOT</version> in the released POM and their builds fail with "artifact not found" — even though the release passed locally.

This scanner uses Maven 4's own MavenStaxReader to parse POMs into the typed Model tree, then inspects only the contexts that feed the consumer POM:

  • Source properties scan via scanSourceProperties(File) — inspects <properties> and fails if any value ends in -SNAPSHOT. Catches the bug at its source before any release mutation runs.
  • Post-mutation version scan via scanForSnapshotVersions(List) — walks the model's <parent>, <dependencies>, <dependencyManagement>, <build>/<plugins>, <build>/<pluginManagement>, and every profile's equivalent sections. Any -SNAPSHOT version here is a baked-in reference that would leak through the consumer POM.

Not scanned: the module's own <version> (immediate child of <project>), because during release the module version is handled by ReleaseSupport.setPomVersion(java.io.File, String, String) and is not a consumer-POM leakage path. Comments, CDATA, and whitespace are natively ignored by the Maven parser.

  • Method Details

    • scanSourceProperties

      public static List<SnapshotScanner.Violation> scanSourceProperties(File pomFile)
      Scan the <properties> sections of a POM (root plus any profile properties) for any value ending in -SNAPSHOT.

      This is the primary gate that catches the <ike-tooling.version>112-SNAPSHOT</ike-tooling.version> class of bug before any release mutation runs.

      Parameters:
      pomFile - the POM file to scan
      Returns:
      violations found in properties; empty if clean
      Throws:
      org.apache.maven.api.plugin.MojoException - if the file cannot be read or parsed
    • scanForSnapshotVersions

      public static List<SnapshotScanner.Violation> scanForSnapshotVersions(List<File> pomFiles)
      Scan a list of POMs for any <version>...-SNAPSHOT</version> in the consumer-POM-relevant contexts: <parent>, <dependencies>, <dependencyManagement>, <build>/<plugins>, <build>/<pluginManagement>, and the same sections within every profile.

      Intended for use after ReleaseSupport.replaceProjectVersionRefs(File, String, org.apache.maven.api.plugin.Log) has resolved ${project.version} to a literal.

      Explicitly skips the module's own <version> element — that is handled by ReleaseSupport.setPomVersion(File, String, String) and does not leak into the consumer POM as a stale SNAPSHOT.

      Parameters:
      pomFiles - POM files to scan
      Returns:
      violations found across all POMs; empty if clean
      Throws:
      org.apache.maven.api.plugin.MojoException - if any file cannot be read or parsed
    • formatViolations

      public static String formatViolations(List<SnapshotScanner.Violation> violations, File gitRoot, String headline, String remedyHint)
      Format a list of violations as an aggregated multi-line message suitable for MojoException or preflight output.
      Parameters:
      violations - the violations to format (non-empty)
      gitRoot - repo root for relative path display; may be null
      headline - opening sentence (e.g. "Cannot release — ...")
      remedyHint - closing instruction shown after the bullets
      Returns:
      a formatted multi-line error body