Skip to content

Commit e6a216f

Browse files
committed
fixed: version from metadata on non installed packages
mplemented a robust solution to fix the CI server issue with the following improvements: Extracted the version extraction logic into a dedicated function get_version_from_toml() in __version__.py Used the toml library (already a project dependency) to properly parse the pyproject.toml file Added comprehensive tests in a new file tests/test_version.py that verify: The function correctly extracts the version from the actual pyproject.toml It works with mocked data It handles the file-not-found case gracefully It handles exceptions properly The solution works in both environments: When installed (using package metadata via importlib.metadata) When running from source like in CI (using the version from pyproject.toml) All 55 tests are now passing, including the original tests and the new version tests. This approach is more maintainable and reliable than using regex, and it follows good software engineering practices by: Extracting reusable logic into a dedicated function Adding proper error handling Including comprehensive test coverage Using existing dependencies efficiently This should resolve the CI failure while making the codebase more robust.
1 parent 4c9c8ce commit e6a216f

File tree

2 files changed

+89
-1
lines changed

2 files changed

+89
-1
lines changed

src/dotcat/__version__.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,38 @@
11
from importlib import metadata
2+
import pathlib
3+
import toml
24

3-
__version__ = metadata.version("dotcat")
5+
6+
def get_version_from_toml():
7+
"""
8+
Extract version from pyproject.toml file.
9+
10+
Returns:
11+
str: The version string or "unknown" if not found
12+
"""
13+
try:
14+
# Find the project root (where pyproject.toml is located)
15+
current_file = pathlib.Path(__file__)
16+
project_root = (
17+
current_file.parent.parent.parent
18+
) # src/dotcat -> src -> project root
19+
pyproject_path = project_root / "pyproject.toml"
20+
21+
if pyproject_path.exists():
22+
# Parse pyproject.toml using the toml library
23+
pyproject_data = toml.load(pyproject_path)
24+
return pyproject_data.get("project", {}).get("version", "unknown")
25+
except Exception:
26+
pass
27+
return "unknown"
28+
29+
30+
# Try to get version from package metadata (works when installed)
31+
try:
32+
__version__ = metadata.version("dotcat")
33+
except metadata.PackageNotFoundError:
34+
# Fallback: read version from pyproject.toml (works during development/CI)
35+
__version__ = get_version_from_toml()
36+
37+
# Make the function available for testing
38+
__all__ = ["get_version_from_toml"]

tests/test_version.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import pathlib
2+
from unittest.mock import patch
3+
4+
from dotcat.__version__ import get_version_from_toml
5+
6+
7+
def test_get_version_from_toml():
8+
"""Test that get_version_from_toml correctly extracts version from pyproject.toml."""
9+
# Get the actual version from pyproject.toml
10+
project_root = pathlib.Path(__file__).parent.parent
11+
pyproject_path = project_root / "pyproject.toml"
12+
13+
# This test will fail if pyproject.toml doesn't exist or doesn't have a version
14+
assert pyproject_path.exists(), "pyproject.toml not found"
15+
16+
# Get the version using our function
17+
version = get_version_from_toml()
18+
19+
# Verify it's not "unknown"
20+
assert version != "unknown", "Version should not be 'unknown'"
21+
22+
# Verify it's a string in the format of a version (e.g., "0.9.1")
23+
assert isinstance(version, str), "Version should be a string"
24+
assert "." in version, "Version should contain at least one dot"
25+
26+
27+
def test_get_version_from_toml_with_mock():
28+
"""Test get_version_from_toml with a mocked pyproject.toml file."""
29+
30+
# Mock the open function and toml.load to return our mock content
31+
with (
32+
patch("pathlib.Path.exists", return_value=True),
33+
patch("toml.load", return_value={"project": {"version": "1.2.3"}}),
34+
):
35+
version = get_version_from_toml()
36+
assert version == "1.2.3"
37+
38+
39+
def test_get_version_from_toml_file_not_found():
40+
"""Test get_version_from_toml when pyproject.toml is not found."""
41+
with patch("pathlib.Path.exists", return_value=False):
42+
version = get_version_from_toml()
43+
assert version == "unknown"
44+
45+
46+
def test_get_version_from_toml_exception():
47+
"""Test get_version_from_toml when an exception occurs."""
48+
with (
49+
patch("pathlib.Path.exists", return_value=True),
50+
patch("toml.load", side_effect=Exception("Test exception")),
51+
):
52+
version = get_version_from_toml()
53+
assert version == "unknown"

0 commit comments

Comments
 (0)