Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/nvd-cache-refresh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ name: NVD Cache Refresh & Vulnerability Scan

on:
schedule:
- cron: '17 2 * * 1' # Every Monday at 02:17 UTC
- cron: '0 7 * * 5' # Every Friday at 07:00 UTC
workflow_dispatch:

Expand Down
56 changes: 46 additions & 10 deletions examples/gherkin-to-asciidoc/indexing/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,17 @@ This example shows:
* That indexing rewrites the source `.feature` files in place, and that this is reflected
automatically in the generated report, since the report is generated *from* the (now numbered)
source files.
* That running the build a second time is a no-op: indexing strips any numbering left over from a
previous run before reapplying it, so already-correctly-numbered files are left untouched.
* That the `-PgherkinToAsciidoc.indexing=<value>` command-line override forces the same `indexing`
value onto every sub-project at once, regardless of what each one's own `build.gradle` configures -
typically used to force `ci` for the whole build in a CI pipeline.
* That running the build a second time is a no-op: with the default `forceRewrite = false`, a line
whose number already reflects the currently configured `indexing` value is left completely untouched.
* That a new feature file added later, even one that sorts alphabetically *before* already-numbered
files, does *not* renumber them - it's given the next number not already in use instead, so
existing numbers stay stable across runs. Setting `forceRewrite = true` (or the equivalent
`-PgherkinToAsciidoc.forceRewrite=true` override) instead recomputes every number from scratch on
every run, the way `indexing` always behaved before `forceRewrite` existed.
* That the `-PgherkinToAsciidoc.indexing=<value>` and `-PgherkinToAsciidoc.forceRewrite=<true|false>`
command-line overrides each force the same value onto every sub-project at once, regardless of what
each one's own `build.gradle` configures - `indexing` typically used to force `ci` for the whole
build in a CI pipeline.

== Project Layout

Expand Down Expand Up @@ -166,6 +172,35 @@ each project's pristine, un-numbered starting content) land under each sub-proje
Run the plain `./gradlew generateFeatureDocs` afterwards to see `off/`, `feature/`, `scenario/`, and `all/`
get numbered as normal - proving the override only affects the run it's passed to.

=== Not renumbering already-numbered files (`forceRewrite`)

Starting from a clean checkout, run the plain command once so `feature/` gets numbered normally, then add
a new feature file that sorts alphabetically *before* the existing one and run it again:

[source,bash]
----
./gradlew generateFeatureDocs
cat > feature/src/test/resources/features-auth/access-control.feature <<'EOF'
Feature: Access control

Scenario: Admin views the audit log
Given an admin user
EOF
./gradlew generateFeatureDocs
----

`feature/src/test/resources/features-auth/authentication.feature` still reads `Feature: 1 - User
authentication` and `features-billing/invoice.feature` still reads `Feature: 2 - Invoice payment` -
unchanged by the second run - while the new `access-control.feature` is numbered `Feature: 3 - Access
control`, even though `access-control.feature` sorts alphabetically before `authentication.feature`. This
is `forceRewrite`'s default (`false`): only lines not yet correctly numbered get numbered.

Run `git checkout -- feature && rm feature/src/test/resources/features-auth/access-control.feature` to
reset, then repeat the same steps but with `-PgherkinToAsciidoc.forceRewrite=true` on the second command
instead - `authentication.feature` becomes `Feature: 2 -` and `invoice.feature` becomes `Feature: 3 -`,
renumbered to make room for `access-control.feature` at `Feature: 1 -`, matching alphabetical order exactly
as `indexing` always did before `forceRewrite` existed.

== What To Expect

Before the build runs, `off/`, `feature/`, `scenario/`, and `all/` all contain the exact same
Expand Down Expand Up @@ -319,9 +354,10 @@ state of the source files, indexing or not:

[NOTE]
====
This example is pinned to `gherkin-to-asciidoc = "2.1.0"` in `gradle/libs.versions.toml` - the version the
`ci` indexing value and the `-PgherkinToAsciidoc.indexing` command-line override are expected to release
as (a purely additive change on top of `indexing`, itself released as `2.0.0`). Verified locally against
the plugin's own source (via a temporary `includeBuild`, since removed) before pinning; won't build
against the Gradle Plugin Portal until `2.1.0` is actually released.
This example is pinned to `gherkin-to-asciidoc = "3.0.0"` in `gradle/libs.versions.toml` - the version the
`forceRewrite` property (and the breaking change to `indexing`'s default numbering behaviour it ships
alongside) is expected to release as. `indexing` itself released as `2.0.0`; its `ci` value and the
`-PgherkinToAsciidoc.indexing` command-line override as the purely additive `2.1.0`. Verified locally
against the plugin's own source (via a temporary `includeBuild`, since removed) before pinning; won't build
against the Gradle Plugin Portal until `3.0.0` is actually released.
====
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ gherkin-to-asciidoc = { id = "com.arc-e-tect.gherkin-to-asciidoc", version.ref =

[versions]

gherkin-to-asciidoc = "2.1.0"
gherkin-to-asciidoc = "3.0.0"
89 changes: 76 additions & 13 deletions gherkin-to-asciidoc/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ gherkinToAsciidoc {
// require groupByFeature = true.
// Default: IndexingMode.OFF
indexing = IndexingMode.OFF

// When true, indexing renumbers every Feature/Scenario from scratch. When false, a line
// whose existing number already reflects the currently configured indexing value is left
// untouched - only lines that aren't yet correctly numbered are numbered.
// Default: false
forceRewrite = false
}
----

Expand All @@ -153,6 +159,7 @@ gherkinToAsciidoc {
// template.set(file("templates/report.mustache"))
// systemUnderTestVersion.set("v1.0.0")
indexing.set(IndexingMode.OFF)
forceRewrite.set(false)
}
----

Expand Down Expand Up @@ -182,6 +189,8 @@ Only consulted when `trackProgress` is `true`.
| `systemUnderTestVersion` | String | the project's `version` | Version of the system under test that the reported scenarios exercise, printed near the top of the generated document (see "System Under Test Version" below).
| `indexing` | `IndexingMode` (`OFF`/`FEATURE`/`SCENARIO`/`ALL`/`CI`) | `OFF` | Numbers `Feature`/`Scenario` titles directly in the source `.feature` files (see "Numbering Features and Scenarios" below).
`FEATURE`/`SCENARIO`/`ALL` require `includeSubDirs = true`; `FEATURE` and `ALL` additionally require `groupByFeature = true`. `CI` skips indexing entirely and is always allowed; overridable for the whole build via the `-PgherkinToAsciidoc.indexing` project property.
| `forceRewrite` | Boolean | `false` | When `true`, `indexing` renumbers every `Feature`/`Scenario` from scratch. When `false`, a line already correctly numbered for the currently configured `indexing` value is left untouched.
Has no effect when `indexing` is `OFF` or `CI`. Overridable for the whole build via the `-PgherkinToAsciidoc.forceRewrite` project property.
|===

[IMPORTANT]
Expand All @@ -204,10 +213,11 @@ to be `true`; `FEATURE` and `ALL` additionally require `groupByFeature` to be `t
`groupByFeature = false`, only `SCENARIO` of those three is allowed. Setting an invalid combination fails
`generateFeatureDocs` with a descriptive error.

The `-PgherkinToAsciidoc.indexing=<value>` project property, when set, overrides `indexing` for every
project in the build regardless of what any project's own `gherkinToAsciidoc { }` block configures - see
"Overriding `indexing` from the Command Line" below. An unrecognised value fails `generateFeatureDocs` with
a descriptive error too.
The `-PgherkinToAsciidoc.indexing=<value>` and `-PgherkinToAsciidoc.forceRewrite=<true|false>` project
properties, when set, each override their respective DSL property for every project in the build
regardless of what any project's own `gherkinToAsciidoc { }` block configures - see "Overriding
`indexing`/`forceRewrite` from the Command Line" below. An unrecognised value fails `generateFeatureDocs`
with a descriptive error too.
====

== Running the Task
Expand Down Expand Up @@ -262,8 +272,12 @@ sub-project that inherits or sets `trackProgress = true` still needs its own `gl
| `indexing`
| Inherited from the root project by default; a sub-project can override it independently, subject to
the usual `includeSubDirs`/`groupByFeature` validation constraints for whichever value is in effect. The
`-PgherkinToAsciidoc.indexing` command-line override (see "Overriding `indexing` from the Command Line"
above) takes precedence over both, for every project in the build at once.
`-PgherkinToAsciidoc.indexing` command-line override (see "Overriding `indexing`/`forceRewrite` from the
Command Line" above) takes precedence over both, for every project in the build at once.
| `forceRewrite`
| Inherited from the root project by default; a sub-project can override it independently. The
`-PgherkinToAsciidoc.forceRewrite` command-line override takes precedence over both, for every project in
the build at once.
| `outputFileName`
| Inherited from the root project by default.
| `template`
Expand Down Expand Up @@ -446,7 +460,7 @@ a Cucumber test run, ...), not only in `generateFeatureDocs`'s own output.
| `FEATURE` | Every feature is numbered, e.g. `Feature: 1 - User authentication`. Scenario titles are untouched.
| `SCENARIO` | Every scenario is numbered continuously across all feature files, e.g. `Scenario: 1 - User logs in`. Feature titles are untouched.
| `ALL` | Both are numbered; scenarios are numbered per feature as `<featureNumber>.<scenarioNumber>`, e.g. `Scenario: 1.1 - User logs in` within `Feature: 1 - User authentication`.
| `CI` | Indexing is skipped entirely: the source files aren't touched at all - unlike `OFF`, not even to strip prior numbering. See "Overriding `indexing` from the Command Line" below.
| `CI` | Indexing is skipped entirely: the source files aren't touched at all - unlike `OFF`, not even to strip prior numbering. See "Overriding `indexing`/`forceRewrite` from the Command Line" below.
|===

Feature files are processed - and numbered - in the same order the generated report lists them in: for each
Expand Down Expand Up @@ -513,14 +527,55 @@ and the generated report reflects the same numbering, since it's parsed from the

[IMPORTANT]
====
Changing `indexing` - including setting it back to `OFF` - rewrites the source `.feature` files on the next
`generateFeatureDocs` run: any numbering left over from a previous run is stripped first, then fresh
numbering is applied for the new mode. This makes the operation idempotent (re-running with the same mode is
a no-op once the files are already correctly numbered), but it does mean the task mutates files that are also
its own inputs - commit the resulting numbered `.feature` files like any other source change.
`indexing` mutates files that are also its own inputs - commit the resulting numbered `.feature` files like
any other source change.
====

=== Overriding `indexing` from the Command Line
=== Not Renumbering Already-Numbered Lines (`forceRewrite`)

By default (`forceRewrite = false`), a `Feature`/`Scenario` line whose existing number already matches the
format the currently configured `indexing` value would itself produce is left completely untouched - only
lines that aren't yet correctly numbered are numbered. Continuing the `ALL`-mode example above, adding a
third feature file that sorts alphabetically *before* `authentication.feature` does *not* renumber the
two files already numbered `1`/`2`:

[source,gherkin]
----
Feature: Access control
----

[source,asciidoc]
----
== 3 - Access control

== 1 - User authentication

* Scenario: 1.1 - User requests a password reset
* Scenario: 1.2 - User logs in successfully

== 2 - Invoice payment

* Scenario: 2.1 - User pays an invoice
----

The new feature is numbered `3` - the next number not already in use - rather than `1`, which would have
required renumbering the two already-numbered files after it. Re-running `generateFeatureDocs` with no
further changes is a complete no-op: every line is already correctly numbered, so nothing is rewritten.

Numbering isn't preserved *unconditionally*, though - only when it already reflects the *currently
configured* `indexing` value. A number left over from a *different* `indexing` value doesn't reflect the
current one, and is still stripped and replaced. For example, with `indexing = IndexingMode.SCENARIO`, a
scenario already reading `Scenario: 3 - ...` keeps that number - but changing `indexing` to
`IndexingMode.ALL` gives that same scenario a fresh `<featureNumber>.<n>` number instead, since its old `3`
doesn't match `ALL`'s format. Setting `indexing` back to `OFF` still always strips every number,
regardless of `forceRewrite`, since `OFF`'s canonical state for every line is unnumbered.

Setting `forceRewrite = true` instead restores the original behaviour (present before `forceRewrite`
existed): every `Feature`/`Scenario` number is recomputed from scratch on every run, exactly as if none of
them had ever been numbered before - the third feature file above would instead become `1`, bumping
`authentication.feature`/`invoice.feature` to `2`/`3`.

=== Overriding `indexing`/`forceRewrite` from the Command Line

A CI pipeline typically shouldn't have `generateFeatureDocs` rewrite committed `.feature` files during a
build - a fresh checkout has no numbering to add, and a build that mutates its own source tree can leave a
Expand All @@ -541,6 +596,14 @@ property's value is matched against `IndexingMode` case-insensitively and accept
(`off`, `feature`, `scenario`, `all`, `ci`), not just `ci` - useful for e.g. temporarily forcing a specific
mode across an entire multi-project build without editing every sub-project's configuration.

`-PgherkinToAsciidoc.forceRewrite=<true|false>` works the same way for `forceRewrite`, e.g. to force a full
renumber for a single run without permanently setting `forceRewrite = true` in any build script:

[source,bash]
----
./gradlew generateFeatureDocs -PgherkinToAsciidoc.forceRewrite=true
----

See the
link:../examples/gherkin-to-asciidoc/indexing/README.adoc[indexing example]
for all five modes applied to the same feature files side by side, with the exact before/after content and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,17 @@ public abstract class GenerateFeatureDocsTask extends DefaultTask {
@Input
public abstract Property<IndexingMode> getIndexing();

/**
* Whether {@link #getIndexing()} renumbers every {@code Feature}/{@code Scenario} from scratch,
* or only the ones not already correctly numbered for the currently configured
* {@link IndexingMode}. Has no effect when {@link #getIndexing()} is {@link IndexingMode#OFF}
* or {@link IndexingMode#CI}.
*
* @return mutable boolean property controlling whether existing numbering is preserved
*/
@Input
public abstract Property<Boolean> getForceRewrite();

/**
* Root directory of the project, used to resolve the default source directory
* when neither {@link #getSourceDirs()} nor {@link #getSourceFile()} is set.
Expand Down Expand Up @@ -244,7 +255,7 @@ public void generate() {
// CI skips indexing entirely - the feature files are left completely untouched, not even
// to strip numbering left over from a previous run, unlike OFF.
if (indexing != IndexingMode.CI) {
new FeatureIndexer().reindex(featureFiles, indexing);
new FeatureIndexer().reindex(featureFiles, indexing, getForceRewrite().get());
}

List<ScenarioInfo> scenarios = new ArrayList<>();
Expand Down
Loading
Loading