Skip to content

Allow empty manifest, fixes #1197#1204

Merged
spoorcc merged 1 commit into
mainfrom
empty-manifest
May 14, 2026
Merged

Allow empty manifest, fixes #1197#1204
spoorcc merged 1 commit into
mainfrom
empty-manifest

Conversation

@spoorcc
Copy link
Copy Markdown
Contributor

@spoorcc spoorcc commented May 14, 2026

Summary by CodeRabbit

  • New Features

    • Manifests can now be created without a projects section, allowing dfetch add to bootstrap an empty manifest.
  • Documentation

    • Updated project setup guide with instructions for bootstrapping manifests from scratch.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Warning

Rate limit exceeded

@spoorcc has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 14 minutes and 50 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 545d7420-cf2d-4e04-ad0d-c83475b3e04f

📥 Commits

Reviewing files that changed from the base of the PR and between b2d9652 and 02d9eb8.

📒 Files selected for processing (11)
  • CHANGELOG.rst
  • dfetch/manifest/manifest.py
  • dfetch/manifest/schema.py
  • doc/howto/adding-a-project.rst
  • features/check-git-repo.feature
  • features/fetch-git-repo.feature
  • features/freeze-projects.feature
  • features/interactive-add.feature
  • features/report-sbom.feature
  • features/validate-manifest.feature
  • tests/test_manifest.py

Walkthrough

The PR enables dfetch manifests to omit the projects section entirely, allowing dfetch add to bootstrap from a minimal YAML containing only version. The Manifest class is hardened to handle missing projects gracefully throughout initialization, access, lookup, insertion, and updates.

Changes

Support empty manifests for bootstrapping

Layer / File(s) Summary
Schema contract: declare projects as optional
dfetch/manifest/schema.py
The MANIFEST_SCHEMA updates projects from required to optional by wrapping in Optional(...), allowing validation of manifests with no projects section.
Manifest initialization and core accessors
dfetch/manifest/manifest.py
Constructor and projects property use defensive .get() instead of direct indexing. Import list expanded to include CommentedSeq for dynamic YAML sequence creation when projects section is inserted.
Project lookup and removal
dfetch/manifest/manifest.py
_find_doc_project() and remove() switch to .get() calls; remove() raises RequestedProjectNotFoundError when projects section is absent instead of crashing.
Project insertion and version updates
dfetch/manifest/manifest.py
append_project_entry() creates the manifest["projects"] node as CommentedSeq when missing before appending. update_project_version() builds error lists from defensive .get() rather than assuming projects exist.
Unit test coverage for empty manifests
tests/test_manifest.py
test_no_projects updated to expect valid parsing with empty projects list. New comprehensive test suite covers append, dump, remove/update error handling, project selection, name uniqueness, and destination guessing on empty manifests.
Documentation and behavioral test scenarios
CHANGELOG.rst, doc/howto/adding-a-project.rst, features/*.feature
Changelog notes the feature, howto guide shows bootstrap workflow, and six feature files verify check, update, freeze, add -i, report, and validate commands all handle empty manifests correctly.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • dfetch-org/dfetch#1111: Prior refactor of Manifest class internals and append_project_entry logic that this PR builds upon.
  • dfetch-org/dfetch#922: Earlier change making MANIFEST_SCHEMA projects field optional, aligning validation contract with this PR's empty-manifest support.

Suggested labels

development, testing, documentation

Suggested reviewers

  • ben-edna
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Allow empty manifest, fixes #1197' directly summarizes the main change in the changeset, which enables manifests without a projects section.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch empty-manifest

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.

@spoorcc
Copy link
Copy Markdown
Contributor Author

spoorcc commented May 14, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
dfetch/manifest/manifest.py (1)

153-155: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Mark projects as NotRequired in the TypedDict.

The projects field is now optional in the schema and handled as potentially absent throughout the code, but the type hint still declares it as required. This creates a type inconsistency.

🔧 Proposed fix
 class ManifestDict(TypedDict, total=True):  # pylint: disable=too-many-ancestors
     """Serialized dict types."""
 
     version: int | str
     remotes: NotRequired[Sequence[RemoteDict | Remote]]
-    projects: Sequence[
+    projects: NotRequired[Sequence[
         ProjectEntryDict | ProjectEntry | dict[str, str | list[str] | dict[str, str]]
-    ]
+    ]]
🤖 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 `@dfetch/manifest/manifest.py` around lines 153 - 155, The TypedDict field
projects is currently declared as required but the schema treats it as optional;
change the projects annotation in the TypedDict to be
NotRequired[Sequence[ProjectEntryDict | ProjectEntry | dict[str, str | list[str]
| dict[str, str]]]] and add an import for NotRequired (from typing_extensions
for compatibility or typing on py3.11+), so the projects key is marked optional
in the TypedDict definition (update the TypedDict declaration and imports
accordingly and run typechecking).
🤖 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.

Outside diff comments:
In `@dfetch/manifest/manifest.py`:
- Around line 153-155: The TypedDict field projects is currently declared as
required but the schema treats it as optional; change the projects annotation in
the TypedDict to be NotRequired[Sequence[ProjectEntryDict | ProjectEntry |
dict[str, str | list[str] | dict[str, str]]]] and add an import for NotRequired
(from typing_extensions for compatibility or typing on py3.11+), so the projects
key is marked optional in the TypedDict definition (update the TypedDict
declaration and imports accordingly and run typechecking).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: d169122c-60f7-4e8b-a880-fe00ad5fd9aa

📥 Commits

Reviewing files that changed from the base of the PR and between 2011364 and b2d9652.

📒 Files selected for processing (11)
  • CHANGELOG.rst
  • dfetch/manifest/manifest.py
  • dfetch/manifest/schema.py
  • doc/howto/adding-a-project.rst
  • features/check-git-repo.feature
  • features/fetch-git-repo.feature
  • features/freeze-projects.feature
  • features/interactive-add.feature
  • features/report-sbom.feature
  • features/validate-manifest.feature
  • tests/test_manifest.py

@spoorcc spoorcc merged commit ed44443 into main May 14, 2026
36 checks passed
@spoorcc spoorcc deleted the empty-manifest branch May 14, 2026 10: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.

1 participant