From 132d1186d950f1743112ac4f0eff98e4d373e06a Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 26 Nov 2015 23:07:05 +0100 Subject: [PATCH] Initial version of libxdg-app This is a highlevel library for working with xdg-app without using the commandline interface. The primary usecase for this is for creating a graphical frontend for app installation/update. --- .gitignore | 4 + Makefile.am | 3 + configure.ac | 77 +++++++- lib/Makefile.am.inc | 88 +++++++++ lib/test-lib.c | 109 +++++++++++ lib/xdg-app-enum-types.c.template | 39 ++++ lib/xdg-app-enum-types.h.template | 24 +++ lib/xdg-app-installation.c | 292 ++++++++++++++++++++++++++++ lib/xdg-app-installation.h | 78 ++++++++ lib/xdg-app-installed-ref-private.h | 36 ++++ lib/xdg-app-installed-ref.c | 234 ++++++++++++++++++++++ lib/xdg-app-installed-ref.h | 58 ++++++ lib/xdg-app-ref.c | 235 ++++++++++++++++++++++ lib/xdg-app-ref.h | 62 ++++++ lib/xdg-app-remote-private.h | 33 ++++ lib/xdg-app-remote.c | 245 +++++++++++++++++++++++ lib/xdg-app-remote.h | 60 ++++++ lib/xdg-app-version-macros.h.in | 36 ++++ lib/xdg-app.c | 3 + lib/xdg-app.h | 37 ++++ xdg-app.pc.in | 6 + 21 files changed, 1758 insertions(+), 1 deletion(-) create mode 100644 lib/Makefile.am.inc create mode 100644 lib/test-lib.c create mode 100644 lib/xdg-app-enum-types.c.template create mode 100644 lib/xdg-app-enum-types.h.template create mode 100644 lib/xdg-app-installation.c create mode 100644 lib/xdg-app-installation.h create mode 100644 lib/xdg-app-installed-ref-private.h create mode 100644 lib/xdg-app-installed-ref.c create mode 100644 lib/xdg-app-installed-ref.h create mode 100644 lib/xdg-app-ref.c create mode 100644 lib/xdg-app-ref.h create mode 100644 lib/xdg-app-remote-private.h create mode 100644 lib/xdg-app-remote.c create mode 100644 lib/xdg-app-remote.h create mode 100644 lib/xdg-app-version-macros.h.in create mode 100644 lib/xdg-app.c create mode 100644 lib/xdg-app.h diff --git a/.gitignore b/.gitignore index a42efe8c..86045e68 100644 --- a/.gitignore +++ b/.gitignore @@ -45,3 +45,7 @@ document-portal/xdp-dbus.[ch] document-portal/xdp-resources.[ch] .dirstamp test-suite*.log +lib/xdg-app-version-macros.h +xdg-app.pc +lib/xdg-app-enum-types.c +lib/xdg-app-enum-types.h diff --git a/Makefile.am b/Makefile.am index 963b0638..e7f8df04 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ NULL = bin_PROGRAMS = $(NULL) +noinst_PROGRAMS = $(NULL) libexec_PROGRAMS = $(NULL) DISTCLEANFILES= $(NULL) BUILT_SOURCES = $(NULL) @@ -38,6 +39,7 @@ dist_triggers_SCRIPTS = \ EXTRA_DIST = +lib_LTLIBRARIES = noinst_LTLIBRARIES = libglnx.la libglnx_srcpath := $(srcdir)/libglnx libglnx_cflags := $(BASE_CFLAGS) "-I$(libglnx_srcpath)" @@ -47,6 +49,7 @@ include libglnx/Makefile-libglnx.am.inc include common/Makefile.am.inc include data/Makefile.am.inc include app/Makefile.am.inc +include lib/Makefile.am.inc include builder/Makefile.am.inc include session-helper/Makefile.am.inc include dbus-proxy/Makefile.am.inc diff --git a/configure.ac b/configure.ac index 98937c4e..537071e4 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,23 @@ AC_PREREQ([2.63]) -AC_INIT([xdg-app],[0.4.5]) +# Making releases: +# XDG_APP_MICRO_VERSION += 1; +# XDG_APP_INTERFACE_AGE += 1; +# XDG_APP_BINARY_AGE += 1; +# if any functions have been added, set XDG_APP_INTERFACE_AGE to 0. +# if backwards compatibility has been broken, +# set XDG_APP_BINARY_AGE and XDG_APP_INTERFACE_AGE to 0. + +m4_define([xdg_app_major_version], [0]) +m4_define([xdg_app_minor_version], [4]) +m4_define([xdg_app_micro_version], [5]) +m4_define([xdg_app_interface_age], [0]) +m4_define([xdg_app_binary_age], + [m4_eval(100 * xdg_app_minor_version + xdg_app_micro_version)]) +m4_define([xdg_app_version], + [xdg_app_major_version.xdg_app_minor_version.xdg_app_micro_version]) + +AC_INIT([xdg-app],[xdg_app_version]) AC_USE_SYSTEM_EXTENSIONS @@ -50,6 +67,7 @@ AC_CHECK_FUNCS(fdwalk) AC_CHECK_HEADER([sys/xattr.h], [], AC_MSG_ERROR([You must have sys/xattr.h from glibc])) AC_CHECK_HEADER([sys/capability.h], have_caps=yes, AC_MSG_ERROR([sys/capability.h header not found])) +AC_SUBST([GLIB_MKENUMS], [`$PKG_CONFIG --variable glib_mkenums glib-2.0`]) AC_SUBST([GLIB_COMPILE_RESOURCES], [`$PKG_CONFIG --variable glib_compile_resources gio-2.0`]) AC_SUBST([GDBUS_CODEGEN], [`$PKG_CONFIG --variable gdbus_codegen gio-2.0`]) @@ -174,9 +192,66 @@ if test x$enable_documentation = xyes; then fi AM_CONDITIONAL(BUILD_DOCUMENTATION, test x$enable_documentation = xyes) +################################################## +# Visibility handling +################################################## + +HIDDEN_VISIBILITY_CFLAGS="" +case "$host" in + *) + dnl on other compilers, check if we can do -fvisibility=hidden + SAVED_CFLAGS="${CFLAGS}" + CFLAGS="-fvisibility=hidden" + AC_MSG_CHECKING([for -fvisibility=hidden compiler flag]) + AC_TRY_COMPILE([], [int main (void) { return 0; }], + AC_MSG_RESULT(yes) + enable_fvisibility_hidden=yes, + AC_MSG_RESULT(no) + enable_fvisibility_hidden=no) + CFLAGS="${SAVED_CFLAGS}" + + AS_IF([test "${enable_fvisibility_hidden}" = "yes"], [ + AC_DEFINE([XDG_APP_EXTERN], [__attribute__((visibility("default"))) extern], + [defines how to decorate public symbols while building]) + HIDDEN_VISIBILITY_CFLAGS="-fvisibility=hidden" + ], [ + AC_DEFINE([XDG_APP_EXTERN], [extern], + [defines how to decorate public symbols while building]) + ]) + ;; +esac +AC_SUBST(HIDDEN_VISIBILITY_CFLAGS) + +XDG_APP_MAJOR_VERSION=xdg_app_major_version +XDG_APP_MINOR_VERSION=xdg_app_minor_version +XDG_APP_MICRO_VERSION=xdg_app_micro_version +XDG_APP_INTERFACE_AGE=xdg_app_interface_age +XDG_APP_VERSION=xdg_app_version +AC_SUBST(XDG_APP_MAJOR_VERSION) +AC_SUBST(XDG_APP_MINOR_VERSION) +AC_SUBST(XDG_APP_MICRO_VERSION) +AC_SUBST(XDG_APP_INTERFACE_AGE) +AC_SUBST(XDG_APP_VERSION) + +# libtool versioning +#LT_RELEASE=$XDG_APP_MAJOR_VERSION.$XDG_APP_MINOR_VERSION +#LT_CURRENT=`expr $XDG_APP_MICRO_VERSION - $XDG_APP_INTERFACE_AGE` +#LT_REVISION=$XDG_APP_INTERFACE_AGE +#LT_AGE=`expr $XDG_APP_BINARY_AGE - $XDG_APP_INTERFACE_AGE` +#LT_CURRENT_MINUS_AGE=`expr $LT_CURRENT - $LT_AGE` + +m4_define([lt_current], [m4_eval(100 * xdg_app_minor_version + xdg_app_micro_version - xdg_app_interface_age)]) +m4_define([lt_revision], [xdg_app_interface_age]) +m4_define([lt_age], [m4_eval(xdg_app_binary_age - xdg_app_interface_age)]) +LT_VERSION_INFO="lt_current:lt_revision:lt_age" +LT_CURRENT_MINUS_AGE=m4_eval(lt_current - lt_age) +AC_SUBST(LT_VERSION_INFO) +AC_SUBST(LT_CURRENT_MINUS_AGE) + AC_CONFIG_FILES([ Makefile doc/Makefile xdg-app.pc +lib/xdg-app-version-macros.h ]) AC_OUTPUT diff --git a/lib/Makefile.am.inc b/lib/Makefile.am.inc new file mode 100644 index 00000000..0ec65b9a --- /dev/null +++ b/lib/Makefile.am.inc @@ -0,0 +1,88 @@ +lib_LTLIBRARIES += libxdg-app.la + +noinst_PROGRAMS += test-libxdg-app + +public_headers = \ + lib/xdg-app.h \ + lib/xdg-app-ref.h \ + lib/xdg-app-installed-ref.h \ + lib/xdg-app-installation.h \ + lib/xdg-app-remote.h \ + lib/xdg-app-version-macros.h \ + $(NULL) + +generated_public_headers = \ + lib/xdg-app-enum-types.h \ + $(NULL) + +BUILT_SOURCES += \ + lib/xdg-app-enum-types.c \ + lib/xdg-app-enum-types.h \ + $(NULL) + +DISTCLEANFILES += \ + lib/xdg-app-enum-types.c \ + lib/xdg-app-enum-types.h \ + $(NULL) + + +lib/xdg-app-enum-types.h: $(public_headers) lib/xdg-app-enum-types.h.template + $(AM_V_GEN) $(GLIB_MKENUMS) --template $(filter %.template,$^) $(filter-out %.template,$^) > \ + lib/xdg-app-enum-types.h.tmp && mv lib/xdg-app-enum-types.h.tmp lib/xdg-app-enum-types.h + +lib/xdg-app-enum-types.c: $(public_headers) lib/xdg-app-enum-types.c.template + $(AM_V_GEN) $(GLIB_MKENUMS) --template $(filter %.template,$^) $(filter-out %.template,$^) > \ + lib/xdg-app-enum-types.c.tmp && mv lib/xdg-app-enum-types.c.tmp lib/xdg-app-enum-types.c + +xdgappincludedir = $(includedir)/xdg-app +xdgappinclude_HEADERS = $(public_headers) $(generated_public_headers) + +libxdg_app_la_SOURCES = \ + $(public_headers) \ + $(generated_public_headers) \ + lib/xdg-app.c \ + lib/xdg-app-enum-types.c \ + lib/xdg-app-ref.c \ + lib/xdg-app-installed-ref.c \ + lib/xdg-app-installed-ref-private.h \ + lib/xdg-app-remote-private.h \ + lib/xdg-app-remote.c \ + lib/xdg-app-installation.c \ + $(NULL) + +libxdg_app_la_CFLAGS = \ + $(HIDDEN_VISIBILITY_CFLAGS) \ + -DXDG_APP_COMPILATION \ + -I$(srcdir)/lib \ + $(AM_CFLAGS) \ + $(BASE_CFLAGS) \ + $(OSTREE_CFLAGS) \ + $(SOUP_CFLAGS) \ + $(NULL) + +libxdg_app_la_LDFLAGS = \ + -version-info $(LT_VERSION_INFO) \ + -export-dynamic \ + -rpath $(libdir) \ + $(NULL) + +libxdg_app_la_LIBADD = \ + libxdgapp-common.la \ + $(BASE_LIBS) \ + $(OSTREE_LIBS) \ + $(SOUP_LIBS) \ + $(NULL) + +test_libxdg_app_SOURCES = \ + lib/test-lib.c \ + $(NULL) + +test_libxdg_app_CFLAGS = \ + $(BASE_CFLAGS) \ + -I$(srcdir)/lib \ + $(NULL) + +test_libxdg_app_LDADD = \ + $(BASE_LIBS) \ + libxdg-app.la \ + $(NULL) diff --git a/lib/test-lib.c b/lib/test-lib.c new file mode 100644 index 00000000..66cd2185 --- /dev/null +++ b/lib/test-lib.c @@ -0,0 +1,109 @@ +#include + +int +main (int argc, char *argv[]) +{ + XdgAppInstallation *installation; + XdgAppInstalledRef **apps; + XdgAppRef **refs; + XdgAppInstalledRef *app1; + XdgAppInstalledRef *app2; + XdgAppInstalledRef **runtimes; + XdgAppRemote **remotes; + int i, j; + + installation = xdg_app_installation_new_user (); + + apps = xdg_app_installation_list_installed_refs (installation, + XDG_APP_REF_KIND_APP, + NULL, NULL); + + for (i = 0; apps[i] != NULL; i++) + { + g_print ("%d %s %s %s %s %s %s %d\n", + xdg_app_ref_get_kind (XDG_APP_REF(apps[i])), + xdg_app_ref_get_name (XDG_APP_REF(apps[i])), + xdg_app_ref_get_arch (XDG_APP_REF(apps[i])), + xdg_app_ref_get_version (XDG_APP_REF(apps[i])), + xdg_app_ref_get_commit (XDG_APP_REF(apps[i])), + xdg_app_installed_ref_get_origin (apps[i]), + xdg_app_installed_ref_get_deploy_dir (apps[i]), + xdg_app_installed_ref_get_current (apps[i])); + g_print ("metadata:\n%s\n", xdg_app_installed_ref_load_metadata (apps[i], NULL, NULL)); + } + + runtimes = xdg_app_installation_list_installed_refs (installation, + XDG_APP_REF_KIND_RUNTIME, + NULL, NULL); + + for (i = 0; runtimes[i] != NULL; i++) + { + g_print ("%d %s %s %s %s %s %s %d\n", + xdg_app_ref_get_kind (XDG_APP_REF(runtimes[i])), + xdg_app_ref_get_name (XDG_APP_REF(runtimes[i])), + xdg_app_ref_get_arch (XDG_APP_REF(runtimes[i])), + xdg_app_ref_get_version (XDG_APP_REF(runtimes[i])), + xdg_app_ref_get_commit (XDG_APP_REF(runtimes[i])), + xdg_app_installed_ref_get_origin (runtimes[i]), + xdg_app_installed_ref_get_deploy_dir (runtimes[i]), + xdg_app_installed_ref_get_current (runtimes[i])); + } + + app1 = xdg_app_installation_get_installed_ref (installation, + XDG_APP_REF_KIND_APP, + "org.gnome.gedit", + NULL, "master", NULL, NULL); + if (app1) + g_print ("gedit master: %d %s %s %s %s %s %s %d\n", + xdg_app_ref_get_kind (XDG_APP_REF(app1)), + xdg_app_ref_get_name (XDG_APP_REF(app1)), + xdg_app_ref_get_arch (XDG_APP_REF(app1)), + xdg_app_ref_get_version (XDG_APP_REF(app1)), + xdg_app_ref_get_commit (XDG_APP_REF(app1)), + xdg_app_installed_ref_get_origin (app1), + xdg_app_installed_ref_get_deploy_dir (app1), + xdg_app_installed_ref_get_current (app1)); + + app2 = xdg_app_installation_get_current_installed_app (installation, + "org.gnome.gedit", + NULL, NULL); + if (app2) + g_print ("gedit current: %d %s %s %s %s %s %s %d\n", + xdg_app_ref_get_kind (XDG_APP_REF(app2)), + xdg_app_ref_get_name (XDG_APP_REF(app2)), + xdg_app_ref_get_arch (XDG_APP_REF(app2)), + xdg_app_ref_get_version (XDG_APP_REF(app2)), + xdg_app_ref_get_commit (XDG_APP_REF(app2)), + xdg_app_installed_ref_get_origin (app2), + xdg_app_installed_ref_get_deploy_dir (app2), + xdg_app_installed_ref_get_current (app2)); + + + remotes = xdg_app_installation_list_remotes (installation, + NULL, NULL); + + for (i = 0; remotes[i] != NULL; i++) + { + g_print ("%s %s %s %d\n", + xdg_app_remote_get_name (remotes[i]), + xdg_app_remote_get_url (remotes[i]), + xdg_app_remote_get_title (remotes[i]), + xdg_app_remote_get_gpg_verify (remotes[i])); + + refs = xdg_app_remote_list_refs (remotes[i], + NULL, NULL); + if (refs) + { + for (j = 0; refs[j] != NULL; j++) + { + g_print ("%d %s %s %s %s\n", + xdg_app_ref_get_kind (refs[j]), + xdg_app_ref_get_name (refs[j]), + xdg_app_ref_get_arch (refs[j]), + xdg_app_ref_get_version (refs[j]), + xdg_app_ref_get_commit (refs[j])); + } + } + } + +} diff --git a/lib/xdg-app-enum-types.c.template b/lib/xdg-app-enum-types.c.template new file mode 100644 index 00000000..1c831a43 --- /dev/null +++ b/lib/xdg-app-enum-types.c.template @@ -0,0 +1,39 @@ +/*** BEGIN file-header ***/ +#include "config.h" +#include +#include +#include + +/*** END file-header ***/ + +/*** BEGIN file-production ***/ +/* enumerations from "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static volatile gsize g_define_type_id__volatile = 0; + + if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + GType g_define_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); + } + + return g_define_type_id__volatile; +} + +/*** END value-tail ***/ diff --git a/lib/xdg-app-enum-types.h.template b/lib/xdg-app-enum-types.h.template new file mode 100644 index 00000000..867d7c89 --- /dev/null +++ b/lib/xdg-app-enum-types.h.template @@ -0,0 +1,24 @@ +/*** BEGIN file-header ***/ +#ifndef __XDG_APP_ENUM_TYPES_H__ +#define __XDG_APP_ENUM_TYPES_H__ + +#include + +G_BEGIN_DECLS +/*** END file-header ***/ + +/*** BEGIN file-production ***/ + +/* enumerations from "@filename@" */ +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +XDG_APP_EXTERN GType @enum_name@_get_type (void) G_GNUC_CONST; +#define @ENUMPREFIX@_TYPE_@ENUMSHORT@ (@enum_name@_get_type ()) +/*** END value-header ***/ + +/*** BEGIN file-tail ***/ +G_END_DECLS + +#endif /* __GIO_ENUM_TYPES_H__ */ +/*** END file-tail ***/ diff --git a/lib/xdg-app-installation.c b/lib/xdg-app-installation.c new file mode 100644 index 00000000..5ba13a94 --- /dev/null +++ b/lib/xdg-app-installation.c @@ -0,0 +1,292 @@ +/* + * Copyright © 2015 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 "xdg-app-installation.h" +#include "xdg-app-installed-ref-private.h" +#include "xdg-app-remote-private.h" +#include "xdg-app-enum-types.h" +#include "xdg-app-dir.h" +#include "xdg-app-utils.h" + +typedef struct _XdgAppInstallationPrivate XdgAppInstallationPrivate; + +struct _XdgAppInstallationPrivate +{ + XdgAppDir *dir; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (XdgAppInstallation, xdg_app_installation, G_TYPE_OBJECT) + +enum { + PROP_0, +}; + +static void +xdg_app_installation_finalize (GObject *object) +{ + XdgAppInstallation *self = XDG_APP_INSTALLATION (object); + XdgAppInstallationPrivate *priv = xdg_app_installation_get_instance_private (self); + + g_object_unref (priv->dir); + + G_OBJECT_CLASS (xdg_app_installation_parent_class)->finalize (object); +} + +static void +xdg_app_installation_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xdg_app_installation_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + + switch (prop_id) + { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xdg_app_installation_class_init (XdgAppInstallationClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = xdg_app_installation_get_property; + object_class->set_property = xdg_app_installation_set_property; + object_class->finalize = xdg_app_installation_finalize; + +} + +static void +xdg_app_installation_init (XdgAppInstallation *self) +{ +} + +static XdgAppInstallation * +xdg_app_installation_new_for_dir (XdgAppDir *dir) +{ + XdgAppInstallation *self = g_object_new (XDG_APP_TYPE_INSTALLATION, NULL); + XdgAppInstallationPrivate *priv = xdg_app_installation_get_instance_private (self); + + priv->dir = dir; + return self; +} + +XdgAppInstallation * +xdg_app_installation_new_system (void) +{ + return xdg_app_installation_new_for_dir (xdg_app_dir_get_system ()); +} + +XdgAppInstallation * +xdg_app_installation_new_user (void) +{ + return xdg_app_installation_new_for_dir (xdg_app_dir_get_user ()); +} + +XdgAppInstallation * +xdg_app_installation_new_for_path (GFile *path, gboolean user) +{ + return xdg_app_installation_new_for_dir (xdg_app_dir_new (path, user)); +} + +gboolean +xdg_app_installation_get_is_user (XdgAppInstallation *self) +{ + XdgAppInstallationPrivate *priv = xdg_app_installation_get_instance_private (self); + + return xdg_app_dir_is_user (priv->dir); +} + +static XdgAppInstalledRef * +get_ref (XdgAppInstallation *self, + const char *full_ref, + GCancellable *cancellable) +{ + XdgAppInstallationPrivate *priv = xdg_app_installation_get_instance_private (self); + g_auto(GStrv) parts = NULL; + g_autofree char *origin = NULL; + g_autofree char *commit = NULL; + g_autoptr(XdgAppDir) dir = NULL; + g_autoptr(GFile) deploy_dir = NULL; + g_autoptr(GFile) deploy_subdir = NULL; + g_autofree char *deploy_path = NULL; + gboolean is_current = FALSE; + + parts = g_strsplit (full_ref, "/", -1); + + origin = xdg_app_dir_get_origin (priv->dir, full_ref, NULL, NULL); + commit = xdg_app_dir_read_active (priv->dir, full_ref, cancellable); + deploy_dir = xdg_app_dir_get_deploy_dir (priv->dir, full_ref); + if (deploy_dir && commit) + { + deploy_subdir = g_file_get_child (deploy_dir, commit); + deploy_path = g_file_get_path (deploy_subdir); + } + + if (strcmp (parts[0], "app") == 0) + { + g_autofree char *current = + xdg_app_dir_current_ref (priv->dir, parts[1], cancellable); + if (current && strcmp (full_ref, current) == 0) + is_current = TRUE; + } + + return xdg_app_installed_ref_new (full_ref, + commit, + origin, + deploy_path, + is_current); +} + +XdgAppInstalledRef * +xdg_app_installation_get_installed_ref (XdgAppInstallation *self, + XdgAppRefKind kind, + const char *name, + const char *arch, + const char *version, + GCancellable *cancellable, + GError **error) +{ + XdgAppInstallationPrivate *priv = xdg_app_installation_get_instance_private (self); + g_autoptr(GFile) deploy = NULL; + g_autofree char *ref = NULL; + + if (arch == NULL) + arch = xdg_app_get_arch (); + + if (kind == XDG_APP_REF_KIND_APP) + ref = xdg_app_build_app_ref (name, version, arch); + else + ref = xdg_app_build_runtime_ref (name, version, arch); + + + deploy = xdg_app_dir_get_if_deployed (priv->dir, + ref, NULL, cancellable); + if (deploy == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "Ref %s no installed", ref); + return NULL; + } + + return get_ref (self, ref, cancellable); +} + +XdgAppInstalledRef * +xdg_app_installation_get_current_installed_app (XdgAppInstallation *self, + const char *name, + GCancellable *cancellable, + GError **error) +{ + XdgAppInstallationPrivate *priv = xdg_app_installation_get_instance_private (self); + g_autoptr(GFile) deploy = NULL; + g_autofree char *current = + xdg_app_dir_current_ref (priv->dir, name, cancellable); + + if (current) + deploy = xdg_app_dir_get_if_deployed (priv->dir, + current, NULL, cancellable); + + if (deploy == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "App %s no installed", name); + return NULL; + } + + return get_ref (self, current, cancellable); +} + +XdgAppInstalledRef ** +xdg_app_installation_list_installed_refs (XdgAppInstallation *self, + XdgAppRefKind kind, + GCancellable *cancellable, + GError **error) +{ + XdgAppInstallationPrivate *priv = xdg_app_installation_get_instance_private (self); + g_auto(GStrv) raw_refs = NULL; + g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref); + int i; + + if (!xdg_app_dir_list_refs (priv->dir, + kind == XDG_APP_REF_KIND_APP ? "app" : "runtime", +&raw_refs, + cancellable, error)) + return NULL; + + for (i = 0; raw_refs[i] != NULL; i++) + { + g_ptr_array_add (refs, + get_ref (self, raw_refs[i], cancellable)); + } + + g_ptr_array_add (refs, NULL); + return (XdgAppInstalledRef **)g_ptr_array_free (g_steal_pointer (&refs), FALSE); +} + +XdgAppRemote ** +xdg_app_installation_list_remotes (XdgAppInstallation *self, + GCancellable *cancellable, + GError **error) +{ + XdgAppInstallationPrivate *priv = xdg_app_installation_get_instance_private (self); + g_auto(GStrv) remote_names = NULL; + g_autoptr(GPtrArray) remotes = g_ptr_array_new_with_free_func (g_object_unref); + guint n_remotes; + OstreeRepo *repo; + int i; + + if (!xdg_app_dir_ensure_repo (priv->dir, cancellable, error)) + return FALSE; + + repo = xdg_app_dir_get_repo (priv->dir); + remote_names = ostree_repo_remote_list (repo, &n_remotes); + + if (remote_names) + { + for (i = 0; remote_names[i] != NULL; i++) + { + g_ptr_array_add (remotes, + xdg_app_remote_new (repo, remote_names[i])); + } + } + + g_ptr_array_add (remotes, NULL); + return (XdgAppRemote **)g_ptr_array_free (g_steal_pointer (&remotes), FALSE); +} diff --git a/lib/xdg-app-installation.h b/lib/xdg-app-installation.h new file mode 100644 index 00000000..95c3ca36 --- /dev/null +++ b/lib/xdg-app-installation.h @@ -0,0 +1,78 @@ +/* + * Copyright © 2015 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 + */ + +#if !defined (__XDG_APP_H_INSIDE__) && !defined (XDG_APP_COMPILATION) +#error "Only can be included installationectly." +#endif + +#ifndef __XDG_APP_INSTALLATION_H__ +#define __XDG_APP_INSTALLATION_H__ + +typedef struct XdgAppInstallation XdgAppInstallation; + +#include +#include +#include + +#define XDG_APP_TYPE_INSTALLATION xdg_app_installation_get_type() +#define XDG_APP_INSTALLATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XDG_APP_TYPE_INSTALLATION, XdgAppInstallation)) +#define XDG_APP_IS_INSTALLATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XDG_APP_TYPE_INSTALLATION)) + +XDG_APP_EXTERN GType xdg_app_installation_get_type (void); + +struct XdgAppInstallation { + GObject parent; +}; + +typedef struct { + GObjectClass parent_class; +} XdgAppInstallationClass; + + +#if !GLIB_CHECK_VERSION(2, 43, 4) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppInstallation, g_object_uninstallation) +#endif + +XDG_APP_EXTERN XdgAppInstallation *xdg_app_installation_new_system (void); +XDG_APP_EXTERN XdgAppInstallation *xdg_app_installation_new_user (void); +XDG_APP_EXTERN XdgAppInstallation *xdg_app_installation_new_for_path (GFile *path, + gboolean user); + +XDG_APP_EXTERN gboolean xdg_app_installation_get_is_user (XdgAppInstallation *self); +XDG_APP_EXTERN XdgAppInstalledRef **xdg_app_installation_list_installed_refs (XdgAppInstallation *self, + XdgAppRefKind kind, + GCancellable *cancellable, + GError **error); +XDG_APP_EXTERN XdgAppInstalledRef * xdg_app_installation_get_installed_ref (XdgAppInstallation *self, + XdgAppRefKind kind, + const char *name, + const char *arch, + const char *version, + GCancellable *cancellable, + GError **error); +XDG_APP_EXTERN XdgAppInstalledRef * xdg_app_installation_get_current_installed_app (XdgAppInstallation *self, + const char *name, + GCancellable *cancellable, + GError **error); +XDG_APP_EXTERN XdgAppRemote ** xdg_app_installation_list_remotes (XdgAppInstallation *self, + GCancellable *cancellable, + GError **error); + +#endif /* __XDG_APP_INSTALLATION_H__ */ diff --git a/lib/xdg-app-installed-ref-private.h b/lib/xdg-app-installed-ref-private.h new file mode 100644 index 00000000..8baa0881 --- /dev/null +++ b/lib/xdg-app-installed-ref-private.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2015 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 + */ + +#if !defined (__XDG_APP_H_INSIDE__) && !defined (XDG_APP_COMPILATION) +#error "Only can be included installed_refectly." +#endif + +#ifndef __XDG_APP_INSTALLED_REF_PRIVATE_H__ +#define __XDG_APP_INSTALLED_REF_PRIVATE_H__ + +#include + +XdgAppInstalledRef *xdg_app_installed_ref_new (const char *full_ref, + const char *commit, + const char *origin, + const char *deploy_dir, + gboolean current); + +#endif /* __XDG_APP_INSTALLED_REF_PRIVATE_H__ */ diff --git a/lib/xdg-app-installed-ref.c b/lib/xdg-app-installed-ref.c new file mode 100644 index 00000000..9e3a814e --- /dev/null +++ b/lib/xdg-app-installed-ref.c @@ -0,0 +1,234 @@ +/* + * Copyright © 2015 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 "xdg-app-installed-ref.h" +#include "xdg-app-enum-types.h" +#include "xdg-app-error.h" + +typedef struct _XdgAppInstalledRefPrivate XdgAppInstalledRefPrivate; + +struct _XdgAppInstalledRefPrivate +{ + gboolean current; + char *origin; + char *deploy_dir; + + char *metadata; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (XdgAppInstalledRef, xdg_app_installed_ref, XDG_APP_TYPE_REF) + +enum { + PROP_0, + + PROP_CURRENT, + PROP_ORIGIN, + PROP_DEPLOY_DIR +}; + +static void +xdg_app_installed_ref_finalize (GObject *object) +{ + XdgAppInstalledRef *self = XDG_APP_INSTALLED_REF (object); + XdgAppInstalledRefPrivate *priv = xdg_app_installed_ref_get_instance_private (self); + + g_free (priv->origin); + g_free (priv->deploy_dir); + g_free (priv->metadata); + + G_OBJECT_CLASS (xdg_app_installed_ref_parent_class)->finalize (object); +} + +static void +xdg_app_installed_ref_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XdgAppInstalledRef *self = XDG_APP_INSTALLED_REF (object); + XdgAppInstalledRefPrivate *priv = xdg_app_installed_ref_get_instance_private (self); + + switch (prop_id) + { + case PROP_CURRENT: + priv->current = g_value_get_boolean (value); + break; + + case PROP_ORIGIN: + g_clear_pointer (&priv->origin, g_free); + priv->origin = g_value_dup_string (value); + break; + + case PROP_DEPLOY_DIR: + g_clear_pointer (&priv->deploy_dir, g_free); + priv->deploy_dir = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xdg_app_installed_ref_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XdgAppInstalledRef *self = XDG_APP_INSTALLED_REF (object); + XdgAppInstalledRefPrivate *priv = xdg_app_installed_ref_get_instance_private (self); + + switch (prop_id) + { + case PROP_CURRENT: + g_value_set_boolean (value, priv->current); + break; + + case PROP_ORIGIN: + g_value_set_string (value, priv->origin); + break; + + case PROP_DEPLOY_DIR: + g_value_set_string (value, priv->deploy_dir); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xdg_app_installed_ref_class_init (XdgAppInstalledRefClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = xdg_app_installed_ref_get_property; + object_class->set_property = xdg_app_installed_ref_set_property; + object_class->finalize = xdg_app_installed_ref_finalize; + + g_object_class_install_property (object_class, + PROP_CURRENT, + g_param_spec_boolean ("current", + "", + "", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_ORIGIN, + g_param_spec_string ("origin", + "", + "", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_DEPLOY_DIR, + g_param_spec_string ("deploy-dir", + "", + "", + NULL, + G_PARAM_READWRITE)); +} + +static void +xdg_app_installed_ref_init (XdgAppInstalledRef *self) +{ +} + +const char * +xdg_app_installed_ref_get_origin (XdgAppInstalledRef *self) +{ + XdgAppInstalledRefPrivate *priv = xdg_app_installed_ref_get_instance_private (self); + + return priv->origin; +} + +const char * +xdg_app_installed_ref_get_deploy_dir (XdgAppInstalledRef *self) +{ + XdgAppInstalledRefPrivate *priv = xdg_app_installed_ref_get_instance_private (self); + + return priv->deploy_dir; +} + +gboolean +xdg_app_installed_ref_get_current (XdgAppInstalledRef *self) +{ + XdgAppInstalledRefPrivate *priv = xdg_app_installed_ref_get_instance_private (self); + + return priv->current; +} + +const char * +xdg_app_installed_ref_load_metadata (XdgAppInstalledRef *self, + GCancellable *cancellable, + GError **error) +{ + XdgAppInstalledRefPrivate *priv = xdg_app_installed_ref_get_instance_private (self); + + if (priv->metadata == NULL) + { + g_autofree char *path = NULL; + if (priv->deploy_dir == NULL) + { + g_set_error (error, XDG_APP_ERROR, XDG_APP_ERROR_NOT_FOUND, + "Unknown deploy directory"); + return NULL; + } + + path = g_build_filename (priv->deploy_dir, "metadata", NULL); + if (!g_file_get_contents (path, &priv->metadata, NULL, error)) + return NULL; + } + + return priv->metadata; +} + +XdgAppInstalledRef * +xdg_app_installed_ref_new (const char *full_ref, + const char *commit, + const char *origin, + const char *deploy_dir, + gboolean current) +{ + XdgAppRefKind kind = XDG_APP_REF_KIND_APP; + g_auto(GStrv) parts = NULL; + + parts = g_strsplit (full_ref, "/", -1); + + if (strcmp (parts[0], "app") != 0) + kind = XDG_APP_REF_KIND_RUNTIME; + + return g_object_new (XDG_APP_TYPE_INSTALLED_REF, + "kind", kind, + "name", parts[1], + "arch", parts[2], + "version", parts[3], + "commit", commit, + "origin", origin, + "current", current, + "deploy-dir", deploy_dir, + NULL); +} diff --git a/lib/xdg-app-installed-ref.h b/lib/xdg-app-installed-ref.h new file mode 100644 index 00000000..ddb8970a --- /dev/null +++ b/lib/xdg-app-installed-ref.h @@ -0,0 +1,58 @@ +/* + * Copyright © 2015 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 + */ + +#if !defined (__XDG_APP_H_INSIDE__) && !defined (XDG_APP_COMPILATION) +#error "Only can be included installed_refectly." +#endif + +#ifndef __XDG_APP_INSTALLED_REF_H__ +#define __XDG_APP_INSTALLED_REF_H__ + +typedef struct XdgAppInstalledRef XdgAppInstalledRef; + +#include +#include + +#define XDG_APP_TYPE_INSTALLED_REF xdg_app_installed_ref_get_type() +#define XDG_APP_INSTALLED_REF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XDG_APP_TYPE_INSTALLED_REF, XdgAppInstalledRef)) +#define XDG_APP_IS_INSTALLED_REF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XDG_APP_TYPE_INSTALLED_REF)) + +XDG_APP_EXTERN GType xdg_app_installed_ref_get_type (void); + +struct XdgAppInstalledRef { + XdgAppRef parent; +}; + +typedef struct { + XdgAppRefClass parent_class; +} XdgAppInstalledRefClass; + +#if !GLIB_CHECK_VERSION(2, 43, 4) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppInstalledRef, g_object_unref) +#endif + +XDG_APP_EXTERN const char * xdg_app_installed_ref_get_origin (XdgAppInstalledRef *self); +XDG_APP_EXTERN const char * xdg_app_installed_ref_get_deploy_dir (XdgAppInstalledRef *self); +XDG_APP_EXTERN gboolean xdg_app_installed_ref_get_current (XdgAppInstalledRef *self); +XDG_APP_EXTERN const char * xdg_app_installed_ref_load_metadata (XdgAppInstalledRef *self, + GCancellable *cancellable, + GError **error); + +#endif /* __XDG_APP_INSTALLED_REF_H__ */ diff --git a/lib/xdg-app-ref.c b/lib/xdg-app-ref.c new file mode 100644 index 00000000..9276a7cb --- /dev/null +++ b/lib/xdg-app-ref.c @@ -0,0 +1,235 @@ +/* + * Copyright © 2015 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 "xdg-app-ref.h" +#include "xdg-app-enum-types.h" + +typedef struct _XdgAppRefPrivate XdgAppRefPrivate; + +struct _XdgAppRefPrivate +{ + char *name; + char *arch; + char *version; + char *commit; + XdgAppRefKind kind; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (XdgAppRef, xdg_app_ref, G_TYPE_OBJECT) + +enum { + PROP_0, + + PROP_NAME, + PROP_ARCH, + PROP_VERSION, + PROP_COMMIT, + PROP_KIND +}; + +static void +xdg_app_ref_finalize (GObject *object) +{ + XdgAppRef *self = XDG_APP_REF (object); + XdgAppRefPrivate *priv = xdg_app_ref_get_instance_private (self); + + g_free (priv->name); + g_free (priv->arch); + g_free (priv->version); + g_free (priv->commit); + + G_OBJECT_CLASS (xdg_app_ref_parent_class)->finalize (object); +} + +static void +xdg_app_ref_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XdgAppRef *self = XDG_APP_REF (object); + XdgAppRefPrivate *priv = xdg_app_ref_get_instance_private (self); + + switch (prop_id) + { + case PROP_NAME: + g_clear_pointer (&priv->name, g_free); + priv->name = g_value_dup_string (value); + break; + + case PROP_ARCH: + g_clear_pointer (&priv->arch, g_free); + priv->arch = g_value_dup_string (value); + break; + + case PROP_VERSION: + g_clear_pointer (&priv->version, g_free); + priv->version = g_value_dup_string (value); + break; + + case PROP_COMMIT: + g_clear_pointer (&priv->commit, g_free); + priv->commit = g_value_dup_string (value); + break; + + case PROP_KIND: + priv->kind = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xdg_app_ref_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XdgAppRef *self = XDG_APP_REF (object); + XdgAppRefPrivate *priv = xdg_app_ref_get_instance_private (self); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + + case PROP_ARCH: + g_value_set_string (value, priv->arch); + break; + + case PROP_VERSION: + g_value_set_string (value, priv->version); + break; + + case PROP_COMMIT: + g_value_set_string (value, priv->commit); + break; + + case PROP_KIND: + g_value_set_enum (value, priv->kind); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xdg_app_ref_class_init (XdgAppRefClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = xdg_app_ref_get_property; + object_class->set_property = xdg_app_ref_set_property; + object_class->finalize = xdg_app_ref_finalize; + + g_object_class_install_property (object_class, + PROP_NAME, + g_param_spec_string ("name", + "", + "", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_ARCH, + g_param_spec_string ("arch", + "", + "", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_VERSION, + g_param_spec_string ("version", + "", + "", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_COMMIT, + g_param_spec_string ("commit", + "", + "", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_KIND, + g_param_spec_enum ("kind", + "", + "", + XDG_TYPE_APP_REF_KIND, + XDG_APP_REF_KIND_APP, + G_PARAM_READWRITE)); +} + +static void +xdg_app_ref_init (XdgAppRef *self) +{ + XdgAppRefPrivate *priv = xdg_app_ref_get_instance_private (self); + + priv->kind = XDG_APP_REF_KIND_APP; +} + +const char * +xdg_app_ref_get_name (XdgAppRef *self) +{ + XdgAppRefPrivate *priv = xdg_app_ref_get_instance_private (self); + + return priv->name; +} + +const char * +xdg_app_ref_get_arch (XdgAppRef *self) +{ + XdgAppRefPrivate *priv = xdg_app_ref_get_instance_private (self); + + return priv->arch; +} + +const char * +xdg_app_ref_get_version (XdgAppRef *self) +{ + XdgAppRefPrivate *priv = xdg_app_ref_get_instance_private (self); + + return priv->version; +} + +const char * +xdg_app_ref_get_commit (XdgAppRef *self) +{ + XdgAppRefPrivate *priv = xdg_app_ref_get_instance_private (self); + + return priv->commit; +} + +XdgAppRefKind +xdg_app_ref_get_kind (XdgAppRef *self) +{ + XdgAppRefPrivate *priv = xdg_app_ref_get_instance_private (self); + + return priv->kind; +} + diff --git a/lib/xdg-app-ref.h b/lib/xdg-app-ref.h new file mode 100644 index 00000000..e5e68e08 --- /dev/null +++ b/lib/xdg-app-ref.h @@ -0,0 +1,62 @@ +/* + * Copyright © 2015 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 + */ + +#if !defined (__XDG_APP_H_INSIDE__) && !defined (XDG_APP_COMPILATION) +#error "Only can be included refectly." +#endif + +#ifndef __XDG_APP_REF_H__ +#define __XDG_APP_REF_H__ + +typedef struct XdgAppRef XdgAppRef; + +#include + +#define XDG_APP_TYPE_REF xdg_app_ref_get_type() +#define XDG_APP_REF(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XDG_APP_TYPE_REF, XdgAppRef)) +#define XDG_APP_IS_REF(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XDG_APP_TYPE_REF)) + +XDG_APP_EXTERN GType xdg_app_ref_get_type (void); + +struct XdgAppRef { + GObject parent; +}; + +typedef struct { + GObjectClass parent_class; +} XdgAppRefClass; + + +#if !GLIB_CHECK_VERSION(2, 43, 4) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppRef, g_object_unref) +#endif + +typedef enum { + XDG_APP_REF_KIND_APP, + XDG_APP_REF_KIND_RUNTIME, +} XdgAppRefKind; + +XDG_APP_EXTERN const char * xdg_app_ref_get_name (XdgAppRef *self); +XDG_APP_EXTERN const char * xdg_app_ref_get_arch (XdgAppRef *self); +XDG_APP_EXTERN const char * xdg_app_ref_get_version (XdgAppRef *self); +XDG_APP_EXTERN const char * xdg_app_ref_get_commit (XdgAppRef *self); +XDG_APP_EXTERN XdgAppRefKind xdg_app_ref_get_kind (XdgAppRef *self); + +#endif /* __XDG_APP_REF_H__ */ diff --git a/lib/xdg-app-remote-private.h b/lib/xdg-app-remote-private.h new file mode 100644 index 00000000..548ede45 --- /dev/null +++ b/lib/xdg-app-remote-private.h @@ -0,0 +1,33 @@ +/* + * Copyright © 2015 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 + */ + +#if !defined (__XDG_APP_H_INSIDE__) && !defined (XDG_APP_COMPILATION) +#error "Only can be included installed_refectly." +#endif + +#ifndef __XDG_APP_REMOTE_PRIVATE_H__ +#define __XDG_APP_REMOTE_PRIVATE_H__ + +#include +#include + +XdgAppRemote *xdg_app_remote_new (OstreeRepo *repo, const char *name); + +#endif /* __XDG_APP_REMOTE_PRIVATE_H__ */ diff --git a/lib/xdg-app-remote.c b/lib/xdg-app-remote.c new file mode 100644 index 00000000..f1eb98d1 --- /dev/null +++ b/lib/xdg-app-remote.c @@ -0,0 +1,245 @@ +/* + * Copyright © 2015 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 "xdg-app-remote-private.h" +#include "xdg-app-enum-types.h" +#include "xdg-app-utils.h" + +#include + +typedef struct _XdgAppRemotePrivate XdgAppRemotePrivate; + +struct _XdgAppRemotePrivate +{ + char *name; + char *url; + char *title; + OstreeRepo *repo; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (XdgAppRemote, xdg_app_remote, G_TYPE_OBJECT) + +enum { + PROP_0, + + PROP_NAME, +}; + +static void +xdg_app_remote_finalize (GObject *object) +{ + XdgAppRemote *self = XDG_APP_REMOTE (object); + XdgAppRemotePrivate *priv = xdg_app_remote_get_instance_private (self); + + g_free (priv->name); + g_free (priv->url); + g_free (priv->title); + g_object_unref (priv->repo); + + G_OBJECT_CLASS (xdg_app_remote_parent_class)->finalize (object); +} + +static void +xdg_app_remote_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + XdgAppRemote *self = XDG_APP_REMOTE (object); + XdgAppRemotePrivate *priv = xdg_app_remote_get_instance_private (self); + + switch (prop_id) + { + case PROP_NAME: + g_clear_pointer (&priv->name, g_free); + priv->name = g_value_dup_string (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xdg_app_remote_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + XdgAppRemote *self = XDG_APP_REMOTE (object); + XdgAppRemotePrivate *priv = xdg_app_remote_get_instance_private (self); + + switch (prop_id) + { + case PROP_NAME: + g_value_set_string (value, priv->name); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +xdg_app_remote_class_init (XdgAppRemoteClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = xdg_app_remote_get_property; + object_class->set_property = xdg_app_remote_set_property; + object_class->finalize = xdg_app_remote_finalize; + + g_object_class_install_property (object_class, + PROP_NAME, + g_param_spec_string ("name", + "", + "", + NULL, + G_PARAM_READWRITE)); +} + +static void +xdg_app_remote_init (XdgAppRemote *self) +{ +} + +const char * +xdg_app_remote_get_name (XdgAppRemote *self) +{ + XdgAppRemotePrivate *priv = xdg_app_remote_get_instance_private (self); + + return priv->name; +} + +const char * +xdg_app_remote_get_url (XdgAppRemote *self) +{ + XdgAppRemotePrivate *priv = xdg_app_remote_get_instance_private (self); + + if (priv->url == NULL) + ostree_repo_remote_get_url (priv->repo, priv->name, &priv->url, NULL); + + return priv->url; +} + +const char * +xdg_app_remote_get_title (XdgAppRemote *self) +{ + XdgAppRemotePrivate *priv = xdg_app_remote_get_instance_private (self); + GKeyFile *config; + + if (priv->title == NULL) + { + g_autofree char *group = g_strdup_printf ("remote \"%s\"", priv->name); + config = ostree_repo_get_config (priv->repo); + priv->title = g_key_file_get_string (config, group, "xa.title", NULL); + } + + return priv->title ? priv->title : priv->name; +} + +gboolean +xdg_app_remote_get_gpg_verify (XdgAppRemote *self) +{ + XdgAppRemotePrivate *priv = xdg_app_remote_get_instance_private (self); + gboolean res; + + if (ostree_repo_remote_get_gpg_verify (priv->repo, priv->name, &res, NULL)) + return res; + + return FALSE; +} + +static XdgAppRef * +get_ref (XdgAppRemote *self, + const char *full_ref, + const char *commit) +{ + g_auto(GStrv) parts = NULL; + XdgAppRefKind kind = XDG_APP_REF_KIND_APP; + + parts = g_strsplit (full_ref, "/", -1); + + if (strcmp (parts[0], "app") != 0) + kind = XDG_APP_REF_KIND_RUNTIME; + + return g_object_new (XDG_APP_TYPE_REF, + "kind", kind, + "name", parts[1], + "arch", parts[2], + "version", parts[3], + "commit", commit, + NULL); +} + +XdgAppRef ** +xdg_app_remote_list_refs (XdgAppRemote *self, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GPtrArray) refs = g_ptr_array_new_with_free_func (g_object_unref); + g_autoptr(GHashTable) ht = NULL; + const char *url; + g_autofree char *title = NULL; + GHashTableIter iter; + gpointer key; + gpointer value; + + url = xdg_app_remote_get_url (self); + g_print ("url: %s\n", url); + if (url) + { + if (!ostree_repo_load_summary (url, &ht, &title, cancellable, error)) + return FALSE; + + g_hash_table_iter_init (&iter, ht); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + const char *refspec = key; + const char *checksum = value; + + g_ptr_array_add (refs, + get_ref (self, refspec, checksum)); + } + } + + g_ptr_array_add (refs, NULL); + return (XdgAppRef **)g_ptr_array_free (g_steal_pointer (&refs), FALSE); +} + + +XdgAppRemote * +xdg_app_remote_new (OstreeRepo *repo, + const char *name) +{ + XdgAppRemotePrivate *priv; + XdgAppRemote *self = g_object_new (XDG_APP_TYPE_REMOTE, + "name", name, + NULL); + + priv = xdg_app_remote_get_instance_private (self); + priv->repo = g_object_ref (repo); + + return self; +} diff --git a/lib/xdg-app-remote.h b/lib/xdg-app-remote.h new file mode 100644 index 00000000..7f238095 --- /dev/null +++ b/lib/xdg-app-remote.h @@ -0,0 +1,60 @@ +/* + * Copyright © 2015 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 + */ + +#if !defined (__XDG_APP_H_INSIDE__) && !defined (XDG_APP_COMPILATION) +#error "Only can be included remoteectly." +#endif + +#ifndef __XDG_APP_REMOTE_H__ +#define __XDG_APP_REMOTE_H__ + +typedef struct XdgAppRemote XdgAppRemote; + +#include +#include + +#define XDG_APP_TYPE_REMOTE xdg_app_remote_get_type() +#define XDG_APP_REMOTE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XDG_APP_TYPE_REMOTE, XdgAppRemote)) +#define XDG_APP_IS_REMOTE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XDG_APP_TYPE_REMOTE)) + +XDG_APP_EXTERN GType xdg_app_remote_get_type (void); + +struct XdgAppRemote { + GObject parent; +}; + +typedef struct { + GObjectClass parent_class; +} XdgAppRemoteClass; + +#if !GLIB_CHECK_VERSION(2, 43, 4) +G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppRemote, g_object_unremote) +#endif + +XDG_APP_EXTERN const char * xdg_app_remote_get_url (XdgAppRemote *self); +XDG_APP_EXTERN const char * xdg_app_remote_get_name (XdgAppRemote *self); +XDG_APP_EXTERN const char * xdg_app_remote_get_title (XdgAppRemote *self); +XDG_APP_EXTERN gboolean xdg_app_remote_get_gpg_verify (XdgAppRemote *self); + +XDG_APP_EXTERN XdgAppRef ** xdg_app_remote_list_refs (XdgAppRemote *self, + GCancellable *cancellable, + GError **error); + +#endif /* __XDG_APP_REMOTE_H__ */ diff --git a/lib/xdg-app-version-macros.h.in b/lib/xdg-app-version-macros.h.in new file mode 100644 index 00000000..56191b79 --- /dev/null +++ b/lib/xdg-app-version-macros.h.in @@ -0,0 +1,36 @@ +/* + * Copyright © 2015 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 + */ + +#if !defined (__XDG_APP_H_INSIDE__) && !defined (XDG_APP_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __XDG_APP_VERSION_MACROS_H__ +#define __XDG_APP_VERSION_MACROS_H__ + +#define XDG_APP_MAJOR_VERSION (@XDG_APP_MAJOR_VERSION@) +#define XDG_APP_MINOR_VERSION (@XDG_APP_MINOR_VERSION@) +#define XDG_APP_MICRO_VERSION (@XDG_APP_MICRO_VERSION@) + +#ifndef XDG_APP_EXTERN +#define XDG_APP_EXTERN extern +#endif + +#endif /* __XDG_APP_VERSION_MACROS_H__ */ diff --git a/lib/xdg-app.c b/lib/xdg-app.c new file mode 100644 index 00000000..4a71720c --- /dev/null +++ b/lib/xdg-app.c @@ -0,0 +1,3 @@ +#include "config.h" + +#include "xdg-app-version-macros.h" diff --git a/lib/xdg-app.h b/lib/xdg-app.h new file mode 100644 index 00000000..72fa1f98 --- /dev/null +++ b/lib/xdg-app.h @@ -0,0 +1,37 @@ +/* + * Copyright © 2015 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 + */ + +#ifndef __XDG_APP_H__ +#define __XDG_APP_H__ + +#define __XDG_APP_H_INSIDE__ + +#include + +#include +#include +#include +#include +#include +#include + +#undef __XDG_APP_H_INSIDE__ + +#endif /* __XDG_APP_H__ */ diff --git a/xdg-app.pc.in b/xdg-app.pc.in index e7fb8c2c..906eb05a 100644 --- a/xdg-app.pc.in +++ b/xdg-app.pc.in @@ -1,6 +1,8 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ +libdir=@libdir@ datarootdir=@datarootdir@ +includedir=@includedir@ datadir=@datadir@ interfaces_dir=${datadir}/dbus-1/interfaces/ @@ -8,3 +10,7 @@ interfaces_dir=${datadir}/dbus-1/interfaces/ Name: xdg-app Description: Application sandboxing framework Version: @VERSION@ +Requires: glib-2.0 gio-2.0 +Requires.private: gio-unix-2.0 ostree-1 libgsystem +Libs: -L${libdir} -lxdg-app +Cflags: -I${includedir}/xdg-app