From f64f3e852416698d97c959f8ada10a5ccd44af6a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 21 Mar 2024 11:35:29 +1100 Subject: [PATCH] Extensions: recursively remove custom-directories on repo removal Even though there is a dialog users must accept when removing a repository & directory being removed is shown, it's possible users assume this only removes files which are part of the repository after pointing the custom-directory to their home directory or similar. Removing repositories which point to a custom-directory now only remove packages and server meta-data to prevent accidents. Resolves #119481. --- source/blender/blenkernel/BKE_callbacks.hh | 1 + .../editors/space_userpref/userpref_ops.cc | 21 ++++++++++++++++--- .../blender/python/intern/bpy_app_handlers.cc | 2 ++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/BKE_callbacks.hh b/source/blender/blenkernel/BKE_callbacks.hh index 587bdd5a408..5f77cebcb11 100644 --- a/source/blender/blenkernel/BKE_callbacks.hh +++ b/source/blender/blenkernel/BKE_callbacks.hh @@ -110,6 +110,7 @@ enum eCbEvent { BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST, BKE_CB_EVT_EXTENSION_REPOS_SYNC, BKE_CB_EVT_EXTENSION_REPOS_UPGRADE, + BKE_CB_EVT_EXTENSION_REPOS_FILES_CLEAR, BKE_CB_EVT_TOT, }; diff --git a/source/blender/editors/space_userpref/userpref_ops.cc b/source/blender/editors/space_userpref/userpref_ops.cc index 3dd002e2bf9..5c6fe2f2e5e 100644 --- a/source/blender/editors/space_userpref/userpref_ops.cc +++ b/source/blender/editors/space_userpref/userpref_ops.cc @@ -578,10 +578,25 @@ static int preferences_extension_repo_remove_exec(bContext *C, wmOperator *op) char dirpath[FILE_MAX]; BKE_preferences_extension_repo_dirpath_get(repo, dirpath, sizeof(dirpath)); if (dirpath[0] && BLI_is_dir(dirpath)) { - if (BLI_delete(dirpath, true, true) != 0) { + + /* Removing custom directories has the potential to remove user data + * if users accidently point this to their home directory or similar. + * Even though the UI shows a warning, we better prevent any accidents + * caused by recursive removal, see #119481. + * Only check custom directories because the non-custom directory is always + * a spesific location under Blender's local extensions directory. */ + const bool recursive = (repo->flag & USER_EXTENSION_REPO_FLAG_USE_CUSTOM_DIRECTORY) == 0; + + /* Perform package manager spesific clear operations, + * needed when `recursive` is false so the empty directory can be removed. + * If it's not empty there will be a warning that the directory couldn't be removed. + * The user will have to do this manually which is good since unknown files may user data. */ + BKE_callback_exec_string(bmain, BKE_CB_EVT_EXTENSION_REPOS_FILES_CLEAR, dirpath); + + if (BLI_delete(dirpath, true, recursive) != 0) { BKE_reportf(op->reports, - RPT_ERROR, - "Error removing directory: %s", + RPT_WARNING, + "Unable to remove directory: %s", errno ? strerror(errno) : "unknown"); } } diff --git a/source/blender/python/intern/bpy_app_handlers.cc b/source/blender/python/intern/bpy_app_handlers.cc index 121bbb2f391..293329f23b2 100644 --- a/source/blender/python/intern/bpy_app_handlers.cc +++ b/source/blender/python/intern/bpy_app_handlers.cc @@ -96,6 +96,8 @@ static PyStructSequence_Field app_cb_info_fields[] = { {"_extension_repos_update_post", "on changes to extension repos (after)"}, {"_extension_repos_sync", "on creating or synchronizing the active repository"}, {"_extension_repos_upgrade", "on upgrading the active repository"}, + {"_extension_repos_files_clear", + "remove files from the repository directory (uses as a string argument)"}, /* sets the permanent tag */ #define APP_CB_OTHER_FIELDS 1