Class FeatureIndexer
Feature/Scenario titles directly in the source .feature files
according to a configured IndexingMode.
A line whose existing number already matches the format mode would itself produce -
a single integer for a Feature, or for a Scenario/Scenario Outline
either a single integer (IndexingMode.SCENARIO) or <featureNumber>.<n>
(IndexingMode.ALL, matched against that line's own feature's resolved number) - is left
completely untouched: its number is "pinned". Every other numbered line (wrong format, or a
leftover from a different mode, or IndexingMode.OFF itself never expecting a number at
all) is stripped and, if mode numbers lines of that kind, assigned a fresh number one
past the highest pinned number seen so far (or from 1, if none are pinned yet) - so a newly
added file that happens to sort alphabetically before already-numbered files never bumps their
numbers, and fresh numbers always read as a continuation of the existing sequence rather than
backfilling a gap earlier in it. Passing forceRewrite = true instead ignores existing
numbers entirely and renumbers everything from scratch, exactly as if every file were being
numbered for the first time.
If two lines' existing numbers collide - e.g. two features or two scenarios within the same feature were each numbered independently on separate branches and now coexist after a merge - only the first one encountered keeps the pinned number; the other is treated as unnumbered and assigned a fresh one, so the collision is resolved instead of leaving both lines untouched.
Feature numbering (and, for IndexingMode.SCENARIO, Scenario numbering
too) is additionally scoped by projectDirectories when given a non-empty list: each
feature file is assigned to whichever directory in that list is its nearest enclosing ancestor,
and every such group is numbered as its own independent 1-based sequence, completely unaware of
every other group's numbers - so, in a multi-project Gradle build, passing every project's own
directory numbers each project's features from 1 rather than continuing one build-wide count
across all of them. An empty list (the default for the overloads that don't accept one) instead
treats featureFiles as a single group, exactly as if every file belonged to the same
project - today's only behaviour, and the one still used for a build-wide consolidated count.
IndexingMode.ALL's Scenario numbering is unaffected either way: it's already
scoped per Feature - strictly finer-grained than per-project - by resetting to 1 within
every feature regardless of projectDirectories.
Never called with IndexingMode.CI: the caller skips invoking this class entirely for
that mode, since CI means the feature files must be left completely untouched, not even
to strip prior numbering the way IndexingMode.OFF does.
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidreindex(List<File> featureFiles, IndexingMode mode, boolean forceRewrite) Rewrites every file infeatureFilesin place permodeandforceRewrite- see the class documentation for exactly what changes and what's left alone.voidreindex(List<File> featureFiles, IndexingMode mode, boolean forceRewrite, Runnable onFileReindexed) Same asreindex(List, IndexingMode, boolean), additionally invokingonFileReindexedonce for every file infeatureFilesas it finishes being reindexed, so a caller can drive a progress indicator during what would otherwise be a single opaque, potentially long-running call.voidreindex(List<File> featureFiles, IndexingMode mode, boolean forceRewrite, List<File> projectDirectories, Runnable onFileReindexed) Same asreindex(List, IndexingMode, boolean, Runnable), additionally scopingFeature/cross-fileScenarionumbering to each ofprojectDirectories- see the class documentation for exactly how.
-
Constructor Details
-
FeatureIndexer
public FeatureIndexer()Creates a newFeatureIndexer.
-
-
Method Details
-
reindex
Rewrites every file infeatureFilesin place permodeandforceRewrite- see the class documentation for exactly what changes and what's left alone. Files are numbered in the order they appear infeatureFiles- the caller is responsible for ordering that list the way numbers should be assigned. A file is only rewritten on disk when its content actually changes. Equivalent toreindex(List, IndexingMode, boolean, Runnable)with a callback that does nothing.- Parameters:
featureFiles- the feature files collected for this run, in the order to number them inmode- the indexing mode to applyforceRewrite- whentrue, ignores existing numbers and renumbers everything from scratch; whenfalse, leaves already-correctly-numbered lines alone
-
reindex
public void reindex(List<File> featureFiles, IndexingMode mode, boolean forceRewrite, Runnable onFileReindexed) Same asreindex(List, IndexingMode, boolean), additionally invokingonFileReindexedonce for every file infeatureFilesas it finishes being reindexed, so a caller can drive a progress indicator during what would otherwise be a single opaque, potentially long-running call.- Parameters:
featureFiles- the feature files collected for this run, in the order to number them inmode- the indexing mode to applyforceRewrite- whentrue, ignores existing numbers and renumbers everything from scratch; whenfalse, leaves already-correctly-numbered lines aloneonFileReindexed- invoked once per file infeatureFiles, in order; nevernull
-
reindex
public void reindex(List<File> featureFiles, IndexingMode mode, boolean forceRewrite, List<File> projectDirectories, Runnable onFileReindexed) Same asreindex(List, IndexingMode, boolean, Runnable), additionally scopingFeature/cross-fileScenarionumbering to each ofprojectDirectories- see the class documentation for exactly how. Passing an empty list is equivalent toreindex(List, IndexingMode, boolean, Runnable).- Parameters:
featureFiles- the feature files collected for this run, in the order to number them inmode- the indexing mode to applyforceRewrite- whentrue, ignores existing numbers and renumbers everything from scratch; whenfalse, leaves already-correctly-numbered lines aloneprojectDirectories- the directories numbering is independently scoped to, or empty for a single build-wide sequenceonFileReindexed- invoked once per file infeatureFiles, in order; nevernull
-