[packagekit] packagekit: Branch 'master' - 25 commits

Richard Hughes hughsient at kemper.freedesktop.org
Sat Mar 29 05:14:32 PDT 2008


 backends/dummy/pk-backend-dummy.c       |   89 ++++++++++-----
 backends/yum2/helpers/yumDBUSBackend.py |   25 +---
 client/pk-console.c                     |   29 ++++-
 client/pk-import-desktop.c              |   24 +++-
 client/pk-import-specspo.c              |   13 +-
 configure.ac                            |   18 +++
 docs/html/pk-faq.html                   |   15 ++
 docs/spec/pk-concepts.xml               |   11 +
 docs/spec/pk-methods.xml                |    7 +
 libpackagekit/pk-client.c               |  183 ++++++++++++++++++++------------
 libpackagekit/pk-client.h               |   81 +++++++++-----
 libpackagekit/pk-common.c               |  109 +++++++++++++++++++
 libpackagekit/pk-common.h               |    2 
 libpackagekit/pk-enum.c                 |    2 
 libpackagekit/pk-enum.h                 |    2 
 libpackagekit/pk-filter.c               |   12 ++
 libpackagekit/pk-filter.h               |    2 
 libpackagekit/pk-package-list.c         |    2 
 src/Makefile.am                         |    2 
 19 files changed, 475 insertions(+), 153 deletions(-)

New commits:
commit 432046796fa420f57ab6c71081f7ba14e9a92574
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 11:54:26 2008 +0000

    add a stress test for PkClient into the self tests

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index fd529c9..3d327d7 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -3767,6 +3767,10 @@ libst_client (LibSelfTest *test)
 {
 	PkClient *client;
 	gboolean ret;
+	GError *error = NULL;
+	guint size;
+	guint size_new;
+	guint i;
 
 	if (libst_start (test, "PkClient", CLASS_AUTO) == FALSE) {
 		return;
@@ -3785,20 +3789,65 @@ libst_client (LibSelfTest *test)
 	g_signal_connect (client, "finished",
 			  G_CALLBACK (libst_client_finished_cb), NULL);
 
-	/************************************************************/
-	libst_title (test, "do any method");
-	/* we don't care if this fails */
+	/* run the method */
 	pk_client_set_synchronous (client, TRUE, NULL);
-	ret = pk_client_search_name (client, "none", "moooo", NULL);
-	libst_success (test, "did something");
+	ret = pk_client_search_name (client, "none", "power", NULL);
 
 	/************************************************************/
 	libst_title (test, "we finished?");
-	if (finished) {
+	if (ret && finished) {
+		libst_success (test, NULL);
+	} else {
+		libst_failed (test, NULL);
+	}
+
+	/************************************************************/
+	libst_title (test, "get new client");
+	client = pk_client_new ();
+	if (client != NULL) {
 		libst_success (test, NULL);
 	} else {
 		libst_failed (test, NULL);
 	}
+	pk_client_set_synchronous (client, TRUE, NULL);
+	pk_client_set_use_buffer (client, TRUE, NULL);
+
+	/************************************************************/
+	libst_title (test, "search for power");
+	ret = pk_client_search_name (client, "none", "power", &error);
+	if (!ret) {
+		libst_failed (test, "failed: %s", error->message);
+		g_error_free (error);
+	}
+
+	/* get size */
+	size = pk_client_package_buffer_get_size (client);
+	if (size == 0) {
+		libst_failed (test, "failed: to get any results");
+	}
+	libst_success (test, "search name with %i entries", size);
+
+	/************************************************************/
+	libst_title (test, "do lots of loops");
+	for (i=0;i<10;i++) {
+		ret = pk_client_reset (client, &error);
+		if (!ret) {
+			libst_failed (test, "failed: to reset: %s", error->message);
+			g_error_free (error);
+		}
+		ret = pk_client_search_name (client, "none", "power", &error);
+		if (!ret) {
+			libst_failed (test, "failed to search: %s", error->message);
+			g_error_free (error);
+		}
+		/* check we got the same results */
+		size_new = pk_client_package_buffer_get_size (client);
+		if (size != size_new) {
+			libst_failed (test, "old size %i, new size %", size, size_new);
+		}
+	}
+	libst_success (test, "10 search name loops completed in %ims", libst_elapsed (test));
+	g_object_unref (client);
 
 	libst_end (test);
 }
commit b9a7c412f87bb87d09cd4fcac22c13d9db0971fb
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 10:57:04 2008 +0000

    only process the desktop file if we got the package name

diff --git a/client/pk-import-desktop.c b/client/pk-import-desktop.c
index 9731ce1..b4c3736 100644
--- a/client/pk-import-desktop.c
+++ b/client/pk-import-desktop.c
@@ -221,7 +221,11 @@ pk_desktop_process_directory (const gchar *directory)
 			package_name = pk_desktop_get_name_for_file (filename);
 
 			/* process the file */
-			pk_desktop_process_desktop (package_name, filename);
+			if (package_name != NULL) {
+				pk_desktop_process_desktop (package_name, filename);
+			} else {
+				g_print ("%s ignored, failed to get package name\n", filename);
+			}
 			g_free (package_name);
 			g_free (filename);
 		}
commit cd9642515aa2f7dd7c6c0e4782793a26bd0b54f6
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 10:49:14 2008 +0000

    only enable PkClient things in the pk-import-desktop once

diff --git a/client/pk-import-desktop.c b/client/pk-import-desktop.c
index c387845..9731ce1 100644
--- a/client/pk-import-desktop.c
+++ b/client/pk-import-desktop.c
@@ -57,8 +57,6 @@ pk_desktop_get_name_for_file (const gchar *filename)
 		return NULL;
 	}
 
-	pk_client_set_use_buffer (client, TRUE, NULL);
-	pk_client_set_synchronous (client, TRUE, NULL);
 	ret = pk_client_search_file (client, "installed", filename, &error);
 	if (!ret) {
 		pk_warning ("failed to search file: %s", error->message);
@@ -269,6 +267,9 @@ main (int argc, char *argv[])
 	}
 
 	client = pk_client_new ();
+	pk_client_set_use_buffer (client, TRUE, NULL);
+	pk_client_set_synchronous (client, TRUE, NULL);
+
 	extra = pk_extra_new ();
 	ret = pk_extra_set_database (extra, database_location);
 	if (!ret) {
commit 639d6fa05b48033241f4acf98f3e751fd5a20594
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 10:21:55 2008 +0000

    add a note to the docs about GetUpdates and NEWEST

diff --git a/docs/spec/pk-methods.xml b/docs/spec/pk-methods.xml
index 89a0720..d56d020 100644
--- a/docs/spec/pk-methods.xml
+++ b/docs/spec/pk-methods.xml
@@ -710,6 +710,7 @@
     <para>
       This function should return a list of packages that are installed and
       are upgradable.
+      It should only return the newest update for each installed package.
     </para>
     <para>
       The arguments are:
commit 11c0fd97d88050fbafea2ec6fdc161e19a5a9291
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 10:20:33 2008 +0000

    add NEWEST to PkFilter and correct the enum name - pointed out by Marcin, thanks.

diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index 716ef9e..53308ba 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -170,8 +170,8 @@ static PkEnumMatch enum_filter[] = {
 	{PK_FILTER_ENUM_NOT_SUPPORTED,		"~supported"},
 	{PK_FILTER_ENUM_BASENAME,		"basename"},
 	{PK_FILTER_ENUM_NOT_BASENAME,		"~basename"},
-	{PK_FILTER_ENUM_NEWEST,			"basename"},
-	{PK_FILTER_ENUM_NOT_NEWEST,		"~basename"},
+	{PK_FILTER_ENUM_NEWEST,			"newest"},
+	{PK_FILTER_ENUM_NOT_NEWEST,		"~newest"},
 	{0, NULL}
 };
 
diff --git a/libpackagekit/pk-filter.c b/libpackagekit/pk-filter.c
index 4fe80a2..37dabd5 100644
--- a/libpackagekit/pk-filter.c
+++ b/libpackagekit/pk-filter.c
@@ -114,6 +114,8 @@ pk_filter_set_all (PkFilter *filter, gboolean value)
 	filter->not_visible = value;
 	filter->basename = value;
 	filter->not_basename = value;
+	filter->newest = value;
+	filter->not_newest = value;
 	return TRUE;
 }
 
