Skip to content

Commit

Permalink
fix: more robust determination of the app version
Browse files Browse the repository at this point in the history
Instead of default to the installed metadata, first try to use the app's
main package (via the standard __version__ attribute), *then* fallback
to importlib.metadata, *then* fallback to "dev".

Fixes #90
  • Loading branch information
tigarmo committed Oct 5, 2023
1 parent bc0ea79 commit c4f2419
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
16 changes: 15 additions & 1 deletion craft_application/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import argparse
import functools
import importlib
import os
import pathlib
import signal
Expand Down Expand Up @@ -67,7 +68,20 @@ class AppMetadata:

def __post_init__(self) -> None:
setter = super().__setattr__
setter("version", metadata.version(self.name))

# Try to determine the app version.
try:
# First, via the __version__ attribute on the app's main package.
version = importlib.import_module(self.name).__version__
except (AttributeError, ModuleNotFoundError):
try:
# If that fails, try via the installed metadata.
version = metadata.version(self.name)
except metadata.PackageNotFoundError:
# If that fails too, default to "dev".
version = "dev"

setter("version", version)
if self.summary is None:
md = metadata.metadata(self.name)
setter("summary", md["summary"])
Expand Down
27 changes: 27 additions & 0 deletions tests/unit/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# with this program. If not, see <http://www.gnu.org/licenses/>.
"""Unit tests for craft-application app classes."""
import argparse
import importlib
import importlib.metadata
import pathlib
import re
import subprocess
Expand Down Expand Up @@ -46,6 +48,31 @@ def test_app_metadata_post_init_correct(summary):
pytest_check.is_not_none(app.summary)


def test_app_metadata_version_attribute(tmp_path, monkeypatch):
"""Set the AppMetadata version from the main app package."""
monkeypatch.syspath_prepend(tmp_path)
(tmp_path / "dummycraft_version.py").write_text("__version__ = '1.2.3'")

app = application.AppMetadata(name="dummycraft_version", summary="dummy craft")
assert app.version == "1.2.3"


def test_app_metadata_importlib(tmp_path, monkeypatch, mocker):
"""Set the AppMetadata version via importlib."""
monkeypatch.syspath_prepend(tmp_path)
(tmp_path / "dummycraft_importlib.py").write_text("print('hi')")

mocker.patch.object(importlib.metadata, "version", return_value="4.5.6")

app = application.AppMetadata(name="dummycraft_importlib", summary="dummy craft")
assert app.version == "4.5.6"


def test_app_metadata_dev():
app = application.AppMetadata(name="dummycraft_dev", summary="dummy craft")
assert app.version == "dev"


@pytest.fixture()
def app(app_metadata, fake_services):
return application.Application(app_metadata, fake_services)
Expand Down

0 comments on commit c4f2419

Please sign in to comment.