Extensions: use the TOML manifest as a source for extensions bl_info

This commit is contained in:
Campbell Barton 2024-01-25 13:56:36 +11:00
parent b686f2a536
commit 8841990764

@ -83,6 +83,10 @@ def _fake_module(mod_name, mod_path, speedy=True, force_support=None):
if _bpy.app.debug_python:
print("fake_module", mod_path, mod_name)
if mod_name.startswith(_ext_base_pkg_idname_with_dot):
return _fake_module_from_extension(mod_name, mod_path, force_support=force_support)
import ast
ModuleType = type(ast)
try:
@ -562,21 +566,25 @@ def _blender_manual_url_prefix():
return "https://docs.blender.org/manual/%s/%d.%d" % (_bpy.utils.manual_language_code(), *_bpy.app.version[:2])
def _bl_info_basis():
return {
"name": "",
"author": "",
"version": (),
"blender": (),
"location": "",
"description": "",
"doc_url": "",
"support": 'COMMUNITY',
"category": "",
"warning": "",
"show_expanded": False,
}
def module_bl_info(mod, *, info_basis=None):
if info_basis is None:
info_basis = {
"name": "",
"author": "",
"version": (),
"blender": (),
"location": "",
"description": "",
"doc_url": "",
"support": 'COMMUNITY',
"category": "",
"warning": "",
"show_expanded": False,
}
info_basis = _bl_info_basis()
addon_info = getattr(mod, "bl_info", {})
@ -606,6 +614,55 @@ def module_bl_info(mod, *, info_basis=None):
return addon_info
# -----------------------------------------------------------------------------
# Extension Utilities
def _fake_module_from_extension(mod_name, mod_path, force_support=None):
# Extract the `bl_info` from an extensions manifest.
# This is returned as a module which has a `bl_info` variable.
# When support for non-extension add-ons is dropped (Blender v5.0 perhaps)
# this can be updated not to use a fake module.
import os
import tomllib
bl_info = _bl_info_basis()
filepath = os.path.join(os.path.dirname(mod_path), _ext_manifest_filename_toml)
try:
with open(filepath, "rb") as fh:
data = tomllib.load(fh)
bl_info["name"] = data["name"]
bl_info["version"] = data["version"]
bl_info["author"] = data["author"]
bl_info["category"] = "Development" # Dummy, will be removed.
except BaseException as ex:
print("Error:", str(ex), "in", filepath)
return None
# Full validation must be done on install.
try:
assert type(bl_info["name"]) is str
assert type(bl_info["version"]) is str
assert type(bl_info["author"]) is str
assert type(bl_info["category"]) is str
except BaseException as ex:
print("Error:", str(ex), "in", filepath)
return None
if force_support is not None:
bl_info["support"] = force_support
ModuleType = type(os)
mod = ModuleType(mod_name)
mod.bl_info = bl_info
# TODO: implement a way to update based on the time of the TOML file.
mod.__file__ = mod_path
mod.__time__ = os.path.getmtime(mod_path)
return mod
# -----------------------------------------------------------------------------
# Extensions
@ -634,6 +691,7 @@ class _ext_global:
# The name (in `sys.modules`) keep this short because it's stored as part of add-on modules name.
_ext_base_pkg_idname = "bl_ext"
_ext_base_pkg_idname_with_dot = _ext_base_pkg_idname + "."
_ext_manifest_filename_toml = "bl_manifest.toml"
def _extension_preferences_idmap():