Uh oh!
There was an error while loading. Please reload this page.
Add @command behave tags to all feature files - #1141
Conversation
Warning Rate limit exceeded
Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 32 minutes and 26 seconds. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (5)
WalkthroughReplaces single-mode scenario inclusion with a builder-aware system: HTML renders scenarios inline (with optional Changes
Sequence Diagram(s)sequenceDiagram
participant Sphinx as Sphinx App
participant Directive as scenario-include/<br/>scenario-appendix
participant Doctree as Doctree
participant Resolver as doctree-resolved<br/>Handler
participant Env as Sphinx Env
participant Renderer as HTML/PDF Renderer
Directive->>Env: record scenario metadata (PDF mode)
Directive->>Doctree: insert inline nodes (HTML mode) or placeholder node (PDF mode)
Sphinx->>Resolver: emit doctree-resolved
Resolver->>Doctree: find & replace placeholders
Resolver->>Env: retrieve collected scenarios grouped by tag
Resolver->>Doctree: inject appendix sections (PDF mode)
Doctree->>Renderer: final doctree for output generation
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@doc/_ext/scenario_directive.py`:
- Around line 179-196: The directive currently hardcodes "Scenario:" when
building the literalinclude bounds; update the parsing code in _all_scenarios()
to preserve the original header token (e.g., header = "Scenario" or "Scenario
Outline") alongside title and use that header when composing the start-after and
end-before lines in directive_rst (e.g., f":start-after: {header}: {title}" and
f":end-before: {header}: {title}" when applicable), ensuring end_before remains
empty for the last item as before.
- Around line 235-249: The appendix entry currently stores a single "source_doc"
and is removed when that one doc is reread, dropping references from other
pages; change the entry shape to track a set of referencing docs (e.g. replace
"source_doc" with "source_docs" as a set when creating the entry in
env.scenario_appendix_entries for feature_abs), update merging logic to add
env.docname into existing["source_docs"] when appending scenarios (alongside
existing["scenarios"].append), and update the purge/remove logic (the code that
deletes entries on document re-read) to remove the current env.docname from
existing["source_docs"] and only delete the whole entry if that set is empty.
Ensure all places that read/write "source_doc" are updated to use the new
"source_docs" set.
- Around line 349-352: The PDF/LaTeX appendix currently always emits the full
feature via _full_feature_content(entry["feature_abs"]) into a
nodes.literal_block (assigned to code and appended to feat_section), which
ignores the :scenario: filter; change the PDF path to either (A) build the
literal_block from only entry["scenarios"] (i.e., render and join only the
selected scenarios instead of calling _full_feature_content) when the builder is
LaTeX/PDF, or (B) detect the LaTeX/PDF builder (via app.builder.name or
buildername) and raise/emit a clear error/warning rejecting the :scenario:
option for PDF builds; update the code that constructs code =
nodes.literal_block(...) and the content source to use the chosen approach so
HTML and PDF outputs remain consistent.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: f9f4a274-e2f9-42ba-bbf5-f63a6c85d8d2
📒 Files selected for processing (55)
doc/_ext/scenario_directive.pydoc/appendix/scenarios.rstdoc/conf.pydoc/index.rstfeatures/add-project-through-cli.featurefeatures/check-archive.featurefeatures/check-git-repo.featurefeatures/check-report-code-climate.featurefeatures/check-report-jenkins.featurefeatures/check-report-sarif.featurefeatures/check-specific-projects.featurefeatures/check-svn-repo.featurefeatures/checked-project-has-dependencies.featurefeatures/diff-in-git.featurefeatures/diff-in-svn.featurefeatures/fetch-archive.featurefeatures/fetch-checks-destination.featurefeatures/fetch-file-pattern-git.featurefeatures/fetch-file-pattern-svn.featurefeatures/fetch-git-repo-with-submodule.featurefeatures/fetch-git-repo.featurefeatures/fetch-single-file-git.featurefeatures/fetch-single-file-svn.featurefeatures/fetch-specific-project.featurefeatures/fetch-svn-repo.featurefeatures/fetch-with-ignore-git.featurefeatures/fetch-with-ignore-svn.featurefeatures/format-patch-in-git.featurefeatures/format-patch-in-svn.featurefeatures/freeze-archive.featurefeatures/freeze-inplace.featurefeatures/freeze-projects.featurefeatures/freeze-specific-projects.featurefeatures/guard-against-overwriting-git.featurefeatures/guard-against-overwriting-svn.featurefeatures/handle-invalid-metadata.featurefeatures/import-from-git.featurefeatures/import-from-svn.featurefeatures/interactive-add.featurefeatures/journey-basic-patching.featurefeatures/journey-basic-usage.featurefeatures/keep-license-in-project.featurefeatures/list-projects.featurefeatures/patch-after-fetch-git.featurefeatures/patch-after-fetch-svn.featurefeatures/patch-fuzzy-matching-git.featurefeatures/remove-project.featurefeatures/report-sbom-archive.featurefeatures/report-sbom-license.featurefeatures/report-sbom.featurefeatures/suggest-project-name.featurefeatures/update-patch-in-git.featurefeatures/update-patch-in-svn.featurefeatures/updated-project-has-dependencies.featurefeatures/validate-manifest.feature
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
3abcbbd to
ea1a3eeComparespoorcc
commented
Apr 15, 2026
@coderabbitai review |
✅ Actions performedReview triggered.
|
ea1a3ee to
b32e6ebCompareEach feature file now carries a tag identifying the dfetch command it exercises (e.g. @update, @check, @diff, @add, @remove, @report, @Freeze, @import, @Validate, @format-patch, @update-patch). Journey features that exercise multiple commands receive all relevant tags (e.g. @update@check for journey-basic-usage.feature). Files that already had @remote-svn retain it and gain the new command tag on the same line (e.g. @remote-svn @update). This makes it possible to run only the scenarios for a specific command, for example: behave features/ --tags=update https://claude.ai/code/session_01BvyikyxX9c3sDXev8HdP4f
The scenario-include directive now has two modes: HTML (unchanged): Scenarios are rendered inline as collapsible <details> blocks, exactly as before. PDF / LaTeX: Scenarios are moved to an auto-generated appendix page grouped by dfetch command (update, check, add, …). In the place of the directive the text shows a cross-reference: "Scenarios: see <Feature title> in the appendix." The command grouping is derived from the @command behave tag added to each feature file in the previous commit. New directive option :inline: keeps a scenario in its original position even in PDF mode, for cases where the example is essential reading in context: .. scenario-include:: ../features/journey-basic-usage.feature :inline: New directive scenario-appendix renders the collected scenarios in the PDF appendix; in HTML it emits an orientation note instead. doc/appendix/scenarios.rst added as the appendix landing page; it is wired into the index.rst toctree under a new "Appendix" caption. https://claude.ai/code/session_01BvyikyxX9c3sDXev8HdP4f
Three changes: 1. Remove hardcoded _NON_COMMAND_TAGS, _TAG_LABELS, _TAG_ORDER constants. The directive no longer knows anything about dfetch commands. 2. Sort appendix sections alphabetically by tag. The previous fixed ordering (update, check, add, …) was dfetch-specific. 3. Expose scenario_non_command_tags as a conf.py config value (default []). Any tag in that list is skipped when choosing the group tag for a feature file. dfetch's conf.py now sets: scenario_non_command_tags = ["remote-svn"] Section titles are derived from the tag itself (title-cased, hyphens replaced by spaces), so no label map is needed. https://claude.ai/code/session_01BvyikyxX9c3sDXev8HdP4f
b32e6eb to
812915dCompareThere was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@doc/_ext/scenario_directive.py`:
- Around line 306-313: After computing available = _all_scenarios(feature_abs)
and scenario_titles = self._requested_scenarios(available) in run(), validate
the requested titles before calling _render_pdf() and raise a directive error if
any requested title is missing or if the user specified :scenario: but no
matching scenarios were found; specifically, compare scenario_titles against
available (or check for requested vs matched counts) and call self.error(...)
with a clear message when there's a mismatch so the PDF path (_render_pdf) never
receives silently-omitted scenario requests.
- Around line 22-35: Add a user-facing documentation page that explains how to
use the scenario-include and scenario-appendix directives, documents the
scenario_non_command_tags configuration and the :inline: flag, and clearly
describes the PDF/LaTeX appendix behavior and grouping rules; include a short
example showing a scenario-include with and without :inline:, an example
scenario-appendix placement, and a note about how non-excluded behave tags
affect appendix grouping so readers can reproduce the behavior and configure it.
- Around line 257-299: The generated appendix IDs can collide because label =
f"appendix-{basename}" and group_label = f"appendix-{tag}" share a namespace and
basename alone ignores path; fix by introducing and using a collision-resistant
helper (e.g., _appendix_id(value, *, kind)) that slug-normalizes and namespaces
values (include file path or feature_abs for feature IDs, and prefix/group for
group IDs) and replace usages: set label = _appendix_id(feature_abs,
kind="feature"), group_label = _appendix_id(tag, kind="group"), and store the
same stable IDs in env.scenario_appendix_entries and in the ScenarioAppendixRef
node (ensure ScenarioAppendixRef["label"], ["group_label"] and keys in
env.scenario_appendix_entries use the new helper-generated IDs).
- Around line 421-458: When appendix_docname is None we should warn so authors
know examples will be omitted: add "from sphinx.util import logging" and create
a module logger (e.g. logger = logging.getLogger(__name__)), then inside the
loop where appendix_docname is checked (the block that currently does the else:
para += nodes.Text(f"See …")), call logger.warning with a clear message about
the missing ".. scenario-appendix::" directive and its effect (e.g. "PDF build
will omit deferred examples because scenario_appendix_docname is not set; add ..
scenario-appendix:: to include them"), passing location=ref_node to attach the
warning to the source location of the ScenarioAppendixRef node. Ensure the
warning runs only when appendix_docname is falsy so behavior for the existing
branch is unchanged.
In `@features/fetch-git-repo-with-submodule.feature`:
- Line 1: The feature file features/fetch-git-repo-with-submodule.feature is
currently tagged only with `@update` but also exercises dfetch report; add the
missing `@report` tag alongside `@update` at the top of the feature so command-based
test filtering includes both commands (i.e., change the feature tag line to
include both `@update` and `@report`); ensure the tag text matches the existing
tagging style used in other features.
In `@features/guard-against-overwriting-svn.feature`:
- Line 1: The feature file guard-against-overwriting-svn.feature only has the
`@update` tag but should follow the established pattern of using `@remote-svn`
alongside command tags; edit the file header to add the `@remote-svn` tag so the
top line reads both `@remote-svn` and `@update`, mirroring other SVN features like
fetch-svn-repo.feature and check-svn-repo.feature (i.e., include the `@remote-svn`
tag next to `@update`).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 43210ba6-65b1-4d6f-ba4e-099bfd7e98e0
📒 Files selected for processing (57)
AGENTS.mddoc/_ext/scenario_directive.pydoc/appendix/scenarios.rstdoc/conf.pydoc/howto/contributing.rstdoc/index.rstfeatures/add-project-through-cli.featurefeatures/check-archive.featurefeatures/check-git-repo.featurefeatures/check-report-code-climate.featurefeatures/check-report-jenkins.featurefeatures/check-report-sarif.featurefeatures/check-specific-projects.featurefeatures/check-svn-repo.featurefeatures/checked-project-has-dependencies.featurefeatures/diff-in-git.featurefeatures/diff-in-svn.featurefeatures/fetch-archive.featurefeatures/fetch-checks-destination.featurefeatures/fetch-file-pattern-git.featurefeatures/fetch-file-pattern-svn.featurefeatures/fetch-git-repo-with-submodule.featurefeatures/fetch-git-repo.featurefeatures/fetch-single-file-git.featurefeatures/fetch-single-file-svn.featurefeatures/fetch-specific-project.featurefeatures/fetch-svn-repo.featurefeatures/fetch-with-ignore-git.featurefeatures/fetch-with-ignore-svn.featurefeatures/format-patch-in-git.featurefeatures/format-patch-in-svn.featurefeatures/freeze-archive.featurefeatures/freeze-inplace.featurefeatures/freeze-projects.featurefeatures/freeze-specific-projects.featurefeatures/guard-against-overwriting-git.featurefeatures/guard-against-overwriting-svn.featurefeatures/handle-invalid-metadata.featurefeatures/import-from-git.featurefeatures/import-from-svn.featurefeatures/interactive-add.featurefeatures/journey-basic-patching.featurefeatures/journey-basic-usage.featurefeatures/keep-license-in-project.featurefeatures/list-projects.featurefeatures/patch-after-fetch-git.featurefeatures/patch-after-fetch-svn.featurefeatures/patch-fuzzy-matching-git.featurefeatures/remove-project.featurefeatures/report-sbom-archive.featurefeatures/report-sbom-license.featurefeatures/report-sbom.featurefeatures/suggest-project-name.featurefeatures/update-patch-in-git.featurefeatures/update-patch-in-svn.featurefeatures/updated-project-has-dependencies.featurefeatures/validate-manifest.feature
| **PDF / LaTeX builds** automatically move examples to an appendix grouped by | ||
| the first non-excluded behave tag found on the feature file. The directive's | ||
| original location receives a cross-reference to the appendix entry instead. | ||
| Use the ``:inline:`` flag to keep a specific inclusion in place even when | ||
| building a PDF: | ||
| .. scenario-include:: ../features/fetch-git-repo.feature | ||
| :inline: | ||
| The appendix itself is rendered by placing the companion directive anywhere in | ||
| the document tree: | ||
| .. scenario-appendix:: |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
git ls-files doc/ | head -30Repository: dfetch-org/dfetch
Length of output: 1100
🏁 Script executed:
cat -n doc/_ext/scenario_directive.py | head -100Repository: dfetch-org/dfetch
Length of output: 4100
🏁 Script executed:
find doc -type f -name "*.rst" -o -name "*.md"| grep -E "(how-to|reference)"| head -20Repository: dfetch-org/dfetch
Length of output: 226
🏁 Script executed:
rg -l "scenario-include|scenario-appendix|:inline:" doc/Repository: dfetch-org/dfetch
Length of output: 304
🏁 Script executed:
cat -n doc/appendix/scenarios.rst | head -50Repository: dfetch-org/dfetch
Length of output: 681
🏁 Script executed:
cat -n doc/_ext/scenario_directive.py | sed -n '510,530p'Repository: dfetch-org/dfetch
Length of output: 920
🏁 Script executed:
rg "scenario-include|scenario-appendix" doc/appendix/scenarios.rst -B 2 -A 2Repository: dfetch-org/dfetch
Length of output: 191
🏁 Script executed:
find doc/howto -type f -exec grep -l "scenario" {} \;Repository: dfetch-org/dfetch
Length of output: 239
🏁 Script executed:
find doc -type f \( -name "*.rst" -o -name "*.md"\)| grep -E "(howto|reference)"| xargs grep -l "directive"2>/dev/null | head -10Repository: dfetch-org/dfetch
Length of output: 43
Add user-facing documentation for the scenario directives and PDF behavior.
This adds public directives (scenario-include, scenario-appendix), configuration (scenario_non_command_tags), and features (:inline: flag, PDF appendix grouping). While the module docstring documents these well, the repo requires user-visible changes in doc/howto/ or doc/reference/. Create a dedicated guide explaining how to use the scenario-include directive, the :inline: flag, and how PDF/LaTeX builds automatically organize examples via the appendix.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@doc/_ext/scenario_directive.py` around lines 22 - 35, Add a user-facing
documentation page that explains how to use the scenario-include and
scenario-appendix directives, documents the scenario_non_command_tags
configuration and the :inline: flag, and clearly describes the PDF/LaTeX
appendix behavior and grouping rules; include a short example showing a
scenario-include with and without :inline:, an example scenario-appendix
placement, and a note about how non-excluded behave tags affect appendix
grouping so readers can reproduce the behavior and configure it.
| basename = os.path.splitext(os.path.basename(feature_abs))[0] | ||
| label = f"appendix-{basename}" | ||
| tag = _group_tag(feature_abs, non_group_tags) | ||
| title = _feature_title(feature_abs) | ||
| # ---------------------------------------------------------- | ||
| # Store entry so the appendix directive can render it later. | ||
| # The dict is keyed by absolute path to deduplicate across | ||
| # multiple RST files that reference the same feature. | ||
| # ---------------------------------------------------------- | ||
| if not hasattr(env, "scenario_appendix_entries"): | ||
| env.scenario_appendix_entries = {} | ||
| if feature_abs not in env.scenario_appendix_entries: | ||
| env.scenario_appendix_entries[feature_abs] = { | ||
| "feature_file": feature_file, | ||
| "feature_abs": feature_abs, | ||
| "feature_title": title, | ||
| "group_tag": tag, | ||
| "label": label, | ||
| "source_docs": {env.docname}, | ||
| "scenarios": list(scenario_titles), | ||
| } | ||
| else: | ||
| existing = env.scenario_appendix_entries[feature_abs] | ||
| existing["source_docs"].add(env.docname) | ||
| for s in scenario_titles: | ||
| if s not in existing["scenarios"]: | ||
| existing["scenarios"].append(s) | ||
| # ---------------------------------------------------------- | ||
| # Return a deferred ScenarioAppendixRef block node. It is | ||
| # resolved to a full paragraph with make_refnode links during | ||
| # doctree-resolved, once the appendix document name is known. | ||
| # Sphinx's make_refnode handles LaTeX/HTML builder differences, | ||
| # producing a proper \hyperref in PDF output. | ||
| # ---------------------------------------------------------- | ||
| ref_node = ScenarioAppendixRef() | ||
| ref_node["label"] = label | ||
| ref_node["reftitle"] = title | ||
| ref_node["group_tag"] = tag | ||
| ref_node["group_label"] = f"appendix-{tag}" | ||
| ref_node["scenario_count"] = len(scenario_titles) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash# Description: Find current feature/tag pairs that would generate duplicate appendix IDs.
python - <<'PY'from collections import defaultdictfrom pathlib import Pathnon_group_tags = {"remote-svn"}ids = defaultdict(list)for path in Path(".").rglob("*.feature"): tags = [] try: lines = path.read_text(encoding="utf-8").splitlines() except UnicodeDecodeError: continue for line in lines: stripped = line.strip() if stripped.startswith("Feature:"): break if stripped.startswith("@"): tags.extend(token.lstrip("@") for token in stripped.split()) group = next((tag for tag in tags if tag not in non_group_tags), "other") feature_id = f"appendix-{path.stem}" group_id = f"appendix-{group}" ids[feature_id].append(f"feature {path}") ids[group_id].append(f"group {group} from {path}")for target_id, owners in sorted(ids.items()): if len(owners) > 1: print(target_id) for owner in owners: print(f" - {owner}")PYRepository: dfetch-org/dfetch
Length of output: 3136
🏁 Script executed:
# First, read the actual code at the mentioned lines
head -n 310 doc/_ext/scenario_directive.py | tail -n 55Repository: dfetch-org/dfetch
Length of output: 2676
🏁 Script executed:
# Also check the other location mentioned (lines 378-388)
sed -n '370,395p' doc/_ext/scenario_directive.pyRepository: dfetch-org/dfetch
Length of output: 1095
🏁 Script executed:
# Check if any .feature file has a tag matching its own basename
python - <<'PY'from pathlib import Pathnon_group_tags = {"remote-svn"}for path in sorted(Path(".").rglob("*.feature")): basename = path.stem tags = [] try: lines = path.read_text(encoding="utf-8").splitlines() except UnicodeDecodeError: continue for line in lines: stripped = line.strip() if stripped.startswith("Feature:"): break if stripped.startswith("@"): tags.extend(token.lstrip("@") for token in stripped.split()) # Check for basename matching a tag for tag in tags: if tag == basename or tag.startswith(basename + "-") or basename.endswith("-" + tag): print(f"Match found: {path.stem} has tag {tag}") print(f" file: {path}") print(f" tags: {tags}") breakPYRepository: dfetch-org/dfetch
Length of output: 158
🏁 Script executed:
# Check for duplicate basenames across different directories
python - <<'PY'from collections import defaultdictfrom pathlib import Pathbasenames = defaultdict(list)for path in sorted(Path(".").rglob("*.feature")): basename = path.stem basenames[basename].append(str(path))for basename in sorted(basenames.keys()): paths = basenames[basename] if len(paths) > 1: print(f"Duplicate basename '{basename}':") for p in paths: print(f" - {p}")PYRepository: dfetch-org/dfetch
Length of output: 43
Use collision-safe IDs for group and feature appendix targets.
The current ID generation can produce collisions: label = f"appendix-{basename}" (line 264) and group_label = f"appendix-{tag}" (line 296) share the same namespace. A feature file with basename matching its group tag (e.g., update.feature with @update tag) would generate duplicate section IDs. Additionally, if the same feature basename appears in different directories, they'd share a single ID, causing ambiguous cross-references. The proposed fix using a collision-resistant _appendix_id() helper with slug normalization resolves this:
Proposed fix
+def _appendix_id(prefix: str, value: str) -> str:+ """Return a stable docutils-safe appendix target id."""+ slug = re.sub(r"[^a-z0-9]+", "-", value.lower()).strip("-")+ return f"scenario-appendix-{prefix}-{slug or 'item'}"++
def _tag_section_title(tag: str) -> str:
"""Human-readable section title derived from *tag* alone."""
return tag.replace("-", " ").title()
@@
env = self._env()
non_group_tags = frozenset(getattr(env.config, "scenario_non_command_tags", []))
basename = os.path.splitext(os.path.basename(feature_abs))[0]
- label = f"appendix-{basename}"
tag = _group_tag(feature_abs, non_group_tags)
+ label = _appendix_id("feature", feature_file)+ group_label = _appendix_id("group", tag)
title = _feature_title(feature_abs)
@@
ref_node["label"] = label
ref_node["reftitle"] = title
ref_node["group_tag"] = tag
- ref_node["group_label"] = f"appendix-{tag}"+ ref_node["group_label"] = group_label
ref_node["scenario_count"] = len(scenario_titles)
return [ref_node]
@@
for tag in sorted(by_tag):
tag_entries = sorted(by_tag[tag], key=lambda e: e["feature_title"])
- label = f"appendix-{tag}"+ label = _appendix_id("group", tag)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@doc/_ext/scenario_directive.py` around lines 257 - 299, The generated
appendix IDs can collide because label = f"appendix-{basename}" and group_label
= f"appendix-{tag}" share a namespace and basename alone ignores path; fix by
introducing and using a collision-resistant helper (e.g., _appendix_id(value, *,
kind)) that slug-normalizes and namespaces values (include file path or
feature_abs for feature IDs, and prefix/group for group IDs) and replace usages:
set label = _appendix_id(feature_abs, kind="feature"), group_label =
_appendix_id(tag, kind="group"), and store the same stable IDs in
env.scenario_appendix_entries and in the ScenarioAppendixRef node (ensure
ScenarioAppendixRef["label"], ["group_label"] and keys in
env.scenario_appendix_entries use the new helper-generated IDs).
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Each feature file now carries a tag identifying the dfetch command it
exercises (e.g. @update, @check, @diff, @add, @remove, @report,
@Freeze, @import, @Validate, @format-patch, @update-patch).
Journey features that exercise multiple commands receive all relevant
tags (e.g. @update@check for journey-basic-usage.feature).
Files that already had @remote-svn retain it and gain the new command
tag on the same line (e.g. @remote-svn @update).
This makes it possible to run only the scenarios for a specific
command, for example:
https://claude.ai/code/session_01BvyikyxX9c3sDXev8HdP4f
Summary by CodeRabbit
Documentation
Chores