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

Richard Hughes hughsient at kemper.freedesktop.org
Fri Oct 19 06:43:47 PDT 2007


 TODO                               |   16 ---
 backends/yum/helpers/yumBackend.py |   38 ++++---
 client/pk-console.c                |  183 +++++++++++++++----------------------
 configure.ac                       |    1 
 data/Makefile.am                   |    4 
 data/tests/.gitignore              |    4 
 data/tests/Makefile.am             |   21 ++++
 data/tests/pk-spawn-test.sh        |   31 ++++++
 docs/pk-introduction.xml           |   34 ++++++
 html/index.html                    |    4 
 html/pk-faq.html                   |  124 +++++++++++++++++++++++++
 libpackagekit/pk-client.c          |   24 ++++
 libpackagekit/pk-client.h          |    5 -
 libpackagekit/pk-enum.c            |  123 ++++++++++++++++++++++++
 libpackagekit/pk-enum.h            |    1 
 libpackagekit/pk-package-list.c    |   33 ++++--
 libpackagekit/pk-package-list.h    |    6 -
 python/packagekit/backend.py       |    2 
 src/Makefile.am                    |    4 
 src/pk-engine.c                    |   10 --
 src/pk-spawn.c                     |   92 ++++++++++++++----
 src/pk-spawn.h                     |    8 +
 tools/add-error-enum.sh            |    2 
 23 files changed, 589 insertions(+), 181 deletions(-)

New commits:
commit 1a7a3b57fc5c19a82fe8bf2ba3530ade01673d3d
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 14:15:13 2007 +0100

    don't export the private data array in PkClient or PkPackageList - breaks API with gnome-packagekit

diff --git a/libpackagekit/pk-client.c b/libpackagekit/pk-client.c
index a4f359e..fab6b2b 100644
--- a/libpackagekit/pk-client.c
+++ b/libpackagekit/pk-client.c
@@ -168,15 +168,31 @@ pk_client_get_require_restart (PkClient *client)
 }
 
 /**
- * pk_client_get_package_buffer:
+ * pk_client_package_buffer_get_size:
  **/
-GPtrArray *
-pk_client_get_package_buffer (PkClient *client)
+guint
+pk_client_package_buffer_get_size (PkClient *client)
 {
+	g_return_val_if_fail (client != NULL, 0);
+	g_return_val_if_fail (PK_IS_CLIENT (client), 0);
+	if (client->priv->use_buffer == FALSE) {
+		return 0;
+	}
+	return pk_package_list_get_size (client->priv->package_list);
+}
+
+/**
+ * pk_client_package_buffer_get_item:
+ **/
+PkPackageItem *
+pk_client_package_buffer_get_item (PkClient *client, guint item)
+{
+	g_return_val_if_fail (client != NULL, FALSE);
+	g_return_val_if_fail (PK_IS_CLIENT (client), FALSE);
 	if (client->priv->use_buffer == FALSE) {
 		return NULL;
 	}
-	return pk_package_list_get_buffer (client->priv->package_list);
+	return pk_package_list_get_item (client->priv->package_list, item);
 }
 
 /**
diff --git a/libpackagekit/pk-client.h b/libpackagekit/pk-client.h
index f0b7473..8196043 100644
--- a/libpackagekit/pk-client.h
+++ b/libpackagekit/pk-client.h
@@ -25,6 +25,7 @@
 #include <glib-object.h>
 #include "pk-enum.h"
 #include "pk-enum-list.h"
+#include "pk-package-list.h"
 
 G_BEGIN_DECLS
 
@@ -126,7 +127,9 @@ gboolean	 pk_client_repo_set_data		(PkClient	*client,
 							 const gchar	*value);
 
 /* cached stuff */
-GPtrArray	*pk_client_get_package_buffer		(PkClient	*client);
+guint		 pk_client_package_buffer_get_size	(PkClient	*client);
+PkPackageItem	*pk_client_package_buffer_get_item	(PkClient	*client,
+							 guint		 item);
 PkRestartEnum	 pk_client_get_require_restart		(PkClient	*client);
 
 /* not job specific */
diff --git a/libpackagekit/pk-package-list.c b/libpackagekit/pk-package-list.c
index 7c549e3..f528e12 100644
--- a/libpackagekit/pk-package-list.c
+++ b/libpackagekit/pk-package-list.c
@@ -58,13 +58,13 @@ G_DEFINE_TYPE (PkPackageList, pk_package_list, G_TYPE_OBJECT)
 gboolean
 pk_package_list_add (PkPackageList *plist, PkInfoEnum info, const gchar *package_id, const gchar *summary)
 {
-	PkPackageListItem *item;
+	PkPackageItem *item;
 
 	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);
-	item = g_new0 (PkPackageListItem, 1);
+	item = g_new0 (PkPackageItem, 1);
 	item->info = info;
 	item->package_id = g_strdup (package_id);
 	item->summary = g_strdup (summary);
@@ -79,7 +79,7 @@ pk_package_list_add (PkPackageList *plist, PkInfoEnum info, const gchar *package
 gchar *
 pk_package_list_get_string (PkPackageList *plist)
 {
-	PkPackageListItem *item;
+	PkPackageItem *item;
 	guint i;
 	guint length;
 	const gchar *info_text;
@@ -105,14 +105,29 @@ pk_package_list_get_string (PkPackageList *plist)
 }
 
 /**
- * pk_plist_get_package_buffer:
+ * pk_package_list_get_size:
  **/
-GPtrArray *
-pk_package_list_get_buffer (PkPackageList *plist)
+guint
+pk_package_list_get_size (PkPackageList *plist)
+{
+	g_return_val_if_fail (plist != NULL, 0);
+	g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), 0);
+	return plist->priv->array->len;
+}
+
+/**
+ * pk_package_list_get_item:
+ **/
+PkPackageItem *
+pk_package_list_get_item (PkPackageList *plist, guint item)
 {
 	g_return_val_if_fail (plist != NULL, NULL);
 	g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), NULL);
