mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Optimisations for editable installs of plugins (#3634)
* out-of-scope: add function to check if a package is editable * out-of-scope: move to included meta toolset for metadata discovery * out-of-scope: make lookup safe for editable installs
This commit is contained in:
parent
2601cf0279
commit
abf133384b
@ -7,9 +7,7 @@ import pkgutil
|
||||
import subprocess
|
||||
import sysconfig
|
||||
import traceback
|
||||
from importlib.metadata import (PackageNotFoundError, distributions,
|
||||
entry_points)
|
||||
from importlib.util import find_spec
|
||||
from importlib.metadata import entry_points
|
||||
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
@ -71,18 +69,21 @@ def handle_error(error, do_raise: bool = True, do_log: bool = True, log_name: st
|
||||
package_name = pathlib.Path(package_path).relative_to(install_path).parts[0]
|
||||
except ValueError:
|
||||
# is file - loaded -> form a name for that
|
||||
path_obj = pathlib.Path(package_path).relative_to(settings.BASE_DIR)
|
||||
path_parts = [*path_obj.parts]
|
||||
path_parts[-1] = path_parts[-1].replace(path_obj.suffix, '') # remove suffix
|
||||
try:
|
||||
path_obj = pathlib.Path(package_path).relative_to(settings.BASE_DIR)
|
||||
path_parts = [*path_obj.parts]
|
||||
path_parts[-1] = path_parts[-1].replace(path_obj.suffix, '') # remove suffix
|
||||
|
||||
# remove path prefixes
|
||||
if path_parts[0] == 'plugin':
|
||||
path_parts.remove('plugin')
|
||||
path_parts.pop(0)
|
||||
else:
|
||||
path_parts.remove('plugins') # pragma: no cover
|
||||
# remove path prefixes
|
||||
if path_parts[0] == 'plugin':
|
||||
path_parts.remove('plugin')
|
||||
path_parts.pop(0)
|
||||
else:
|
||||
path_parts.remove('plugins') # pragma: no cover
|
||||
|
||||
package_name = '.'.join(path_parts)
|
||||
package_name = '.'.join(path_parts)
|
||||
except Exception:
|
||||
package_name = package_path
|
||||
|
||||
if do_log:
|
||||
log_kwargs = {}
|
||||
@ -231,37 +232,6 @@ 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)
|
||||
|
||||
if not spec: # pragma: no cover
|
||||
raise PackageNotFoundError(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: # pragma: no cover
|
||||
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: # pragma: no cover
|
||||
raise PackageNotFoundError(mdl_name)
|
||||
|
||||
# Return metadata
|
||||
return result.metadata
|
||||
# endregion
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@ import inspect
|
||||
import logging
|
||||
import warnings
|
||||
from datetime import datetime
|
||||
from distutils.sysconfig import get_python_lib
|
||||
from importlib.metadata import PackageNotFoundError, metadata
|
||||
from pathlib import Path
|
||||
|
||||
@ -13,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, get_module_meta
|
||||
from plugin.helpers import GitStatus, get_git_log
|
||||
|
||||
logger = logging.getLogger("inventree")
|
||||
|
||||
@ -325,6 +326,13 @@ class InvenTreePlugin(VersionMixin, MixinBase, MetaBase):
|
||||
"""Get last git commit for the plugin."""
|
||||
return get_git_log(str(self.file()))
|
||||
|
||||
@classmethod
|
||||
def is_editable(cls):
|
||||
"""Returns if the current part is editable."""
|
||||
pkg_name = cls.__name__.split('.')[0]
|
||||
dist_info = list(Path(get_python_lib()).glob(f'{pkg_name}-*.dist-info'))
|
||||
return bool(len(dist_info) == 1)
|
||||
|
||||
@classmethod
|
||||
def _get_package_metadata(cls):
|
||||
"""Get package metadata for plugin."""
|
||||
@ -334,7 +342,7 @@ class InvenTreePlugin(VersionMixin, MixinBase, MetaBase):
|
||||
meta = metadata(cls.__name__)
|
||||
# Simpel lookup did not work - get data from module
|
||||
except PackageNotFoundError:
|
||||
meta = get_module_meta(cls.__module__)
|
||||
meta = metadata(cls.__module__.split('.')[0])
|
||||
|
||||
return {
|
||||
'author': meta['Author-email'],
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from .helpers import get_module_meta, render_template
|
||||
from .helpers import render_template
|
||||
|
||||
|
||||
class HelperTests(TestCase):
|
||||
@ -21,15 +21,3 @@ class HelperTests(TestCase):
|
||||
response = render_template(ErrorSource(), 'sample/wrongsample.html', {'abc': 123})
|
||||
self.assertTrue('lert alert-block alert-danger' in response)
|
||||
self.assertTrue('Template file <em>sample/wrongsample.html</em>' in response)
|
||||
|
||||
def test_get_module_meta(self):
|
||||
"""Test for get_module_meta."""
|
||||
|
||||
# We need a stable, known good that will be in enviroment for sure
|
||||
# and it can't be stdlib because does might differ depending on the abstraction layer
|
||||
# and version
|
||||
meta = get_module_meta('django')
|
||||
|
||||
# Lets just hope they do not change the name or author
|
||||
self.assertEqual(meta['Name'], 'Django')
|
||||
self.assertEqual(meta['Author'], 'Django Software Foundation')
|
||||
|
Loading…
Reference in New Issue
Block a user