mirror of
https://projects.blender.org/blender/blender.git
synced 2025-01-22 07:22:12 -05:00
Extensions: support system repositories & BLENDER_SYSTEM_EXTENSIONS
Support for "System" extensions as an alternative to the current "User" extensions repository. The purpose of this change is to support bundling extensions for offline work or in environments where users setting up thier own extensions isn't desirable, see #122512. Details: The default "System" repository on Linux will for example use: - `/usr/share/blender/4.2/extensions/{system}` For system installs. - `./4.2/extensions/{system}` For portable installs. - Blender's default startup now has a "System" repository which users or administrators may populate. - Repositories can select between User/System paths, setting a custom path overrides overrides this setting. - Add "BLENDER_SYSTEM_EXTENSIONS" (matching "BLENDER_LOCAL_EXTENSIONS"). Ref !122832
This commit is contained in:
parent
f423ec8848
commit
dc9430c480
Notes:
blender-bot
2024-06-07 04:45:52 +02:00
Referenced by issue #119521, Extensions Platform: beta launch
13 changed files with 115 additions and 7 deletions
7
release/extensions/system/readme.txt
Normal file
7
release/extensions/system/readme.txt
Normal file
|
@ -0,0 +1,7 @@
|
|||
System Extensions
|
||||
|
||||
Extensions extracted into this directory will be available from the
|
||||
default "System" repository.
|
||||
|
||||
This allows extensions to be bundled with Blender outside of
|
||||
user repositories.
|
|
@ -2211,6 +2211,10 @@ class USERPREF_PT_extensions_repos(Panel):
|
|||
# valid UTF-8 which will raise a Python exception when passed in as text.
|
||||
sub.prop(active_repo, "directory", text="")
|
||||
|
||||
row = layout_panel.row()
|
||||
row.active = not use_custom_directory
|
||||
row.prop(active_repo, "source")
|
||||
|
||||
if active_repo.use_remote_url:
|
||||
row = layout_panel.row(align=True, heading="Authentication")
|
||||
row.prop(active_repo, "use_access_token")
|
||||
|
|
|
@ -168,7 +168,8 @@ enum {
|
|||
/* system */
|
||||
BLENDER_SYSTEM_DATAFILES = 52,
|
||||
BLENDER_SYSTEM_SCRIPTS = 53,
|
||||
BLENDER_SYSTEM_PYTHON = 54,
|
||||
BLENDER_SYSTEM_EXTENSIONS = 54,
|
||||
BLENDER_SYSTEM_PYTHON = 55,
|
||||
};
|
||||
|
||||
/** For #BKE_appdir_folder_id_version only. */
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 55
|
||||
#define BLENDER_FILE_SUBVERSION 56
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
|
|
@ -90,6 +90,7 @@ bUserExtensionRepo *BKE_preferences_extension_repo_add(UserDef *userdef,
|
|||
void BKE_preferences_extension_repo_remove(UserDef *userdef, bUserExtensionRepo *repo);
|
||||
bUserExtensionRepo *BKE_preferences_extension_repo_add_default_remote(UserDef *userdef);
|
||||
bUserExtensionRepo *BKE_preferences_extension_repo_add_default_user(UserDef *userdef);
|
||||
bUserExtensionRepo *BKE_preferences_extension_repo_add_default_system(UserDef *userdef);
|
||||
/** Create all default repositories, only use when repositories are empty. */
|
||||
void BKE_preferences_extension_repo_add_defaults_all(UserDef *userdef);
|
||||
|
||||
|
|
|
@ -656,6 +656,18 @@ bool BKE_appdir_folder_id_ex(const int folder_id,
|
|||
}
|
||||
return false;
|
||||
|
||||
case BLENDER_SYSTEM_EXTENSIONS:
|
||||
if (get_path_environment(path, path_maxncpy, subfolder, "BLENDER_SYSTEM_EXTENSIONS")) {
|
||||
break;
|
||||
}
|
||||
if (get_path_system(path, path_maxncpy, "extensions", subfolder)) {
|
||||
break;
|
||||
}
|
||||
if (get_path_local(path, path_maxncpy, "extensions", subfolder)) {
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
|
||||
case BLENDER_SYSTEM_PYTHON:
|
||||
if (get_path_environment(path, path_maxncpy, subfolder, "BLENDER_SYSTEM_PYTHON")) {
|
||||
break;
|
||||
|
|
|
@ -216,11 +216,19 @@ bUserExtensionRepo *BKE_preferences_extension_repo_add_default_user(UserDef *use
|
|||
return repo;
|
||||
}
|
||||
|
||||
bUserExtensionRepo *BKE_preferences_extension_repo_add_default_system(UserDef *userdef)
|
||||
{
|
||||
bUserExtensionRepo *repo = BKE_preferences_extension_repo_add(userdef, "System", "system", "");
|
||||
repo->source = USER_EXTENSION_REPO_SOURCE_SYSTEM;
|
||||
return repo;
|
||||
}
|
||||
|
||||
void BKE_preferences_extension_repo_add_defaults_all(UserDef *userdef)
|
||||
{
|
||||
BLI_assert(BLI_listbase_is_empty(&userdef->extension_repos));
|
||||
BKE_preferences_extension_repo_add_default_remote(userdef);
|
||||
BKE_preferences_extension_repo_add_default_user(userdef);
|
||||
BKE_preferences_extension_repo_add_default_system(userdef);
|
||||
}
|
||||
|
||||
void BKE_preferences_extension_repo_name_set(UserDef *userdef,
|
||||
|
@ -269,8 +277,19 @@ size_t BKE_preferences_extension_repo_dirpath_get(const bUserExtensionRepo *repo
|
|||
return BLI_strncpy_rlen(dirpath, repo->custom_dirpath, dirpath_maxncpy);
|
||||
}
|
||||
|
||||
std::optional<std::string> path = BKE_appdir_folder_id_user_notest(BLENDER_USER_EXTENSIONS,
|
||||
nullptr);
|
||||
std::optional<std::string> path = std::nullopt;
|
||||
|
||||
switch (repo->source) {
|
||||
case USER_EXTENSION_REPO_SOURCE_SYSTEM: {
|
||||
path = BKE_appdir_folder_id(BLENDER_SYSTEM_EXTENSIONS, nullptr);
|
||||
break;
|
||||
}
|
||||
default: { /* #USER_EXTENSION_REPO_SOURCE_USER. */
|
||||
path = BKE_appdir_folder_id_user_notest(BLENDER_USER_EXTENSIONS, nullptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Highly unlikely to fail as the directory doesn't have to exist. */
|
||||
if (!path) {
|
||||
dirpath[0] = '\0';
|
||||
|
|
|
@ -973,6 +973,10 @@ void blo_do_versions_userdef(UserDef *userdef)
|
|||
userdef->sequencer_editor_flag |= USER_SEQ_ED_SIMPLE_TWEAKING;
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(402, 56)) {
|
||||
BKE_preferences_extension_repo_add_default_system(userdef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||
* code here, and wrap it inside a USER_VERSION_ATLEAST check.
|
||||
|
|
|
@ -649,8 +649,11 @@ typedef struct bUserExtensionRepo {
|
|||
char custom_dirpath[1024]; /* FILE_MAX */
|
||||
char remote_url[1024]; /* FILE_MAX */
|
||||
|
||||
int flag;
|
||||
char _pad0[4];
|
||||
uint8_t flag;
|
||||
/** The source location when the custom directory isn't used (#eUserExtensionRepo_Source).*/
|
||||
uint8_t source;
|
||||
|
||||
char _pad0[6];
|
||||
} bUserExtensionRepo;
|
||||
|
||||
typedef enum eUserExtensionRepo_Flag {
|
||||
|
@ -663,6 +666,15 @@ typedef enum eUserExtensionRepo_Flag {
|
|||
USER_EXTENSION_REPO_FLAG_USE_ACCESS_TOKEN = 1 << 5,
|
||||
} eUserExtensionRepo_Flag;
|
||||
|
||||
/**
|
||||
* The source to use (User or System), only valid when the
|
||||
* #USER_EXTENSION_REPO_FLAG_USE_CUSTOM_DIRECTORY flag isn't set.
|
||||
*/
|
||||
typedef enum eUserExtensionRepo_Source {
|
||||
USER_EXTENSION_REPO_SOURCE_USER = 0,
|
||||
USER_EXTENSION_REPO_SOURCE_SYSTEM = 1,
|
||||
} eUserExtensionRepo_Source;
|
||||
|
||||
typedef struct SolidLight {
|
||||
int flag;
|
||||
float smooth;
|
||||
|
|
|
@ -439,6 +439,15 @@ static void rna_userdef_extension_repo_use_remote_url_set(PointerRNA *ptr, bool
|
|||
ptr, value, USER_EXTENSION_REPO_FLAG_USE_REMOTE_URL);
|
||||
}
|
||||
|
||||
static void rna_userdef_extension_repo_source_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
Main *bmain = G.main;
|
||||
bUserExtensionRepo *repo = (bUserExtensionRepo *)ptr->data;
|
||||
BKE_callback_exec_null(bmain, BKE_CB_EVT_EXTENSION_REPOS_UPDATE_PRE);
|
||||
repo->source = value;
|
||||
BKE_callback_exec_null(bmain, BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST);
|
||||
}
|
||||
|
||||
static void rna_userdef_script_autoexec_update(Main * /*bmain*/,
|
||||
Scene * /*scene*/,
|
||||
PointerRNA *ptr)
|
||||
|
@ -6750,6 +6759,20 @@ static void rna_def_userdef_filepaths_extension_repo(BlenderRNA *brna)
|
|||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static const EnumPropertyItem source_type_items[] = {
|
||||
{USER_EXTENSION_REPO_SOURCE_USER,
|
||||
"USER",
|
||||
0,
|
||||
"User",
|
||||
"Repository managed by the user, stored in user directories"},
|
||||
{USER_EXTENSION_REPO_SOURCE_SYSTEM,
|
||||
"SYSTEM",
|
||||
0,
|
||||
"System",
|
||||
"Read-only repository provided by the system"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "UserExtensionRepo", nullptr);
|
||||
RNA_def_struct_sdna(srna, "bUserExtensionRepo");
|
||||
RNA_def_struct_ui_text(
|
||||
|
@ -6801,6 +6824,14 @@ static void rna_def_userdef_filepaths_extension_repo(BlenderRNA *brna)
|
|||
"rna_userdef_extension_repo_access_token_length",
|
||||
"rna_userdef_extension_repo_access_token_set");
|
||||
|
||||
prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, source_type_items);
|
||||
RNA_def_property_enum_funcs(prop, nullptr, "rna_userdef_extension_repo_source_set", nullptr);
|
||||
RNA_def_property_ui_text(
|
||||
prop,
|
||||
"Source",
|
||||
"Select if the repository is in a user managed or system provided directory");
|
||||
|
||||
/* NOTE(@ideasman42): this is intended to be used by a package manger component
|
||||
* which is not yet integrated. */
|
||||
prop = RNA_def_property(srna, "use_cache", PROP_BOOLEAN, PROP_NONE);
|
||||
|
|
|
@ -266,7 +266,7 @@ PyDoc_STRVAR(
|
|||
"\n"
|
||||
" Return a system resource path.\n"
|
||||
"\n"
|
||||
" :arg type: string in ['DATAFILES', 'SCRIPTS', 'PYTHON'].\n"
|
||||
" :arg type: string in ['DATAFILES', 'SCRIPTS', 'EXTENSIONS', 'PYTHON'].\n"
|
||||
" :type type: string\n"
|
||||
" :arg path: Optional subdirectory.\n"
|
||||
" :type path: string or bytes\n");
|
||||
|
@ -275,6 +275,7 @@ static PyObject *bpy_system_resource(PyObject * /*self*/, PyObject *args, PyObje
|
|||
const PyC_StringEnumItems type_items[] = {
|
||||
{BLENDER_SYSTEM_DATAFILES, "DATAFILES"},
|
||||
{BLENDER_SYSTEM_SCRIPTS, "SCRIPTS"},
|
||||
{BLENDER_SYSTEM_EXTENSIONS, "EXTENSIONS"},
|
||||
{BLENDER_SYSTEM_PYTHON, "PYTHON"},
|
||||
{0, nullptr},
|
||||
};
|
||||
|
|
|
@ -1659,6 +1659,13 @@ if(DEFINED TARGETDIR_TEXT)
|
|||
)
|
||||
endif()
|
||||
|
||||
# Create a system extensions directory (users or administrators may populate this).
|
||||
# This only contains a `readme.txt` explaining it's purpose.
|
||||
install(
|
||||
DIRECTORY ${CMAKE_SOURCE_DIR}/release/extensions
|
||||
DESTINATION ${TARGETDIR_VER}
|
||||
)
|
||||
|
||||
# Install more files specified elsewhere.
|
||||
delayed_do_install(${TARGETDIR_VER})
|
||||
|
||||
|
|
|
@ -853,6 +853,7 @@ static void print_help(bArgs *ba, bool all)
|
|||
PRINT("\n");
|
||||
PRINT(" $BLENDER_SYSTEM_RESOURCES Replace default directory of all bundled resource files.\n");
|
||||
PRINT(" $BLENDER_SYSTEM_SCRIPTS Directory to add more bundled scripts.\n");
|
||||
PRINT(" $BLENDER_SYSTEM_EXTENSIONS Directory for system extensions repository.\n");
|
||||
PRINT(" $BLENDER_SYSTEM_DATAFILES Directory to replace bundled datafiles.\n");
|
||||
PRINT(" $BLENDER_SYSTEM_PYTHON Directory to replace bundled Python libraries.\n");
|
||||
|
||||
|
@ -1533,6 +1534,9 @@ static const char arg_handle_env_system_set_doc_scripts[] =
|
|||
static const char arg_handle_env_system_set_doc_python[] =
|
||||
"\n\t"
|
||||
"Set the " STRINGIFY_ARG(BLENDER_SYSTEM_PYTHON) " environment variable.";
|
||||
static const char arg_handle_env_system_set_doc_extensions[] =
|
||||
"\n\t"
|
||||
"Set the " STRINGIFY_ARG(BLENDER_SYSTEM_EXTENSIONS) " environment variable.";
|
||||
|
||||
static int arg_handle_env_system_set(int argc, const char **argv, void * /*data*/)
|
||||
{
|
||||
|
@ -2542,6 +2546,11 @@ void main_args_setup(bContext *C, bArgs *ba, bool all)
|
|||
ba, nullptr, "--env-system-scripts", CB_EX(arg_handle_env_system_set, scripts), nullptr);
|
||||
BLI_args_add(
|
||||
ba, nullptr, "--env-system-python", CB_EX(arg_handle_env_system_set, python), nullptr);
|
||||
BLI_args_add(ba,
|
||||
nullptr,
|
||||
"--env-system-extensions",
|
||||
CB_EX(arg_handle_env_system_set, extensions),
|
||||
nullptr);
|
||||
|
||||
BLI_args_add(ba, "-t", "--threads", CB(arg_handle_threads_set), nullptr);
|
||||
|
||||
|
|
Loading…
Reference in a new issue