-	return plist->priv->array;
+	if (item >= plist->priv->array->len) {
+		pk_debug ("item too large!");
+		return NULL;
+	}
+	return g_ptr_array_index (plist->priv->array, item);
 }
 
 /**
@@ -121,7 +136,7 @@ pk_package_list_get_buffer (PkPackageList *plist)
 gboolean
 pk_package_list_clear (PkPackageList *plist)
 {
-	PkPackageListItem *item;
+	PkPackageItem *item;
 
 	g_return_val_if_fail (plist != NULL, FALSE);
 	g_return_val_if_fail (PK_IS_PACKAGE_LIST (plist), FALSE);
@@ -142,7 +157,7 @@ pk_package_list_clear (PkPackageList *plist)
 gboolean
 pk_package_list_contains (PkPackageList *plist, const gchar *package_id)
 {
-	PkPackageListItem *item;
+	PkPackageItem *item;
 	guint i;
 	guint length;
 	gboolean ret = FALSE;
diff --git a/libpackagekit/pk-package-list.h b/libpackagekit/pk-package-list.h
index f1f733f..4d4da2c 100644
--- a/libpackagekit/pk-package-list.h
+++ b/libpackagekit/pk-package-list.h
@@ -52,7 +52,7 @@ typedef struct
 	PkInfoEnum		 info;
 	gchar			*package_id;
 	gchar			*summary;
-} PkPackageListItem;
+} PkPackageItem;
 
 GType		 pk_package_list_get_type		(void);
 PkPackageList	*pk_package_list_new			(void);
@@ -63,7 +63,9 @@ gboolean	 pk_package_list_add			(PkPackageList		*plist,
 gboolean	 pk_package_list_contains		(PkPackageList		*plist,
 							 const gchar		*package_id);
 gchar		*pk_package_list_get_string		(PkPackageList		*plist);
-GPtrArray	*pk_package_list_get_buffer		(PkPackageList		*plist);
+guint		 pk_package_list_get_size		(PkPackageList		*plist);
+PkPackageItem	*pk_package_list_get_item		(PkPackageList		*plist,
+							 guint			 item);
 gboolean	 pk_package_list_clear			(PkPackageList		*plist);
 
 G_END_DECLS
diff --git a/src/pk-engine.c b/src/pk-engine.c
index 3aa2221..2a6423a 100644
--- a/src/pk-engine.c
+++ b/src/pk-engine.c
@@ -953,19 +953,17 @@ pk_engine_get_updates (PkEngine *engine, const gchar *tid, GError **error)
 
 	/* try and reuse cache */
 	if (engine->priv->updates_cache != NULL) {
-		PkPackageListItem *package;
-		GPtrArray *plist;
+		PkPackageItem *package;
 		guint i;
 		guint length;
 
-		plist = pk_package_list_get_buffer (engine->priv->updates_cache);
-		pk_warning ("we have cached data (%i) we could use!", plist->len);
+		length = pk_package_list_get_size (engine->priv->updates_cache);
+		pk_warning ("we have cached data (%i) we could use!", length);
 
 		/* emulate the backend */
 		pk_backend_set_role (item->backend, PK_ROLE_ENUM_GET_UPDATES);
-		length = plist->len;
 		for (i=0; i<length; i++) {
-			package = g_ptr_array_index (plist, i);
+			package = pk_package_list_get_item (engine->priv->updates_cache, i);
 			pk_engine_package_cb (item->backend, package->info, package->package_id, package->summary, engine);
 		}
 		pk_engine_finished_cb (item->backend, PK_EXIT_ENUM_SUCCESS, engine);
commit fb39fc68b13f86155189368c68c7ac149f95604c
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 13:48:13 2007 +0100

    add the start pf the resolve client bits

diff --git a/client/pk-console.c b/client/pk-console.c
index 641c7e7..efacc89 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -192,12 +192,54 @@ static gboolean
 pk_client_wait (void)
 {
 	pk_debug ("starting loop");
-	loop = g_main_loop_new (NULL, FALSE);
 	g_main_loop_run (loop);
 	return TRUE;
 }
 
 /**
+ * pk_console_finished_cb:
+ **/
+static void
+pk_console_finished_cb (PkClient *client, PkStatusEnum status, guint runtime, gpointer data)
+{
+	g_print ("Runtime was %i seconds\n", runtime);
+	if (loop != NULL) {
+		g_main_loop_quit (loop);
+	}
+}
+
+/**
+ * pk_console_install_package:
+ **/
+static gboolean
+pk_console_install_package (PkClient *client, const gchar *package_id)
+{
+//xxx
+	gboolean ret;
+	gboolean valid;
+	PkClient *client_resolve;
+	valid = pk_package_id_check (package_id);
+
+	/* have we passed a complete package_id? */
+	if (valid == TRUE) {
+		return pk_client_install_package (client, package_id);
+	}
+
+	/* we need to resolve it */
+	client_resolve = pk_client_new ();
+	g_signal_connect (client_resolve, "finished",
+			  G_CALLBACK (pk_console_finished_cb), NULL);
+	ret = pk_client_resolve (client_resolve, package_id);
+	if (ret == FALSE) {
+		pk_warning ("Resolve not supported");
+	} else {
+		g_main_loop_run (loop);
+	}
+	pk_error ("resolve functionality not finished yet");
+	return TRUE;
+}
+
+/**
  * pk_console_process_commands:
  **/
 static gboolean
@@ -257,7 +299,7 @@ pk_console_process_commands (PkClient *client, int argc, char *argv[], GError **
 			g_set_error (error, 0, 0, "you need to specify a package to install");
 			return FALSE;
 		} else {
-			wait = pk_client_install_package (client, value);
+			wait = pk_console_install_package (client, value);
 		}
 	} else if (strcmp (mode, "remove") == 0) {
 		if (value == NULL) {
@@ -365,18 +407,6 @@ pk_console_process_commands (PkClient *client, int argc, char *argv[], GError **
 }
 
 /**
- * pk_console_finished_cb:
- **/
-static void
-pk_console_finished_cb (PkClient *client, PkStatusEnum status, guint runtime, gpointer data)
-{
-	g_print ("Runtime was %i seconds\n", runtime);
-	if (loop != NULL) {
-		g_main_loop_quit (loop);
-	}
-}
-
-/**
  * pk_console_error_code_cb:
  **/
 static void
@@ -473,13 +503,14 @@ main (int argc, char *argv[])
 		return 0;
 	}
 
-	pk_debug_init (verbose);
-
 	if (argc < 2) {
 		g_print (options_help);
 		return 1;
 	}
 
+	pk_debug_init (verbose);
+	loop = g_main_loop_new (NULL, FALSE);
+
 	client = pk_client_new ();
 	g_signal_connect (client, "package",
 			  G_CALLBACK (pk_console_package_cb), NULL);
commit 3d5a865715687a86a76164a9e471643a0ab58346
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 13:23:34 2007 +0100

    make pkcon only support one transaction per command - which takes out the array nonsense

diff --git a/client/pk-console.c b/client/pk-console.c
index 0682502..641c7e7 100644
--- a/client/pk-console.c
+++ b/client/pk-console.c
@@ -158,7 +158,7 @@ pk_console_percentage_changed_cb (PkClient *client, guint percentage, gpointer d
 	g_print ("%i%%\n", percentage);
 }
 
-gchar *summary =
+const gchar *summary =
 	"PackageKit Console Interface\n"
 	"\n"
 	"Subcommands:\n"
@@ -198,67 +198,56 @@ pk_client_wait (void)
 }
 
 /**
- * pk_console_parse_multiple_commands:
+ * pk_console_process_commands:
  **/
