diff --git a/app/Makefile.am.inc b/app/Makefile.am.inc
index f82e16ec..70ac90cc 100644
--- a/app/Makefile.am.inc
+++ b/app/Makefile.am.inc
@@ -10,6 +10,7 @@ xdg_app_SOURCES = \
app/xdg-app-builtins-list-remotes.c \
app/xdg-app-builtins-repo-contents.c \
app/xdg-app-builtins-install.c \
+ app/xdg-app-builtins-override.c \
app/xdg-app-builtins-make-current.c \
app/xdg-app-builtins-update.c \
app/xdg-app-builtins-uninstall.c \
diff --git a/app/xdg-app-builtins-override.c b/app/xdg-app-builtins-override.c
new file mode 100644
index 00000000..679542c4
--- /dev/null
+++ b/app/xdg-app-builtins-override.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright © 2014 Red Hat, Inc
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see .
+ *
+ * Authors:
+ * Alexander Larsson
+ */
+
+#include "config.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "libgsystem.h"
+#include "libglnx/libglnx.h"
+
+#include "xdg-app-builtins.h"
+#include "xdg-app-utils.h"
+#include "xdg-app-run.h"
+
+static GOptionEntry options[] = {
+ { NULL }
+};
+
+gboolean
+xdg_app_builtin_override (int argc, char **argv, GCancellable *cancellable, GError **error)
+{
+ g_autoptr(GOptionContext) context = NULL;
+ gboolean ret = FALSE;
+ const char *app;
+ g_autoptr(XdgAppContext) arg_context = NULL;
+ g_autoptr(XdgAppDir) dir = NULL;
+ g_autoptr(GKeyFile) metakey = NULL;
+ g_autoptr(XdgAppContext) overrides = NULL;
+
+ context = g_option_context_new ("APP - Override settings for application");
+
+ arg_context = xdg_app_context_new ();
+ g_option_context_add_group (context, xdg_app_context_get_options (arg_context));
+
+ if (!xdg_app_option_context_parse (context, options, &argc, &argv, 0, &dir, cancellable, error))
+ return FALSE;
+
+ if (argc < 2)
+ {
+ usage_error (context, "APP must be specified", error);
+ return FALSE;
+ }
+
+ app = argv[1];
+
+ if (!xdg_app_is_valid_name (app))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "'%s' is not a valid application name", app);
+ return FALSE;
+ }
+
+ metakey = xdg_app_load_override_keyfile (app, xdg_app_dir_is_user (dir), error);
+ if (metakey == NULL)
+ return FALSE;
+
+ overrides = xdg_app_context_new ();
+ if (!xdg_app_context_load_metadata (overrides, metakey, error))
+ return FALSE;
+
+ xdg_app_context_merge (overrides, arg_context);
+
+ xdg_app_context_save_metadata (overrides, metakey);
+
+ if (!xdg_app_save_override_keyfile (metakey, app, xdg_app_dir_is_user (dir), error))
+ return FALSE;
+
+ ret = TRUE;
+
+ out:
+ /* if (context)
+ g_option_context_free (context);*/
+ return ret;
+}
diff --git a/app/xdg-app-builtins.h b/app/xdg-app-builtins.h
index c6107f50..90949450 100644
--- a/app/xdg-app-builtins.h
+++ b/app/xdg-app-builtins.h
@@ -68,6 +68,7 @@ BUILTINPROTO(build_finish);
BUILTINPROTO(build_export);
BUILTINPROTO(repo_update);
BUILTINPROTO(export_file);
+BUILTINPROTO(override);
#undef BUILTINPROTO
diff --git a/app/xdg-app-main.c b/app/xdg-app-main.c
index e966b7e1..f40da309 100644
--- a/app/xdg-app-main.c
+++ b/app/xdg-app-main.c
@@ -51,6 +51,7 @@ static XdgAppCommand commands[] = {
{ "list-runtimes", xdg_app_builtin_list_runtimes },
{ "install-app", xdg_app_builtin_install_app },
{ "update-app", xdg_app_builtin_update_app },
+ { "override", xdg_app_builtin_override },
{ "make-app-current", xdg_app_builtin_make_current_app },
{ "uninstall-app", xdg_app_builtin_uninstall_app },
{ "list-apps", xdg_app_builtin_list_apps },
diff --git a/lib/xdg-app-dir.c b/lib/xdg-app-dir.c
index ab86b632..e99e6431 100644
--- a/lib/xdg-app-dir.c
+++ b/lib/xdg-app-dir.c
@@ -50,8 +50,8 @@ struct XdgAppDeploy {
GFile *dir;
GKeyFile *metadata;
- GKeyFile *system_overrides;
- GKeyFile *user_overrides;
+ XdgAppContext *system_overrides;
+ XdgAppContext *user_overrides;
};
typedef struct {
@@ -81,8 +81,8 @@ xdg_app_deploy_finalize (GObject *object)
g_clear_object (&self->dir);
g_clear_pointer (&self->metadata, g_key_file_unref);
- g_clear_pointer (&self->system_overrides, g_key_file_unref);
- g_clear_pointer (&self->user_overrides, g_key_file_unref);
+ g_clear_pointer (&self->system_overrides, g_object_unref);
+ g_clear_pointer (&self->user_overrides, g_object_unref);
G_OBJECT_CLASS (xdg_app_deploy_parent_class)->finalize (object);
}
@@ -116,22 +116,13 @@ xdg_app_deploy_get_files (XdgAppDeploy *deploy)
XdgAppContext *
xdg_app_deploy_get_overrides (XdgAppDeploy *deploy)
{
- GError *local_error = NULL;
XdgAppContext *overrides = xdg_app_context_new ();
- if (deploy->system_overrides &&
- !xdg_app_context_load_metadata (overrides, deploy->system_overrides, &local_error))
- {
- g_warning ("Invalid system override file: %s\n", local_error->message);
- g_clear_error (&local_error);
- }
+ if (deploy->system_overrides)
+ xdg_app_context_merge (overrides, deploy->system_overrides);
- if (deploy->user_overrides &&
- !xdg_app_context_load_metadata (overrides, deploy->user_overrides, &local_error))
- {
- g_warning ("Invalid user override file: %s\n", local_error->message);
- g_clear_error (&local_error);
- }
+ if (deploy->user_overrides)
+ xdg_app_context_merge (overrides, deploy->user_overrides);
return overrides;
}
@@ -265,14 +256,15 @@ xdg_app_dir_get_path (XdgAppDir *self)
return self->basedir;
}
-static GKeyFile *
-xdg_app_load_override_file (const char *app_id, gboolean user)
+GKeyFile *
+xdg_app_load_override_keyfile (const char *app_id, gboolean user, GError **error)
{
g_autoptr(GFile) base_dir = NULL;
g_autoptr(GFile) override_dir = NULL;
g_autoptr(GFile) file = NULL;
g_autofree char *metadata_contents = NULL;
gsize metadata_size;
+ g_autoptr(GKeyFile) metakey = g_key_file_new ();
if (user)
base_dir = xdg_app_get_user_base_dir_location ();
@@ -285,17 +277,61 @@ xdg_app_load_override_file (const char *app_id, gboolean user)
if (g_file_load_contents (file, NULL,
&metadata_contents, &metadata_size, NULL, NULL))
{
- g_autoptr(GError) local_error = NULL;
- g_autoptr(GKeyFile) metakey = g_key_file_new ();
if (!g_key_file_load_from_data (metakey,
metadata_contents, metadata_size,
- 0, &local_error))
- g_warning ("Invalid override file: %s\n", local_error->message);
- else
- return g_steal_pointer (&metakey);
+ 0, error))
+ return NULL;
}
- return NULL;
+
+ return g_steal_pointer (&metakey);
+}
+
+XdgAppContext *
+xdg_app_load_override_file (const char *app_id, gboolean user, GError **error)
+{
+ XdgAppContext *overrides = xdg_app_context_new ();
+ g_autoptr(GKeyFile) metakey = NULL;
+
+ metakey = xdg_app_load_override_keyfile (app_id, user, error);
+ if (metakey == NULL)
+ return NULL;
+
+ if (!xdg_app_context_load_metadata (overrides, metakey, error))
+ return NULL;
+
+ return g_steal_pointer (&overrides);
+}
+
+gboolean
+xdg_app_save_override_keyfile (GKeyFile *metakey,
+ const char *app_id,
+ gboolean user,
+ GError **error)
+{
+ g_autoptr(GFile) base_dir = NULL;
+ g_autoptr(GFile) override_dir = NULL;
+ g_autoptr(GFile) file = NULL;
+ g_autofree char *filename = NULL;
+ g_autofree char *parent = NULL;
+
+ if (user)
+ base_dir = xdg_app_get_user_base_dir_location ();
+ else
+ base_dir = xdg_app_get_system_base_dir_location ();
+
+ override_dir = g_file_get_child (base_dir, "overrides");
+ file = g_file_get_child (override_dir, app_id);
+
+ filename = g_file_get_path (file);
+ parent = g_path_get_dirname (filename);
+ if (g_mkdir_with_parents (parent, 0755))
+ {
+ glnx_set_error_from_errno (error);
+ return FALSE;
+ }
+
+ return g_key_file_save_to_file (metakey, filename, error);
}
XdgAppDeploy *
@@ -338,10 +374,16 @@ xdg_app_dir_load_deployed (XdgAppDir *self,
{
/* Only load system overrides for system installed apps */
if (!self->user)
- deploy->system_overrides = xdg_app_load_override_file (ref_parts[1], FALSE);
+ {
+ deploy->system_overrides = xdg_app_load_override_file (ref_parts[1], FALSE, error);
+ if (deploy->system_overrides == NULL)
+ return NULL;
+ }
/* Always load user overrides */
- deploy->user_overrides = xdg_app_load_override_file (ref_parts[1], TRUE);
+ deploy->user_overrides = xdg_app_load_override_file (ref_parts[1], TRUE, error);
+ if (deploy->user_overrides == NULL)
+ return NULL;
}
return deploy;
diff --git a/lib/xdg-app-dir.h b/lib/xdg-app-dir.h
index e6d086c2..88d674ee 100644
--- a/lib/xdg-app-dir.h
+++ b/lib/xdg-app-dir.h
@@ -55,6 +55,17 @@ GQuark xdg_app_dir_error_quark (void);
GFile * xdg_app_get_system_base_dir_location (void);
GFile * xdg_app_get_user_base_dir_location (void);
+GKeyFile * xdg_app_load_override_keyfile (const char *app_id,
+ gboolean user,
+ GError **error);
+XdgAppContext *xdg_app_load_override_file (const char *app_id,
+ gboolean user,
+ GError **error);
+gboolean xdg_app_save_override_keyfile (GKeyFile *metakey,
+ const char *app_id,
+ gboolean user,
+ GError **error);
+
GFile * xdg_app_deploy_get_dir (XdgAppDeploy *deploy);
GFile * xdg_app_deploy_get_files (XdgAppDeploy *deploy);
XdgAppContext *xdg_app_deploy_get_overrides (XdgAppDeploy *deploy);