Skip to content

Add RPM and PyPI example plugins, restructure as workspace#7

Merged
brandonrc merged 5 commits intomainfrom
feat/6-more-examples
Feb 21, 2026
Merged

Add RPM and PyPI example plugins, restructure as workspace#7
brandonrc merged 5 commits intomainfrom
feat/6-more-examples

Conversation

@brandonrc
Copy link
Contributor

Summary

  • Restructure the repo from a single crate into a Cargo workspace with three example plugins under plugins/
  • Add RPM format plugin: binary lead magic validation (0xed 0xab 0xee 0xdb), right-to-left filename parsing for name/version/release/arch, JSON index generation
  • Add PyPI format plugin: PEP 427 wheel filename parsing, PEP 503 package name normalization, source distribution parsing, HTML Simple Repository + JSON index generation
  • Move existing Unity plugin into the workspace structure
  • Update CI to build/test/upload all three plugins
  • Update release workflow to package each plugin as a separate ZIP
  • Rewrite README with workspace-oriented documentation
  • Update SonarCloud sources path

Test results

57 total tests (12 Unity + 18 RPM + 27 PyPI), all passing. Clippy clean, fmt clean.

Test plan

  • cargo build --release --target wasm32-wasip2 --workspace builds all three plugins
  • cargo clippy --target wasm32-wasip2 --workspace -- -D warnings passes
  • cargo test --workspace passes (57 tests)
  • cargo fmt --check passes
  • CI workflow passes

Closes #6

Convert the repo from a single plugin into a Cargo workspace with
three example format handler plugins:

- Unity (.unitypackage): gzip validation, path-based version extraction
- RPM (.rpm): binary lead magic validation, right-to-left filename parsing
- PyPI (.whl, .tar.gz): PEP 427 wheel parsing, PEP 503 name normalization,
  HTML + JSON index generation

Each plugin demonstrates different aspects of WASM plugin development.
57 total tests across all three plugins.

Updated CI to build/test all plugins, release workflow packages each
plugin as a separate ZIP, and README documents the full workspace.

Closes #6
Avoid conflicts with native format handlers that use the
'rpm' and 'pypi' keys. Custom plugin format keys use the
'-custom' suffix so both can coexist in the same instance.
Implement the format-plugin-v2 WIT world in both example plugins so
they can serve native client protocols directly from WASM:

- PyPI plugin: serves PEP 503 simple API (package listing and per-package
  version pages) so pip install works against plugin-backed repos
- RPM plugin: serves repodata XML (repomd.xml, primary.xml.gz) so dnf/yum
  can resolve and install packages from plugin-backed repos
- Update WIT file with request-handler interface and format-plugin-v2 world
- Add handle_request = true to both plugin manifests
Each example plugin is an independent crate that implements the same WIT
interface. Cross-plugin code similarity is expected and intentional since
each plugin is meant to be a self-contained, copy-pasteable template.

Configuring SonarCloud modules so duplication is measured within each
plugin rather than across the whole repo. This avoids false positives
from the structural similarity between format handler implementations.
The sonar.modules approach does not isolate CPD (copy-paste detection)
across modules. SonarCloud still compares files across all modules,
flagging the WIT interface boilerplate (Metadata construction, validate
pattern, handle_request scaffolding) as duplication.

Replace the module-based config with sonar.cpd.exclusions to skip
cross-plugin false positives entirely. Each plugin is an independent,
copy-pasteable template where structural similarity is expected.
@sonarqubecloud
Copy link

@brandonrc brandonrc merged commit 83baa89 into main Feb 21, 2026
4 checks passed
@brandonrc brandonrc deleted the feat/6-more-examples branch February 21, 2026 04:46
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.

Add more examples that make it easy for people to develop with

1 participant