diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml
index 1990c2f5..0d68960b 100644
--- a/.github/workflows/check.yml
+++ b/.github/workflows/check.yml
@@ -20,7 +20,7 @@ jobs:
- name: Install Dependencies
run: |
sudo apt-get update
- sudo apt-get install -y libglib2.0 attr automake appstream-compose gettext autopoint bison dbus gtk-doc-tools \
+ sudo apt-get install -y libglib2.0 attr automake libappstream-compose-dev gettext autopoint bison dbus gtk-doc-tools \
libfuse-dev ostree libostree-dev libarchive-dev libcap-dev libattr1-dev libdw-dev libelf-dev \
libjson-glib-dev shared-mime-info desktop-file-utils libpolkit-agent-1-dev libpolkit-gobject-1-dev \
libseccomp-dev libsystemd-dev libxml2-utils libgpgme11-dev gobject-introspection \
@@ -53,7 +53,7 @@ jobs:
- name: Install Dependencies
run: |
sudo apt-get update
- sudo apt-get install -y libglib2.0 attr automake appstream-compose gettext autopoint bison dbus gtk-doc-tools \
+ sudo apt-get install -y libglib2.0 attr automake libappstream-compose-dev gettext autopoint bison dbus gtk-doc-tools \
libfuse-dev ostree libostree-dev libarchive-dev libcap-dev libattr1-dev libdw-dev libelf-dev \
libjson-glib-dev shared-mime-info desktop-file-utils libpolkit-agent-1-dev libpolkit-gobject-1-dev \
libseccomp-dev libsystemd-dev libxml2-utils libgpgme11-dev gobject-introspection \
@@ -95,7 +95,7 @@ jobs:
attr \
automake \
autopoint \
- appstream-compose \
+ libappstream-compose-dev \
bison \
debugedit \
dbus \
diff --git a/configure.ac b/configure.ac
index bfee7888..113b9889 100644
--- a/configure.ac
+++ b/configure.ac
@@ -41,22 +41,6 @@ else
[AC_MSG_ERROR([You need at least version $FLATPAK_REQS of flatpak, your version is $FLATPAK_VERSION])])
fi
-AC_CHECK_PROG([APPSTREAMCLI], [appstreamcli], [appstreamcli], [false])
-if test "x$APPSTREAMCLI" = xfalse; then
- AC_MSG_ERROR([You need appstreamcli installed])
- APPSTREAMCLI_VERSION=`$APPSTREAMCLI --version | sed 's,.*\ \([0-9]*\.[0-9]*\.[0-9]*\)$,\1,'`
- AX_COMPARE_VERSION([$APPSTREAMCLI_REQS],[gt],[$APPSTREAMCLI_VERSION],
- [AC_MSG_ERROR([You need at least version $APPSTREAMCLI_REQS of appstreamcli, your version is $APPSTREAMCLI_VERSION])])
-fi
-
-AC_MSG_CHECKING([whether appstreamcli has compose support])
-AS_IF([appstreamcli compose --help >/dev/null 2>&1],
- [AC_MSG_RESULT(yes)],
- [
- AC_MSG_RESULT(no)
- AC_MSG_ERROR([appstreamcli must have compose support enabled and installed])
- ])
-
LT_PREREQ([2.2.6])
LT_INIT([disable-static])
@@ -102,7 +86,7 @@ PKG_PROG_PKG_CONFIG([0.24])
# For libglnx
AC_CHECK_HEADER([sys/xattr.h], [], [AC_MSG_ERROR([You must have sys/xattr.h from glibc])])
-PKG_CHECK_MODULES(BASE, [glib-2.0 >= $GLIB_REQS gio-2.0 gio-unix-2.0 ostree-1 >= $OSTREE_REQS json-glib-1.0 libxml-2.0 >= 2.4 libcurl])
+PKG_CHECK_MODULES(BASE, [glib-2.0 >= $GLIB_REQS gio-2.0 gio-unix-2.0 ostree-1 >= $OSTREE_REQS json-glib-1.0 libxml-2.0 >= 2.4 libcurl appstream >= $APPSTREAMCLI_REQS appstream-compose >= $APPSTREAMCLI_REQS])
dnl ************************
dnl *** check for libelf ***
diff --git a/doc/flatpak-builder.xml b/doc/flatpak-builder.xml
index 8ae33f55..97571d27 100644
--- a/doc/flatpak-builder.xml
+++ b/doc/flatpak-builder.xml
@@ -587,6 +587,22 @@
+
+
+
+
+ Allow screencasts in Appstream catalogue.
+
+
+
+
+
+
+ Use partial URLs in Appstream catalogue. Requires
+ appstream >= 0.16.3.
+
+
+
diff --git a/meson.build b/meson.build
index 1085a8f7..8a2d7425 100644
--- a/meson.build
+++ b/meson.build
@@ -40,10 +40,6 @@ endforeach
# The debugedit program is a hard dependency
debugedit = find_program('debugedit', version: '>= 5.0')
-# Require appstream with compose plugin installed
-appstreamcli = find_program('appstreamcli', version: '>= 0.15.0')
-appstreamcli_compose = run_command(appstreamcli, ['compose', '--help'], check: true)
-
subdir('src')
subdir('doc')
if get_option('tests')
diff --git a/src/Makefile.am.inc b/src/Makefile.am.inc
index cc426df8..da2d1503 100644
--- a/src/Makefile.am.inc
+++ b/src/Makefile.am.inc
@@ -53,4 +53,4 @@ flatpak_builder_SOURCES = \
$(NULL)
flatpak_builder_LDADD = $(AM_LDADD) $(BASE_LIBS) $(LIBELF_LIBS) $(YAML_LIBS) libglnx.la
-flatpak_builder_CFLAGS = $(AM_CFLAGS) $(BASE_CFLAGS) $(YAML_CFLAGS)
+flatpak_builder_CFLAGS = -I$(top_srcdir)/src $(AM_CFLAGS) $(BASE_CFLAGS) $(YAML_CFLAGS)
diff --git a/src/asc-font.h b/src/asc-font.h
new file mode 100644
index 00000000..158168b4
--- /dev/null
+++ b/src/asc-font.h
@@ -0,0 +1,20 @@
+/*
+ * asc-font.h (stub)
+ *
+ * This header is intentionally provided as a no-op.
+ *
+ * In AppStream < 1.0.6, the public header
+ * appstream-compose.h -> asc-canvas.h
+ * includes the private header "asc-font.h".
+ *
+ * That private header is not installed by default, and nothing in
+ * the public API actually depends on its declarations.
+ *
+ * To allow building against older AppStream releases, we provide
+ * this empty stub so the include resolves cleanly.
+ *
+ * Safe to remove once the minimum required AppStream is >= 1.0.6.
+ */
+#ifndef __ASC_FONT_H
+#define __ASC_FONT_H
+#endif
diff --git a/src/builder-context.c b/src/builder-context.c
index 508ab91f..27ca98b5 100644
--- a/src/builder-context.c
+++ b/src/builder-context.c
@@ -86,6 +86,8 @@ struct BuilderContext
gboolean no_shallow_clone;
gboolean opt_export_only;
char *opt_mirror_screenshots_url;
+ gboolean opt_compose_enable_screencasts;
+ gboolean opt_compose_enable_partial_urls;
BuilderSdkConfig *sdk_config;
};
@@ -376,6 +378,32 @@ builder_context_get_opt_mirror_screenshots_url (BuilderContext *self)
return self->opt_mirror_screenshots_url;
}
+void
+builder_context_set_opt_compose_enable_screencasts (BuilderContext *self,
+ gboolean opt_compose_enable_screencasts)
+{
+ self->opt_compose_enable_screencasts = !!opt_compose_enable_screencasts;
+}
+
+gboolean
+builder_context_get_opt_compose_enable_screencasts (BuilderContext *self)
+{
+ return self->opt_compose_enable_screencasts;
+}
+
+void
+builder_context_set_opt_compose_enable_partial_urls (BuilderContext *self,
+ gboolean opt_compose_enable_partial_urls)
+{
+ self->opt_compose_enable_partial_urls = !!opt_compose_enable_partial_urls;
+}
+
+gboolean
+builder_context_get_opt_compose_enable_partial_urls (BuilderContext *self)
+{
+ return self->opt_compose_enable_partial_urls;
+}
+
GFile *
builder_context_find_in_sources_dirs (BuilderContext *self,
...)
diff --git a/src/builder-context.h b/src/builder-context.h
index 69671398..1828ad16 100644
--- a/src/builder-context.h
+++ b/src/builder-context.h
@@ -180,6 +180,16 @@ void builder_context_set_opt_mirror_screenshots_url (BuilderContext *
const char * builder_context_get_opt_mirror_screenshots_url (BuilderContext *self);
+void builder_context_set_opt_compose_enable_screencasts (BuilderContext *self,
+ gboolean opt_compose_enable_screencasts);
+
+gboolean builder_context_get_opt_compose_enable_screencasts (BuilderContext *self);
+
+void builder_context_set_opt_compose_enable_partial_urls (BuilderContext *self,
+ gboolean opt_compose_enable_partial_urls);
+
+gboolean builder_context_get_opt_compose_enable_partial_urls (BuilderContext *self);
+
BuilderSdkConfig * builder_context_get_sdk_config (BuilderContext *self);
gboolean builder_context_create_state_dir (BuilderContext *self,
diff --git a/src/builder-main.c b/src/builder-main.c
index 606e4d33..abda3b7f 100644
--- a/src/builder-main.c
+++ b/src/builder-main.c
@@ -89,6 +89,8 @@ static gboolean opt_log_session_bus;
static gboolean opt_log_system_bus;
static gboolean opt_yes;
static gint64 opt_source_date_epoch = -1;
+static gboolean opt_compose_enable_screencasts;
+static gboolean opt_compose_enable_partial_urls;
static GOptionEntry entries[] = {
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose, "Print debug information during command processing", NULL },
@@ -144,6 +146,8 @@ static GOptionEntry entries[] = {
{ "assumeyes", 'y', 0, G_OPTION_ARG_NONE, &opt_yes, N_("Automatically answer yes for all questions"), NULL },
{ "no-shallow-clone", 0, 0, G_OPTION_ARG_NONE, &opt_no_shallow_clone, "Don't use shallow clones when mirroring git repos", NULL },
{ "override-source-date-epoch", 0, 0, G_OPTION_ARG_INT64, &opt_source_date_epoch, "Use this timestamp to perform the build, instead of the last modification time of the manifest.", NULL },
+ { "compose-enable-screencasts", 0, 0, G_OPTION_ARG_NONE, &opt_compose_enable_screencasts, "Allow screencasts in Appstream catalogue", NULL },
+ { "compose-enable-partial-urls", 0, 0, G_OPTION_ARG_NONE, &opt_compose_enable_partial_urls, "Allow partial URLs in Appstream catalogue", NULL },
{ NULL }
};
@@ -605,6 +609,8 @@ main (int argc,
builder_context_set_bundle_sources (build_context, opt_bundle_sources);
builder_context_set_opt_export_only (build_context, opt_export_only);
builder_context_set_opt_mirror_screenshots_url (build_context, opt_mirror_screenshots_url);
+ builder_context_set_opt_compose_enable_screencasts (build_context, opt_compose_enable_screencasts);
+ builder_context_set_opt_compose_enable_partial_urls (build_context, opt_compose_enable_partial_urls);
git_init_email ();
diff --git a/src/builder-manifest.c b/src/builder-manifest.c
index bcea7b3d..cb272274 100644
--- a/src/builder-manifest.c
+++ b/src/builder-manifest.c
@@ -30,6 +30,25 @@
#include
#include
+/* Remove for newer appstream */
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wstrict-prototypes"
+#elif defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wstrict-prototypes"
+#endif
+
+#define I_KNOW_THE_APPSTREAM_COMPOSE_API_IS_SUBJECT_TO_CHANGE
+#include
+#include
+
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#elif defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
#include "builder-manifest.h"
#include "builder-utils.h"
#include "builder-flatpak-utils.h"
@@ -2404,26 +2423,69 @@ cmpstringp (const void *p1, const void *p2)
}
static gboolean
-appstreamcli_compose (GError **error,
- ...)
+builder_appstreamcli_compose (const gchar *origin,
+ const gchar *app_id,
+ const gchar *result_root,
+ const gchar *data_dir,
+ const gchar *icon_dir,
+ const gchar *media_dir,
+ const gchar *hint_dir,
+ const gchar *media_baseurl,
+ gboolean enable_screencasts,
+ gboolean enable_partial_urls,
+ GError **error)
{
- g_autoptr(GPtrArray) args = NULL;
- const gchar *arg;
- va_list ap;
+ g_autoptr(AscCompose) compose = NULL;
+ g_autoptr(AscDirectoryUnit) dirunit = NULL;
+ g_autofree gchar *desktop_component = NULL;
- args = g_ptr_array_new_with_free_func (g_free);
- g_ptr_array_add (args, g_strdup ("appstreamcli"));
- g_ptr_array_add (args, g_strdup ("compose"));
+ g_return_val_if_fail (origin != NULL, FALSE);
+ g_return_val_if_fail (app_id != NULL, FALSE);
+ g_return_val_if_fail (result_root != NULL, FALSE);
+ g_return_val_if_fail (data_dir != NULL, FALSE);
+ g_return_val_if_fail (icon_dir != NULL, FALSE);
+ g_return_val_if_fail (hint_dir != NULL, FALSE);
- va_start (ap, error);
- while ((arg = va_arg (ap, const gchar *)))
- g_ptr_array_add (args, g_strdup (arg));
- g_ptr_array_add (args, NULL);
- va_end (ap);
+ compose = asc_compose_new ();
+
+ asc_compose_set_format (compose, AS_FORMAT_KIND_XML);
+ asc_compose_set_origin (compose, origin);
+ asc_compose_set_prefix (compose, "/");
+
+ asc_compose_add_allowed_cid (compose, app_id);
+ desktop_component = g_strdup_printf ("%s.desktop", app_id);
+ asc_compose_add_allowed_cid (compose, desktop_component);
+
+ dirunit = asc_directory_unit_new (result_root);
+ asc_compose_add_unit (compose, ASC_UNIT (dirunit));
+
+ asc_compose_set_data_result_dir (compose, data_dir);
+ asc_compose_set_icons_result_dir (compose, icon_dir);
+ asc_compose_set_media_baseurl (compose, media_baseurl);
+ asc_compose_set_media_result_dir (compose, media_dir);
+ asc_compose_set_hints_result_dir (compose, hint_dir);
- if (!flatpak_spawnv (NULL, NULL, 0, error, (const char * const *)args->pdata, NULL))
+ asc_compose_add_flags (compose, ASC_COMPOSE_FLAG_PROPAGATE_CUSTOM);
+
+#if AS_CHECK_VERSION(0, 16, 3)
+ if (!enable_partial_urls)
+ asc_compose_add_flags (compose, ASC_COMPOSE_FLAG_NO_PARTIAL_URLS);
+#endif
+
+ if (!enable_screencasts)
+ asc_compose_remove_flags (compose, ASC_COMPOSE_FLAG_ALLOW_SCREENCASTS);
+
+ g_autoptr(GPtrArray) results = asc_compose_run (compose, NULL, error);
+ if (results == NULL)
{
- g_prefix_error (error, "ERROR: appstreamcli compose failed: ");
+ g_prefix_error (error, "AppStream compose failed: ");
+ return FALSE;
+ }
+
+ if (asc_compose_has_errors (compose))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "AppStream compose completed with errors");
return FALSE;
}
@@ -3033,56 +3095,52 @@ builder_manifest_cleanup (BuilderManifest *self,
if (self->appstream_compose && appdata_file != NULL)
{
- g_autofree char *origin = g_strdup_printf ("--origin=%s",
- builder_manifest_get_id (self));
- g_autofree char *components_arg = g_strdup_printf ("--components=%s,%s.desktop",
- self->id, self->id);
const char *app_root_path = flatpak_file_get_path_cached (app_root);
- g_autofree char *result_root_arg = g_strdup_printf ("--result-root=%s", app_root_path);
- g_autoptr(GFile) xml_dir = flatpak_build_file (app_root, "share/app-info/xmls", NULL);
+ g_autoptr(GFile) data_out = flatpak_build_file (app_root, "share/app-info/xmls", NULL);
g_autoptr(GFile) icon_out = flatpak_build_file (app_root, "share/app-info/icons/flatpak", NULL);
- g_autoptr(GFile) media_dir = flatpak_build_file (app_root, "share/app-info/media", NULL);
- g_autofree char *data_dir = g_strdup_printf ("--data-dir=%s",
- flatpak_file_get_path_cached (xml_dir));
- g_autofree char *icon_dir = g_strdup_printf ("--icons-dir=%s",
- flatpak_file_get_path_cached (icon_out));
+ g_autoptr(GFile) media_out = flatpak_build_file (app_root, "share/app-info/media", NULL);
+ g_autoptr(GFile) hint_out = flatpak_build_file (app_root, "appstream", NULL);
+ const char *data_dir = flatpak_file_get_path_cached(data_out);
+ const char *icon_dir = flatpak_file_get_path_cached(icon_out);
+ const char *media_dir = flatpak_file_get_path_cached(media_out);
+ const char *hint_dir = flatpak_file_get_path_cached(hint_out);
const char *opt_mirror_screenshots_url = builder_context_get_opt_mirror_screenshots_url (context);
gboolean opt_export_only = builder_context_get_opt_export_only (context);
+ gboolean opt_enable_screencasts = builder_context_get_opt_compose_enable_screencasts(context);
+ gboolean opt_enable_partial_urls = builder_context_get_opt_compose_enable_partial_urls(context);
+ g_print ("Running appstreamcli compose\n");
if (opt_mirror_screenshots_url && !opt_export_only)
{
g_autofree char *url = g_build_filename (opt_mirror_screenshots_url, NULL);
- g_autofree char *arg_base_url = g_strdup_printf ("--media-baseurl=%s", url);
- g_autofree char *arg_media_dir = g_strdup_printf ("--media-dir=%s",
- flatpak_file_get_path_cached (media_dir));
-
- g_print ("Running appstreamcli compose\n");
- g_print ("Saving screenshots in %s\n", flatpak_file_get_path_cached (media_dir));
- if (!appstreamcli_compose (error,
- "--prefix=/",
- origin,
- arg_base_url,
- arg_media_dir,
- result_root_arg,
- data_dir,
- icon_dir,
- components_arg,
- app_root_path,
- NULL))
- return FALSE;
+
+ g_print ("Saving screenshots in %s\n", media_dir);
+ if (!builder_appstreamcli_compose (builder_manifest_get_id (self),
+ self->id,
+ app_root_path,
+ data_dir,
+ icon_dir,
+ media_dir,
+ hint_dir,
+ url,
+ opt_enable_screencasts,
+ opt_enable_partial_urls,
+ error))
+ return FALSE;
}
else
{
- g_print ("Running appstreamcli compose\n");
- if (!appstreamcli_compose (error,
- "--prefix=/",
- origin,
- result_root_arg,
- data_dir,
- icon_dir,
- components_arg,
- app_root_path,
- NULL))
+ if (!builder_appstreamcli_compose (builder_manifest_get_id (self),
+ self->id,
+ app_root_path,
+ data_dir,
+ icon_dir,
+ NULL,
+ hint_dir,
+ NULL,
+ FALSE,
+ opt_enable_partial_urls,
+ error))
return FALSE;
}
}
diff --git a/src/meson.build b/src/meson.build
index 91798347..a15073bc 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -57,12 +57,15 @@ flatpak_builder_deps = [
dependency('libglnx', default_options: ['tests=false']),
dependency('libxml-2.0', version: '>= 2.4'),
dependency('ostree-1', version: '>= 2017.14'),
+ dependency('appstream', version: '>=0.15.0'),
+ dependency('appstream-compose', version: '>=0.15.0'),
yaml_dep,
]
flatpak_builder = executable(
'flatpak-builder',
flatpak_builder_sources,
+ include_directories: include_directories('.'),
dependencies: flatpak_builder_deps,
install: true,
)