forked from bitcoinafterlife/bal-electrum-plugin
v0.6.1: read version from manifest.json (single source of truth)
Read the plugin version at runtime from bal/manifest.json via importlib.resources (zip-safe, works from inside a zip on Windows). Removes the four-file duplication (VERSION, __init__.py, plugin_base.py, manifest.json) and deletes the bal/VERSION file. - bal/core/plugin_base.py: new get_version() function, BalPlugin.version is now a @property, removed hardcoded __version__ - bal/__init__.py: removed __version__, replaced with a comment - bal/core/willexecutors.py: user-agent uses get_version() - bal/gui/qt/dialogs.py, widgets.py: call sites use .version property - tests/test_version_source.py: 7 tests incl. zip-safe subprocess check - HANDOFF.md: updated to single-source-of-truth documentation - CHANGELOG.md: entries 43-46 - bal/manifest.json: version bumped to 0.6.1 PR #4 (branch bitcoinafterlife-patch-5).
This commit is contained in:
@@ -21,6 +21,7 @@ serialised together with the wallet file.
|
||||
This module performs **no** GUI work and imports nothing from PyQt / electrum.gui.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import platform
|
||||
from datetime import date, datetime, timedelta
|
||||
@@ -33,6 +34,45 @@ from electrum.transaction import tx_from_any
|
||||
_logger = get_logger(__name__)
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Plugin version - single source of truth
|
||||
# --------------------------------------------------------------------------- #
|
||||
# The version lives ONLY in bal/manifest.json (the file Electrum itself reads).
|
||||
# We used to hardcode it in four files and keep them in sync with a pre-commit
|
||||
# hook; reading it from the manifest removes that duplication.
|
||||
#
|
||||
# importlib.resources is used on purpose: it reads a data file bundled inside
|
||||
# the ``bal`` package and works identically whether the plugin runs from an
|
||||
# extracted directory or from INSIDE a zip (Electrum loads external plugins via
|
||||
# zipimport). It never builds a path by hand, so there is no os.path.join
|
||||
# backslash issue on Windows inside a zip.
|
||||
_VERSION_CACHE = None
|
||||
|
||||
|
||||
def get_version():
|
||||
"""Return the plugin version from ``bal/manifest.json`` (cached).
|
||||
|
||||
Zip-safe and independent of the current working directory. Falls back to
|
||||
``"unknown"`` if the manifest cannot be read, so importing the plugin never
|
||||
fails just because of version lookup.
|
||||
"""
|
||||
global _VERSION_CACHE
|
||||
if _VERSION_CACHE is None:
|
||||
try:
|
||||
import importlib.resources
|
||||
|
||||
data = (
|
||||
importlib.resources.files("bal")
|
||||
.joinpath("manifest.json")
|
||||
.read_text(encoding="utf-8")
|
||||
)
|
||||
_VERSION_CACHE = json.loads(data)["version"]
|
||||
except Exception as e: # noqa: BLE001 - never break import over version
|
||||
_logger.error(f"failed to read version from manifest.json: {e}")
|
||||
_VERSION_CACHE = "unknown"
|
||||
return _VERSION_CACHE
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# Wallet-DB registration
|
||||
# --------------------------------------------------------------------------- #
|
||||
@@ -120,9 +160,6 @@ class BalPlugin(BasePlugin):
|
||||
layer (or unit tests) can use the plugin logic without importing Qt.
|
||||
"""
|
||||
|
||||
_version = None
|
||||
__version__ = "0.5.18" # AUTOMATICALLY GENERATED DO NOT EDIT
|
||||
|
||||
# Command used to open an .ics calendar file, per operating system.
|
||||
default_app = {
|
||||
"Linux": "xdg-open",
|
||||
@@ -138,18 +175,11 @@ class BalPlugin(BasePlugin):
|
||||
# Default geometry hint for some dialogs (kept from the original code).
|
||||
SIZE = (159, 97)
|
||||
|
||||
@property
|
||||
def version(self):
|
||||
"""Return the plugin version, read once from the ``VERSION`` file."""
|
||||
if not self._version:
|
||||
try:
|
||||
f = ""
|
||||
with open("{}/VERSION".format(self.plugin_dir), "r") as fi:
|
||||
f = str(fi.read())
|
||||
self._version = f.strip()
|
||||
except Exception as e:
|
||||
_logger.error(f"failed to get version: {e}")
|
||||
self._version = "unknown"
|
||||
return self._version
|
||||
"""Plugin version, read from ``bal/manifest.json`` (single source of
|
||||
truth). See :func:`get_version`."""
|
||||
return get_version()
|
||||
|
||||
def __init__(self, parent, config, name):
|
||||
self.logger = get_logger(__name__)
|
||||
|
||||
Reference in New Issue
Block a user