From fe057591ac70682299c468a6d9f942d85aeea7d3 Mon Sep 17 00:00:00 2001 From: Walter Boring Date: Fri, 28 Aug 2026 18:25:31 -0400 Subject: [PATCH] chore: migrate from pbr to setuptools-scm for dynamic versioning Replace pbr with setuptools-scm so the package version is derived from git tags (e.g. v0.5.0 -> 0.5.0) rather than a hardcoded '0.0.0'. Changes: - [build-system] requires: swap pbr for setuptools-scm - [project]: remove static version = '0.0.0', add dynamic = ['version'] - [tool.pbr]: replace with [tool.setuptools_scm] - __init__.py: replace pbr.version.VersionInfo with importlib.metadata.version() The latest tag is v0.5.0 so new builds will report 0.5.0 (or 0.5.0.devN+gHASH for untagged commits). Closes #3 --- aprsd_twitter_plugin/__init__.py | 19 +++++-------------- pyproject.toml | 12 +++++------- tests/test_aprsd_twitter_plugin.py | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/aprsd_twitter_plugin/__init__.py b/aprsd_twitter_plugin/__init__.py index 63f1e41..f331c23 100644 --- a/aprsd_twitter_plugin/__init__.py +++ b/aprsd_twitter_plugin/__init__.py @@ -1,15 +1,6 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. +from importlib.metadata import PackageNotFoundError, version -import pbr.version - -__version__ = pbr.version.VersionInfo("aprsd_twitter_plugin").version_string() +try: + __version__ = version("aprsd_twitter_plugin") +except PackageNotFoundError: + __version__ = "unknown" diff --git a/pyproject.toml b/pyproject.toml index 51ec6bf..04003d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,10 @@ [build-system] -requires = ["setuptools>=61.0", "wheel", "pbr"] +requires = ["setuptools>=61.0", "wheel", "setuptools-scm"] build-backend = "setuptools.build_meta" [project] name = "aprsd_twitter_plugin" -version = "0.0.0" # Version managed by pbr +dynamic = ["version"] description = "Python APRSD plugin to send tweets" readme = "README.rst" requires-python = ">=3.11" @@ -20,7 +20,6 @@ classifiers = [ "Programming Language :: Python :: 3.11", ] dependencies = [ - "pbr", "tweepy", "oslo.config", ] @@ -29,7 +28,6 @@ dependencies = [ dev = [ "pip", "pip-tools", - "bump2version", "wheel", "watchdog", "ruff", @@ -39,7 +37,7 @@ dev = [ "Sphinx", "twine", "pytest", - "gray", + "aprsd", ] [tool.setuptools] @@ -57,8 +55,8 @@ packages = ["aprsd_twitter_plugin"] [project.scripts] "aprsd-twitter-plugin-export-config" = "aprsd_twitter_plugin.cli:main" -[tool.pbr] -# PBR configuration +[tool.setuptools_scm] +# version is derived from git tags (e.g. v1.0.0 -> 1.0.0) [tool.mypy] ignore_missing_imports = true diff --git a/tests/test_aprsd_twitter_plugin.py b/tests/test_aprsd_twitter_plugin.py index eccccd2..f01e613 100644 --- a/tests/test_aprsd_twitter_plugin.py +++ b/tests/test_aprsd_twitter_plugin.py @@ -6,9 +6,27 @@ from unittest.mock import MagicMock, patch import pytest +import aprsd_twitter_plugin from aprsd_twitter_plugin.twitter import SendTweetPlugin +class TestVersion: + """Tests for package version metadata.""" + + def test_version_is_set(self): + """__version__ must be a non-empty string.""" + assert isinstance(aprsd_twitter_plugin.__version__, str) + assert len(aprsd_twitter_plugin.__version__) > 0 + + def test_version_not_unknown(self): + """Version must not be 'unknown' when installed via pip install -e .""" + # When installed with setuptools-scm and a git tag the version is + # derived from the tag. 'unknown' means the package could not be found + # in the metadata at all — that should never happen for an editable + # install. + assert aprsd_twitter_plugin.__version__ != "unknown" + + @pytest.fixture def mock_conf(): """Create a mock configuration object."""