Merge branch 'master' into master

This commit is contained in:
Hubhubhurra
2022-09-23 06:51:53 +02:00
committed by GitHub
2 changed files with 86 additions and 11 deletions

View File

@@ -116,6 +116,7 @@ class Addon:
self.internal_workbenches: Set[str] = set() # Required internal workbenches
self.python_required: Set[str] = set()
self.python_optional: Set[str] = set()
self.python_min_version = {"major": 3, "minor": 0}
class ResolutionFailed(RuntimeError):
"""An exception type for dependency resolution failure."""
@@ -168,13 +169,14 @@ class Addon:
self.installed_version = None
# Each repo is also a node in a directed dependency graph (referenced by name so
# they cen be serialized):
# they can be serialized):
self.requires: Set[str] = set()
self.blocks: Set[str] = set()
# And maintains a list of required and optional Python dependencies from metadata.txt
# And maintains a list of required and optional Python dependencies
self.python_requires: Set[str] = set()
self.python_optional: Set[str] = set()
self.python_min_version = {"major": 3, "minor": 0}
def __str__(self) -> str:
result = f"FreeCAD {self.repo_type}\n"
@@ -334,11 +336,50 @@ class Addon:
return
for dep in metadata.Depend:
# Simple version for now: eventually support all of the version params...
self.requires.add(dep["package"])
FreeCAD.Console.PrintLog(
f"Package {self.name}: Adding dependency on {dep['package']}\n"
)
if dep["package"].lower() == "python":
# We only support the "version_gte" attribute for Python itself
if "version_gte" in dep and "." in dep["version_gte"]:
split_version_string = dep["version_gte"].split(".")
if len(split_version_string) >= 2:
try:
self.python_min_version["major"] = int(
split_version_string[0]
)
self.python_min_version["minor"] = int(
split_version_string[1]
)
FreeCAD.Console.PrintLog(
f"Package {self.name}: Requires Python {split_version_string[0]}.{split_version_string[1]} or greater\n"
)
except ValueError:
FreeCAD.Console.PrintWarning(
f"Package {self.name}: Invalid Python version requirment specified\n"
)
elif "type" in dep:
if dep["type"] == "internal":
if dep["package"] in INTERNAL_WORKBENCHES:
self.requires.add(dep["package"])
else:
FreeCAD.Console.PrintWarning(
translate(
"AddonsInstaller",
"{}: Unrecognized internal workbench '{}'",
).format(self.name, dep["package"])
)
elif dep["type"] == "addon":
self.requires.add(dep["package"])
elif dep["type"] == "python":
if "optional" in dep and dep["optional"].lower() == "true":
self.python_optional.add(dep["package"])
else:
self.python_required.add(dep["package"])
else:
# Automatic resolution happens later, once we have a complete list of Addons
self.requires.add(dep["package"])
else:
# Automatic resolution happens later, once we have a complete list of Addons
self.requires.add(dep["package"])
for dep in metadata.Conflict:
self.blocks.add(dep["package"])
@@ -478,6 +519,17 @@ class Addon:
deps.python_required |= self.python_requires
deps.python_optional |= self.python_optional
deps.python_min_version["major"] = max(
deps.python_min_version["major"], self.python_min_version["major"]
)
if deps.python_min_version["major"] == 3:
deps.python_min_version["minor"] = max(
deps.python_min_version["minor"], self.python_min_version["minor"]
)
else:
FreeCAD.Console.PrintWarning("Unrecognized Python version information")
for dep in self.requires:
if dep in all_repos:
if not dep in deps.required_external_addons:

View File

@@ -28,6 +28,7 @@ import os
import functools
import shutil
import stat
import sys
import tempfile
import hashlib
import threading
@@ -128,10 +129,10 @@ class CommandAddonManager:
restart_required = False
def __init__(self):
#FreeCADGui.addPreferencePage(
# FreeCADGui.addPreferencePage(
# os.path.join(os.path.dirname(__file__), "AddonManagerOptions.ui"),
# translate("AddonsInstaller", "Addon Manager"),
#)
# )
FreeCADGui.addPreferencePage(
AddonManagerOptions,
translate("AddonsInstaller", "Addon Manager"),
@@ -374,7 +375,7 @@ class CommandAddonManager:
self.dialog.buttonDevTools.hide()
# Only shown if there are available Python package updates
#self.dialog.buttonUpdateDependencies.hide()
# self.dialog.buttonUpdateDependencies.hide()
# connect slots
self.dialog.rejected.connect(self.reject)
@@ -934,7 +935,9 @@ class CommandAddonManager:
def show_python_updates_dialog(self) -> None:
if not hasattr(self, "manage_python_packages_dialog"):
self.manage_python_packages_dialog = PythonPackageManager(self.item_model.repos)
self.manage_python_packages_dialog = PythonPackageManager(
self.item_model.repos
)
self.manage_python_packages_dialog.show()
def show_developer_tools(self) -> None:
@@ -1077,6 +1080,7 @@ class CommandAddonManager:
self.wbs.append(dep)
# Check the Python dependencies:
self.python_min_version = deps.python_min_version
self.python_required = []
for py_dep in deps.python_required:
if py_dep not in self.python_required:
@@ -1250,6 +1254,25 @@ class CommandAddonManager:
if self.handle_disallowed_python(missing.python_required):
return
# For now only look at the minor version, since major is always Python 3
minor_required = missing.python_min_version["minor"]
if sys.version_info.minor < minor_required:
QtWidgets.QMessageBox.critical(
self.dialog,
translate("AddonsInstaller", "Incompatible Python version"),
translate(
"AddonsInstaller",
"This Addon (or one if its dependencies) requires Python {}.{}, and your system is running {}.{}. Installation cancelled.",
).format(
missing.python_min_version["major"],
missing.python_min_version["minor"],
sys.version_info.major,
sys.version_info.minor,
),
QtWidgets.QMessageBox.Cancel,
)
return
good_packages = []
for dep in missing.python_optional:
if dep in self.allowed_packages: