Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Release 0.14.0 (unreleased)
* Add new ``remove`` command to remove projects from manifest and disk (#26)
* Fix "unsafe symlink target" error for archives containing relative ``..`` symlinks (#1122)
* Fix ``dfetch add`` crashing with a ``ValueError`` when the remote URL has a trailing slash (#1137)
* Fix unhelpful message when a metadata file (#1145)
Comment thread
spoorcc marked this conversation as resolved.
Outdated

Release 0.13.0 (released 2026-03-30)
====================================
Expand Down
6 changes: 5 additions & 1 deletion dfetch/project/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ def from_project_entry(cls, project: ProjectEntry) -> "Metadata":
def from_file(cls, path: str) -> "Metadata":
"""Load metadata file."""
with open(path, encoding="utf-8") as metadata_file:
data: Options = yaml.safe_load(metadata_file)["dfetch"]
try:
data: Options = yaml.safe_load(metadata_file)["dfetch"]
except yaml.YAMLError as exc:
raise ValueError(str(exc)) from exc
Comment thread
spoorcc marked this conversation as resolved.
Outdated

return cls(data)
Comment thread
coderabbitai[bot] marked this conversation as resolved.

def fetched(
Expand Down
4 changes: 2 additions & 2 deletions dfetch/project/subproject.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ def on_disk_version(self) -> Version | None:

try:
return Metadata.from_file(self.__metadata.path).version
except TypeError:
except (TypeError, ValueError):
logger.print_warning_line(
self.__project.name,
f"{pathlib.Path(self.__metadata.path).relative_to(os.getcwd()).as_posix()}"
Expand All @@ -367,7 +367,7 @@ def _on_disk_hash(self) -> str | None:

try:
return Metadata.from_file(self.__metadata.path).hash
except TypeError:
except (TypeError, ValueError):
logger.print_warning_line(
self.__project.name,
f"{pathlib.Path(self.__metadata.path).relative_to(os.getcwd()).as_posix()}"
Expand Down
24 changes: 24 additions & 0 deletions features/handle-invalid-metadata.feature
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,30 @@ Feature: Handle invalid metadata files
to unpredictable behavior in *DFetch*.
For instance, the metadata may be invalid

Scenario: Metadata with invalid YAML syntax is treated as invalid
Given the manifest 'dfetch.yaml'
"""
manifest:
version: '0.0'

projects:
- name: ext/test-repo-tag
url: https://github.com/dfetch-org/test-repo
tag: v1

"""
And all projects are updated
And the metadata file ".dfetch_data.yaml" of "ext/test-repo-tag" has invalid yaml
When I run "dfetch update"
Then the output shows
"""
Dfetch (0.13.0)
ext/test-repo-tag:
> ext/test-repo-tag/.dfetch_data.yaml is an invalid metadata file, not checking on disk version!
> ext/test-repo-tag/.dfetch_data.yaml is an invalid metadata file, not checking local hash!
> Fetched v1
"""
Comment thread
coderabbitai[bot] marked this conversation as resolved.

Scenario: Invalid metadata is ignored
Given the manifest 'dfetch.yaml'
"""
Expand Down
8 changes: 8 additions & 0 deletions features/steps/generic_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,14 @@ def step_impl(_, metadata_file, project_path):
)


@given('the metadata file "{metadata_file}" of "{project_path}" has invalid yaml')
def step_impl(_, metadata_file, project_path):
generate_file(
os.path.join(os.getcwd(), project_path, metadata_file),
"key: [unclosed bracket\n",
)


@given('the metadata file "{metadata_file}" of "{project_path}" is changed')
def step_impl(_, metadata_file, project_path):
extend_file(
Expand Down
Loading