Addon Manager: Support setting min Python version

This commit is contained in:
Chris Hennes
2022-09-22 20:43:07 -05:00
parent 3937da0c46
commit 7bf7c45706
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: