mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Plugin meta detection improvements (#3516)
* refactor entrypoint into helpers * Add lookup by metadata This is geared towards plugins packaged in pkgs that differ in name from their top module * Make module lookup predictable in changing pkg-envs
This commit is contained in:
parent
4ae3cf9a9c
commit
1010a6296f
@ -7,6 +7,9 @@ import pkgutil
|
||||
import subprocess
|
||||
import sysconfig
|
||||
import traceback
|
||||
from importlib.metadata import (PackageNotFoundError, distributions,
|
||||
entry_points)
|
||||
from importlib.util import find_spec
|
||||
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
@ -92,6 +95,11 @@ def handle_error(error, do_raise: bool = True, do_log: bool = True, log_name: st
|
||||
if settings.TESTING_ENV and package_name != 'integration.broken_sample' and isinstance(error, IntegrityError):
|
||||
raise error # pragma: no cover
|
||||
raise IntegrationPluginError(package_name, str(error))
|
||||
|
||||
|
||||
def get_entrypoints():
|
||||
"""Returns list for entrypoints for InvenTree plugins."""
|
||||
return entry_points().get('inventree_plugins', [])
|
||||
# endregion
|
||||
|
||||
|
||||
@ -223,6 +231,34 @@ def get_plugins(pkg, baseclass, path=None):
|
||||
plugins.append(plugin)
|
||||
|
||||
return plugins
|
||||
|
||||
|
||||
def get_module_meta(mdl_name):
|
||||
"""Return distribution for module.
|
||||
|
||||
Modified form source: https://stackoverflow.com/a/60975978/17860466
|
||||
"""
|
||||
# Get spec for module
|
||||
spec = find_spec(mdl_name)
|
||||
|
||||
# Try to get specific package for the module
|
||||
result = None
|
||||
for dist in distributions():
|
||||
try:
|
||||
relative = pathlib.Path(spec.origin).relative_to(dist.locate_file(''))
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
if relative in dist.files:
|
||||
result = dist
|
||||
|
||||
# Check if a distribution was found
|
||||
# A no should not be possible here as a call can only be made on a discovered module but better save then sorry
|
||||
if not result:
|
||||
raise PackageNotFoundError(mdl_name)
|
||||
|
||||
# Return metadata
|
||||
return result.metadata
|
||||
# endregion
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@ import os
|
||||
import pathlib
|
||||
import warnings
|
||||
from datetime import datetime
|
||||
from importlib.metadata import metadata
|
||||
from importlib.metadata import PackageNotFoundError, metadata
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.utils import OperationalError, ProgrammingError
|
||||
@ -14,7 +14,7 @@ from django.urls.base import reverse
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from plugin.helpers import GitStatus, get_git_log
|
||||
from plugin.helpers import GitStatus, get_git_log, get_module_meta
|
||||
|
||||
logger = logging.getLogger("inventree")
|
||||
|
||||
@ -294,7 +294,13 @@ class InvenTreePlugin(MixinBase, MetaBase):
|
||||
@classmethod
|
||||
def _get_package_metadata(cls):
|
||||
"""Get package metadata for plugin."""
|
||||
meta = metadata(cls.__name__)
|
||||
|
||||
# Try simple metadata lookup
|
||||
try:
|
||||
meta = metadata(cls.__name__)
|
||||
# Simpel lookup did not work - get data from module
|
||||
except PackageNotFoundError:
|
||||
meta = get_module_meta(cls.__module__)
|
||||
|
||||
return {
|
||||
'author': meta['Author-email'],
|
||||
|
@ -8,7 +8,7 @@ import importlib
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
from importlib import metadata, reload
|
||||
from importlib import reload
|
||||
from pathlib import Path
|
||||
from typing import OrderedDict
|
||||
|
||||
@ -24,8 +24,8 @@ from maintenance_mode.core import (get_maintenance_mode, maintenance_mode_on,
|
||||
|
||||
from InvenTree.config import get_setting
|
||||
|
||||
from .helpers import (IntegrationPluginError, get_plugins, handle_error,
|
||||
log_error)
|
||||
from .helpers import (IntegrationPluginError, get_entrypoints, get_plugins,
|
||||
handle_error, log_error)
|
||||
from .plugin import InvenTreePlugin
|
||||
|
||||
logger = logging.getLogger('inventree')
|
||||
@ -266,7 +266,7 @@ class PluginsRegistry:
|
||||
# Check if not running in testing mode and apps should be loaded from hooks
|
||||
if (not settings.PLUGIN_TESTING) or (settings.PLUGIN_TESTING and settings.PLUGIN_TESTING_SETUP):
|
||||
# Collect plugins from setup entry points
|
||||
for entry in metadata.entry_points().get('inventree_plugins', []): # pragma: no cover
|
||||
for entry in get_entrypoints(): # pragma: no cover
|
||||
try:
|
||||
plugin = entry.load()
|
||||
plugin.is_package = True
|
||||
|
Loading…
Reference in New Issue
Block a user