diff --git a/xdg-app-builtins-build-finish.c b/xdg-app-builtins-build-finish.c index 563cd326..557d32b3 100644 --- a/xdg-app-builtins-build-finish.c +++ b/xdg-app-builtins-build-finish.c @@ -34,10 +34,12 @@ static char *opt_command; static char **opt_allow; +static char **opt_env_override; static GOptionEntry options[] = { { "command", 0, 0, G_OPTION_ARG_STRING, &opt_command, "Command to set", "COMMAND" }, { "allow", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_allow, "Environment options to set to true", "KEY" }, + { "env", 0, 0, G_OPTION_ARG_STRING_ARRAY, &opt_env_override, "Override an environment variable", "VARIABLE=[VALUE]" }, { NULL } }; @@ -315,6 +317,24 @@ update_metadata (GFile *base, GCancellable *cancellable, GError **error) } } + if (opt_env_override) + { + for (i = 0; opt_env_override[i]; i++) + { + glnx_strfreev char **split = g_strsplit (opt_env_override[i], "=", 2); + if (split && split[0] && split[1]) + { + g_key_file_set_string (keyfile, "Vars", split[0], split[1]); + } + else + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Cannot parse variable %s", opt_env_override[i]); + goto out; + } + } + } + + if (!g_key_file_save_to_file (keyfile, path, error)) goto out; diff --git a/xdg-app-builtins-run.c b/xdg-app-builtins-run.c index a0949154..7f34f18e 100644 --- a/xdg-app-builtins-run.c +++ b/xdg-app-builtins-run.c @@ -54,6 +54,20 @@ static GOptionEntry options[] = { { NULL } }; +typedef struct { + char *name; + char *value; +} EnvVar; + +static void +free_envvar (void *p) +{ + EnvVar *v = (EnvVar *) p; + g_free (v->name); + g_free (v->value); + g_free (v); +} + static void add_extension_arg (const char *directory, const char *type, const char *extension, const char *arch, const char *branch, @@ -139,6 +153,30 @@ add_extension_args (GKeyFile *metakey, const char *full_ref, return ret; } +static void +add_env_overrides (GKeyFile *metakey, GPtrArray *env_array) +{ + gsize i, keys_count; + /* Only free the array of keys, not the actual values */ + g_autofree char **keys; + + if (!g_key_file_has_group (metakey, "Vars")) + return; + + keys = g_key_file_get_keys (metakey, "Vars", &keys_count, NULL); + if (!keys) + return; + + for (i = 0; i < keys_count; i++) + { + EnvVar *var = malloc (sizeof (EnvVar)); + var->name = keys[i]; + var->value = g_key_file_get_string (metakey, "Vars", keys[i], NULL); + + g_ptr_array_add (env_array, var); + } +} + gboolean xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **error) { @@ -169,6 +207,7 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** g_autoptr (GError) my_error = NULL; g_autoptr (GError) my_error2 = NULL; g_autoptr(GPtrArray) argv_array = NULL; + g_autoptr(GPtrArray) env_array = NULL; g_autofree char *monitor_path = NULL; gsize metadata_size, runtime_metadata_size; const char *app; @@ -261,6 +300,8 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** path = g_file_get_path (runtime_deploy); g_debug ("Using runtime in %s", path); + env_array = g_ptr_array_new_with_free_func (free_envvar); + runtime_metadata = g_file_get_child (runtime_deploy, "metadata"); if (g_file_load_contents (runtime_metadata, cancellable, &runtime_metadata_contents, &runtime_metadata_size, NULL, NULL)) { @@ -271,8 +312,13 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** if (!add_extension_args (runtime_metakey, runtime_ref, argv_array, cancellable, error)) goto out; + + add_env_overrides (runtime_metakey, env_array); } + /* Load application environment overrides *after* runtime */ + add_env_overrides (metakey, env_array); + if ((app_id_dir = xdg_app_ensure_data_dir (app, cancellable, error)) == NULL) goto out; @@ -339,6 +385,15 @@ xdg_app_builtin_run (int argc, char **argv, GCancellable *cancellable, GError ** g_setenv ("XDG_CONFIG_HOME", gs_file_get_path_cached (app_id_dir_config), TRUE); g_setenv ("XDG_CACHE_HOME", gs_file_get_path_cached (app_id_dir_cache), TRUE); + for (i = 0; i < env_array->len; i++) + { + EnvVar *var = g_ptr_array_index (env_array, i); + if (!var->value || !var->value[0]) + g_unsetenv (var->name); + else + g_setenv (var->name, var->value, TRUE); + } + xdg_app_run_in_transient_unit (app); if (execv (HELPER, (char **)argv_array->pdata) == -1)