84 lines
2.4 KiB
Python
84 lines
2.4 KiB
Python
|
import sys
|
||
|
from pathlib import Path
|
||
|
|
||
|
import bpy
|
||
|
|
||
|
PATH_SCRIPT = str(Path(__file__).resolve().parent)
|
||
|
sys.path.insert(0, str(PATH_SCRIPT))
|
||
|
import info # noqa: E402
|
||
|
import pack # noqa: E402
|
||
|
|
||
|
sys.path.remove(str(PATH_SCRIPT))
|
||
|
|
||
|
|
||
|
def install_and_enable_addon(addon_name: str, addon_zip: Path) -> None:
|
||
|
"""Strongly inspired by Blender's addon_utils.py."""
|
||
|
# Check if Addon is Installable
|
||
|
if any(
|
||
|
[
|
||
|
(mod := sys.modules.get(addon_name)) is not None,
|
||
|
addon_name in bpy.context.preferences.addons,
|
||
|
any(
|
||
|
(Path(addon_path) / addon_name).exists()
|
||
|
for addon_path in bpy.utils.script_paths(subdir='addons')
|
||
|
),
|
||
|
]
|
||
|
):
|
||
|
## TODO: Check if addon file path exists?
|
||
|
in_pref_addons = addon_name in bpy.context.preferences.addons
|
||
|
existing_files_found = {
|
||
|
addon_path: (Path(addon_path) / addon_name).exists()
|
||
|
for addon_path in bpy.utils.script_paths(subdir='addons')
|
||
|
if (Path(addon_path) / addon_name).exists()
|
||
|
}
|
||
|
msg = f"Addon (module = '{mod}') is not installable (in preferences.addons: {in_pref_addons}) (existing files found: {existing_files_found})"
|
||
|
raise ValueError(msg)
|
||
|
|
||
|
# Install Addon
|
||
|
bpy.ops.preferences.addon_install(filepath=str(addon_zip))
|
||
|
if not any(
|
||
|
(Path(addon_path) / addon_name).exists()
|
||
|
for addon_path in bpy.utils.script_paths(subdir='addons')
|
||
|
):
|
||
|
msg = f"Couldn't install addon {addon_name}"
|
||
|
raise RuntimeError(msg)
|
||
|
|
||
|
# Enable Addon
|
||
|
bpy.ops.preferences.addon_enable(module=addon_name)
|
||
|
if addon_name not in bpy.context.preferences.addons:
|
||
|
msg = f"Couldn't enable addon {addon_name}"
|
||
|
raise RuntimeError(msg)
|
||
|
|
||
|
# Save User Preferences
|
||
|
bpy.ops.wm.save_userpref()
|
||
|
|
||
|
|
||
|
def setup_for_development(addon_name: str, path_addon_dev_deps: Path) -> None:
|
||
|
addon_prefs = bpy.context.preferences.addons[addon_name].preferences
|
||
|
|
||
|
# PyDeps Path
|
||
|
addon_prefs.use_default_pydeps_path = False
|
||
|
addon_prefs.pydeps_path = path_addon_dev_deps
|
||
|
|
||
|
# Save User Preferences
|
||
|
bpy.ops.wm.save_userpref()
|
||
|
|
||
|
|
||
|
####################
|
||
|
# - Main
|
||
|
####################
|
||
|
if __name__ == '__main__':
|
||
|
with pack.zipped_addon(
|
||
|
info.PATH_ADDON_PKG,
|
||
|
info.PATH_ADDON_ZIP,
|
||
|
info.PATH_ROOT / 'pyproject.toml',
|
||
|
info.PATH_ROOT / 'requirements.lock',
|
||
|
initial_log_level=info.BOOTSTRAP_LOG_LEVEL,
|
||
|
) as path_zipped:
|
||
|
install_and_enable_addon(info.ADDON_NAME, path_zipped)
|
||
|
|
||
|
setup_for_development(info.ADDON_NAME, info.PATH_ADDON_DEV_DEPS)
|
||
|
|
||
|
bpy.ops.wm.quit_blender()
|
||
|
sys.exit(info.STATUS_INSTALLED_ADDON)
|