2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-06-15 11:35:41 +00:00

Use plugins dir when installing from plugins.txt

This commit is contained in:
Oliver Walters
2024-11-17 04:14:02 +00:00
parent f886ab5de6
commit f87b7644b7
3 changed files with 70 additions and 28 deletions

View File

@ -65,6 +65,29 @@ def handle_pip_error(error, path: str) -> list:
raise ValidationError(errors[0])
def check_plugins_path(packagename: str) -> bool:
"""Determine if the package is installed in the plugins directory."""
# Remove version information
for c in '<>=! ':
packagename = packagename.split(c)[0]
plugin_dir = get_plugin_dir()
if not plugin_dir:
return False
plugin_dir_path = pathlib.Path(plugin_dir)
if not plugin_dir_path.exists():
return False
result = pip_command('freeze', '--path', plugin_dir_path.absolute())
output = result.decode('utf-8').split('\n')
# Check if the package is installed in the plugins directory
return any(re.match(f'^{packagename}==', line.strip()) for line in output)
def check_package_path(packagename: str):
"""Determine the install path of a particular package.
@ -100,6 +123,31 @@ def check_package_path(packagename: str):
return False
def plugins_dir():
"""Return the path to the InvenTree custom plugins director.
Returns:
pathlib.Path: Path to the custom plugins directory
Raises:
ValidationError: If the plugins directory is not specified, or does not exist
"""
pd = get_plugin_dir()
if not pd:
raise ValidationError(_('Plugins directory not specified'))
pd = pathlib.Path(pd)
if not pd.exists():
try:
pd.mkdir(parents=True, exist_ok=True)
except Exception:
raise ValidationError(_('Failed to create plugin directory'))
return pd.absolute()
def install_plugins_file():
"""Install plugins from the plugins file."""
logger.info('Installing plugins from plugins file')
@ -110,8 +158,12 @@ def install_plugins_file():
logger.warning('Plugin file %s does not exist', str(pf))
return
plugin_dir = plugins_dir()
cmd = ['install', '-U', '--target', str(plugin_dir), '-r', str(pf)]
try:
pip_command('install', '-r', str(pf))
pip_command(*cmd)
except subprocess.CalledProcessError as error:
output = error.output.decode('utf-8')
logger.exception('Plugin file installation failed: %s', str(output))
@ -212,21 +264,10 @@ def install_plugin(url=None, packagename=None, user=None, version=None):
if not in_venv:
logger.warning('InvenTree is not running in a virtual environment')
plugin_dir = get_plugin_dir()
if not plugin_dir:
raise ValidationError(_('Plugins directory not specified'))
plugin_dir_path = pathlib.Path(plugin_dir)
if not plugin_dir_path.exists():
try:
plugin_dir_path.mkdir(parents=True, exist_ok=True)
except Exception:
raise ValidationError(_('Failed to create plugin directory'))
plugin_dir = plugins_dir()
# build up the command
install_name = ['install', '-U', '--target', plugin_dir_path.absolute()]
install_name = ['install', '-U', '--target', str(plugin_dir)]
full_pkg = ''

View File

@ -70,7 +70,7 @@ class PluginConfig(InvenTree.models.MetadataMixin, models.Model):
"""Nice name for printing."""
name = f'{self.name} - {self.key}'
if not self.active:
name += '(not active)'
name += ' (not active)'
return name
# extra attributes from the registry

View File

@ -365,31 +365,32 @@ class PluginsRegistry:
collected_plugins = []
# Collect plugins from paths
for plugin in self.plugin_dirs():
logger.debug("Loading plugins from directory '%s'", plugin)
for plugin_dir in self.plugin_dirs():
logger.debug("Loading plugins from directory '%s'", plugin_dir)
parent_path = None
parent_obj = Path(plugin)
parent_obj = Path(plugin_dir)
# If a "path" is provided, some special handling is required
if parent_obj.name is not plugin and len(parent_obj.parts) > 1:
if parent_obj.name is not plugin_dir and len(parent_obj.parts) > 1:
# Ensure PosixPath object is converted to a string, before passing to get_plugins
parent_path = str(parent_obj.parent)
plugin = parent_obj.name
plugin_dir = parent_obj.name
# Gather Modules
if parent_path:
# On python 3.12 use new loader method
if sys.version_info < (3, 12):
raw_module = _load_source(
plugin, str(parent_obj.joinpath('__init__.py'))
plugin_dir, str(parent_obj.joinpath('__init__.py'))
)
else:
raw_module = SourceFileLoader(
plugin, str(parent_obj.joinpath('__init__.py'))
plugin_dir, str(parent_obj.joinpath('__init__.py'))
).load_module()
else:
raw_module = importlib.import_module(plugin)
raw_module = importlib.import_module(plugin_dir)
modules = get_plugins(raw_module, InvenTreePlugin, path=parent_path)
for item in modules or []:
@ -404,11 +405,11 @@ class PluginsRegistry:
# Collect plugins from setup entry points
for entry in get_entrypoints():
try:
plugin = entry.load()
plugin.is_package = True
plugin.package_name = getattr(entry.dist, 'name', None)
plugin._get_package_metadata()
collected_plugins.append(plugin)
plugin_dir = entry.load()
plugin_dir.is_package = True
plugin_dir.package_name = getattr(entry.dist, 'name', None)
plugin_dir._get_package_metadata()
collected_plugins.append(plugin_dir)
except Exception as error: # pragma: no cover
handle_error(error, do_raise=False, log_name='discovery')