-static void
-pk_console_parse_multiple_commands (PkClient *client, GPtrArray *array, GError **error)
+static gboolean
+pk_console_process_commands (PkClient *client, int argc, char *argv[], GError **error)
 {
 	const gchar *mode;
 	const gchar *value = NULL;
 	const gchar *details = NULL;
 	gboolean wait = FALSE;
-	guint remove;
 	PkEnumList *elist;
 
-	mode = g_ptr_array_index (array, 0);
-	if (array->len > 1) {
-		value = g_ptr_array_index (array, 1);
+	mode = argv[1];
+	if (argc > 2) {
+		value = argv[2];
 	}
-	if (array->len > 2) {
-		details = g_ptr_array_index (array, 2);
+	if (argc > 3) {
+		details = argv[3];
 	}
-	remove = 1;
 
 	if (strcmp (mode, "search") == 0) {
 		if (value == NULL) {
 			g_set_error (error, 0, 0, "you need to specify a search type");
-			remove = 1;
-			goto out;
+			return FALSE;
 		} else if (strcmp (value, "name") == 0) {
 			if (details == NULL) {
 				g_set_error (error, 0, 0, "you need to specify a search term");
-				remove = 2;
-				goto out;
+				return FALSE;
 			} else {
 				wait = pk_client_search_name (client, "none", details);
-				remove = 3;
 			}
 		} else if (strcmp (value, "details") == 0) {
 			if (details == NULL) {
 				g_set_error (error, 0, 0, "you need to specify a search term");
-				remove = 2;
-				goto out;
+				return FALSE;
 			} else {
 				wait = pk_client_search_details (client, "none", details);
-				remove = 3;
 			}
 		} else if (strcmp (value, "group") == 0) {
 			if (details == NULL) {
 				g_set_error (error, 0, 0, "you need to specify a search term");
-				remove = 2;
-				goto out;
+				return FALSE;
 			} else {
 				wait = pk_client_search_group (client, "none", details);
-				remove = 3;
 			}
 		} else if (strcmp (value, "file") == 0) {
 			if (details == NULL) {
 				g_set_error (error, 0, 0, "you need to specify a search term");
-				remove = 2;
-				goto out;
+				return FALSE;
 			} else {
 				wait = pk_client_search_file (client, "none", details);
-				remove = 3;
 			}
 		} else {
 			g_set_error (error, 0, 0, "invalid search type");
@@ -266,122 +255,95 @@ pk_console_parse_multiple_commands (PkClient *client, GPtrArray *array, GError *
 	} else if (strcmp (mode, "install") == 0) {
 		if (value == NULL) {
 			g_set_error (error, 0, 0, "you need to specify a package to install");
-			remove = 1;
-			goto out;
+			return FALSE;
 		} else {
 			wait = pk_client_install_package (client, value);
-			remove = 2;
 		}
 	} else if (strcmp (mode, "remove") == 0) {
 		if (value == NULL) {
 			g_set_error (error, 0, 0, "you need to specify a package to remove");
-			remove = 1;
-			goto out;
+			return FALSE;
 		} else {
 			wait = pk_client_remove_package (client, value, FALSE);
-			remove = 2;
 		}
 	} else if (strcmp (mode, "update") == 0) {
 		if (value == NULL) {
 			g_set_error (error, 0, 0, "you need to specify a package to update");
-			remove = 1;
-			goto out;
+			return FALSE;
 		} else {
 			wait = pk_client_update_package (client, value);
-			remove = 2;
 		}
 	} else if (strcmp (mode, "resolve") == 0) {
 		if (value == NULL) {
 			g_set_error (error, 0, 0, "you need to specify a package name to resolve");
-			remove = 1;
-			goto out;
+			return FALSE;
 		} else {
 			wait = pk_client_resolve (client, value);
-			remove = 2;
 		}
 	} else if (strcmp (mode, "enable-repo") == 0) {
 		if (value == NULL) {
 			g_set_error (error, 0, 0, "you need to specify a repo name");
-			remove = 1;
-			goto out;
+			return FALSE;
 		} else {
 			pk_client_repo_enable (client, value, TRUE);
-			remove = 2;
 		}
 	} else if (strcmp (mode, "disable-repo") == 0) {
 		if (value == NULL) {
 			g_set_error (error, 0, 0, "you need to specify a repo name");
-			remove = 1;
-			goto out;
+			return FALSE;
 		} else {
 			wait = pk_client_repo_enable (client, value, FALSE);
-			remove = 2;
 		}
 	} else if (strcmp (mode, "get") == 0) {
 		if (value == NULL) {
 			g_set_error (error, 0, 0, "you need to specify a get type");
-			remove = 1;
-			goto out;
+			return FALSE;
 		} else if (strcmp (value, "depends") == 0) {
 			if (details == NULL) {
 				g_set_error (error, 0, 0, "you need to specify a search term");
-				remove = 2;
-				goto out;
+				return FALSE;
 			} else {
 				wait = pk_client_get_depends (client, details);
-				remove = 3;
 			}
 		} else if (strcmp (value, "updatedetail") == 0) {
 			if (details == NULL) {
 				g_set_error (error, 0, 0, "you need to specify a search term");
-				remove = 2;
-				goto out;
+				return FALSE;
 			} else {
 				wait = pk_client_get_update_detail (client, details);
-				remove = 3;
 			}
 		} else if (strcmp (value, "requires") == 0) {
 			if (details == NULL) {
 				g_set_error (error, 0, 0, "you need to specify a search term");
-				remove = 2;
-				goto out;
+				return FALSE;
 			} else {
 				wait = pk_client_get_requires (client, details);
-				remove = 3;
 			}
 		} else if (strcmp (value, "description") == 0) {
 			if (details == NULL) {
 				g_set_error (error, 0, 0, "you need to specify a package to find the description for");
-				remove = 2;
-				goto out;
+				return FALSE;
 			} else {
 				wait = pk_client_get_description (client, details);
-				remove = 3;
 			}
 		} else if (strcmp (value, "updates") == 0) {
 			wait = pk_client_get_updates (client);
-			remove = 2;
 		} else if (strcmp (value, "actions") == 0) {
 			elist = pk_client_get_actions (client);
 			pk_enum_list_print (elist);
 			g_object_unref (elist);
-			remove = 2;
 		} else if (strcmp (value, "filters") == 0) {
 			elist = pk_client_get_filters (client);
 			pk_enum_list_print (elist);
 			g_object_unref (elist);
-			remove = 2;
 		} else if (strcmp (value, "repos") == 0) {
 			wait = pk_client_get_repo_list (client);
-			remove = 2;
 		} else if (strcmp (value, "groups") == 0) {
 			elist = pk_client_get_groups (client);
 			pk_enum_list_print (elist);
 			g_object_unref (elist);
-			remove = 2;
 		} else if (strcmp (value, "transactions") == 0) {
 			wait = pk_client_get_old_transactions (client, 10);
-			remove = 2;
 		} else {
 			g_set_error (error, 0, 0, "invalid get type");
 		}
@@ -399,16 +361,7 @@ pk_console_parse_multiple_commands (PkClient *client, GPtrArray *array, GError *
 	if (wait == TRUE) {
 		pk_client_wait ();
 	}
-
-out:
-	/* remove the right number of items from the pointer index */
-	g_ptr_array_remove_index (array, 0);
-	if (remove > 1) {
-		g_ptr_array_remove_index (array, 0);
-	}
-	if (remove > 2) {
-		g_ptr_array_remove_index (array, 0);
-	}
+	return TRUE;
 }
 
 /**
@@ -480,8 +433,6 @@ main (int argc, char *argv[])
 	DBusGConnection *system_connection;
 	GError *error = NULL;
 	PkClient *client;
-	GPtrArray *array;
-	guint i;
 	gboolean verbose = FALSE;
 	gboolean program_version = FALSE;
 	GOptionContext *context;
@@ -549,24 +500,15 @@ main (int argc, char *argv[])
 	g_signal_connect (client, "error-code",
 			  G_CALLBACK (pk_console_error_code_cb), NULL);
 
-	/* add argv to a pointer array */
-	array = g_ptr_array_new ();
-	for (i=1; i<argc; i++) {
-		g_ptr_array_add (array, (gpointer) argv[i]);
-	}
-	/* process all the commands */
-	while (array->len > 0) {
-		pk_console_parse_multiple_commands (client, array, &error);
-		if (error != NULL) {
-			g_print ("Error:\n  %s\n\n", error->message);
-			g_error_free (error);
-			g_print (options_help);
-			break;
-		}
+	/* run the commands */
+	pk_console_process_commands (client, argc, argv, &error);
+	if (error != NULL) {
+		g_print ("Error:\n  %s\n\n", error->message);
+		g_error_free (error);
+		g_print (options_help);
 	}
 
 	g_free (options_help);
-	g_ptr_array_free (array, TRUE);
 	g_object_unref (client);
 
 	return 0;
commit 51a3c9563956c62dcedded6720e75b859f946db0
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 13:04:56 2007 +0100

    use a HTML FAQ page - users were getting confused once in the wiki

diff --git a/html/index.html b/html/index.html
index 6973d62..6da3608 100644
--- a/html/index.html
+++ b/html/index.html
@@ -30,12 +30,12 @@
 <tr>
  <td align="middle"><a href="pk-help.html"><img src="img/large-system-users.png" width="128"/></a></td>
  <td align="middle"><a href="pk-screenshots.html"><img src="img/large-emblem-photos.png" width="128"/></a></td>
- <td align="middle"><a href="wiki/index.php/FAQ"><img src="img/large-help-browser.png" width="128"/></a></td>
+ <td align="middle"><a href="pk-faq.html"><img src="img/large-help-browser.png" width="128"/></a></td>
 </tr>
 <tr>
  <td><a href="pk-help.html"><p class="indextitle">How can I help?</p></a></td>
  <td><a href="pk-screenshots.html"><p class="indextitle">Screenshots</p></a></td>
- <td><a href="wiki/index.php/FAQ"><p class="indextitle">Frequently<br>asked questions</p></a></td>
+ <td><a href="pk-faq.html"><p class="indextitle">Frequently<br>asked questions</p></a></td>
 </tr>
 </table>
 
diff --git a/html/pk-faq.html b/html/pk-faq.html
new file mode 100644
index 0000000..d016814
--- /dev/null
+++ b/html/pk-faq.html
@@ -0,0 +1,124 @@
+<html>
+<head>
+<title>PackageKit</title>
+<link rel="stylesheet" href="style.css" type="text/css" media="screen"/></center>
+</head>
+<body>
+
+<table align="center" class="title">
+<tr>
+ <td><center><img src="img/packagekit.png"/></center></td>
+ <td width="95%" valign="middle"><p class="title">Screenshots</p></td>
+ <td><center><img src="img/packagekit.png"/></center></td>
+</tr>
+</table>
+
+<p>Back to the <a href="index.html">main page</a></p>
+
+<h1>Frequently asked questions</h1>
+
+<h3>What if the backend package manager doesn't support percentage updates?</h3>
+<p>
+You don't have to have a backend that supports percentage updates.
+If you don't know the progress, just emit NoPercentageUpdates and then the UI
+should just do the right thing and spin.
+</p>
+
+<h3>With all the differences between backends, how will PackageKit support all the different options?</h3>
+<p>
+Backends don't have to support all options of all methods.
+Just set an error and return false if not implemented.
+</p>
+
+<h3>But error codes are different on each backend?</h3>
+<p>
+Error codes have to be standardized so they can be localized.
+The error detail field can just be the untranslatable output.
+If you are creating a backend and you need another error enum, mention it
+and we can add it to the supported list.
+</p>
+
+<h3>How will PackageKit handle installation an application that needs user interaction?</h3>
+<p>
+Upgrading, installing or removing packages <b>has to be 100% silent</b>.
+</p>
+<p>
+The user cannot be prompted for questions "set applet setuid?" as these will
+not be handled in PackageKit.
+The backend should do the right thing, as these messages mean very little to
+the average user and cannot be translated.
+</p>
+
+<h3>Does PackageKit replace up2date?</h3>
+<p>
+PackageKit does not replace up2date.
+PackageKit is a way for users to interact with the packaging system, not for an
+administrator to install software on remote machines.
+</p>
+
+<h3>Is PackageKit a system daemon, always running and using resources?</h3>
+<p>
+PackageKit is not yet another system daemon.
+It quits when not doing anything, and only starts when something wants
+information or a task completed.
+</p>
+
+<h3>How does PackageKit handle dependencies?</h3>
+<p>
+PackageKit <b>does not do</b> dependency resolution.
+This problem has already been solved by the backend systems and we don't really
+want to re-invent the wheel.
+</p>
+<p>
+PackageKit does not have the fine-grained API to do everything.
+For instance, synaptic should still use libapt as can do much more than can be
+provided by PackageKit.
+</p>
+
+<h3>Does PackageKit replace the Red Carpet service?</h3>
+<p>
+PackageKit is not a replacement to red carpet.
+Red carpet was really great and years ahead of it's time, but tried to do
+everything package related on the system, and moved onto the enterprise
+centralized management model.
+Although cool, this latter point made things too political in my opinion.
+</p>
+
+<h3>How fast is PackageKit?</h3>
+<p>
+PackageKit is really fast.
+It takes about 1 second to search for installed and available packages
+with "power" in the description - no blocking of the UI happens at all as it's
+all asyncronous.
+All the applications start instantly with no root password needed at startup.
+</p>
+
+<h3>How does PackageKit work with multiple users?</h3>
+<p>
+PackageKit is designed from the ground up to work with fast user switching and
+logging in and out of sessions during upgrades.
+You can start a system upgrade, log out, log in as another user, and be notified
+when the upgrade is complete, all without risking your rpmdb.
+</p>
+
+<h3>Can users still use their normal package managers and backends, such as Yum, APT or Conary?</h3>
+<p>
+PackageKit does not stop you using the low level tools yourself.
+You can use rpm and yum or dpkg and apt when PK is inactive (99.999% of the time)
+when you really need some command line love.
+No more fighting over <code>yum</code>, <code>yum-updatesd</code>,
+<code>pup</code> and <code>pirut</code>.
+</p>
+
+<h3>Is there an organization or corporation sponsoring development of PackageKit?</h3>
+<p>
+PackageKit is not sponsored by anyone.
+Whilst interning at RedHat I spent a few days on the API and some UI designs,
+but all the coding is done in my free time.
+</p>
+
+<p>Back to the <a href="index.html">main page</a></p>
+
+</body>
+</html>
+
commit ae56df28fe6465a501e701195c93ca8a4de135f7
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 12:53:16 2007 +0100

    Explain SIGQUIT and SIGKILL in the docs

diff --git a/TODO b/TODO
index b46b19f..9cd7741 100644
--- a/TODO
+++ b/TODO
@@ -44,6 +44,3 @@ if not a valid package_id then
         error
     }
 
-*** backend docbook ***
-Explain SIGQUIT and SIGKILL in the docs
-
diff --git a/docs/pk-introduction.xml b/docs/pk-introduction.xml
index fd110e5..6c9c3e7 100644
--- a/docs/pk-introduction.xml
+++ b/docs/pk-introduction.xml
@@ -404,11 +404,36 @@
         This allows for example the yum download to be cancelled, but not the
         install transaction.
         By cancelling a job all subtransactions are killed.
-        By default actions cannot be cancelled unless enabled in the compiled backend.
+      </para>
+      <para>
+        By default actions cannot be cancelled unless enabled in the backend.
         Use <literal>AllowInterrupt(true)</literal> to enable cancellation
         and <literal>AllowInterrupt(false)</literal> to disable it.
         This can be done for any job type.
       </para>
+      <para>
+        For compiled backends that are threaded, the
+        <literal>cancel()</literal> method can be used to terminate
+        the thread.
+      </para>
+      <para>
+        For spawned backends, there are two staggered signals send to allow
+        locks to be released or for the backend to clean up after itself:
+      </para>
+      <itemizedlist>
+        <listitem>
+          <para>Send the process <literal>SIGQUIT</literal>.</para>
+        </listitem>
+        <listitem>
+          <para>Wait 500ms</para>
+        </listitem>
+        <listitem>
+          <para>
+            If the process has not already quit, send the process
+            <literal>SIGKILL</literal> to terminate it.
+          </para>
+        </listitem>
+      </itemizedlist>
     </sect2>
 
     <sect2 id="introduction-ideas-transactionid">
commit d80ae5ac67afa41c06dae4bf6d8c704d51010ed1
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Fri Oct 19 11:50:51 2007 +0200

    yum: only signal-wait once when waiting for the yum lock

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 0affba0..1deed9e 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -78,7 +78,8 @@ class PackageKitYumBackend(PackageKitBaseBackend):
                 self.yumbase.doLock( YUM_PID_FILE )
                 PackageKitBaseBackend.doLock(self)
             except:
-                self.status(STATE_WAIT)
+                if retries == 0:
+                    self.status(STATE_WAIT)
                 time.sleep(2)
                 retries += 1
                 if retries > 100:
commit 099821ddc343d32a24bf83ab519f8427d8ba8fe9
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 10:41:56 2007 +0100

    update TODO

diff --git a/TODO b/TODO
index 57994fe..b46b19f 100644
--- a/TODO
+++ b/TODO
@@ -24,6 +24,9 @@ To do rollbacks sanely in PK we need a few things:
 
 *** Use resolve for pkcon operations ***
 'pkcon install zsh' should work as well as 'pkcon install "zsh;1.0;i386;repo"'
+
+--- RELEASE BLOCKER ---
+
 def command_resolve(package, filter_enum)
 ret=client_resolve (package, filter)
 if ret wait()
@@ -41,9 +44,6 @@ if not a valid package_id then
         error
     }
 
-*** Unit tests ***
-PkSpawn is a complex and untested bit of code.
-
 *** backend docbook ***
 Explain SIGQUIT and SIGKILL in the docs
 
commit 2d1c9c52a429301bc7dfcdf011ab15702676a692
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 10:39:13 2007 +0100

    make the return types from the spawn code enumerated

diff --git a/TODO b/TODO
index 474a139..57994fe 100644
--- a/TODO
+++ b/TODO
@@ -44,13 +44,6 @@ if not a valid package_id then
 *** Unit tests ***
 PkSpawn is a complex and untested bit of code.
 
-*** PkSpawn enum return value ***
-pk_test_finished_cb (PkSpawn *spawn, gint exitcode, gpointer data)
-- exitcode is undefined - make an enum
-	PK_SPAWN_EXIT_SUCCESS
-	PK_SPAWN_EXIT_FAILED
-	PK_SPAWN_EXIT_KILLED
-
 *** backend docbook ***
 Explain SIGQUIT and SIGKILL in the docs
 
diff --git a/src/pk-spawn.c b/src/pk-spawn.c
index 7f49c5e..29c3206 100644
--- a/src/pk-spawn.c
+++ b/src/pk-spawn.c
@@ -61,6 +61,7 @@ struct PkSpawnPrivate
 	guint			 poll_id;
 	guint			 kill_id;
 	gboolean		 finished;
+	PkSpawnExit		 exit;
 	GString			*stderr_buf;
 	GString			*stdout_buf;
 };
@@ -174,8 +175,14 @@ pk_spawn_check_child (PkSpawn *spawn)
 
 	if (WEXITSTATUS (status) > 0) {
 		pk_warning ("Running fork failed with return value %d", WEXITSTATUS (status));
+		if (spawn->priv->exit == PK_SPAWN_EXIT_UNKNOWN) {
+			spawn->priv->exit = PK_SPAWN_EXIT_FAILED;
+		}
 	} else {
 		pk_debug ("Running fork successful");
+		if (spawn->priv->exit == PK_SPAWN_EXIT_UNKNOWN) {
+			spawn->priv->exit = PK_SPAWN_EXIT_SUCCESS;
+		}
 	}
 
 	/* officially done, although no signal yet */
@@ -187,8 +194,8 @@ pk_spawn_check_child (PkSpawn *spawn)
 		spawn->priv->kill_id = 0;
 	}
 
-	pk_debug ("emitting finished %i", WEXITSTATUS (status));
-	g_signal_emit (spawn, signals [PK_SPAWN_FINISHED], 0, WEXITSTATUS (status));
+	pk_debug ("emitting finished %i", spawn->priv->exit);
+	g_signal_emit (spawn, signals [PK_SPAWN_FINISHED], 0, spawn->priv->exit);
 
 	return FALSE;
 }
@@ -207,6 +214,9 @@ pk_spawn_sigkill_cb (PkSpawn *spawn)
 		return FALSE;
 	}
 
+	/* we won't overwrite this if not unknown */
+	spawn->priv->exit = PK_SPAWN_EXIT_KILL;
+
 	pk_warning ("sending SIGKILL %i", spawn->priv->child_pid);
 	retval = kill (spawn->priv->child_pid, SIGKILL);
 	if (retval == EINVAL) {
@@ -239,6 +249,9 @@ pk_spawn_kill (PkSpawn *spawn)
 		return FALSE;
 	}
 
+	/* we won't overwrite this if not unknown */
+	spawn->priv->exit = PK_SPAWN_EXIT_QUIT;
+
 	pk_warning ("sending SIGQUIT %i", spawn->priv->child_pid);
 	retval = kill (spawn->priv->child_pid, SIGQUIT);
 	if (retval == EINVAL) {
@@ -349,6 +362,7 @@ pk_spawn_init (PkSpawn *spawn)
 	spawn->priv->poll_id = 0;
 	spawn->priv->kill_id = 0;
 	spawn->priv->finished = FALSE;
+	spawn->priv->exit = PK_SPAWN_EXIT_UNKNOWN;
 
 	spawn->priv->stderr_buf = g_string_new ("");
 	spawn->priv->stdout_buf = g_string_new ("");
@@ -405,9 +419,10 @@ pk_spawn_new (void)
  ***************************************************************************/
 #ifdef PK_BUILD_TESTS
 #include <libselftest.h>
+#define BAD_EXIT 999
 
 static GMainLoop *loop;
-gint mexitcode = -1;
+PkSpawnExit mexit = BAD_EXIT;
 guint stdout_count = 0;
 guint stderr_count = 0;
 guint finished_count = 0;
@@ -443,10 +458,10 @@ pk_test_get_data (const gchar *filename)
  * pk_test_finished_cb:
  **/
 static void
-pk_test_finished_cb (PkSpawn *spawn, gint exitcode, LibSelfTest *test)
+pk_test_finished_cb (PkSpawn *spawn, PkSpawnExit exit, LibSelfTest *test)
 {
-	pk_debug ("spawn exitcode=%i", exitcode);
-	mexitcode = exitcode;
+	pk_debug ("spawn exit=%i", exit);
+	mexit = exit;
 	finished_count++;
 	g_main_loop_quit (loop);
 }
@@ -502,7 +517,7 @@ libst_spawn (LibSelfTest *test)
 
 	/************************************************************/
 	libst_title (test, "make sure return error for missing file");
-	mexitcode = -1;
+	mexit = BAD_EXIT;
 	ret = pk_spawn_command (spawn, "pk-spawn-test-xxx.sh");
 	if (ret == FALSE) {
 		libst_success (test, "failed to run invalid file");
@@ -512,7 +527,7 @@ libst_spawn (LibSelfTest *test)
 
 	/************************************************************/
 	libst_title (test, "make sure finished wasn't called");
-	if (mexitcode == -1) {
+	if (mexit == BAD_EXIT) {
 		libst_success (test, NULL);
 	} else {
 		libst_failed (test, "Called finish for bad file!");
@@ -520,7 +535,7 @@ libst_spawn (LibSelfTest *test)
 
 	/************************************************************/
 	libst_title (test, "make sure run correct helper");
-	mexitcode = -1;
+	mexit = -1;
 	ret = pk_spawn_command (spawn, path);
 	if (ret == TRUE) {
 		libst_success (test, "ran correct file");
@@ -534,7 +549,7 @@ libst_spawn (LibSelfTest *test)
 
 	/************************************************************/
 	libst_title (test, "make sure finished okay");
-	if (mexitcode == 0) {
+	if (mexit == PK_SPAWN_EXIT_SUCCESS) {
 		libst_success (test, NULL);
 	} else {
 		libst_failed (test, "finish was okay!");
@@ -564,9 +579,18 @@ libst_spawn (LibSelfTest *test)
 		libst_failed (test, "wrong stderr count %i", stderr_count);
 	}
 
+	g_object_unref (spawn);
+	spawn = pk_spawn_new ();
+	g_signal_connect (spawn, "finished",
+			  G_CALLBACK (pk_test_finished_cb), test);
+	g_signal_connect (spawn, "stdout",
+			  G_CALLBACK (pk_test_stdout_cb), test);
+	g_signal_connect (spawn, "stderr",
+			  G_CALLBACK (pk_test_stderr_cb), test);
+
 	/************************************************************/
 	libst_title (test, "make sure run correct helper, and kill it");
-	mexitcode = -1;
+	mexit = BAD_EXIT;
 	ret = pk_spawn_command (spawn, path);
 	if (ret == TRUE) {
 		libst_success (test, NULL);
@@ -580,11 +604,11 @@ libst_spawn (LibSelfTest *test)
 	g_main_loop_run (loop);
 
 	/************************************************************/
-	libst_title (test, "make sure finished broken");
-	if (mexitcode == 0) {
+	libst_title (test, "make sure finished in SIGKILL");
+	if (mexit == PK_SPAWN_EXIT_KILL) {
 		libst_success (test, NULL);
 	} else {
-		libst_failed (test, "finish %i!", mexitcode);
+		libst_failed (test, "finish %i!", mexit);
 	}
 
 	g_object_unref (spawn);
diff --git a/src/pk-spawn.h b/src/pk-spawn.h
index f2770e0..a13d9b9 100644
--- a/src/pk-spawn.h
+++ b/src/pk-spawn.h
@@ -48,6 +48,14 @@ typedef struct
 	GObjectClass	parent_class;
 } PkSpawnClass;
 
+typedef enum {
+	PK_SPAWN_EXIT_SUCCESS,
+	PK_SPAWN_EXIT_FAILED,
+	PK_SPAWN_EXIT_QUIT,
+	PK_SPAWN_EXIT_KILL,
+	PK_SPAWN_EXIT_UNKNOWN
+} PkSpawnExit;
+
 GType		 pk_spawn_get_type		  	(void);
 PkSpawn		*pk_spawn_new				(void);
 
commit 704df4b3909f67c47fa4489cdd498d06b39284d6
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 10:24:04 2007 +0100

    add the no-cache error enum

diff --git a/docs/pk-introduction.xml b/docs/pk-introduction.xml
index 913b321..fd110e5 100644
--- a/docs/pk-introduction.xml
+++ b/docs/pk-introduction.xml
@@ -284,6 +284,13 @@
               </entry>
             </row>
             <row>
+              <entry><literal>no-cache</literal></entry>
+              <entry>
+                The operation is trying to read from the cache, but the cache
+                is not present or invalid.
+              </entry>
+            </row>
+            <row>
               <entry><literal>package-already-installed</literal></entry>
               <entry>
                 The package that is trying to be installed or updated is already
diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index 65f1c94..060fd95 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -85,6 +85,7 @@ static PkTaskEnumMatch task_role[] = {
 static PkTaskEnumMatch task_error[] = {
 	{PK_ERROR_ENUM_UNKNOWN,			"unknown"},	/* fall though value */
 	{PK_ERROR_ENUM_OOM,			"out-of-memory"},
+	{PK_ERROR_ENUM_NO_CACHE,		"no-cache"},
 	{PK_ERROR_ENUM_NO_NETWORK,		"no-network"},
 	{PK_ERROR_ENUM_NOT_SUPPORTED,		"not-supported"},
 	{PK_ERROR_ENUM_INTERNAL_ERROR,		"internal-error"},
diff --git a/libpackagekit/pk-enum.h b/libpackagekit/pk-enum.h
index 4a5376c..09c94df 100644
--- a/libpackagekit/pk-enum.h
+++ b/libpackagekit/pk-enum.h
@@ -105,6 +105,7 @@ typedef enum {
 	PK_ERROR_ENUM_FILTER_INVALID,
 	PK_ERROR_ENUM_CREATE_THREAD_FAILED,
 	PK_ERROR_ENUM_TRANSACTION_ERROR,
+	PK_ERROR_ENUM_NO_CACHE,
 	PK_ERROR_ENUM_UNKNOWN
 } PkErrorCodeEnum;
 
diff --git a/tools/add-error-enum.sh b/tools/add-error-enum.sh
index f6efe85..35131fa 100755
--- a/tools/add-error-enum.sh
+++ b/tools/add-error-enum.sh
@@ -1,4 +1,4 @@
 #!/bin/sh
 
-$EDITOR docs/introduction.xml libpackagekit/pk-enum.h libpackagekit/pk-enum.c ../gnome-packagekit/src/pk-common.c backends/yum/helpers/packagekit.py
+$EDITOR docs/pk-introduction.xml libpackagekit/pk-enum.h libpackagekit/pk-enum.c ../gnome-packagekit/src/pk-common-gui.c backends/yum/helpers/packagekit.py
 
commit fcbe8779f7d4038157c3837e984883f0937c2d96
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 10:15:20 2007 +0100

    dist the test files so the PkSpawn backend can do it's unit tests in make distcheck

diff --git a/configure.ac b/configure.ac
index ff47b84..ecf4e8c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -386,6 +386,7 @@ backends/test/helpers/Makefile
 backends/yum/Makefile
 backends/yum/helpers/Makefile
 data/Makefile
+data/tests/Makefile
 libselftest/Makefile
 libgbus/Makefile
 libpackagekit/Makefile
diff --git a/data/Makefile.am b/data/Makefile.am
index e9a8150..c2d02d6 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -3,6 +3,10 @@ AUTOMAKE_OPTIONS = 1.7
 
 NULL =
 
+SUBDIRS = 						\
+	tests						\
+	$(NULL)
+
 servicedir       = $(DBUS_SERVICES_DIR)
 service_in_files = org.freedesktop.PackageKit.service.in
 service_DATA     = $(service_in_files:.service.in=.service)
diff --git a/data/tests/.gitignore b/data/tests/.gitignore
new file mode 100644
index 0000000..7f1b6a5
--- /dev/null
+++ b/data/tests/.gitignore
@@ -0,0 +1,4 @@
+.deps
+.libs
+*.o
+
diff --git a/data/tests/Makefile.am b/data/tests/Makefile.am
new file mode 100644
index 0000000..22aaf57
--- /dev/null
+++ b/data/tests/Makefile.am
@@ -0,0 +1,21 @@
+## We require new-style dependency handling.
+AUTOMAKE_OPTIONS = 1.7
+
+NULL =
+
+TEST_FILES =						\
+	pk-spawn-test.sh				\
+	$(NULL)
+
+EXTRA_DIST =						\
+	$(TEST_FILES)					\
+	$(NULL)
+
+clean-local:
+	rm -f *~
+
+MAINTAINERCLEANFILES =					\
+	*~			      			\
+	Makefile.in					\
+	$(NULL)
+
diff --git a/data/tests/pk-spawn-test.sh b/data/tests/pk-spawn-test.sh
new file mode 100755
index 0000000..1c8fc4f
--- /dev/null
+++ b/data/tests/pk-spawn-test.sh
@@ -0,0 +1,31 @@
+
+time=0.30
+
+echo -e "percentage\t0" > /dev/stderr
+echo -e "percentage\t10" > /dev/stderr
+sleep ${time}
+echo -e "percentage\t20" > /dev/stderr
+sleep ${time}
+echo -e "percentage\t30" > /dev/stderr
+sleep ${time}
+echo -e "percentage\t40" > /dev/stderr
+sleep ${time}
+echo -e "package:1\tpolkit\tPolicyKit daemon"
+echo -e "package:0\tpolkit-gnome\tPolicyKit helper for GNOME"
+sleep ${time}
+echo -e -n "package:0\tConsoleKit"
+sleep ${time}
+echo -e "\tSystem console checker"
+echo -e "percentage\t50" > /dev/stderr
+sleep ${time}
+echo -e "percentage\t60" > /dev/stderr
+sleep ${time}
+echo -e "percentage\t70" > /dev/stderr
+sleep ${time}
+echo -e "percentage\t80" > /dev/stderr
+sleep ${time}
+echo -e "percentage\t90" > /dev/stderr
+echo -e "package:0\tgnome-power-manager\tMore useless software"
+sleep ${time}
+echo -e "percentage\t100" > /dev/stderr
+
diff --git a/src/Makefile.am b/src/Makefile.am
index bd1bc4c..92ab7f5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -109,6 +109,9 @@ pk-interface.h: pk-interface.xml
 check_PROGRAMS =					\
 	pk-self-test
 
+noinst_PROGRAMS =					\
+	pk-self-test
+
 pk_self_test_SOURCES =					\
 	pk-inhibit.h					\
 	pk-inhibit.c					\
@@ -143,7 +146,6 @@ pk_self_test_CPPFLAGS=	\
 EXTRA_DIST =						\
 	pk-marshal.list					\
 	pk-interface.xml				\
-	pk-spawn-test.sh				\
 	$(NULL)
 
 clean-local:
diff --git a/src/pk-spawn.c b/src/pk-spawn.c
index ba96c85..7f49c5e 100644
--- a/src/pk-spawn.c
+++ b/src/pk-spawn.c
@@ -413,6 +413,33 @@ guint stderr_count = 0;
 guint finished_count = 0;
 
 /**
+ * pk_test_get_data:
+ **/
+static gchar *
+pk_test_get_data (const gchar *filename)
+{
+	gboolean ret;
+	gchar *full;
+
+	/* check to see if we are being run in the build root */
+	full = g_build_filename ("..", "data", "tests", filename, NULL);
+	ret = g_file_test (full, G_FILE_TEST_EXISTS);
+	if (ret == TRUE) {
+		return full;
+	}
+	g_free (full);
+
+	/* check to see if we are being run in make check */
+	full = g_build_filename ("..", "..", "data", "tests", filename, NULL);
+	ret = g_file_test (full, G_FILE_TEST_EXISTS);
+	if (ret == TRUE) {
+		return full;
+	}
+	g_free (full);
+	return NULL;
+}
+
+/**
  * pk_test_finished_cb:
  **/
 static void
@@ -457,6 +484,7 @@ libst_spawn (LibSelfTest *test)
 {
 	PkSpawn *spawn;
 	gboolean ret;
+	gchar *path;
 
 	if (libst_start (test, "PkSpawn", CLASS_AUTO) == FALSE) {
 		return;
@@ -470,16 +498,18 @@ libst_spawn (LibSelfTest *test)
 	g_signal_connect (spawn, "stderr",
 			  G_CALLBACK (pk_test_stderr_cb), test);
 
+	path = pk_test_get_data ("pk-spawn-test.sh");
+
 	/************************************************************/
 	libst_title (test, "make sure return error for missing file");
 	mexitcode = -1;
-	ret = pk_spawn_command (spawn, "./pk-spawn-test-xxx.sh");
+	ret = pk_spawn_command (spawn, "pk-spawn-test-xxx.sh");
 	if (ret == FALSE) {
 		libst_success (test, "failed to run invalid file");
 	} else {
 		libst_failed (test, "ran incorrect file");
 	}
-#if 0
+
 	/************************************************************/
 	libst_title (test, "make sure finished wasn't called");
 	if (mexitcode == -1) {
@@ -491,7 +521,7 @@ libst_spawn (LibSelfTest *test)
 	/************************************************************/
 	libst_title (test, "make sure run correct helper");
 	mexitcode = -1;
-	ret = pk_spawn_command (spawn, "./pk-spawn-test.sh");
+	ret = pk_spawn_command (spawn, path);
 	if (ret == TRUE) {
 		libst_success (test, "ran correct file");
 	} else {
@@ -537,7 +567,7 @@ libst_spawn (LibSelfTest *test)
 	/************************************************************/
 	libst_title (test, "make sure run correct helper, and kill it");
 	mexitcode = -1;
-	ret = pk_spawn_command (spawn, "./pk-spawn-test.sh");
+	ret = pk_spawn_command (spawn, path);
 	if (ret == TRUE) {
 		libst_success (test, NULL);
 	} else {
@@ -556,9 +586,9 @@ libst_spawn (LibSelfTest *test)
 	} else {
 		libst_failed (test, "finish %i!", mexitcode);
 	}
-#endif
 
 	g_object_unref (spawn);
+	g_free (path);
 
 	libst_end (test);
 }
commit 8941b801b306105ee315af440f2c639c64409126
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Fri Oct 19 10:40:43 2007 +0200

    yum: signal "error\\tno-cache" if cache is invalid in search-* helpers (this time is works)

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 93e50d0..0affba0 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -113,23 +113,23 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         self.yumbase.conf.cache = 1 # Only look in cache.
         try:
             res = self.yumbase.searchGenerator(searchlist, [key])
+            fltlist = filters.split(';')
+    
+            available = []
+            count = 1
+            for (pkg,values) in res:
+                if count > 100:
+                    break
+                count+=1
+                # are we installed?
+                if pkg.repoid == 'installed':
+                    if FILTER_NON_INSTALLED not in fltlist:
+                        if self._do_extra_filtering(pkg,fltlist):
+                            self._show_package(pkg, INFO_INSTALLED)
+                else:
+                    available.append(pkg)
         except yum.Errors.RepoError,e:
-            self.error(ERROR_NO_CACHE)
-        fltlist = filters.split(';')
-
-        available = []
-        count = 1
-        for (pkg,values) in res:
-            if count > 100:
-                break
-            count+=1
-            # are we installed?
-            if pkg.repoid == 'installed':
-                if FILTER_NON_INSTALLED not in fltlist:
-                    if self._do_extra_filtering(pkg,fltlist):
-                        self._show_package(pkg, INFO_INSTALLED)
-            else:
-                available.append(pkg)
+            self.error(ERROR_NO_CACHE,"Yum cache is invalid")
 
         # Now show available packages.
         if FILTER_INSTALLED not in fltlist:
commit 7d5c4ed34c3720002ad4370b33a821b7c50630f8
Author: Tim Lauridsen <timlau at fedoraproject.org>
Date:   Fri Oct 19 10:33:02 2007 +0200

    yum: signal "error\\tno-cache" if cache is invalid in search-* helpers

diff --git a/backends/yum/helpers/yumBackend.py b/backends/yum/helpers/yumBackend.py
index 15f5a1a..93e50d0 100644
--- a/backends/yum/helpers/yumBackend.py
+++ b/backends/yum/helpers/yumBackend.py
@@ -111,7 +111,10 @@ class PackageKitYumBackend(PackageKitBaseBackend):
         '''
         self.yumbase.doConfigSetup(errorlevel=0,debuglevel=0)# Setup Yum Config
         self.yumbase.conf.cache = 1 # Only look in cache.
-        res = self.yumbase.searchGenerator(searchlist, [key])
+        try:
+            res = self.yumbase.searchGenerator(searchlist, [key])
+        except yum.Errors.RepoError,e:
+            self.error(ERROR_NO_CACHE)
         fltlist = filters.split(';')
 
         available = []
diff --git a/python/packagekit/backend.py b/python/packagekit/backend.py
index d89ca49..7303157 100644
--- a/python/packagekit/backend.py
+++ b/python/packagekit/backend.py
@@ -38,6 +38,8 @@ ERROR_DEP_RESOLUTION_FAILED = "dep-resolution-failed"
 ERROR_CREATE_THREAD_FAILED = "create-thread-failed"
 ERROR_FILTER_INVALID = "filter-invalid"
 ERROR_TRANSACTION_ERROR = "transaction-error"
+ERROR_TRANSACTION_ERROR = "transaction-error"
+ERROR_NO_CACHE = "no-cache"
 
 STATE_DOWNLOAD = "download"
 STATE_INSTALL = "install"
commit f3d7bcb92ce8a4a384adc8d63ad4ea5cfa4fb962
Author: Richard Hughes <richard at hughsie.com>
Date:   Fri Oct 19 09:22:48 2007 +0100

    add some more unit tests to PkEnum

diff --git a/libpackagekit/pk-enum.c b/libpackagekit/pk-enum.c
index c3baab6..65f1c94 100644
--- a/libpackagekit/pk-enum.c
+++ b/libpackagekit/pk-enum.c
@@ -430,6 +430,7 @@ libst_enum (LibSelfTest *test)
 {
 	const gchar *string;
 	PkRoleEnum value;
+	guint i;
 
 	if (libst_start (test, "PkEnum", CLASS_AUTO) == FALSE) {
 		return;
@@ -471,6 +472,127 @@ libst_enum (LibSelfTest *test)
 		libst_failed (test, NULL);
 	}
 
+	/************************************************************/
+	libst_title (test, "check we convert all the role enums");
+	for (i=0; i<=PK_ROLE_ENUM_UNKNOWN; i++) {
+		string = pk_role_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the status enums");
+	for (i=0; i<=PK_STATUS_ENUM_UNKNOWN; i++) {
+		string = pk_status_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the exit enums");
+	for (i=0; i<=PK_EXIT_ENUM_UNKNOWN; i++) {
+		string = pk_exit_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the filter enums");
+	for (i=0; i<=PK_FILTER_ENUM_UNKNOWN; i++) {
+		string = pk_filter_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the restart enums");
+	for (i=0; i<=PK_RESTART_ENUM_UNKNOWN; i++) {
+		string = pk_restart_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the error_code enums");
+	for (i=0; i<=PK_ERROR_ENUM_UNKNOWN; i++) {
+		string = pk_error_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the group enums");
+	for (i=0; i<=PK_GROUP_ENUM_UNKNOWN; i++) {
+		string = pk_group_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the freq enums");
+	for (i=0; i<=PK_FREQ_ENUM_UNKNOWN; i++) {
+		string = pk_freq_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the update enums");
+	for (i=0; i<=PK_UPDATE_ENUM_UNKNOWN; i++) {
+		string = pk_update_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the info enums");
+	for (i=0; i<=PK_INFO_ENUM_UNKNOWN; i++) {
+		string = pk_info_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
+	/************************************************************/
+	libst_title (test, "check we convert all the sig_type enums");
+	for (i=0; i<=PK_SIGTYPE_ENUM_UNKNOWN; i++) {
+		string = pk_sig_type_enum_to_text (i);
+		if (string == NULL) {
+			libst_failed (test, "failed to get %i", i);
+			break;
+		}
+	}
+	libst_success (test, NULL);
+
 	libst_end (test);
 }
 #endif



More information about the PackageKit mailing list