From c4a0bbb1f4d5e9496bc79ed767a58c156a49820d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 15 May 2024 22:21:00 +1000 Subject: [PATCH] Extensions: Support online extensions and move add-ons outside Blender MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The extensions system allows to extend Blender with connectivity to the internet. Right now it means Blender can discover and install add-ons and themes directly from the internet, and notify users about their updates. By default this is disabled (opt-in), and users can enable it the first time they try to install an extension or visit the Prefences > Extensions tab. If this is enabled, Blender will automatically check for updates for extensions.blender.org upon startup. When will Blender access the remote repositories: * Every time you open the Preferences → Extensions: ALL the enabled repositories get checked for the latest info (json) * Every time you try to install by dragging: ALL the enabled repositories get checked for the latest info (json). * Every time you start Blender: selected repositories get checked for the latest info (json). ------------------ From the Blender code point of view, this means that most of the add-ons and themes originally bundled with Blender will now be available from the online platform, instead of bundled with Blender. The exception are add-ons which are deemed core functionality which just happened to be written as Python add-ons. Links: * Original Extenesions Platform Announcement: https://code.blender.org/2022/10/blender-extensions-platform/ * Extensions website: https://extensions.blender.org/ * User Manual: https://docs.blender.org/manual/en/4.2/extensions/index.html#extensions-index * Technical specifications: https://developer.blender.org/docs/features/extensions/ * Changes on add-ons bundling: https://devtalk.blender.org/t/changes-to-add-on-bundling-4-2-onwards/34593 ------------------ This PR does the following: * Move extensions out of experimental. * No longer install `scripts/addons` & `scripts/addons_contrib`. * Add `scripts/addons_core` to blender's repository. These add-ons will still be bundled with Blender and will be always enabled in the future, with their preferences moved to be more closely integrated with the rest of Blender. This will happen during the remaining bcon2 period. For more details, see #121830 From scripts/addons: * copy_global_transform.py * hydra_storm * io_anim_bvh * io_curve_svg * io_mesh_uv_layout * io_scene_fbx * io_scene_gltf2 * pose_library * ui_translate * viewport_vr_preview Extra: bl_pkg (scripts/addons_contrib) Note: The STL (legacy) add-on is going to be moved to the extensions platform. There is already a C++ version on core which is enabled by default. All the other add-ons are already available at extensions.blender.org. To use them you need to: * Go to User Preferences > Extensions * You will be greated with an "Online Extensions" message, click on "Enable Repository". * Search the add-on you are looking for (e.g, Import Images as Planes). * Click on Install Over time their maintaince will be transferred over to the community so their development can carry on. If you used to help maintain a bundled add-on please read: https://devtalk.blender.org/t/changes-to-add-on-bundling-4-2-onwards/34593 Ref: !121825 --- build_files/utils/make_source_archive.py | 16 ---- build_files/utils/make_update.py | 24 ------ doc/python_api/sphinx_doc_gen.py | 5 +- intern/cycles/CMakeLists.txt | 4 +- pyproject.toml | 3 +- scripts/addons_core/bl_pkg/__init__.py | 28 +++---- .../addons_core/bl_pkg/bl_extension_ops.py | 2 +- scripts/addons_core/bl_pkg/bl_extension_ui.py | 30 ++++++-- .../addons_core/bl_pkg/tests/test_blender.py | 3 - .../bl_pkg/tests/test_cli_blender.py | 7 +- .../blender/exp/gltf2_blender_gather_tree.py | 1 - scripts/modules/addon_utils.py | 77 ++++++++++--------- scripts/startup/bl_operators/userpref.py | 2 +- scripts/startup/bl_ui/space_userpref.py | 9 +-- source/blender/blenkernel/intern/blendfile.cc | 2 - .../editors/space_userpref/userpref_ops.cc | 6 -- source/blender/makesdna/DNA_userdef_types.h | 6 +- source/blender/makesrna/intern/rna_userdef.cc | 33 +------- source/creator/CMakeLists.txt | 14 +--- tools/check_source/check_licenses.py | 4 +- tools/check_source/check_spelling_config.py | 2 +- 21 files changed, 96 insertions(+), 182 deletions(-) diff --git a/build_files/utils/make_source_archive.py b/build_files/utils/make_source_archive.py index b8964b38fd0..c811a45988f 100755 --- a/build_files/utils/make_source_archive.py +++ b/build_files/utils/make_source_archive.py @@ -115,7 +115,6 @@ def create_manifest( with outpath.open("w", encoding="utf-8") as outfile: main_files_to_manifest(blender_srcdir, outfile) assets_to_manifest(blender_srcdir, outfile) - submodules_to_manifest(blender_srcdir, version, outfile) if packages_dir: packages_to_manifest(outfile, packages_dir) @@ -128,21 +127,6 @@ def main_files_to_manifest(blender_srcdir: Path, outfile: TextIO) -> None: print(path, file=outfile) -def submodules_to_manifest( - blender_srcdir: Path, version: make_utils.BlenderVersion, outfile: TextIO -) -> None: - skip_addon_contrib = version.is_release() - assert not blender_srcdir.is_absolute() - - for submodule in ("scripts/addons", "scripts/addons_contrib"): - # Don't use native slashes as GIT for MS-Windows outputs forward slashes. - if skip_addon_contrib and submodule == "scripts/addons_contrib": - continue - - for path in git_ls_files(blender_srcdir / submodule): - print(path, file=outfile) - - def assets_to_manifest(blender_srcdir: Path, outfile: TextIO) -> None: assert not blender_srcdir.is_absolute() diff --git a/build_files/utils/make_update.py b/build_files/utils/make_update.py index 26f7b0dc496..5fd8e78f57d 100755 --- a/build_files/utils/make_update.py +++ b/build_files/utils/make_update.py @@ -576,27 +576,6 @@ def submodules_lib_update(args: argparse.Namespace, branch: Optional[str]) -> st return msg -def scripts_submodules_update(args: argparse.Namespace, branch: Optional[str]) -> str: - """Update working trees of addons and addons_contrib within the scripts/ directory""" - msg = "" - - msg += external_scripts_update(args, "blender-addons", "addons", branch) - msg += external_scripts_update(args, "blender-addons-contrib", "addons_contrib", branch) - - return msg - - -def submodules_code_update(args: argparse.Namespace, branch: Optional[str]) -> str: - """Update submodules or other externally tracked source trees""" - print_stage("Updating Submodules") - - msg = "" - - msg += scripts_submodules_update(args, branch) - - return msg - - if __name__ == "__main__": args = parse_arguments() blender_skip_msg = "" @@ -627,9 +606,6 @@ if __name__ == "__main__": libraries_skip_msg += initialize_tests_data_files(args) libraries_skip_msg += submodules_lib_update(args, branch) - if not args.no_submodules: - submodules_skip_msg += submodules_code_update(args, branch) - # Report any skipped repositories at the end, so it's not as easy to miss. skip_msg = blender_skip_msg + libraries_skip_msg + submodules_skip_msg if skip_msg: diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py index 6b8ad2c0183..8efe1613656 100644 --- a/doc/python_api/sphinx_doc_gen.py +++ b/doc/python_api/sphinx_doc_gen.py @@ -1830,7 +1830,6 @@ def pyrna2sphinx(basepath): def write_ops(): API_BASEURL = "https://projects.blender.org/blender/blender/src/branch/main/scripts" API_BASEURL_ADDON = "https://projects.blender.org/blender/blender-addons" - API_BASEURL_ADDON_CONTRIB = "https://projects.blender.org/blender/blender-addons-contrib" op_modules = {} op = None @@ -1868,9 +1867,7 @@ def pyrna2sphinx(basepath): location = op.get_location() if location != (None, None): - if location[0].startswith("addons_contrib" + os.sep): - url_base = API_BASEURL_ADDON_CONTRIB - elif location[0].startswith("addons" + os.sep): + if location[0].startswith("addons_core" + os.sep): url_base = API_BASEURL_ADDON else: url_base = API_BASEURL diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 266458dc973..19a23b3d077 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -11,9 +11,9 @@ else() # be started with --env-system-scripts pointing to the release folder, which will # lack the cycles addon, and we don't want to write into it. if(NOT WINDOWS_PYTHON_DEBUG) - set(CYCLES_INSTALL_PATH "scripts/addons/cycles") + set(CYCLES_INSTALL_PATH "scripts/addons_core/cycles") else() - set(CYCLES_INSTALL_PATH "$ENV{appdata}/blender foundation/blender/${BLENDER_VERSION}/scripts/addons/cycles") + set(CYCLES_INSTALL_PATH "$ENV{appdata}/blender foundation/blender/${BLENDER_VERSION}/scripts/addons_core/cycles") endif() endif() diff --git a/pyproject.toml b/pyproject.toml index 272f121450f..d026fd6357b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,8 +39,7 @@ aggressive = 2 # - `./scripts/modules/rna_manual_reference.py` because it's a generated data-file. exclude = """ ./extern/*, -./scripts/addons/*, -./scripts/addons_contrib/*, +./scripts/addons_core/*, ./scripts/modules/rna_manual_reference.py, ./tools/svn_rev_map/sha1_to_rev.py, ./tools/svn_rev_map/rev_to_sha1.py, diff --git a/scripts/addons_core/bl_pkg/__init__.py b/scripts/addons_core/bl_pkg/__init__.py index 926784f00b3..92e7b734907 100644 --- a/scripts/addons_core/bl_pkg/__init__.py +++ b/scripts/addons_core/bl_pkg/__init__.py @@ -115,9 +115,6 @@ def repo_paths_or_none(repo_item): def repo_active_or_none(): prefs = bpy.context.preferences - if not prefs.experimental.use_extension_repos: - return - extensions = prefs.extensions active_extension_index = extensions.active_repo try: @@ -147,19 +144,18 @@ def repos_to_notify(): # if any repositories are marked to run notifications. prefs = bpy.context.preferences - if prefs.experimental.use_extension_repos: - extension_repos = prefs.extensions.repos - for repo_item in extension_repos: - if not repo_item.enabled: - continue - if not repo_item.use_sync_on_startup: - continue - if not repo_item.use_remote_url: - continue - # Invalid, if there is no remote path this can't update. - if not repo_item.remote_url: - continue - repos_notify.append(repo_item) + extension_repos = prefs.extensions.repos + for repo_item in extension_repos: + if not repo_item.enabled: + continue + if not repo_item.use_sync_on_startup: + continue + if not repo_item.use_remote_url: + continue + # Invalid, if there is no remote path this can't update. + if not repo_item.remote_url: + continue + repos_notify.append(repo_item) return repos_notify diff --git a/scripts/addons_core/bl_pkg/bl_extension_ops.py b/scripts/addons_core/bl_pkg/bl_extension_ops.py index 125f21908fe..fd21f92fd86 100644 --- a/scripts/addons_core/bl_pkg/bl_extension_ops.py +++ b/scripts/addons_core/bl_pkg/bl_extension_ops.py @@ -2218,7 +2218,7 @@ class BlPkgShowUpgrade(Operator): wm = context.window_manager prefs = context.preferences - prefs.active_section = 'ADDONS' + prefs.active_section = 'EXTENSIONS' prefs.view.show_addons_enabled_only = False # Show only extensions that will be updated. diff --git a/scripts/addons_core/bl_pkg/bl_extension_ui.py b/scripts/addons_core/bl_pkg/bl_extension_ui.py index 9b8478066ee..9de77e5d9a7 100644 --- a/scripts/addons_core/bl_pkg/bl_extension_ui.py +++ b/scripts/addons_core/bl_pkg/bl_extension_ui.py @@ -85,9 +85,28 @@ def pkg_repo_and_id_from_theme_path(repos_all, filepath): return None +def module_parent_dirname(module_filepath): + """ + Return the name of the directory above the module (it's name only). + """ + import os + parts = module_filepath.rsplit(os.sep, 3) + # Unlikely. + if not parts: + return "" + if parts[-1] == "__init__.py": + if len(parts) >= 3: + return parts[-3] + else: + if len(parts) >= 2: + return parts[-2] + return "" + + # ----------------------------------------------------------------------------- # Extensions UI (Legacy) + def extensions_panel_draw_legacy_addons( layout, context, @@ -153,7 +172,11 @@ def extensions_panel_draw_legacy_addons( sub = row.row() sub.active = is_enabled - sub.label(text="Legacy: " + bl_info["name"]) + + if module_parent_dirname(mod.__file__) == "addons_core": + sub.label(text="Core: " + bl_info["name"]) + else: + sub.label(text="Legacy: " + bl_info["name"]) if bl_info["warning"]: sub.label(icon='ERROR') @@ -690,11 +713,6 @@ class USERPREF_MT_extensions_bl_pkg_settings(Menu): def extensions_panel_draw(panel, context): prefs = context.preferences - if not prefs.experimental.use_extension_repos: - # Unexpected, the extension is disabled but this add-on is. - # In this case don't show the UI as it is confusing. - return - from .bl_extension_ops import ( blender_filter_by_type_map, ) diff --git a/scripts/addons_core/bl_pkg/tests/test_blender.py b/scripts/addons_core/bl_pkg/tests/test_blender.py index db416828aaf..5c7c51c9fd7 100644 --- a/scripts/addons_core/bl_pkg/tests/test_blender.py +++ b/scripts/addons_core/bl_pkg/tests/test_blender.py @@ -113,9 +113,6 @@ def blender_test_run(temp_dir_local: str) -> None: preferences = bpy.context.preferences - preferences.view.show_developer_ui = True - preferences.experimental.use_extension_repos = True - addon_dir = os.path.normpath(os.path.join(BASE_DIR, "..", "blender_addon")) ensure_script_directory(addon_dir) diff --git a/scripts/addons_core/bl_pkg/tests/test_cli_blender.py b/scripts/addons_core/bl_pkg/tests/test_cli_blender.py index 06c3be5f310..1feb44004d3 100644 --- a/scripts/addons_core/bl_pkg/tests/test_cli_blender.py +++ b/scripts/addons_core/bl_pkg/tests/test_cli_blender.py @@ -34,18 +34,13 @@ VERBOSE_CMD = False BLENDER_BIN = os.environ.get("BLENDER_BIN") if BLENDER_BIN is None: + sys.exit(0) raise Exception("BLENDER_BIN: environment variable not defined") # Arguments to ensure extensions are enabled (currently it's an experimental feature). BLENDER_ENABLE_EXTENSION_ARGS = [ "--python-exit-code", "1", - # Code begin/end text because of Blender's chatty reporting of version and that it quit. - "--python-expr", '''\ -from bpy import context -context.preferences.view.show_developer_ui = True -context.preferences.experimental.use_extension_repos = True -''', ] BASE_DIR = os.path.abspath(os.path.dirname(__file__)) diff --git a/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py b/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py index 1cfe6374fbd..e13e568a873 100644 --- a/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py +++ b/scripts/addons_core/io_scene_gltf2/blender/exp/gltf2_blender_gather_tree.py @@ -13,7 +13,6 @@ from ...io.com import gltf2_io_constants from ...io.exp import gltf2_io_binary_data from ..com.gltf2_blender_default import BLENDER_GLTF_SPECIAL_COLLECTION from . import gltf2_blender_gather_accessors -from .gltf2_blender_gather_joints import gather_joint_vnode class VExportNode: diff --git a/scripts/modules/addon_utils.py b/scripts/modules/addon_utils.py index d808ecbf2c7..427f29ebdfd 100644 --- a/scripts/modules/addon_utils.py +++ b/scripts/modules/addon_utils.py @@ -37,16 +37,22 @@ def _initialize_once(): def paths(): - return [ - path for subdir in ( - # RELEASE SCRIPTS: official scripts distributed in Blender releases. - "addons", - # CONTRIB SCRIPTS: good for testing but not official scripts yet - # if folder addons_contrib/ exists, scripts in there will be loaded too. - "addons_contrib", - ) - for path in _bpy.utils.script_paths(subdir=subdir) - ] + import os + + paths = [] + for p in _bpy.utils.script_paths(): + # Bundled add-ons. + addon_dir = os.path.join(p, "addons_core") + if os.path.isdir(addon_dir): + paths.append(addon_dir) + # The system path if for core add-ons only, + # if the `addons` directory exists it's likely from an old "make install" target. + continue + # User defined add-ons, custom scripts directory. + addon_dir = os.path.join(p, "addons") + if os.path.isdir(addon_dir): + paths.append(addon_dir) + return paths # A version of `paths` that includes extension repositories returning a list `(path, package)` pairs. @@ -65,14 +71,13 @@ def _paths_with_extension_repos(): import os addon_paths = [(path, "") for path in paths()] - if _preferences.experimental.use_extension_repos: - for repo in _preferences.extensions.repos: - if not repo.enabled: - continue - dirpath = repo.directory - if not os.path.isdir(dirpath): - continue - addon_paths.append((dirpath, "{:s}.{:s}".format(_ext_base_pkg_idname, repo.module))) + for repo in _preferences.extensions.repos: + if not repo.enabled: + continue + dirpath = repo.directory + if not os.path.isdir(dirpath): + continue + addon_paths.append((dirpath, "{:s}.{:s}".format(_ext_base_pkg_idname, repo.module))) return addon_paths @@ -178,7 +183,11 @@ def modules_refresh(*, module_cache=addons_fake_modules): for path, pkg_id in _paths_with_extension_repos(): # Force all user contributed add-ons to be 'TESTING'. - force_support = 'TESTING' if ((not pkg_id) and path.endswith("addons_contrib")) else None + + # TODO: remove this option entirely. + force_support = None + # Was part of support `addons_contrib`. + # `force_support = 'TESTING' if ((not pkg_id) and path.endswith("addons_contrib")) else None` for mod_name, mod_path in _bpy.path.module_names(path, package=pkg_id): modules_stale.discard(mod_name) @@ -756,10 +765,9 @@ def _fake_module_from_extension(mod_name, mod_path, force_support=None): # Extensions def _initialize_ensure_extensions_addon(): - if _preferences.experimental.use_extension_repos: - module_name = "bl_pkg" - if module_name not in _preferences.addons: - enable(module_name, default_set=True, persistent=True) + module_name = "bl_pkg" + if module_name not in _preferences.addons: + enable(module_name, default_set=True, persistent=True) # Module-like class, store singletons. @@ -786,22 +794,20 @@ _ext_manifest_filename_toml = "blender_manifest.toml" def _extension_preferences_idmap(): repos_idmap = {} repos_idmap_disabled = {} - if _preferences.experimental.use_extension_repos: - for repo in _preferences.extensions.repos: - if repo.enabled: - repos_idmap[repo.as_pointer()] = repo.module - else: - repos_idmap_disabled[repo.as_pointer()] = repo.module + for repo in _preferences.extensions.repos: + if repo.enabled: + repos_idmap[repo.as_pointer()] = repo.module + else: + repos_idmap_disabled[repo.as_pointer()] = repo.module return repos_idmap, repos_idmap_disabled def _extension_dirpath_from_preferences(): repos_dict = {} - if _preferences.experimental.use_extension_repos: - for repo in _preferences.extensions.repos: - if not repo.enabled: - continue - repos_dict[repo.module] = repo.directory + for repo in _preferences.extensions.repos: + if not repo.enabled: + continue + repos_dict[repo.module] = repo.directory return repos_dict @@ -979,7 +985,8 @@ def _initialize_extension_repos_post(*_, is_first=False): # Map `module_id` -> `repo.as_pointer()`. repos_idmap_next_reverse = {value: key for key, value in repos_idmap_next.items()} - # Mainly needed when the `preferences.experimental.use_extension_repos` option is enabled at run-time. + # Mainly needed when the state of repositories changes at run-time: + # factory settings then load preferences for example. # # Filter `repos_idmap_prev` so only items which were also in the `repos_info_prev` are included. # This is an awkward situation, they should be in sync, however when enabling the experimental option diff --git a/scripts/startup/bl_operators/userpref.py b/scripts/startup/bl_operators/userpref.py index b96e6529df4..130fce80185 100644 --- a/scripts/startup/bl_operators/userpref.py +++ b/scripts/startup/bl_operators/userpref.py @@ -870,7 +870,7 @@ class PREFERENCES_OT_addon_show(Operator): bl_info = addon_utils.module_bl_info(mod) bl_info["show_expanded"] = True - context.preferences.active_section = 'ADDONS' + context.preferences.active_section = 'EXTENSIONS' context.preferences.view.show_addons_enabled_only = False context.window_manager.addon_filter = 'All' context.window_manager.addon_search = bl_info["name"] diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index 4c09816d554..afff25bdc51 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -2179,7 +2179,7 @@ class USERPREF_PT_addons_filter(Panel): class AddOnPanel: bl_space_type = 'PREFERENCES' bl_region_type = 'WINDOW' - bl_context = "addons" + bl_context = "extensions" class USERPREF_PT_addons(AddOnPanel, Panel): @@ -2275,11 +2275,7 @@ class USERPREF_PT_addons(AddOnPanel, Panel): prefs = context.preferences - if ( - prefs.view.show_developer_ui and - prefs.experimental.use_extension_repos and - self.is_extended() - ): + if self.is_extended(): # Rely on the draw function being appended to by the extensions add-on. return @@ -2720,7 +2716,6 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel): ({"property": "use_grease_pencil_version3"}, ("blender/blender/projects/6", "Grease Pencil 3.0")), ({"property": "use_grease_pencil_version3_convert_on_load"}, ("blender/blender/projects/6", "Grease Pencil 3.0")), ({"property": "enable_overlay_next"}, ("blender/blender/issues/102179", "#102179")), - ({"property": "use_extension_repos"}, ("/blender/blender/issues/117286", "#117286")), ({"property": "use_extension_utils"}, ("/blender/blender/issues/117286", "#117286")), ({"property": "use_animation_baklava"}, ("/blender/blender/issues/120406", "#120406")), ), diff --git a/source/blender/blenkernel/intern/blendfile.cc b/source/blender/blenkernel/intern/blendfile.cc index e4d552c44f1..71206383d3e 100644 --- a/source/blender/blenkernel/intern/blendfile.cc +++ b/source/blender/blenkernel/intern/blendfile.cc @@ -1206,11 +1206,9 @@ UserDef *BKE_blendfile_userdef_from_defaults() const char *addons[] = { "io_anim_bvh", "io_curve_svg", - "io_mesh_stl", "io_mesh_uv_layout", "io_scene_fbx", "io_scene_gltf2", - "io_scene_x3d", "cycles", "pose_library", }; diff --git a/source/blender/editors/space_userpref/userpref_ops.cc b/source/blender/editors/space_userpref/userpref_ops.cc index 808b44a2d7b..026fcd14c29 100644 --- a/source/blender/editors/space_userpref/userpref_ops.cc +++ b/source/blender/editors/space_userpref/userpref_ops.cc @@ -925,9 +925,6 @@ static void PREFERENCES_OT_unassociate_blend(wmOperatorType *ot) static bool drop_extension_url_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/) { - if (!U.experimental.use_extension_repos) { - return false; - } if (drag->type != WM_DRAG_STRING) { return false; } @@ -977,9 +974,6 @@ static void drop_extension_url_copy(bContext * /*C*/, wmDrag *drag, wmDropBox *d static bool drop_extension_path_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/) { - if (!U.experimental.use_extension_repos) { - return false; - } if (drag->type != WM_DRAG_PATH) { return false; } diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 0ad56061f83..05d5a2e2751 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -732,11 +732,10 @@ typedef struct UserDef_Experimental { char enable_overlay_next; char use_new_volume_nodes; char use_shader_node_previews; - char use_extension_repos; char use_extension_utils; char use_grease_pencil_version3_convert_on_load; char use_animation_baklava; - char _pad[2]; + char _pad[3]; /** `makesdna` does not allow empty structs. */ } UserDef_Experimental; @@ -1115,7 +1114,7 @@ typedef enum eUserPref_Section { USER_SECTION_SYSTEM = 3, USER_SECTION_THEME = 4, USER_SECTION_INPUT = 5, - USER_SECTION_ADDONS = 6, + USER_SECTION_EXTENSIONS = 6, USER_SECTION_LIGHT = 7, USER_SECTION_KEYMAP = 8, #ifdef WITH_USERDEF_WORKSPACES @@ -1128,7 +1127,6 @@ typedef enum eUserPref_Section { USER_SECTION_NAVIGATION = 14, USER_SECTION_FILE_PATHS = 15, USER_SECTION_EXPERIMENTAL = 16, - USER_SECTION_EXTENSIONS = 17, } eUserPref_Section; /** #UserDef_SpaceData.flag (State of the user preferences UI). */ diff --git a/source/blender/makesrna/intern/rna_userdef.cc b/source/blender/makesrna/intern/rna_userdef.cc index d1dce5f0118..2d8c76fa722 100644 --- a/source/blender/makesrna/intern/rna_userdef.cc +++ b/source/blender/makesrna/intern/rna_userdef.cc @@ -60,7 +60,7 @@ const EnumPropertyItem rna_enum_preference_section_items[] = { {USER_SECTION_EDITING, "EDITING", 0, "Editing", ""}, {USER_SECTION_ANIMATION, "ANIMATION", 0, "Animation", ""}, RNA_ENUM_ITEM_SEPR, - {USER_SECTION_ADDONS, "ADDONS", 0, "Add-ons", ""}, + {USER_SECTION_EXTENSIONS, "EXTENSIONS", 0, "Extensions", ""}, #if 0 /* def WITH_USERDEF_WORKSPACES */ RNA_ENUM_ITEM_SEPR, {USER_SECTION_WORKSPACE_CONFIG, "WORKSPACE_CONFIG", 0, "Configuration File", ""}, @@ -307,19 +307,6 @@ static void rna_userdef_screen_update_header_default(Main *bmain, Scene *scene, USERDEF_TAG_DIRTY; } -static void rna_PreferencesExperimental_use_extension_repos_set(PointerRNA * /*ptr*/, bool value) -{ - Main *bmain = G.main; - if (bool(U.experimental.use_extension_repos) != value) { - BKE_callback_exec_null(bmain, BKE_CB_EVT_EXTENSION_REPOS_UPDATE_PRE); - U.experimental.use_extension_repos = value; - BKE_callback_exec_null(bmain, BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST); - } - - /* Needed to redraw the preferences window. */ - WM_main_add_notifier(NC_WINDOW, nullptr); -} - static void rna_userdef_font_update(Main * /*bmain*/, Scene * /*scene*/, PointerRNA * /*ptr*/) { BLF_cache_clear(); @@ -721,9 +708,8 @@ static const EnumPropertyItem *rna_UseDef_active_section_itemf(bContext * /*C*/, UserDef *userdef = static_cast(ptr->data); const bool use_developer_ui = (userdef->flag & USER_DEVELOPER_UI) != 0; - const bool use_extension_repos = use_developer_ui && U.experimental.use_extension_repos; - if (use_developer_ui && use_extension_repos == false) { + if (use_developer_ui) { *r_free = false; return rna_enum_preference_section_items; } @@ -741,13 +727,6 @@ static const EnumPropertyItem *rna_UseDef_active_section_itemf(bContext * /*C*/, } RNA_enum_item_add(&items, &totitem, it); - - /* Rename "Add-ons" to "Extensions" when extensions are enabled. */ - if (it->value == USER_SECTION_ADDONS) { - if (use_extension_repos) { - items[totitem - 1].name = "Extensions"; - } - } } RNA_enum_item_end(&items, &totitem); @@ -7280,14 +7259,6 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) prop, "Shader Node Previews", "Enables previews in the shader node editor"); RNA_def_property_update(prop, 0, "rna_userdef_ui_update"); - prop = RNA_def_property(srna, "use_extension_repos", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_ui_text(prop, - "Extensions", - "Enables support for extensions, accessible from the \"Extensions\" " - "section of the preferences"); - RNA_def_property_boolean_funcs( - prop, nullptr, "rna_PreferencesExperimental_use_extension_repos_set"); - prop = RNA_def_property(srna, "use_extension_utils", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text( prop, "Extensions Development Utilities", "Developer support utilities for extensions"); diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index a660aaccf81..d7033fd0ea2 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -443,15 +443,6 @@ endif() if(WITH_PYTHON) # install(CODE "message(\"copying blender scripts...\")") - # exclude addons_contrib if release branch - if("${BLENDER_VERSION_CYCLE}" STREQUAL "release" OR - "${BLENDER_VERSION_CYCLE}" STREQUAL "rc" OR - "${BLENDER_VERSION_CYCLE}" STREQUAL "beta") - set(ADDON_EXCLUDE_CONDITIONAL "addons_contrib/*") - else() - set(ADDON_EXCLUDE_CONDITIONAL "_addons_contrib/*") # Dummy, won't do anything. - endif() - # do not install freestyle dir if disabled if(NOT WITH_FREESTYLE) set(FREESTYLE_EXCLUDE_CONDITIONAL "freestyle/*") @@ -469,7 +460,9 @@ if(WITH_PYTHON) PATTERN ".arcconfig" EXCLUDE PATTERN "__pycache__" EXCLUDE PATTERN "site" EXCLUDE - PATTERN "${ADDON_EXCLUDE_CONDITIONAL}" EXCLUDE + # Legacy sub-module which is no longer used. + PATTERN "addons/*" EXCLUDE + PATTERN "addons_contrib/*" EXCLUDE PATTERN "${FREESTYLE_EXCLUDE_CONDITIONAL}" EXCLUDE ) @@ -486,7 +479,6 @@ if(WITH_PYTHON) ) endif() endif() - unset(ADDON_EXCLUDE_CONDITIONAL) unset(FREESTYLE_EXCLUDE_CONDITIONAL) endif() diff --git a/tools/check_source/check_licenses.py b/tools/check_source/check_licenses.py index 68fdc9d302c..4d9f24a5d74 100644 --- a/tools/check_source/check_licenses.py +++ b/tools/check_source/check_licenses.py @@ -497,7 +497,6 @@ def main() -> None: source_paths_exclude=( # Directories: "./extern", - "./scripts/addons_contrib", "./scripts/templates_osl", "./tools", # Exclude library sources (GIT-LFS). @@ -541,8 +540,7 @@ def main() -> None: "./lib", # Just data. "./doc/python_api/examples", - "./scripts/addons/presets", - "./scripts/addons_contrib", + "./scripts/addons_core", "./scripts/presets", "./scripts/templates_py", diff --git a/tools/check_source/check_spelling_config.py b/tools/check_source/check_spelling_config.py index f98ac646d90..9cd333f8881 100644 --- a/tools/check_source/check_spelling_config.py +++ b/tools/check_source/check_spelling_config.py @@ -873,5 +873,5 @@ files_ignore = { directories_ignore = { "scripts/addons", - "scripts/addons_contrib", + "scripts/addons_core", }