Skip to content

feat: add cyclonedx.model.dependency.Dependency.provides - #1036

Open
saquibsaifee wants to merge 8 commits into
CycloneDX:mainfrom
saquibsaifee:feat-uzair-provides-7524676707032308925
Open

saquibsaifee wants to merge 8 commits into
CycloneDX:mainfrom
saquibsaifee:feat-uzair-provides-7524676707032308925

Conversation

@saquibsaifee

@saquibsaifee saquibsaifee commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Description

Add support for cyclonedx.model.dependency.Dependency.provides) field in Dependency, originally implemented in PR #735 by Uzair.

Fixes #691

AI Tool Disclosure

  • My contribution includes AI-generated content, as disclosed below:
    • AI Tools: Gemini Jules
    • LLMs and versions: Gemini 3.1 Pro

Affirmation


Co-authored-by: Uzair Chhapra uzairchhapra@gmail.com
Signed-off-by: saquibsaifee saquibsaifee2@gmail.com

@saquibsaifee
saquibsaifee requested a review from a team as a code owner September 1, 2026 01:52
@read-the-docs-community

read-the-docs-community Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

@codacy-production

codacy-production Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 12 complexity · 0 duplication

Metric Results
Complexity 12
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@saquibsaifee
saquibsaifee force-pushed the feat-uzair-provides-7524676707032308925 branch from e606ca5 to beac7ca Compare September 1, 2026 18:06
@saquibsaifee saquibsaifee changed the title Feat uzair provides 7524676707032308925 feat: add cyclonedx.model.dependency.Dependency.provides Sep 1, 2026
@saquibsaifee
saquibsaifee force-pushed the feat-uzair-provides-7524676707032308925 branch from beac7ca to 9988631 Compare September 1, 2026 18:12
@saquibsaifee

Copy link
Copy Markdown
Contributor Author

@jkowalleck does this look promising?

@saquibsaifee
saquibsaifee force-pushed the feat-uzair-provides-7524676707032308925 branch from 9386458 to 9988631 Compare September 1, 2026 19:01
@jkowalleck jkowalleck added enhancement New feature or request schema 1.6 labels Sep 15, 2026
@jkowalleck
jkowalleck requested a balanced review from Copilot September 15, 2026 12:17

Copilot AI 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.

🟡 Changes recommended

The registration path mishandles generator inputs, mutates hash-bearing set elements, and weakens regression coverage.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds CycloneDX 1.6+ support for dependency provides relationships across modeling, serialization, validation, and graph flattening.

Changes:

  • Adds Dependency.provides and BOM registration/validation support.
  • Preserves provides during dependency graph flattening.
  • Adds model tests and versioned serialization snapshots.
File summaries
File Description
cyclonedx/model/dependency.py Models and serializes provides.
cyclonedx/model/bom.py Registers and validates provided references.
cyclonedx/contrib/bom/utils.py Preserves provides while flattening.
tests/test_model_dependency.py Tests the new model field.
tests/test_contrib/test_bom_utils.py Tests graph flattening.
tests/_data/models.py Adds a BOM fixture with provides.
tests/_data/snapshots/get_bom_with_provides-1.7.xml.bin XML 1.7 snapshot.
tests/_data/snapshots/get_bom_with_provides-1.7.json.bin JSON 1.7 snapshot.
tests/_data/snapshots/get_bom_with_provides-1.6.xml.bin XML 1.6 snapshot.
tests/_data/snapshots/get_bom_with_provides-1.6.json.bin JSON 1.6 snapshot.
tests/_data/snapshots/get_bom_with_provides-1.5.xml.bin XML 1.5 omission snapshot.
tests/_data/snapshots/get_bom_with_provides-1.5.json.bin JSON 1.5 omission snapshot.
tests/_data/snapshots/get_bom_with_provides-1.4.xml.bin XML 1.4 omission snapshot.
tests/_data/snapshots/get_bom_with_provides-1.4.json.bin JSON 1.4 omission snapshot.
tests/_data/snapshots/get_bom_with_provides-1.3.xml.bin XML 1.3 omission snapshot.
tests/_data/snapshots/get_bom_with_provides-1.3.json.bin JSON 1.3 omission snapshot.
tests/_data/snapshots/get_bom_with_provides-1.2.xml.bin XML 1.2 omission snapshot.
tests/_data/snapshots/get_bom_with_provides-1.2.json.bin JSON 1.2 omission snapshot.
tests/_data/snapshots/get_bom_with_provides-1.1.xml.bin XML 1.1 snapshot.
tests/_data/snapshots/get_bom_with_provides-1.0.xml.bin XML 1.0 snapshot.
Review details
  • Files reviewed: 20/20 changed files
  • Comments generated: 4
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cyclonedx/model/bom.py Resolved
Comment thread cyclonedx/model/bom.py Resolved
Comment thread tests/_data/models.py Resolved
Comment thread tests/test_model_dependency.py Resolved
@saquibsaifee
saquibsaifee force-pushed the feat-uzair-provides-7524676707032308925 branch from 059c882 to e17bbb5 Compare September 17, 2026 06:04
saquibsaifee and others added 4 commits September 17, 2026 02:06
Fixes CycloneDX#691

- Add `Dependency.provides` property with schema view limited to v1.6+
- Add `Dependency.provides_as_bom_refs()` helper
- Fix `BomDependencyGraphFlatMerger._flatten_merge()` to preserve `provides`
  during JSON serialization pipeline (was silently dropped before)
