Skip to content

test: add extension package-data contract coverage#108

Merged
SSobol77 merged 1 commit into
mainfrom
issue/99-extension-tree-package-data-contract
Jun 21, 2026
Merged

test: add extension package-data contract coverage#108
SSobol77 merged 1 commit into
mainfrom
issue/99-extension-tree-package-data-contract

Conversation

@SSobol77

@SSobol77 SSobol77 commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Adds contract coverage for the imported ECLI Extensions Layer assets under src/ecli/extensions.

Scope:

  • adds repository tree contract tests for representative imported extension assets
  • verifies forbidden import-shape artifacts are absent, including nested src/ecli/extensions/extensions/ and EXTENSIONS_FOLDER-structure.md
  • adds wheel and sdist package-data contract tests
  • builds package artifacts in pytest temp directories and inspects them with standard-library zipfile and tarfile
  • documents that test: add extension tree and package-data contract coverage #99 proves representative extension assets are included in wheel/sdist

Representative checked assets:

  • src/ecli/extensions/cgmanifest.json
  • src/ecli/extensions/bat/package.json
  • src/ecli/extensions/bat/language-configuration.json
  • src/ecli/extensions/bat/syntaxes/batchfile.tmLanguage.json
  • src/ecli/extensions/bat/snippets/batchfile.code-snippets
  • src/ecli/extensions/python/package.json
  • src/ecli/extensions/python/language-configuration.json
  • src/ecli/extensions/json/package.json
  • src/ecli/extensions/javascript/package.json
  • src/ecli/extensions/markdown-basics/package.json
  • src/ecli/extensions/cpp/package.json

Confirmed:

  • no imported upstream extension files modified
  • no pyproject.toml package-data change required
  • no runtime/source behavior added
  • no VS Code extension host
  • no Node/TypeScript activation
  • no Copilot runtime activation
  • no hidden command execution
  • no generic PTY terminal emulator
  • F11 remains the PySH Console Panel
  • no VMLab, QEMU, or QMP behavior added
  • no manifest registry, grammar catalog, syntax service, theme bridge, diagnostics, snippets, or language-configuration loaders

Validation:

  • uv run ruff check src tests
  • uv run ruff format --check src tests
  • uv run python scripts/check_runtime_imports.py
  • uv run pytest -q tests/extensions tests/packaging tests/docs tests/ui/test_terminal_panel_reservation.py tests/ui/test_pysh_console_panel.py tests/ui/test_pysh_console_panel_keybindings.py

Closes #99.

Summary by CodeRabbit

  • Documentation

    • Added architecture guidance on extensions packaging and distribution requirements.
  • Tests

    • Added contract tests to verify extension assets are properly included in distribution packages.
    • Added contract tests to validate the extensions directory structure and required files.

@coderabbitai

coderabbitai Bot commented Jun 21, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Two new contract test modules are added under tests/extensions/: one verifies the extensions source tree structure via filesystem assertions, and one builds wheel and sdist artifacts and checks that representative extension asset files are present inside them. Architecture documentation is updated to note the test locations and confirm no pyproject.toml packaging changes are needed.

Changes

Extensions Layer Contract Tests and Docs

Layer / File(s) Summary
Extensions tree contract tests
tests/extensions/test_extensions_tree_contract.py
Defines EXTENSIONS_ROOT, representative asset paths, forbidden paths, and glob-type patterns. Implements parametrized tests asserting directory existence, per-file presence and non-emptiness, forbidden path absence, and at least one file matching each recursive glob pattern.
Wheel and sdist package-data contract tests
tests/extensions/test_extensions_package_data_contract.py
Defines REPRESENTATIVE_SOURCE_PATHS and WHEEL_MEMBER_PATHS, implements a module-scoped fixture that invokes uv build or python -m build (skipping if neither is available), then asserts all expected asset paths exist inside the produced wheel zip and sdist tarball.
Architecture docs update
docs/architecture/extensions-layer.md
Adds a subsection under "Release / package-data impact" naming both test files and stating that Hatchling's existing packages = ["src/ecli"] selection covers the imported extension data files without new force-include/include entries.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • SSobol77/ecli#106: Introduced the docs/architecture/extensions-layer.md file that this PR directly extends with the contract test location subsection.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly corresponds to the main change: adding package-data contract tests for the extensions layer.
Linked Issues check ✅ Passed All objectives from issue #99 are met: tree contract tests verify asset presence, package-data tests confirm wheel/sdist inclusion, and representative files are validated.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the issue scope: two contract test files and one documentation update about release/package-data impact.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue/99-extension-tree-package-data-contract

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/architecture/extensions-layer.md`:
- Around line 200-207: There is a contradiction in the extensions-layer.md
documentation regarding packaging requirements for non-`.py` extension assets.
The status note (`#99`) at lines 205-207 states that no additional
`force-include`/`include` entries were required in `pyproject.toml` for the test
case, but earlier bullets in the same section claim such entries are necessary
for non-`.py` extension assets. Review both statements to determine the actual
packaging contract and revise whichever statement is inaccurate so that the
documentation clearly and consistently explains when and why
`force-include`/`include` entries are or are not required in `pyproject.toml`
for extension assets.