@@ -201,6 +203,10 @@ pk_filter_new_from_string (const gchar *filter_text)
 			filter->not_basename = FALSE;
 		} else if (pk_strequal (sections[i], "~basename")) {
 			filter->basename = FALSE;
+		} else if (pk_strequal (sections[i], "newest")) {
+			filter->not_newest = FALSE;
+		} else if (pk_strequal (sections[i], "~newest")) {
+			filter->newest = FALSE;
 		} else {
 			pk_warning ("element '%s' not recognised", sections[i]);
 			ret = FALSE;
@@ -276,6 +282,12 @@ pk_filter_to_string (PkFilter *filter)
 	if (filter->not_basename && !filter->basename) {
 		g_string_append (string, "~basename;");
 	}
+	if (filter->newest && !filter->not_newest) {
+		g_string_append (string, "newest;");
+	}
+	if (filter->not_newest && !filter->newest) {
+		g_string_append (string, "~newest;");
+	}
 
 	/* remove trailing ; */
 	if (string->len > 0) {
diff --git a/libpackagekit/pk-filter.h b/libpackagekit/pk-filter.h
index 2c59094..e3e5262 100644
--- a/libpackagekit/pk-filter.h
+++ b/libpackagekit/pk-filter.h
@@ -44,6 +44,8 @@ typedef struct {
 	gboolean not_visible;
 	gboolean basename;
 	gboolean not_basename;
+	gboolean newest;
+	gboolean not_newest;
 } PkFilter;
 
 gboolean	 pk_filter_check			(const gchar	*filter)
commit d0838b94445f31be1a0c9039ec85f40b20de2a22
Author: Luke Macken <lmacken at redhat.com>
Date:   Sat Mar 29 02:43:44 2008 -0400

    Fix some indentation issues in _get_update_extras, and clean it up a bit.

diff --git a/backends/yum2/helpers/yumDBUSBackend.py b/backends/yum2/helpers/yumDBUSBackend.py
index 626d44e..f57fdd8 100755
--- a/backends/yum2/helpers/yumDBUSBackend.py
+++ b/backends/yum2/helpers/yumDBUSBackend.py
@@ -1793,25 +1793,22 @@ class PackageKitYumBackend(PackageKitBaseBackend):
             return ""
 
     def _get_update_extras(self,pkg):
-        md = self.updateMetadata
-        notice = md.get_notice((pkg.name, pkg.version, pkg.release))
-        urls = {'bugzilla':[], 'cve' : [], 'vendor': []}
+        urls = {'bugzilla': [], 'cve': [], 'vendor': []}
+        notice = self.updateMetadata.get_notice((pkg.name, pkg.version, pkg.release))
         if notice:
             # Update Description
             desc = notice['description']
+
             # Update References (Bugzilla,CVE ...)
-            refs = notice['references']
-            if refs:
-                for ref in refs:
-                    typ = ref['type']
-            href = ref['href']
-            title = ref['title']
-                    if typ in ('bugzilla','cve') and href != None:
-            if title == None:
-                title = ""
-                        urls[typ].append("%s;%s" % (href,title))
+            for ref in notice['references']:
+                type_ = ref['type']
+                href = ref['href']
+                title = ref['title'] or ""
+                if href:
+                    if type_ in ('bugzilla', 'cve'):
+                        urls[type_].append("%s;%s" % (href, title))
                     else:
-                        urls['vendor'].append("%s;%s" % (ref['href'],ref['title']))
+                        urls['vendor'].append("%s;%s" % (href, title))
 
             # Reboot flag
             if notice.get_metadata().has_key('reboot_suggested') and notice['reboot_suggested']:
commit eaf83fe7bebeefd23dfd6b522e8177db07fa3926
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 02:22:44 2008 +0000

    optimise some pk_client_set_* calls

diff --git a/client/pk-console.c b/client/pk-console.c
index e1b6a6c..bc7d237 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -605,8 +605,6 @@ pk_console_remove_package (PkClient *client, const gchar *package, GError **erro
 		pk_warning ("failed to reset");
 		return FALSE;
 	}
-	pk_client_set_use_buffer (client_task, TRUE, NULL);
-	pk_client_set_synchronous (client_task, TRUE, NULL);
 
 	pk_debug (_("Getting installed requires for %s"), package_id);
 	ret = pk_client_get_requires (client_task, "installed", package_id, TRUE, error);
commit 8808d1288b6bdcf225f716d6d084602c1dd6469c
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 02:19:17 2008 +0000

    warn when we are doing PkClient actions when we don't need to

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 6d200f7..fd529c9 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -297,6 +297,14 @@ pk_client_set_promiscuous (PkClient *client, gboolean enabled, GError **error)
 				     "cannot set promiscuous on a tid client");
 		return FALSE;
 	}
+
+	/* are we doing this without any need? */
+	if (client->priv->promiscuous) {
+		pk_client_error_set (error, PK_CLIENT_ERROR_FAILED,
+				     "already set promiscuous!");
+		return FALSE;
+	}
+
 	client->priv->promiscuous = enabled;
 	return TRUE;
 }
@@ -360,6 +368,13 @@ pk_client_set_use_buffer (PkClient *client, gboolean use_buffer, GError **error)
 	g_return_val_if_fail (client != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
 
+	/* are we doing this without any need? */
+	if (client->priv->use_buffer) {
+		pk_client_error_set (error, PK_CLIENT_ERROR_FAILED,
+				     "already set use_buffer!");
+		return FALSE;
+	}
+
 	client->priv->use_buffer = use_buffer;
 	return TRUE;
 }
