Class CommitAnalyzer

java.lang.Object
io.github.duckasteroid.gradle.versioning.CommitAnalyzer

public final class CommitAnalyzer extends Object
Minimal Java port of the semantic-release commit-analyzer concept (https://github.com/semantic-release/commit-analyzer), scoped to the default Conventional Commits (https://www.conventionalcommits.org/) / Angular rule set only - there is deliberately no configurable "preset" system here, unlike the JS original, since this plugin only ever needs the one rule set. The default rules:
   feat                                  -> MINOR
   fix, perf                             -> PATCH
   docs, style, refactor, test,
   chore, build, ci                      -> NONE  (known, deliberately-no-release types)
   anything that doesn't conform to the
   "type: description" shape at all, or
   uses a type outside the lists above    -> PATCH, and a warning is printed to stderr
 

...except that a '!' after the type/scope (e.g. "feat!:" or "feat(api)!:"), OR a "BREAKING CHANGE:" (or "BREAKING-CHANGE:") footer anywhere in the message, always forces MAJOR regardless of the type - a breaking fix is still a breaking change.

The non-conforming rule (-> PATCH + warning, rather than silently NONE) is a deliberate departure from the semantic-release original, which just ignores anything it doesn't recognize: here, a commit that isn't in Conventional Commits form at all - a typo'd type, a merge commit's default message, a commit predating this convention's adoption, someone not bothering to follow the convention - is treated as a small, defensive PATCH bump instead. The rationale is that silently ignoring an unrecognized commit risks silently ignoring a real, released change; a PATCH bump (the smallest possible) plus a visible warning errs towards "the version moved, and you were told why" rather than "nothing happened and nobody noticed".

Configuring which types map to which bump

Which type-word maps to which CommitAnalyzer.Bump is data, not hardcoded logic: it's a Map<Bump, Set<String>> (see DEFAULT_TYPE_RULES), optionally passed to analyze(List, Map) / analyzeOne(String, Map) to override or extend it. Consumers of the Gradle plugin do this via the commitAnalyzer { } extension registered by VersionPlugin (see CommitAnalyzerExtension), which exposes one SetProperty<String> per bump level (majorTypes, minorTypes, patchTypes, noBumpTypes) - each can be appended to (.add(...)/.addAll(...)) or replaced outright (.set(...)) independently of the others.

majorTypes defaults to empty, since MAJOR is normally driven by the structural '!'/BREAKING CHANGE detection above rather than by type at all - it exists so a project can ALSO force specific types (e.g. security) to always be MAJOR on their own, without needing every such commit to remember the '!' marker.

When classifying a single type, the four levels are checked from most to least severe (MAJOR, MINOR, PATCH, NONE - see analyzeOne(String, Map)), so if a type is (mis)configured into more than one set, the highest-severity match wins: a type present in both majorTypes and patchTypes resolves to MAJOR.

See VersionResolver for how the result of analyzing a batch of commits gets turned into an actual version number, and ChangelogGenerator (release-flow plugin) for how parse(String) - the syntactic parse, independent of typeRules - gets turned into release notes.