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.
This commit is contained in:
Campbell Barton 2024-03-21 11:35:29 +11:00
parent 2df06a05ae
commit f64f3e8524
3 changed files with 21 additions and 3 deletions

View File

@ -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,
};

View File

@ -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");
}
}

View File

@ -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