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
This commit is contained in:
2026-08-28 18:25:31 -04:00
parent 2cfd0d2293
commit c6a99a95c2
19 changed files with 2134 additions and 21 deletions
+58
View File
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="e8b493d0-fcb6-4b7e-8e7e-246fffe8addd" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/AUTHORS" beforeDir="false" afterPath="$PROJECT_DIR$/AUTHORS" afterDir="false" />
<change beforePath="$PROJECT_DIR$/ChangeLog" beforeDir="false" afterPath="$PROJECT_DIR$/ChangeLog" afterDir="false" />
<change beforePath="$PROJECT_DIR$/aprsd_twitter_plugin/conf/twitter.py" beforeDir="false" afterPath="$PROJECT_DIR$/aprsd_twitter_plugin/conf/twitter.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/aprsd_twitter_plugin/twitter.py" beforeDir="false" afterPath="$PROJECT_DIR$/aprsd_twitter_plugin/twitter.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectId" id="1zPUKlWDSbiM3qLdoC8O65AHCve" />
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent">{
&quot;keyToString&quot;: {
&quot;dart.analysis.tool.window.visible&quot;: &quot;false&quot;,
&quot;last_opened_file_path&quot;: &quot;/Users/i530566/devel/mine/hamradio/aprsd-twitter-plugin&quot;
}
}</component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="e8b493d0-fcb6-4b7e-8e7e-246fffe8addd" name="Changes" comment="" />
<created>1634049154353</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1634049154353</updated>
</task>
<servers />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
</project>
+148
View File
@@ -0,0 +1,148 @@
Metadata-Version: 2.4
Name: aprsd_twitter_plugin
Version: 1.0.2.dev0+g9c3ee1586.d20260828
Summary: Python APRSD plugin to send tweets
Author: Walter A. Boring IV
Author-email: "Walter A. Boring IV" <waboring@hemna.com>
License: MIT
Classifier: License :: OSI Approved :: MIT License
Classifier: Topic :: Communications :: Ham Radio
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.11
Requires-Python: >=3.11
Description-Content-Type: text/x-rst
License-File: LICENSE
Requires-Dist: tweepy
Requires-Dist: oslo.config
Provides-Extra: dev
Requires-Dist: pip; extra == "dev"
Requires-Dist: pip-tools; extra == "dev"
Requires-Dist: wheel; extra == "dev"
Requires-Dist: watchdog; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: tox; extra == "dev"
Requires-Dist: tox-uv; extra == "dev"
Requires-Dist: coverage; extra == "dev"
Requires-Dist: Sphinx; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Requires-Dist: aprsd; extra == "dev"
Dynamic: license-file
Send tweet via Ham RADIO!
=========================
|PyPI| |Status| |Python Version| |License|
|Read the Docs| |Tests| |Codecov|
|pre-commit|
.. |PyPI| image:: https://img.shields.io/pypi/v/aprsd-twitter-plugin.svg
:target: https://pypi.org/project/aprsd-twitter-plugin/
:alt: PyPI
.. |Status| image:: https://img.shields.io/pypi/status/aprsd-twitter-plugin.svg
:target: https://pypi.org/project/aprsd-twitter-plugin/
:alt: Status
.. |Python Version| image:: https://img.shields.io/pypi/pyversions/aprsd-twitter-plugin
:target: https://pypi.org/project/aprsd-twitter-plugin
:alt: Python Version
.. |License| image:: https://img.shields.io/pypi/l/aprsd-twitter-plugin
:target: https://opensource.org/licenses/MIT
:alt: License
.. |Read the Docs| image:: https://img.shields.io/readthedocs/aprsd-twitter-plugin/latest.svg?label=Read%20the%20Docs
:target: https://aprsd-twitter-plugin.readthedocs.io/
:alt: Read the documentation at https://aprsd-twitter-plugin.readthedocs.io/
.. |Tests| image:: https://github.com/hemna/aprsd-twitter-plugin/workflows/Tests/badge.svg
:target: https://github.com/hemna/aprsd-twitter-plugin/actions?workflow=Tests
:alt: Tests
.. |Codecov| image:: https://codecov.io/gh/hemna/aprsd-twitter-plugin/branch/main/graph/badge.svg
:target: https://codecov.io/gh/hemna/aprsd-twitter-plugin
:alt: Codecov
.. |pre-commit| image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white
:target: https://github.com/pre-commit/pre-commit
:alt: pre-commit
Features
--------
* Sent a tweet from your personal twitter account!
* to tweet send a message of "t Hello World #aprs #hamradio"
Requirements
------------
* This plugin requires you have a twitter account and create a developer
account with:
* api key
* api key secret
* access token
* access token secret
Add the following entries to the aprsd.yml file
.. code:: yaml
services:
twitter:
apiKey: <your api key here>
apiKey_secret: <your api key secret here>
access_token: <your Twitter app access token>
access_token_secret: <your Twitter app access token secret>
Installation
------------
You can install *Send tweet via Ham RADIO!* via pip_ from PyPI_:
.. code:: console
$ pip install aprsd-twitter-plugin
Usage
-----
Please see the `Command-line Reference <Usage_>`_ for details.
Contributing
------------
Contributions are very welcome.
To learn more, see the `Contributor Guide`_.
License
-------
Distributed under the terms of the `MIT license`_,
*Send tweet via Ham RADIO!* is free and open source software.
Issues
------
If you encounter any problems,
please `file an issue`_ along with a detailed description.
Credits
-------
This project was generated from `@hemna`_'s `APRSD Plugin Python Cookiecutter`_ template.
.. _@hemna: https://github.com/hemna
.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _MIT license: https://opensource.org/licenses/MIT
.. _PyPI: https://pypi.org/
.. _APRSD Plugin Python Cookiecutter: https://github.com/hemna/cookiecutter-aprsd-plugin
.. _file an issue: https://github.com/hemna/aprsd-twitter-plugin/issues
.. _pip: https://pip.pypa.io/
.. github-only
.. _Contributor Guide: CONTRIBUTING.rst
.. _Usage: https://aprsd-twitter-plugin.readthedocs.io/en/latest/usage.html
+43
View File
@@ -0,0 +1,43 @@
.pre-commit-config.yaml
AUTHORS
ChangeLog
LICENSE
Makefile
README.rst
pyproject.toml
setup.cfg
setup.py
tox.ini
uv.lock
.github/FUNDING.yml
.idea/workspace.xml
aprsd_twitter_plugin/__init__.py
aprsd_twitter_plugin/cli.py
aprsd_twitter_plugin/twitter.py
aprsd_twitter_plugin.egg-info/PKG-INFO
aprsd_twitter_plugin.egg-info/SOURCES.txt
aprsd_twitter_plugin.egg-info/dependency_links.txt
aprsd_twitter_plugin.egg-info/entry_points.txt
aprsd_twitter_plugin.egg-info/requires.txt
aprsd_twitter_plugin.egg-info/scm_file_list.json
aprsd_twitter_plugin.egg-info/scm_version.json
aprsd_twitter_plugin.egg-info/top_level.txt
aprsd_twitter_plugin/__pycache__/__init__.cpython-313.pyc
aprsd_twitter_plugin/__pycache__/twitter.cpython-313.pyc
aprsd_twitter_plugin/conf/__init__.py
aprsd_twitter_plugin/conf/opts.py
aprsd_twitter_plugin/conf/twitter.py
aprsd_twitter_plugin/conf/__pycache__/__init__.cpython-313.pyc
aprsd_twitter_plugin/conf/__pycache__/twitter.cpython-313.pyc
docs/Makefile
docs/authors.rst
docs/clean_docs.py
docs/conf.py
docs/contributing.rst
docs/history.rst
docs/index.rst
docs/installation.rst
tests/__init__.py
tests/test_aprsd_twitter_plugin.py
tests/__pycache__/__init__.cpython-313.pyc
tests/__pycache__/test_aprsd_twitter_plugin.cpython-313-pytest-9.1.1.pyc
@@ -0,0 +1,8 @@
[console_scripts]
aprsd-twitter-plugin-export-config = aprsd_twitter_plugin.cli:main
[oslo.config.opts]
aprsd_twitter_plugin.conf = aprsd_twitter_plugin.conf.opts:list_opts
[oslo.config.opts.defaults]
aprsd_twitter_plugin.conf = aprsd_twitter_plugin.conf.opts:defaults
@@ -0,0 +1,16 @@
tweepy
oslo.config
[dev]
pip
pip-tools
wheel
watchdog
ruff
tox
tox-uv
coverage
Sphinx
twine
pytest
aprsd
@@ -0,0 +1,45 @@
{
"files": [
".github/FUNDING.yml",
".idea/workspace.xml",
".pre-commit-config.yaml",
"AUTHORS",
"ChangeLog",
"LICENSE",
"Makefile",
"README.rst",
"aprsd_twitter_plugin.egg-info/PKG-INFO",
"aprsd_twitter_plugin.egg-info/SOURCES.txt",
"aprsd_twitter_plugin.egg-info/dependency_links.txt",
"aprsd_twitter_plugin.egg-info/entry_points.txt",
"aprsd_twitter_plugin.egg-info/requires.txt",
"aprsd_twitter_plugin.egg-info/top_level.txt",
"aprsd_twitter_plugin/__init__.py",
"aprsd_twitter_plugin/__pycache__/__init__.cpython-313.pyc",
"aprsd_twitter_plugin/__pycache__/twitter.cpython-313.pyc",
"aprsd_twitter_plugin/cli.py",
"aprsd_twitter_plugin/conf/__init__.py",
"aprsd_twitter_plugin/conf/__pycache__/__init__.cpython-313.pyc",
"aprsd_twitter_plugin/conf/__pycache__/twitter.cpython-313.pyc",
"aprsd_twitter_plugin/conf/opts.py",
"aprsd_twitter_plugin/conf/twitter.py",
"aprsd_twitter_plugin/twitter.py",
"docs/Makefile",
"docs/authors.rst",
"docs/clean_docs.py",
"docs/conf.py",
"docs/contributing.rst",
"docs/history.rst",
"docs/index.rst",
"docs/installation.rst",
"pyproject.toml",
"setup.cfg",
"setup.py",
"tests/__init__.py",
"tests/__pycache__/__init__.cpython-313.pyc",
"tests/__pycache__/test_aprsd_twitter_plugin.cpython-313-pytest-9.1.1.pyc",
"tests/test_aprsd_twitter_plugin.py",
"tox.ini",
"uv.lock"
]
}
@@ -0,0 +1,8 @@
{
"tag": "1.0.1",
"distance": 0,
"node": "g9c3ee158646831f28dd34426eb6ea0d51fe20840",
"dirty": true,
"branch": "chore/setuptools-scm",
"node_date": "2026-01-27"
}
@@ -0,0 +1 @@
aprsd_twitter_plugin
+5 -14
View File
@@ -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"
+5 -7
View File
@@ -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
Binary file not shown.
+18
View File
@@ -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."""
Generated
+1779
View File
File diff suppressed because it is too large Load Diff