summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKalev Lember <klember@redhat.com>2017-01-04 12:11:59 +0100
committerKalev Lember <klember@redhat.com>2017-01-04 14:12:09 +0100
commit53761a4608131b3643c6e1701e9e676fdfdd3169 (patch)
tree8969058d6e476581e92a522d212e83c89b3834e7
parent04bb5ec1cfe12745f02674fb8b611ea24498ec6b (diff)
downloadappstream-glib-53761a4608131b3643c6e1701e9e676fdfdd3169.tar.gz
Recursively add subpackage deps into the main package
This fixes appstream data generation for packages that have long dep chains and icons are at a deeper level than in the immediate child package. e.g. in Fedora, 'marble' package depends on 'marble-widget-qt5' which depends on 'marble-astro' which depends on 'marble-common' where we can finally find the app's icon.
-rw-r--r--libappstream-builder/asb-task.c96
1 files changed, 86 insertions, 10 deletions
diff --git a/libappstream-builder/asb-task.c b/libappstream-builder/asb-task.c
index c24e2c0..e7bcac6 100644
--- a/libappstream-builder/asb-task.c
+++ b/libappstream-builder/asb-task.c
@@ -89,9 +89,6 @@ asb_task_explode_extra_package (AsbTask *task,
{
AsbTaskPrivate *priv = GET_PRIVATE (task);
AsbPackage *pkg_extra;
- GPtrArray *deps;
- guint i;
- const gchar *dep;
/* if not found, that's fine */
pkg_extra = asb_context_find_by_pkgname (priv->ctx, pkg_name);
@@ -123,13 +120,6 @@ asb_task_explode_extra_package (AsbTask *task,
error))
return FALSE;
- /* copy all the extra package requires into the main package too */
- deps = asb_package_get_deps (pkg_extra);
- for (i = 0; i < deps->len; i++) {
- dep = g_ptr_array_index (deps, i);
- asb_package_add_dep (priv->pkg, dep);
- }
-
/* free resources */
if (!asb_package_close (pkg_extra, error))
return FALSE;
@@ -140,6 +130,88 @@ asb_task_explode_extra_package (AsbTask *task,
return TRUE;
}
+typedef struct {
+ GPtrArray *results;
+ GHashTable *results_hash;
+} AsbTaskExtraDeps;
+
+static void
+asb_task_extra_deps_free (AsbTaskExtraDeps *extra_deps)
+{
+ g_ptr_array_unref (extra_deps->results);
+ g_hash_table_unref (extra_deps->results_hash);
+ g_slice_free (AsbTaskExtraDeps, extra_deps);
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(AsbTaskExtraDeps, asb_task_extra_deps_free);
+
+static gboolean
+asb_task_get_extra_deps_recursive (AsbTask *task,
+ const gchar *dep,
+ AsbTaskExtraDeps *extra_deps,
+ GError **error)
+{
+ AsbTaskPrivate *priv = GET_PRIVATE (task);
+ AsbPackage *subpkg;
+ GPtrArray *subpkg_deps;
+
+ subpkg = asb_context_find_by_pkgname (priv->ctx, dep);
+ if (subpkg == NULL)
+ return TRUE;
+
+ if (!asb_package_ensure (subpkg,
+ ASB_PACKAGE_ENSURE_DEPS,
+ error))
+ return FALSE;
+
+ subpkg_deps = asb_package_get_deps (subpkg);
+ for (guint i = 0; i < subpkg_deps->len; i++) {
+ const gchar *subpkg_dep = g_ptr_array_index (subpkg_deps, i);
+
+ /* already processed? */
+ if (g_hash_table_lookup (extra_deps->results_hash, subpkg_dep) != NULL)
+ continue;
+
+ /* process recursively */
+ if (!asb_task_get_extra_deps_recursive (task, subpkg_dep, extra_deps, error))
+ return FALSE;
+
+ /* add to results */
+ g_ptr_array_add (extra_deps->results, g_strdup (subpkg_dep));
+ g_hash_table_insert (extra_deps->results_hash, g_strdup (subpkg_dep), GINT_TO_POINTER (1));
+ }
+
+ return TRUE;
+}
+
+static gboolean
+asb_task_add_extra_deps (AsbTask *task, GError **error)
+{
+ AsbTaskPrivate *priv = GET_PRIVATE (task);
+ GPtrArray *deps;
+ g_autoptr(AsbTaskExtraDeps) extra_deps = NULL;
+
+ extra_deps = g_slice_new0 (AsbTaskExtraDeps);
+ extra_deps->results = g_ptr_array_new_with_free_func (g_free);
+ extra_deps->results_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+
+ /* recursively get extra package deps */
+ deps = asb_package_get_deps (priv->pkg);
+ for (guint i = 0; i < deps->len; i++) {
+ const gchar *dep = g_ptr_array_index (deps, i);
+ if (!asb_task_get_extra_deps_recursive (task, dep, extra_deps, error))
+ return FALSE;
+ }
+
+ /* copy all the extra package deps into the main package */
+ for (guint i = 0; i < extra_deps->results->len; i++) {
+ const gchar *extra_dep = g_ptr_array_index (extra_deps->results, i);
+ asb_package_add_dep (priv->pkg, extra_dep);
+ }
+
+ return TRUE;
+}
+
static gboolean
asb_task_explode_extra_packages (AsbTask *task, GError **error)
{
@@ -152,6 +224,10 @@ asb_task_explode_extra_packages (AsbTask *task, GError **error)
g_autoptr(GPtrArray) array = NULL;
g_autoptr(GPtrArray) icon_themes = NULL;
+ /* recursively copy all the extra package deps into the main package */
+ if (!asb_task_add_extra_deps (task, error))
+ return FALSE;
+
/* anything the package requires */
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
for (i = 0; ignore[i] != NULL; i++) {