- Add unit tests for `Dependency.provides` in `test_model_dependency`
- Add unit test for flat-merger preserving `provides` in `test_bom_utils`
- Add snapshot fixture `get_bom_with_provides` across all schema versions;
  v1.6 and v1.7 JSON snapshots include `provides` array

Signed-off-by: saquibsaifee <saquibsaifee2@gmail.com>
Co-authored-by: Uzair Chhapra <uzairchhapra@gmail.com>
Change provides to be a tuple, defaulting to an empty tuple if None.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Saquib Saifee <saquibsaifee2@gmail.com>
- Safely update dependencies and provides without corrupting SortedSet
- Resolve generator exhaustion for depends_on
- Fix fuzzy matching of provides in deserialization tests
- Fix tie-breaker sorting behavior in dependency tests

Signed-off-by: Saquib Saifee <sky@MacBook.local>
@saquibsaifee
saquibsaifee force-pushed the feat-uzair-provides-7524676707032308925 branch from e17bbb5 to 5116014 Compare September 17, 2026 06:07
@saquibsaifee

Copy link
Copy Markdown
Contributor Author

Have addressed the comments by Copilot

jkowalleck commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

review done by Claude Fable 5.1, prompt: "do a review, comment your findings"


Verdict: Looks good to merge, with a few minor nits. The feature is implemented consistently across model, serialization, validation and the flat-merger, and the earlier review feedback appears to be addressed.

What I verified (locally on the PR head 21770c5)

  • Full test suite: 7065 tests, all PR-related tests pass. The only 40 failures (test_validation_json timestamp / no_none cases) are environmental and fail identically on main.
  • mypy, flake8, isort — clean on changed files.
  • Round-trip (output → Bom.from_json/from_xml) preserves provides for 1.6 and 1.7 — correct.
  • Output for 1.0–1.5 silently drops provides (as expected via @serializable.view). Snapshots confirm this.
  • Serialized a node with both dependsOn and provides and ran it through XmlValidator/JsonStrictValidator for 1.6 and 1.7 — passes; XML element order (<dependency> before <provides>) matches the XSD sequence. The fixture get_bom_with_provides only exercises the two in separate nodes, so this combined case isn't covered by snapshots (see nits).
  • register_dependency with a generator for provides now works (it is materialized via tuple(...) up front) — Copilot's earlier concern is resolved.
  • Re-registering an existing target with new provides keeps self._dependencies (a SortedSet) consistent: the entry is removed before mutation and re-added, so hash/order are not corrupted. This actually fixes a latent pre-existing bug for depends_on as well, nice.
  • Bom.validate() raises UnknownComponentDependencyException for a provides ref that isn't a component/service — consistent with dependsOn handling.
  • get_bom_with_provides is correctly not in all_get_bom_funct_with_incomplete_deps, so deserialize tests use strict deep comparison (and Dependency.__eq__ includes provides).
  • test_sort_with_provides now uses the same ref for all entries, so it genuinely exercises the provides tie-breaker.

Nits / suggestions (non-blocking)

  1. Import style — cyclonedx/model/dependency.py uses an absolute import from cyclonedx.schema.schema import ...; every other module in cyclonedx/model/ uses the relative form from ..schema.schema import .... Suggest aligning for consistency.
  2. Redundant early-return in _DependencyRepositorySerializationHelper.serialize: if not o: return [] is a no-op since the list comprehension already yields [] for an empty set. Harmless; could be dropped to keep the diff focused.
  3. register_dependency removal loop — the for i, dep in enumerate(self._dependencies): if dep is _d: del ... adds a second linear scan right after the next(filter(...)) lookup. It works (SortedSet supports __delitem__ by index), but the justification comment ("Empty BomRef elements violate strict weak ordering") is somewhat opaque for future readers; consider expanding it or merging the two scans (track the index while locating _d). Also the # type: ignore[attr-defined] suggests the sortedcontainers stubs are incomplete rather than a real typing problem — a short note would help.
  4. Test coverage gap — no snapshot/fixture has a single Dependency with both dependencies and provides. I validated this case manually and it is correct, but adding it to get_bom_with_provides (e.g. give A a provides too) would lock in the XSD element ordering for free.
  5. Docs — docs/schema-support.rst only has a generic bom.dependencies row, so nothing strictly needs updating; a short mention of provides (1.6+) would be nice-to-have for discoverability. register_dependency has no docstring; adding one that documents the new provides parameter would help API users.

Nothing here blocks merging from my side.

- Align import style in cyclonedx/model/dependency.py to relative import
- Remove redundant early return in _DependencyRepositorySerializationHelper.serialize
- Add docstring to Bom.register_dependency documenting target, depends_on, and provides
- Merge Bom.register_dependency lookup and removal into single pass with clarified comments
- Exercise both dependencies and provides on a single Dependency in get_bom_with_provides fixture and update snapshots
- Update docs/schema-support.rst with provides schema support note

Signed-off-by: Saquib Saifee <saquibsaifee2@gmail.com>
@saquibsaifee
saquibsaifee force-pushed the feat-uzair-provides-7524676707032308925 branch from feefffe to b716f7c Compare November 7, 2026 00:16
@saquibsaifee

Copy link
Copy Markdown
Contributor Author

@jkowalleck applied the nits and pr is ready to be merged.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request schema 1.6

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: add cyclonedx.model.dependency.Dependency.provides

3 participants