@@ -380,6 +395,13 @@ pk_client_set_synchronous (PkClient *client, gboolean synchronous, GError **erro
 	g_return_val_if_fail (client != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
 
+	/* are we doing this without any need? */
+	if (client->priv->synchronous) {
+		pk_client_error_set (error, PK_CLIENT_ERROR_FAILED,
+				     "already set synchronous!");
+		return FALSE;
+	}
+
 	client->priv->synchronous = synchronous;
 	return TRUE;
 }
@@ -3435,6 +3457,7 @@ pk_client_init (PkClient *client)
 	client->priv->loop = g_main_loop_new (NULL, FALSE);
 	client->priv->use_buffer = FALSE;
 	client->priv->promiscuous = FALSE;
+	client->priv->synchronous = FALSE;
 	client->priv->last_status = PK_STATUS_ENUM_UNKNOWN;
 	client->priv->require_restart = PK_RESTART_ENUM_NONE;
 	client->priv->role = PK_ROLE_ENUM_UNKNOWN;
commit 779b2daf7b76c4dbf0062f757e84781ca334482a
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 01:46:37 2008 +0000

    don't reset use_buffer or synchronous in pk_client_reset

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 13c85a4..6d200f7 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -511,8 +511,6 @@ pk_client_reset (PkClient *client, GError **error)
 	client->priv->cached_filter = NULL;
 	client->priv->cached_search = NULL;
 	client->priv->cached_package_ids = NULL;
-	client->priv->use_buffer = FALSE;
-	client->priv->synchronous = FALSE;
 	client->priv->last_status = PK_STATUS_ENUM_UNKNOWN;
 	client->priv->role = PK_ROLE_ENUM_UNKNOWN;
 	client->priv->is_finished = FALSE;
commit d2339b39ffa373b03fb5a3c6216258c566d06705
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 01:34:05 2008 +0000

    improve debuggability of the daemon

diff --git a/libpackagekit/pk-package-list.c b/libpackagekit/pk-package-list.c
index 4820fa8..ee61c5f 100644
--- a/libpackagekit/pk-package-list.c
+++ b/libpackagekit/pk-package-list.c
@@ -76,7 +76,7 @@ pk_package_list_add (PkPackageList *plist, PkInfoEnum info, const gchar *package
 	g_return_val_if_fail (plist != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE);
 
-	pk_debug ("adding to cache array package %i, %s, %s", info, package_id, summary);
+	pk_debug ("adding to cache array package %s, %s, %s", pk_info_enum_to_text (info), package_id, summary);
 	item = g_new0 (PkPackageItem, 1);
 	item->info = info;
 	item->package_id = g_strdup (package_id);
commit ba683d6c3e82760c5d1b7ea799b46970f6805499
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 01:33:48 2008 +0000

    make the update_system smarter for the dummy backend

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index 8c7bb7e..358cabe 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -571,23 +571,23 @@ backend_update_system_timeout (gpointer data)
 		pk_backend_finished (backend);
 		return FALSE;
 	}
-	if (_progress_percentage == 0) {
+	if (_progress_percentage == 0 && !_updated_powertop) {
 		pk_backend_package (backend, PK_INFO_ENUM_DOWNLOADING,
 				    "powertop;1.8-1.fc8;i386;fedora",
 				    "Power consumption monitor");
 	}
-	if (_progress_percentage == 20) {
+	if (_progress_percentage == 20 && !_updated_kernel) {
 		pk_backend_package (backend, PK_INFO_ENUM_DOWNLOADING,
 				    "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed",
 				    "The Linux kernel (the core of the Linux operating system)");
 	}
-	if (_progress_percentage == 30) {
+	if (_progress_percentage == 30 && !_updated_gtkhtml) {
 		pk_backend_package (backend, PK_INFO_ENUM_BLOCKED,
 				    "gtkhtml2;2.19.1-4.fc8;i386;fedora",
 				    "An HTML widget for GTK+ 2.0");
 		_updated_gtkhtml = FALSE;
 	}
-	if (_progress_percentage == 40) {
+	if (_progress_percentage == 40 && !_updated_powertop) {
 		pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE);
 		pk_backend_set_allow_cancel (backend, FALSE);
 		pk_backend_package (backend, PK_INFO_ENUM_INSTALLING,
@@ -595,13 +595,13 @@ backend_update_system_timeout (gpointer data)
 				    "Power consumption monitor");
 		_updated_powertop = TRUE;
 	}
-	if (_progress_percentage == 60) {
+	if (_progress_percentage == 60 && !_updated_kernel) {
 		pk_backend_package (backend, PK_INFO_ENUM_UPDATING,
 				    "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed",
 				    "The Linux kernel (the core of the Linux operating system)");
 		_updated_kernel = TRUE;
 	}
-	if (_progress_percentage == 80) {
+	if (_progress_percentage == 80 && !_updated_kernel) {
 		pk_backend_package (backend, PK_INFO_ENUM_CLEANUP,
 				    "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed",
 				    "The Linux kernel (the core of the Linux operating system)");
commit 980297dab4341f8ebed86cb08fd06eb1017cb6bd
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 00:49:39 2008 +0000

    make the dummy backend keep track of what updates have been updated

diff --git a/backends/dummy/pk-backend-dummy.c b/backends/dummy/pk-backend-dummy.c
index ce06e3f..8c7bb7e 100644
--- a/backends/dummy/pk-backend-dummy.c
+++ b/backends/dummy/pk-backend-dummy.c
@@ -36,6 +36,9 @@ static gboolean _has_service_pack = FALSE;
 static gboolean _repo_enabled_local = FALSE;
 static gboolean _repo_enabled_fedora = TRUE;
 static gboolean _repo_enabled_livna = TRUE;
+static gboolean _updated_gtkhtml = FALSE;
+static gboolean _updated_kernel = FALSE;
+static gboolean _updated_powertop = FALSE;
 
 /**
  * backend_initialize:
@@ -236,15 +239,22 @@ static gboolean
 backend_get_updates_timeout (gpointer data)
 {
 	PkBackend *backend = (PkBackend *) data;
-	pk_backend_package (backend, PK_INFO_ENUM_NORMAL,
-			    "powertop;1.8-1.fc8;i386;fedora",
-			    "Power consumption monitor");
-	pk_backend_package (backend, PK_INFO_ENUM_SECURITY,
-			    "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed",
-			    "The Linux kernel (the core of the Linux operating system)");
-	pk_backend_package (backend, PK_INFO_ENUM_SECURITY,
-			    "gtkhtml2;2.19.1-4.fc8;i386;fedora",
-			    "An HTML widget for GTK+ 2.0");
+
+	if (!_updated_powertop) {
+		pk_backend_package (backend, PK_INFO_ENUM_NORMAL,
+				    "powertop;1.8-1.fc8;i386;fedora",
+				    "Power consumption monitor");
+	}
+	if (!_updated_kernel) {
+		pk_backend_package (backend, PK_INFO_ENUM_SECURITY,
+				    "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed",
+				    "The Linux kernel (the core of the Linux operating system)");
+	}
+	if (!_updated_gtkhtml) {
+		pk_backend_package (backend, PK_INFO_ENUM_SECURITY,
+				    "gtkhtml2;2.19.1-4.fc8;i386;fedora",
+				    "An HTML widget for GTK+ 2.0");
+	}
 	pk_backend_finished (backend);
 	_signal_timeout = 0;
 	return FALSE;
@@ -347,6 +357,12 @@ backend_refresh_cache (PkBackend *backend, gboolean force)
 {
 	g_return_if_fail (backend != NULL);
 	_progress_percentage = 0;
+
+	/* reset */
+	_updated_gtkhtml = FALSE;
+	_updated_kernel = FALSE;
+	_updated_powertop = FALSE;
+
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REFRESH_CACHE);
 	_signal_timeout = g_timeout_add (500, backend_refresh_cache_timeout, backend);
 }
@@ -478,9 +494,23 @@ backend_update_packages_update_timeout (gpointer data)
 {
 	guint len;
 	PkBackend *backend = (PkBackend *) data;
+	const gchar *package;
 
+	package = _package_ids[_package_current];
 	/* emit the next package */
-	pk_backend_package (backend, PK_INFO_ENUM_UPDATING, _package_ids[_package_current], "The same thing");
+	if (pk_strequal (package, "powertop;1.8-1.fc8;i386;fedora")) {
+		pk_backend_package (backend, PK_INFO_ENUM_UPDATING, package, "Power consumption monitor");
+		_updated_powertop = TRUE;
+	}
+	if (pk_strequal (package, "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed")) {
+		pk_backend_package (backend, PK_INFO_ENUM_UPDATING, package,
+				    "The Linux kernel (the core of the Linux operating system)");
+		_updated_kernel = TRUE;
+	}
+	if (pk_strequal (package, "gtkhtml2;2.19.1-4.fc8;i386;fedora")) {
+		pk_backend_package (backend, PK_INFO_ENUM_UPDATING, package, "An HTML widget for GTK+ 2.0");
+		_updated_gtkhtml = TRUE;
+	}
 
 	/* are we done? */
 	_package_current++;
@@ -543,35 +573,38 @@ backend_update_system_timeout (gpointer data)
 	}
 	if (_progress_percentage == 0) {
 		pk_backend_package (backend, PK_INFO_ENUM_DOWNLOADING,
-				    "update1;2.19.1-4.fc8;i386;fedora",
-				    "The first update");
+				    "powertop;1.8-1.fc8;i386;fedora",
+				    "Power consumption monitor");
 	}
 	if (_progress_percentage == 20) {
 		pk_backend_package (backend, PK_INFO_ENUM_DOWNLOADING,
-				    "update2;2.19.1-4.fc8;i386;fedora",
-				    "The second update");
+				    "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed",
+				    "The Linux kernel (the core of the Linux operating system)");
 	}
 	if (_progress_percentage == 30) {
 		pk_backend_package (backend, PK_INFO_ENUM_BLOCKED,
-				    "update3;2.19.1-4.fc8;i386;fedora",
-				    "The third update");
+				    "gtkhtml2;2.19.1-4.fc8;i386;fedora",
+				    "An HTML widget for GTK+ 2.0");
+		_updated_gtkhtml = FALSE;
 	}
 	if (_progress_percentage == 40) {
 		pk_backend_set_status (backend, PK_STATUS_ENUM_UPDATE);
 		pk_backend_set_allow_cancel (backend, FALSE);
 		pk_backend_package (backend, PK_INFO_ENUM_INSTALLING,
-				    "update1;2.19.1-4.fc8;i386;fedora",
-				    "The first update");
+				    "powertop;1.8-1.fc8;i386;fedora",
+				    "Power consumption monitor");
+		_updated_powertop = TRUE;
 	}
 	if (_progress_percentage == 60) {
 		pk_backend_package (backend, PK_INFO_ENUM_UPDATING,
-				    "update2;2.19.1-4.fc8;i386;fedora",
-				    "The second update");
+				    "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed",
+				    "The Linux kernel (the core of the Linux operating system)");
+		_updated_kernel = TRUE;
 	}
 	if (_progress_percentage == 80) {
 		pk_backend_package (backend, PK_INFO_ENUM_CLEANUP,
-				    "update1;2.19.1-4.fc8;i386;fedora",
-				    "The first update (old version)");
+				    "kernel;2.6.23-0.115.rc3.git1.fc8;i386;installed",
+				    "The Linux kernel (the core of the Linux operating system)");
 	}
 	_progress_percentage += 10;
 	pk_backend_set_percentage (backend, _progress_percentage);