In `@tests/extensions/test_extensions_package_data_contract.py`:
- Around line 102-106: The condition checking if result.returncode != 0 should
not automatically skip the test with pytest.skip() because this masks real build
failures and packaging regressions. Instead, distinguish between the build tool
being unavailable versus an actual build failure. Keep the skip only for cases
where the build tool itself is truly unavailable in the environment, but fail
the test hard (using assert or pytest.fail) when the build command actually runs
but returns a non-zero exit code, as this indicates a real packaging problem
that should not pass CI.
🪄 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: bd032be9-116d-4cc6-a110-d0ac37bd3e3d

📥 Commits

Reviewing files that changed from the base of the PR and between 113c8d2 and 67af211.

📒 Files selected for processing (3)
  • docs/architecture/extensions-layer.md
  • tests/extensions/test_extensions_package_data_contract.py
  • tests/extensions/test_extensions_tree_contract.py

Comment on lines +200 to +207
- **Status (#99):** tree and package-data contract tests live in
`tests/extensions/` (`test_extensions_tree_contract.py`,
`test_extensions_package_data_contract.py`). They prove representative
imported extension assets are present in the repository tree and inside the
built wheel and sdist. Hatchling's default file selection for
`packages = ["src/ecli"]` already ships the imported data files, so **no
additional `force-include`/`include` entries were required** in
`pyproject.toml`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reconcile this status note with the earlier packaging rule in the same section.

Lines 205-207 say no additional force-include/include entries were required, but earlier bullets still state such entries are required for non-.py extension assets. Please align both statements so the packaging contract is unambiguous.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/architecture/extensions-layer.md` around lines 200 - 207, There is a
contradiction in the extensions-layer.md documentation regarding packaging
requirements for non-`.py` extension assets. The status note (`#99`) at lines
205-207 states that no additional `force-include`/`include` entries were
required in `pyproject.toml` for the test case, but earlier bullets in the same
section claim such entries are necessary for non-`.py` extension assets. Review
both statements to determine the actual packaging contract and revise whichever
statement is inaccurate so that the documentation clearly and consistently
explains when and why `force-include`/`include` entries are or are not required
in `pyproject.toml` for extension assets.

Comment on lines +102 to +106
if result.returncode != 0:
pytest.skip(
"package build unavailable in this environment "
f"(exit {result.returncode}):\n{result.stdout}\n{result.stderr}"
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Do not skip when the build command fails.

On Line 102, converting a real build failure into pytest.skip(...) masks packaging regressions and can let broken artifact contracts pass CI. Keep the skip only for “frontend unavailable” and fail hard on non-zero exit.

Proposed fix
-    if result.returncode != 0:
-        pytest.skip(
-            "package build unavailable in this environment "
-            f"(exit {result.returncode}):\n{result.stdout}\n{result.stderr}"
-        )
+    assert result.returncode == 0, (
+        "package build failed "
+        f"(exit {result.returncode}):\n{result.stdout}\n{result.stderr}"
+    )

As per coding guidelines, “Every active packaging, workflow, script, platform descriptor, Docker helper, and install/build document must be wired into the contract or removed; empty, stale, decorative, or unused packaging files are forbidden.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/extensions/test_extensions_package_data_contract.py` around lines 102 -
106, The condition checking if result.returncode != 0 should not automatically
skip the test with pytest.skip() because this masks real build failures and
packaging regressions. Instead, distinguish between the build tool being
unavailable versus an actual build failure. Keep the skip only for cases where
the build tool itself is truly unavailable in the environment, but fail the test
hard (using assert or pytest.fail) when the build command actually runs but
returns a non-zero exit code, as this indicates a real packaging problem that
should not pass CI.

Source: Coding guidelines

@SSobol77
SSobol77 merged commit a50a50f into main Jun 21, 2026
5 checks passed
@sonarqubecloud

Copy link
Copy Markdown

@SSobol77
SSobol77 deleted the issue/99-extension-tree-package-data-contract branch June 21, 2026 00:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

test: add extension tree and package-data contract coverage

1 participant