[gnome-software] Add a new packagekit-refine-repos plugin for mapping repos to package IDs
- From: Kalev Lember <klember src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Add a new packagekit-refine-repos plugin for mapping repos to package IDs
- Date: Tue, 27 Feb 2018 16:31:32 +0000 (UTC)
commit ace99c1760bdafb553ff423d12b2fcec2b2881e9
Author: Kalev Lember <klember redhat com>
Date: Tue Feb 27 12:50:34 2018 +0100
Add a new packagekit-refine-repos plugin for mapping repos to package IDs
We need a separate plugin so that we can order it to run after the
"repos" plugin; regular packagekit-refine plugin is currently ordered to
run before the repos plugin.
The way it works is that first the repos plugin sets
repos::repo-filename metadata key, and then in the next pass
packagekit-refine-repos uses the key to figure out what packages these
belong to.
.../packagekit/gs-plugin-packagekit-refine-repos.c | 136 +++++++++++++++++++++
plugins/packagekit/meson.build | 16 +++
plugins/repos/gs-plugin-repos.c | 24 ++++
3 files changed, 176 insertions(+)
---
diff --git a/plugins/packagekit/gs-plugin-packagekit-refine-repos.c
b/plugins/packagekit/gs-plugin-packagekit-refine-repos.c
new file mode 100644
index 00000000..b8bf1115
--- /dev/null
+++ b/plugins/packagekit/gs-plugin-packagekit-refine-repos.c
@@ -0,0 +1,136 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2018 Kalev Lember <klember redhat com>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <config.h>
+
+#include <packagekit-glib2/packagekit.h>
+#include <gnome-software.h>
+
+#include "packagekit-common.h"
+
+/*
+ * SECTION:
+ * Uses the system PackageKit instance to return convert repo filenames to
+ * package-ids.
+ *
+ * Requires: | [repos::repo-filename]
+ * Refines: | [source-id]
+ */
+
+struct GsPluginData {
+ PkClient *client;
+};
+
+void
+gs_plugin_initialize (GsPlugin *plugin)
+{
+ GsPluginData *priv = gs_plugin_alloc_data (plugin, sizeof(GsPluginData));
+ priv->client = pk_client_new ();
+ pk_client_set_background (priv->client, FALSE);
+ pk_client_set_cache_age (priv->client, G_MAXUINT);
+
+ /* need repos::repo-filename */
+ gs_plugin_add_rule (plugin, GS_PLUGIN_RULE_RUN_AFTER, "repos");
+}
+
+void
+gs_plugin_destroy (GsPlugin *plugin)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ g_object_unref (priv->client);
+}
+
+static gboolean
+gs_plugin_packagekit_refine_repo_from_filename (GsPlugin *plugin,
+ GsApp *app,
+ const gchar *filename,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GsPluginData *priv = gs_plugin_get_data (plugin);
+ const gchar *to_array[] = { NULL, NULL };
+ ProgressData data = { 0 };
+ g_autoptr(PkResults) results = NULL;
+ g_autoptr(GPtrArray) packages = NULL;
+
+ data.app = app;
+ data.plugin = plugin;
+
+ to_array[0] = filename;
+ results = pk_client_search_files (priv->client,
+ pk_bitfield_from_enums (PK_FILTER_ENUM_INSTALLED, -1),
+ (gchar **) to_array,
+ cancellable,
+ gs_plugin_packagekit_progress_cb, &data,
+ error);
+ if (!gs_plugin_packagekit_results_valid (results, error)) {
+ g_prefix_error (error, "failed to search file %s: ", filename);
+ return FALSE;
+ }
+
+ /* get results */
+ packages = pk_results_get_package_array (results);
+ if (packages->len == 1) {
+ PkPackage *package = g_ptr_array_index (packages, 0);
+ gs_app_add_source (app, pk_package_get_name (package));
+ gs_app_add_source_id (app, pk_package_get_id (package));
+ } else {
+ g_debug ("failed to find one package for repo %s, %s, [%u]",
+ gs_app_get_id (app), filename, packages->len);
+ }
+ return TRUE;
+}
+
+gboolean
+gs_plugin_refine (GsPlugin *plugin,
+ GsAppList *list,
+ GsPluginRefineFlags flags,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_autoptr(AsProfileTask) ptask = NULL;
+
+ ptask = as_profile_start_literal (gs_plugin_get_profile (plugin),
+ "packagekit-refine-repos[repo-filename->id]");
+ for (guint i = 0; i < gs_app_list_length (list); i++) {
+ GsApp *app = gs_app_list_index (list, i);
+ const gchar *fn;
+ if (gs_app_has_quirk (app, AS_APP_QUIRK_MATCH_ANY_PREFIX))
+ continue;
+ if (gs_app_get_kind (app) != AS_APP_KIND_SOURCE)
+ continue;
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "packagekit") != 0)
+ continue;
+ fn = gs_app_get_metadata_item (app, "repos::repo-filename");
+ if (fn == NULL)
+ continue;
+ /* set the source package name for an installed .repo file */
+ if (!gs_plugin_packagekit_refine_repo_from_filename (plugin,
+ app,
+ fn,
+ cancellable,
+ error))
+ return FALSE;
+ }
+
+ /* success */
+ return TRUE;
+}
diff --git a/plugins/packagekit/meson.build b/plugins/packagekit/meson.build
index b2cfc297..ac36d629 100644
--- a/plugins/packagekit/meson.build
+++ b/plugins/packagekit/meson.build
@@ -50,6 +50,22 @@ shared_module(
dependencies : [ plugin_libs, packagekit ]
)
+shared_module(
+ 'gs_plugin_packagekit-refine-repos',
+ sources : [
+ 'gs-plugin-packagekit-refine-repos.c',
+ 'packagekit-common.c',
+ ],
+ include_directories : [
+ include_directories('../..'),
+ include_directories('../../lib'),
+ ],
+ install : true,
+ install_dir: plugin_dir,
+ c_args : cargs,
+ dependencies : [ plugin_libs, packagekit ]
+)
+
shared_module(
'gs_plugin_packagekit-refresh',
sources : [
diff --git a/plugins/repos/gs-plugin-repos.c b/plugins/repos/gs-plugin-repos.c
index 5db2888c..135cecdf 100644
--- a/plugins/repos/gs-plugin-repos.c
+++ b/plugins/repos/gs-plugin-repos.c
@@ -25,6 +25,7 @@
#include <gnome-software.h>
struct GsPluginData {
+ GHashTable *fns; /* origin : filename */
GHashTable *urls; /* origin : url */
GFileMonitor *monitor;
GMutex mutex;
@@ -51,6 +52,7 @@ gs_plugin_initialize (GsPlugin *plugin)
}
/* we also watch this for changes */
+ priv->fns = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
priv->urls = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
/* need application IDs */
@@ -62,6 +64,8 @@ gs_plugin_destroy (GsPlugin *plugin)
{
GsPluginData *priv = gs_plugin_get_data (plugin);
g_free (priv->reposdir);
+ if (priv->fns != NULL)
+ g_hash_table_unref (priv->fns);
if (priv->urls != NULL)
g_hash_table_unref (priv->urls);
if (priv->monitor != NULL)
@@ -82,6 +86,7 @@ gs_plugin_repos_setup (GsPlugin *plugin, GCancellable *cancellable, GError **err
return TRUE;
/* clear existing */
+ g_hash_table_remove_all (priv->fns);
g_hash_table_remove_all (priv->urls);
/* search all files */
@@ -113,6 +118,11 @@ gs_plugin_repos_setup (GsPlugin *plugin, GCancellable *cancellable, GError **err
groups = g_key_file_get_groups (kf, NULL);
for (i = 0; groups[i] != NULL; i++) {
g_autofree gchar *tmp = NULL;
+
+ g_hash_table_insert (priv->fns,
+ g_strdup (groups[i]),
+ g_strdup (filename));
+
tmp = g_key_file_get_string (kf, groups[i], "baseurl", NULL);
if (tmp != NULL) {
g_hash_table_insert (priv->urls,
@@ -120,6 +130,7 @@ gs_plugin_repos_setup (GsPlugin *plugin, GCancellable *cancellable, GError **err
g_strdup (tmp));
continue;
}
+
tmp = g_key_file_get_string (kf, groups[i], "metalink", NULL);
if (tmp != NULL) {
g_hash_table_insert (priv->urls,
@@ -205,5 +216,18 @@ gs_plugin_refine_app (GsPlugin *plugin,
break;
}
+ /* find filename */
+ switch (gs_app_get_kind (app)) {
+ case AS_APP_KIND_SOURCE:
+ if (gs_app_get_id (app) == NULL)
+ return TRUE;
+ tmp = g_hash_table_lookup (priv->fns, gs_app_get_id (app));
+ if (tmp != NULL)
+ gs_app_set_metadata (app, "repos::repo-filename", tmp);
+ break;
+ default:
+ break;
+ }
+
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]