commit 4d10cc41143d05fd921f71c9d97a2f8eb8b52afa
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 00:31:44 2008 +0000

    enforce with G_GNUC_WARN_UNUSED_RESULT PkClient action methods, the logc being it will help us write client programs with better error handling

diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index 329e285..24605fc 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -201,16 +201,20 @@ gboolean	 pk_client_get_package			(PkClient	*client,
 							 gchar		**package,
 							 GError		**error);
 gboolean	 pk_client_cancel			(PkClient	*client,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_updates			(PkClient	*client,
 							 const gchar	*filter,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_update_system		(PkClient	*client,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_search_name			(PkClient	*client,
 							 const gchar	*filter,
 							 const gchar	*search,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_search_details		(PkClient	*client,
 							 const gchar	*filter,
 							 const gchar	*search,
@@ -218,82 +222,103 @@ gboolean	 pk_client_search_details		(PkClient	*client,
 gboolean	 pk_client_search_group			(PkClient	*client,
 							 const gchar	*filter,
 							 const gchar	*search,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_search_file			(PkClient	*client,
 							 const gchar	*filter,
 							 const gchar	*search,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_depends			(PkClient	*client,
 							 const gchar	*filter,
 							 const gchar	*package_id,
 							 gboolean	 recursive,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_update_detail		(PkClient	*client,
 							 const gchar	*package_id,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_requires			(PkClient	*client,
 							 const gchar	*filter,
 							 const gchar	*package_id,
 							 gboolean	 recursive,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_what_provides		(PkClient	*client,
 							 const gchar	*filter,
 							 PkProvidesEnum	 provides,
 							 const gchar	*search,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_description		(PkClient	*client,
 							 const gchar	*package_id,
 							 GError		**error);
 gboolean	 pk_client_get_files			(PkClient	*client,
 							 const gchar	*package_id,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_remove_package		(PkClient	*client,
 							 const gchar	*package_id,
 							 gboolean	 allow_deps,
 							 gboolean	 autoremove,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_refresh_cache		(PkClient	*client,
 							 gboolean	 force,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_install_package		(PkClient	*client,
 							 const gchar	*package_id,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_update_package		(PkClient	*client,
 							 const gchar	*package_id,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_update_packages		(PkClient	*client,
 							 GError		**error,
-							 const gchar	*package_id, ...);
+							 const gchar	*package_id, ...)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_update_packages_strv		(PkClient	*client,
 							 gchar		**package_ids,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_install_file			(PkClient	*client,
 							 const gchar	*file,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_resolve			(PkClient	*client,
 							 const gchar	*filter,
 							 const gchar	*package,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_rollback			(PkClient	*client,
 							 const gchar	*transaction_id,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_cancel			(PkClient	*client,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_requeue			(PkClient	*client,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 
 /* repo stuff */
 gboolean	 pk_client_get_repo_list		(PkClient	*client,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_repo_enable			(PkClient	*client,
 							 const gchar	*repo_id,
 							 gboolean	 enabled,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_repo_set_data		(PkClient	*client,
 							 const gchar	*repo_id,
 							 const gchar	*parameter,
 							 const gchar	*value,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 
 /* cached stuff */
 guint		 pk_client_package_buffer_get_size	(PkClient	*client);
@@ -306,7 +331,8 @@ PkEnumList	*pk_client_get_actions			(PkClient	*client);
 PkEnumList	*pk_client_get_filters			(PkClient	*client);
 PkEnumList	*pk_client_get_groups			(PkClient	*client);
 gboolean	 pk_client_reset			(PkClient	*client,
-							 GError		**error);
+							 GError		**error)
+							 G_GNUC_WARN_UNUSED_RESULT;
 gboolean	 pk_client_get_old_transactions		(PkClient	*client,
 							 guint		 number,
 							 GError		**error);
commit 83370b80703a513141277dbd3a69436e88af1c8c
Author: Richard Hughes <richard at hughsie.com>
Date:   Sat Mar 29 00:30:37 2008 +0000

    ignore some errors like 'Already finished' when we try to cancel

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 51d871c..13c85a4 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -1213,6 +1213,7 @@ gboolean
 pk_client_cancel (PkClient *client, GError **error)
 {
 	gboolean ret;
+	GError *error_local = NULL;
 
 	g_return_val_if_fail (client != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
@@ -1223,11 +1224,30 @@ pk_client_cancel (PkClient *client, GError **error)
 		return TRUE;
 	}
 
-	ret = dbus_g_proxy_call (client->priv->proxy, "Cancel", error,
+	ret = dbus_g_proxy_call (client->priv->proxy, "Cancel", &error_local,
 				 G_TYPE_STRING, client->priv->tid,
 				 G_TYPE_INVALID, G_TYPE_INVALID);
-	pk_client_error_fixup (error);
-	return ret;
+	/* no error to process */
+	if (ret) {
+		return TRUE;
+	}
+
+	/* special case - if the tid is already finished, then cancel should
+	 * return TRUE as it's what we wanted */
+	if (pk_strequal (error_local->message, "Already finished") ||
+	    g_str_has_prefix (error_local->message, "No tid")) {
+		pk_debug ("error ignored '%s' as we are trying to cancel", error_local->message);
+		g_error_free (error_local);
+		return TRUE;
+	}
+
+	/* if we got an error we don't recognise, just fix it up and copy it */
+	if (error != NULL) {
+		pk_client_error_fixup (&error_local);
+		*error = g_error_copy (error_local);
+		g_error_free (error_local);
+	}
+	return FALSE;
 }
 
 /******************************************************************************
commit b5b9431ed93486e2370f6c4e804e0ce31a1408de
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 23:44:45 2008 +0000

    if we failed to cancel an unused client, return TRUE, as the action succeeded

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index cc46cb3..51d871c 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -1220,7 +1220,7 @@ pk_client_cancel (PkClient *client, GError **error)
 	/* check to see if we have an tid */
 	if (client->priv->tid == NULL) {
 		pk_debug ("Transaction ID not set, assumed never used");
-		return FALSE;
+		return TRUE;
 	}
 
 	ret = dbus_g_proxy_call (client->priv->proxy, "Cancel", error,
commit 5ed5677121c4faacfc10c6b3e3ff312028c0b940
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 23:07:47 2008 +0000

    cancel a running transaction is we try to reset it

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 4de3f82..cc46cb3 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -474,16 +474,26 @@ pk_client_package_buffer_get_item (PkClient *client, guint item)
  * waiting for ::finished, or if we want to reuse the #PkClient without
  * unreffing and creating it again.
  *
+ * If you call pk_client_reset() on a running transaction, then it will be
+ * automatically cancelled. If the cancel fails, the reset will fail.
+ *
  * Return value: %TRUE if we reset the client
  **/
 gboolean
 pk_client_reset (PkClient *client, GError **error)
 {
+	gboolean ret;
+
 	g_return_val_if_fail (client != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
 
 	if (client->priv->is_finished != TRUE) {
-		pk_debug ("not exit status, reset might be invalid");
+		pk_debug ("not exit status, will try to cancel");
+		/* we try to cancel the running tranaction */
+		ret = pk_client_cancel (client, error);
+		if (!ret) {
+			return FALSE;
+		}
 	}
 
 	g_free (client->priv->tid);
commit 7a6c9b45e32b5910088eb9499a1a96daed26c8df
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 23:01:42 2008 +0000

    be more paranoid checking for errors from PkClient methods

diff --git a/client/pk-console.c b/client/pk-console.c
index da7dd80..e1b6a6c 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -455,7 +455,11 @@ pk_console_perhaps_resolve (PkClient *client, PkFilterEnum filter, const gchar *
 
 	/* didn't resolve to anything, try to get a provide */
 	if (length == 0) {
-		pk_client_reset (client_task, NULL);
+		ret = pk_client_reset (client_task, error);
+		if (ret == FALSE) {
+			pk_warning ("failed to reset client task");
+			return NULL;
+		}
 		ret = pk_client_what_provides (client_task, filter_text, PK_PROVIDES_ENUM_ANY, package, error);
 		if (ret == FALSE) {
 			pk_warning (_("WhatProvides is not supported in this backend"));
@@ -596,7 +600,11 @@ pk_console_remove_package (PkClient *client, const gchar *package, GError **erro
 	}
 
 	/* see if any packages require this one */
-	pk_client_reset (client_task, NULL);
+	ret = pk_client_reset (client_task, error);
+	if (!ret) {
+		pk_warning ("failed to reset");
+		return FALSE;
+	}
 	pk_client_set_use_buffer (client_task, TRUE, NULL);
 	pk_client_set_synchronous (client_task, TRUE, NULL);
 
@@ -1068,6 +1076,8 @@ static void
 pk_console_sigint_handler (int sig)
 {
 	PkRoleEnum role;
+	gboolean ret;
+	GError *error = NULL;
 	pk_debug ("Handling SIGINT");
 
 	/* restore default ASAP, as the cancels might hang */
@@ -1076,11 +1086,20 @@ pk_console_sigint_handler (int sig)
 	/* cancel any tasks */
 	pk_client_get_role (client, &role, NULL, NULL);
 	if (role != PK_ROLE_ENUM_UNKNOWN) {
-		pk_client_cancel (client, NULL);
+		ret = pk_client_cancel (client, &error);
+		if (!ret) {
+			pk_warning ("failed to cancel normal client: %s", error->message);
+			g_error_free (error);
+			error = NULL;
+		}
 	}
 	pk_client_get_role (client_task, &role, NULL, NULL);
 	if (role != PK_ROLE_ENUM_UNKNOWN) {
-		pk_client_cancel (client_task, NULL);
+		ret = pk_client_cancel (client_task, &error);
+		if (!ret) {
+			pk_warning ("failed to cancel task client: %s", error->message);
+			g_error_free (error);
+		}
 	}
 
 	/* kill ourselves */
diff --git a/client/pk-import-desktop.c b/client/pk-import-desktop.c
index ab55c92..c387845 100644
--- a/client/pk-import-desktop.c
+++ b/client/pk-import-desktop.c
@@ -47,13 +47,22 @@ pk_desktop_get_name_for_file (const gchar *filename)
 	PkPackageItem *item;
 	PkPackageId *pid;
 	gboolean ret;
+	GError *error = NULL;
 
 	/* use PK to find the correct package */
-	pk_client_reset (client, NULL);
+	ret = pk_client_reset (client, &error);
+	if (!ret) {
+		pk_warning ("failed to reset client: %s", error->message);
+		g_error_free (error);
+		return NULL;
+	}
+
 	pk_client_set_use_buffer (client, TRUE, NULL);
 	pk_client_set_synchronous (client, TRUE, NULL);
-	ret = pk_client_search_file (client, "installed", filename, NULL);
+	ret = pk_client_search_file (client, "installed", filename, &error);
 	if (!ret) {
+		pk_warning ("failed to search file: %s", error->message);
+		g_error_free (error);
 		return NULL;
 	}
 
diff --git a/client/pk-import-specspo.c b/client/pk-import-specspo.c
index 2e2f0d6..b80ff24 100644
--- a/client/pk-import-specspo.c
+++ b/client/pk-import-specspo.c
@@ -54,12 +54,21 @@ pk_import_specspo_get_summary (const gchar *name)
 	guint size;
 	gboolean ret;
 	PkPackageItem *item;
+	GError *error = NULL;
+
+	ret = pk_client_reset (client, &error);
+	if (!ret) {
+		pk_warning ("failed to reset client: %s", error->message);
+		g_error_free (error);
+		return NULL;
+	}
 
-	pk_client_reset (client, NULL);
 	pk_client_set_use_buffer (client, TRUE, NULL);
 	pk_client_set_synchronous (client, TRUE, NULL);
-	ret = pk_client_resolve (client, "none", name, NULL);
+	ret = pk_client_resolve (client, "none", name, &error);
 	if (!ret) {
+		pk_warning ("failed to resolve: %s", error->message);
+		g_error_free (error);
 		return NULL;
 	}
 
diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 740d2bb..4de3f82 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -3715,6 +3715,7 @@ void
 libst_client (LibSelfTest *test)
 {
 	PkClient *client;
+	gboolean ret;
 
 	if (libst_start (test, "PkClient", CLASS_AUTO) == FALSE) {
 		return;
@@ -3737,7 +3738,7 @@ libst_client (LibSelfTest *test)
 	libst_title (test, "do any method");
 	/* we don't care if this fails */
 	pk_client_set_synchronous (client, TRUE, NULL);
-	pk_client_search_name (client, "none", "moooo", NULL);
+	ret = pk_client_search_name (client, "none", "moooo", NULL);
 	libst_success (test, "did something");
 
 	/************************************************************/
commit 5e9fadaf652128657ebba1c9c354fd03ca3d7a65
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 22:26:43 2008 +0000

    add gio configure checks

diff --git a/configure.ac b/configure.ac
index 1c79ff3..e5e0c96 100755
--- a/configure.ac
+++ b/configure.ac
@@ -70,6 +70,7 @@ dnl ---------------------------------------------------------------------------
 dnl - Library dependencies
 dnl ---------------------------------------------------------------------------
 GLIB_REQUIRED=2.14.0
+GIO_REQUIRED=2.16.1
 DBUS_REQUIRED=1.1.1
 DBUS_GLIB_REQUIRED=0.73
 LIBNM_GLIB_REQUIRED=0.6.4
@@ -106,6 +107,22 @@ AC_SUBST(DBUS_CFLAGS)
 AC_SUBST(DBUS_LIBS)
 
 dnl ---------------------------------------------------------------------------
+dnl - Is GIO available?
+dnl ---------------------------------------------------------------------------
+PKG_CHECK_MODULES(GIO, gio-2.0 >= $GIO_REQUIRED, PK_BUILD_GIO="yes", PK_BUILD_GIO="no")
+if test "x$PK_BUILD_GIO" = "xyes"; then
+	with_gio="yes"
+	AC_DEFINE(PK_BUILD_GIO, 1, [define if GIO is installed])
+else
+	with_gio="no"
+	PK_BUILD_GIO=no
+fi
+
+AM_CONDITIONAL(PK_BUILD_GIO, test x$PK_BUILD_GIO = xyes)
+AC_SUBST(GIO_CFLAGS)
+AC_SUBST(GIO_LIBS)
+
+dnl ---------------------------------------------------------------------------
 dnl - Is NetworkManager available?
 dnl ---------------------------------------------------------------------------
 PKG_CHECK_MODULES(LIBNM, libnm_glib >= $LIBNM_GLIB_REQUIRED, PK_BUILD_NETWORKMANAGER="yes", PK_BUILD_NETWORKMANAGER="no")
@@ -625,6 +642,7 @@ echo "
         GCC time profiling:        ${enable_gprof}
         Security framework:        ${with_security_framework}
         Networking stack:          ${with_networking_stack}
+        GIO support:               ${with_gio}
 
         Backends:
         ALPM backend:              ${enable_alpm}
diff --git a/src/Makefile.am b/src/Makefile.am
index a606224..23ce93e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,6 +12,7 @@ SELFTEST_LIBS =						\
 	$(NULL)
 
 INCLUDES =						\
+	$(GIO_CFLAGS)					\
 	$(GLIB_CFLAGS)					\
 	$(DBUS_CFLAGS)					\
 	$(SQLITE_CFLAGS)				\
@@ -98,6 +99,7 @@ packagekitd_LDADD =					\
 	$(PK_LIBS)					\
 	$(POLKIT_LIBS)					\
 	$(SELFTEST_LIBS)				\
+	$(GIO_LIBS)					\
 	$(NULL)
 
 if BACKEND_TYPE_BOX
commit 555d028bafd8206ec9d6870917312f7ba86514bb
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 21:46:44 2008 +0000

    clarify that the search methods should return all results

diff --git a/docs/spec/pk-methods.xml b/docs/spec/pk-methods.xml
index 329cb4a..89a0720 100644
--- a/docs/spec/pk-methods.xml
+++ b/docs/spec/pk-methods.xml
@@ -49,6 +49,12 @@
       should not be sensitive to <literal>_</literal> or <literal>-</literal>.
     </para>
     <para>
+      The search methods should return all results in all repositories.
+      This may mean that multiple versions of package are returned.
+      If this is not what is wanted by the client program, then the
+      <literal>newest</literal> filter should be used.
+    </para>
+    <para>
       This method typically emits
       <literal>Progress</literal>,
       <literal>Error</literal> and
commit 8957e3787a3295be167878de7a90f87bccd024f7
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 20:48:07 2008 +0000

    add the NEWEST filter

diff --git a/docs/html/pk-faq.html b/docs/html/pk-faq.html
index e5239c4..7d15c3c 100644
--- a/docs/html/pk-faq.html
+++ b/docs/html/pk-faq.html
@@ -513,6 +513,21 @@
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
 <td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
 </tr>
+<tr>
+<td><b>Newest</b></td>
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- apt2 -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- alpm -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- box -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- conary -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- opkg -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- pisi -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- poldek -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- smart -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- yum2 -->
+<td><img src="img/status-bad.png" alt="[no]"/></td><!-- zypp -->
+</tr>
 </table>
 
 <hr>
diff --git a/docs/spec/pk-concepts.xml b/docs/spec/pk-concepts.xml
index 10b8944..6ee73f7 100644
--- a/docs/spec/pk-concepts.xml
+++ b/docs/spec/pk-concepts.xml
@@ -106,6 +106,17 @@
               The basename is normally the original name of the source package.
             </entry>
           </row>
+          <row>
+            <entry><literal>newest</literal> or <literal>~newest</literal></entry>
+            <entry>
+              The newest filter will only return the newest package available.
+              This is useful if you are searching for <literal>gimp</literal>
+              and only <literal>gimp-2.4.5-1.fc9.i386</literal> would be returned,
+              not <literal>gimp-2.4.5-1.fc9.i386</literal>,
+              <literal>gimp-2.4.4-1.fc9.i386</literal> and
+              <literal>gimp-2.4.3-1.fc9.i386</literal>.
+            </entry>
+          </row>
         </tbody>
       </tgroup>
     </informaltable>
diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index 8767a12..716ef9e 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -170,6 +170,8 @@ static PkEnumMatch enum_filter[] = {
 	{PK_FILTER_ENUM_NOT_SUPPORTED,		"~supported"},
 	{PK_FILTER_ENUM_BASENAME,		"basename"},
 	{PK_FILTER_ENUM_NOT_BASENAME,		"~basename"},
+	{PK_FILTER_ENUM_NEWEST,			"basename"},
+	{PK_FILTER_ENUM_NOT_NEWEST,		"~basename"},
 	{0, NULL}
 };
 
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index d733652..69bb3c6 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -151,6 +151,8 @@ typedef enum {
 	PK_FILTER_ENUM_NOT_SUPPORTED,
 	PK_FILTER_ENUM_BASENAME,
 	PK_FILTER_ENUM_NOT_BASENAME,
+	PK_FILTER_ENUM_NEWEST,
+	PK_FILTER_ENUM_NOT_NEWEST,
 	PK_FILTER_ENUM_UNKNOWN
 } PkFilterEnum;
 
commit e241af2d19f77199706e2860fe2f8dd7bd1ae161
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 20:23:45 2008 +0000

    remove pk_client_set_name_filter from the PkClient object, it's completely the wrong way to do this

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index 65805b7..740d2bb 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -68,11 +68,9 @@ struct _PkClientPrivate
 	DBusGConnection		*connection;
 	DBusGProxy		*proxy;
 	GMainLoop		*loop;
-	GHashTable		*hash;
 	gboolean		 is_finished;
 	gboolean		 use_buffer;
 	gboolean		 synchronous;
-	gboolean		 name_filter;
 	gboolean		 promiscuous;
 	gchar			*tid;
 	PkPackageList		*package_list;
@@ -387,26 +385,6 @@ pk_client_set_synchronous (PkClient *client, gboolean synchronous, GError **erro
 }
 
 /**
- * pk_client_set_name_filter:
- * @client: a valid #PkClient instance
- * @name_filter: if we should check for previous packages before we emit
- * @error: a %GError to put the error code and message in, or %NULL
- *
- * A name filter lets us do client side filtering.
- *
- * Return value: %TRUE if the name_filter mode was enabled
- **/
-gboolean
-pk_client_set_name_filter (PkClient *client, gboolean name_filter, GError **error)
-{
-	g_return_val_if_fail (client != NULL, FALSE);
-	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
-
-	client->priv->name_filter = name_filter;
-	return TRUE;
-}
-
-/**
  * pk_client_get_use_buffer:
  * @client: a valid #PkClient instance
  *
@@ -525,14 +503,10 @@ pk_client_reset (PkClient *client, GError **error)
 	client->priv->cached_package_ids = NULL;
 	client->priv->use_buffer = FALSE;
 	client->priv->synchronous = FALSE;
-	client->priv->name_filter = FALSE;
 	client->priv->last_status = PK_STATUS_ENUM_UNKNOWN;
 	client->priv->role = PK_ROLE_ENUM_UNKNOWN;
 	client->priv->is_finished = FALSE;
 
-	/* clear hash */
-	g_hash_table_remove_all (client->priv->hash);
-
 	pk_package_list_clear (client->priv->package_list);
 	return TRUE;
 }
@@ -671,8 +645,6 @@ pk_client_package_cb (DBusGProxy   *proxy,
 		      PkClient     *client)
 {
 	PkInfoEnum info;
-	PkPackageId *pid;
-	const gchar *data;
 
 	g_return_if_fail (client != NULL);
 	g_return_if_fail (PK_IS_CLIENT (client));
@@ -682,27 +654,6 @@ pk_client_package_cb (DBusGProxy   *proxy,
 		return;
 	}
 
-	/* filter repeat names */
-	if (client->priv->name_filter) {
-		/* get the package name */
-		pid = pk_package_id_new_from_string (package_id);
-		pk_debug ("searching hash for %s", pid->name);
-
-		/* is already in the cache? */
-		data = (const gchar *) g_hash_table_lookup (client->priv->hash, pid->name);
-		if (data != NULL) {
-			pk_package_id_free (pid);
-			pk_debug ("ignoring as name filter is on, and previous found; %s", data);
-			return;
-		}
-
-		/* add to the cache */
-		pk_debug ("adding %s into the hash", pid->name);
-		g_hash_table_insert (client->priv->hash, g_strdup (pid->name), g_strdup (pid->name));
-		pk_package_id_free (pid);
-	}
-
-
 	pk_debug ("emit package %s, %s, %s", info_text, package_id, summary);
 	info = pk_info_enum_from_text (info_text);
 	g_signal_emit (client , signals [PK_CLIENT_PACKAGE], 0, info, package_id, summary);
@@ -3068,8 +3019,7 @@ pk_client_requeue (PkClient *client, GError **error)
 	client->priv->last_status = PK_STATUS_ENUM_UNKNOWN;
 	client->priv->is_finished = FALSE;
 
-	/* clear hash and package list */
-	g_hash_table_remove_all (client->priv->hash);
+	/* clear package list */
 	pk_package_list_clear (client->priv->package_list);
 
 	/* do the correct action with the cached parameters */
@@ -3454,7 +3404,6 @@ pk_client_init (PkClient *client)
 
 	client->priv = PK_CLIENT_GET_PRIVATE (client);
 	client->priv->tid = NULL;
-	client->priv->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 	client->priv->loop = g_main_loop_new (NULL, FALSE);
 	client->priv->use_buffer = FALSE;
 	client->priv->promiscuous = FALSE;
@@ -3686,9 +3635,6 @@ pk_client_finalize (GObject *object)
 	}
 	g_main_loop_unref (client->priv->loop);
 
-	/* free the hash table */
-	g_hash_table_destroy (client->priv->hash);
-
 	/* disconnect signal handlers */
 	dbus_g_proxy_disconnect_signal (client->priv->proxy, "Finished",
 				        G_CALLBACK (pk_client_finished_cb), client);
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index acd9c7c..329e285 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -178,9 +178,6 @@ gboolean	 pk_client_set_use_buffer		(PkClient	*client,
 gboolean	 pk_client_set_synchronous		(PkClient	*client,
 							 gboolean	 synchronous,
 							 GError		**error);
-gboolean	 pk_client_set_name_filter		(PkClient	*client,
-							 gboolean	 name_filter,
-							 GError		**error);
 gboolean	 pk_client_get_use_buffer		(PkClient	*client);
 gboolean	 pk_client_get_allow_cancel		(PkClient	*client,
 							 gboolean	*allow_cancel,
commit c37c0e154aef25a1b052f209012baeedcd3025b4
Merge: abfcda7... 35a252a...
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 17:55:23 2008 +0000

    Merge branch 'ident'

commit 35a252a7645d047e29ce804e34368d663380bebb
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 16:44:18 2008 +0000

    error out if the database cannot be opened, and be more paranoid about sqlite status

diff --git a/src/pk-transaction-db.c b/src/pk-transaction-db.c
index 635b4c5..37a770b 100644
--- a/src/pk-transaction-db.c
+++ b/src/pk-transaction-db.c
@@ -192,6 +192,7 @@ pk_transaction_db_sql_statement (PkTransactionDb *tdb, const gchar *sql)
 
 	g_return_val_if_fail (tdb != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_TRANSACTION_DB (tdb), FALSE);
+	g_return_val_if_fail (tdb->priv->db != NULL, FALSE);
 
 	pk_debug ("statement=%s", sql);
 	rc = sqlite3_exec (tdb->priv->db, sql, pk_transaction_sqlite_callback, tdb, &error_msg);
@@ -241,6 +242,7 @@ pk_transaction_db_action_time_since (PkTransactionDb *tdb, PkRoleEnum role)
 
 	g_return_val_if_fail (tdb != NULL, 0);
 	g_return_val_if_fail (PK_IS_TRANSACTION_DB (tdb), 0);
+	g_return_val_if_fail (tdb->priv->db != NULL, FALSE);
 
 	role_text = pk_role_enum_to_text (role);
 	pk_debug ("get_time_since_action=%s", role_text);
@@ -280,6 +282,7 @@ pk_transaction_db_action_time_reset (PkTransactionDb *tdb, PkRoleEnum role)
 
 	g_return_val_if_fail (tdb != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_TRANSACTION_DB (tdb), FALSE);
+	g_return_val_if_fail (tdb->priv->db != NULL, FALSE);
 
 	timespec = pk_iso8601_present ();
 	role_text = pk_role_enum_to_text (role);
@@ -449,6 +452,7 @@ pk_transaction_db_empty (PkTransactionDb *tdb)
 
 	g_return_val_if_fail (tdb != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_TRANSACTION_DB (tdb), FALSE);
+	g_return_val_if_fail (tdb->priv->db != NULL, FALSE);
 
 	statement = "TRUNCATE TABLE transactions;";
 	sqlite3_exec (tdb->priv->db, statement, NULL, NULL, NULL);
@@ -468,6 +472,7 @@ pk_transaction_db_create_table_last_action (PkTransactionDb *tdb)
 
 	g_return_val_if_fail (tdb != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_TRANSACTION_DB (tdb), FALSE);
+	g_return_val_if_fail (tdb->priv->db != NULL, FALSE);
 
 	timespec = pk_iso8601_present ();
 	statement = "CREATE TABLE last_action (role TEXT primary key, timespec TEXT);";
@@ -497,6 +502,7 @@ pk_transaction_db_init (PkTransactionDb *tdb)
 	g_return_if_fail (PK_IS_TRANSACTION_DB (tdb));
 
 	tdb->priv = PK_TRANSACTION_DB_GET_PRIVATE (tdb);
+	tdb->priv->db = NULL;
 
 	/* if the database file was not installed (or was nuked) recreate it */
 	create_file = g_file_test (PK_TRANSACTION_DB_FILE, G_FILE_TEST_EXISTS);
@@ -504,8 +510,8 @@ pk_transaction_db_init (PkTransactionDb *tdb)
 	pk_debug ("trying to open database '%s'", PK_TRANSACTION_DB_FILE);
 	rc = sqlite3_open (PK_TRANSACTION_DB_FILE, &tdb->priv->db);
 	if (rc) {
-		pk_warning ("Can't open database: %s\n", sqlite3_errmsg (tdb->priv->db));
 		sqlite3_close (tdb->priv->db);
+		pk_error ("Can't open database: %s\n", sqlite3_errmsg (tdb->priv->db));
 		return;
 	} else {
 		if (create_file == FALSE) {
commit ee3cee820fb6e773cdfb22f26666c049187dafe9
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 16:31:41 2008 +0000

    add foresight to pk_get_distro_id

diff --git a/libpackagekit/pk-common.c b/libpackagekit/pk-common.c
index d508309..269e68d 100644
--- a/libpackagekit/pk-common.c
+++ b/libpackagekit/pk-common.c
@@ -112,6 +112,25 @@ pk_get_distro_id (void)
 		distro = g_strdup_printf ("suse-%s-%s", split[1], split[3]);
 		goto out;
 	}
+
+	/* check for foresight */
+	ret = g_file_get_contents ("/etc/distro-release", &contents, NULL, NULL);
+	if (ret) {
+		/* Foresight Linux 2.0.2 */
+		split = g_strsplit (contents, " ", 0);
+		if (split == NULL)
+			goto out;
+
+		/* we can't get arch from /etc */
+		arch = pk_get_machine_type ();
+		if (arch == NULL)
+			goto out;
+
+		/* complete! */
+		distro = g_strdup_printf ("foresight-%s-%s", split[2], arch);
+		goto out;
+	}
+
 out:
 	g_strfreev (split);
 	g_free (parseable);
commit d33cfcaf5235b62b47caf5d22b8144a4b42964ce
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Mar 28 15:12:39 2008 +0000

    add initial fedora (tested) and suse (untested) distro-id's

diff --git a/libpackagekit/pk-common.c b/libpackagekit/pk-common.c
index 9279af3..d508309 100644
--- a/libpackagekit/pk-common.c
+++ b/libpackagekit/pk-common.c
@@ -33,6 +33,7 @@
 
 #include <string.h>
 #include <sys/types.h>
+#include <sys/utsname.h>
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif /* HAVE_UNISTD_H */
@@ -44,6 +45,82 @@
 #include "pk-enum.h"
 
 /**
+ * pk_get_machine_type:
+ *
+ * Return value: The current machine ID, e.g. "i386"
+ * Note: Don't use this function if you can get this data from /etc/foo
+ **/
+static gchar *
+pk_get_machine_type (void)
+{
+	gint retval;
+	struct utsname buf;
+
+	retval = uname (&buf);
+	if (retval != 0) {
+		return g_strdup ("unknown");
+	}
+	return g_strdup (buf.machine);
+}
+
+/**
+ * pk_get_distro_id:
+ *
+ * Return value: The current distro-id, e.g. fedora-8-i386, or %NULL for an
+ * error or not known
+ **/
+gchar *
+pk_get_distro_id (void)
+{
+	gboolean ret;
+	gchar *contents = NULL;
+	gchar *parseable = NULL;
+	gchar *distro = NULL;
+	gchar *arch = NULL;
+	gchar **split = NULL;
+
+	/* check for fedora */
+	ret = g_file_get_contents ("/etc/fedora-release", &contents, NULL, NULL);
+	if (ret) {
+		/* Fedora release 8.92 (Rawhide) */
+		split = g_strsplit (contents, " ", 0);
+		if (split == NULL)
+			goto out;
+
+		/* we can't get arch from /etc */
+		arch = pk_get_machine_type ();
+		if (arch == NULL)
+			goto out;
+
+		/* complete! */
+		distro = g_strdup_printf ("fedora-%s-%s", split[2], arch);
+		goto out;
+	}
+
+	/* check for suse */
+	ret = g_file_get_contents ("/etc/SuSE-release", &contents, NULL, NULL);
+	if (ret) {
+		/* replace with spaces: openSUSE 11.0 (i586) Alpha3\nVERSION = 11.0 */
+		parseable = g_strdelimit (contents, "()\n", ' ');
+
+		/* openSUSE 11.0  i586  Alpha3 VERSION = 11.0 */
+		split = g_strsplit (parseable, " ", 0);
+		if (split == NULL)
+			goto out;
+
+		/* complete! */
+		distro = g_strdup_printf ("suse-%s-%s", split[1], split[3]);
+		goto out;
+	}
+out:
+	g_strfreev (split);
+	g_free (parseable);
+	g_free (arch);
+	g_free (contents);
+	return distro;
+}
+
+/**
  * pk_iso8601_present:
  *
  * Return value: The current iso8601 date and time
@@ -627,6 +704,19 @@ libst_common (LibSelfTest *test)
 
 	pk_delay_yield (2.0);
 
+
+	/************************************************************
+	 ****************        test distro-id        **************
+	 ************************************************************/
+	libst_title (test, "get distro id");
+	text_safe = pk_get_distro_id ();
+	if (text_safe != NULL) {
+		libst_success (test, "distro_id=%s", text_safe);
+	} else {
+		libst_failed (test, NULL);
+	}
+	g_free (text_safe);
+
 	/************************************************************
 	 ****************        build var args        **************
 	 ************************************************************/
diff --git a/libpackagekit/pk-common.h b/libpackagekit/pk-common.h
index 8bd7f0f..de9fea4 100644
--- a/libpackagekit/pk-common.h
+++ b/libpackagekit/pk-common.h
@@ -86,6 +86,8 @@ gchar		*pk_iso8601_present			(void)
 							 G_GNUC_WARN_UNUSED_RESULT;
 guint		 pk_iso8601_difference			(const gchar	*isodate);
 gboolean	 pk_delay_yield				(gfloat		 delay);
+gchar		*pk_get_distro_id			(void)
+							 G_GNUC_WARN_UNUSED_RESULT;
 
 G_END_DECLS
 



More information about the PackageKit mailing list