[packagekit] [PATCH 5/5] zypp: Add pattern support

Thomas Perl thomas.perl at jolla.com
Wed Jan 22 02:31:52 PST 2014


Support for patterns (http://tr.opensuse.org/Patterns) by prefixing
installation requests with "pattern:" and also listing available
patterns as packages with "pattern:" prefix. This is similar to what
zypper is doing, within the PackageKit framework's restriction (there
is no package "type" for patterns, and it probably doesn't make any
sense to have such a type for non-libzypp-based systems).

Original patch by Pekka Lundstrom <pekka.lundstrom at jolla.com>
---
 backends/zypp/pk-backend-zypp.cpp | 77 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 67 insertions(+), 10 deletions(-)

diff --git a/backends/zypp/pk-backend-zypp.cpp b/backends/zypp/pk-backend-zypp.cpp
index 7e9d8c9..f0783d9 100644
--- a/backends/zypp/pk-backend-zypp.cpp
+++ b/backends/zypp/pk-backend-zypp.cpp
@@ -152,6 +152,21 @@ gchar * _repoName;
  */
 gboolean _updating_self = FALSE;
 
+/*
+ * Test if this is pattern and all its dependencies are installed
+ */
+static gboolean
+zypp_satisfied_pattern(const sat::Solvable &solv)
+{
+	gboolean satisfied = FALSE;
+
+	if (isKind<Pattern>(solv)) {
+		PoolItem patt = PoolItem(solv);
+		satisfied = patt.isSatisfied();
+	}
+	return satisfied;
+}
+
 /**
  * Build a package_id from the specified resolvable.  The returned
  * gchar * should be freed with g_free ().
@@ -161,16 +176,22 @@ zypp_build_package_id_from_resolvable (const sat::Solvable &resolvable)
 {
 	gchar *package_id;
 	const char *arch;
+	string name = resolvable.name ();
+	string repo = resolvable.repository ().alias();
 
-	if (isKind<SrcPackage>(resolvable))
+	if (isKind<Pattern>(resolvable)) {
+		name = "pattern:" + resolvable.name ();
+		arch = "noarch";
+		if (zypp_satisfied_pattern(resolvable))
+			repo = "installed";
+	} else if (isKind<SrcPackage>(resolvable))
 		arch = "source";
-	else
+	else {
 		arch = resolvable.arch ().asString ().c_str ();
-
-	string repo = resolvable.repository ().alias();
-	if (resolvable.isSystem())
-		repo = "installed";
-	package_id = pk_package_id_build (resolvable.name ().c_str (),
+		if (resolvable.isSystem())
+			repo = "installed";
+	}
+	package_id = pk_package_id_build (name.c_str (),
 					  resolvable.edition ().asString ().c_str (),
 					  arch, repo.c_str ());
 	
@@ -859,7 +880,20 @@ zypp_get_packages_by_name (const gchar *package_name,
 			   vector<sat::Solvable> &result,
 			   gboolean include_local = TRUE)
 {
-	ui::Selectable::Ptr sel( ui::Selectable::get( kind, package_name ) );
+	const gchar *search_name;
+	// Patterns are stored in zypper without "pattern:" prefix
+	// We want that to be specified when searching patterns
+	if (kind == ResKind::pattern) {
+		if (g_str_has_prefix (package_name, "pattern:"))
+			search_name = package_name + strlen("pattern:");
+		else {
+			return;
+		}
+	}
+	else
+		search_name = package_name;
+
+	ui::Selectable::Ptr sel( ui::Selectable::get( kind, search_name ) );
 	if ( sel ) {
 		if ( ! sel->installedEmpty() ) {
 			for_( it, sel->installedBegin(), sel->installedEnd() )
@@ -921,14 +955,22 @@ zypp_get_package_by_id (const gchar *package_id)
 	const gchar *arch = id_parts[PK_PACKAGE_ID_ARCH];
 	if (!arch)
 		arch = "noarch";
+	const gchar *name = id_parts[PK_PACKAGE_ID_NAME];
+	const gchar *search_name;
 	bool want_source = !g_strcmp0 (arch, "source");
-	
+	bool want_pattern = g_str_has_prefix (name, "pattern:");
+	if (want_pattern)
+		search_name = name + strlen("pattern:");  // skip pattern
+	else
+		search_name = name;
+
+
 	sat::Solvable package;
 
 	ResPool pool = ResPool::instance();
 
 	// Iterate over the resolvables and mark the one we want to check its dependencies
-	for (ResPool::byName_iterator it = pool.byNameBegin (id_parts[PK_PACKAGE_ID_NAME]);
+	for (ResPool::byName_iterator it = pool.byNameBegin (search_name);
 	     it != pool.byNameEnd (id_parts[PK_PACKAGE_ID_NAME]); ++it) {
 		
 		sat::Solvable pkg = it->satSolvable();
@@ -939,6 +981,11 @@ zypp_get_package_by_id (const gchar *package_id)
 			continue;
 		}
 
+		if (want_pattern && !isKind<Pattern>(pkg)) {
+			//MIL << "not a pattern\n";
+			continue;
+		}
+
 		if (!want_source && (isKind<SrcPackage>(pkg) || g_strcmp0 (pkg.arch().c_str(), arch))) {
 			//MIL << "not a matching arch\n";
 			continue;
@@ -2819,6 +2866,9 @@ backend_find_packages_thread (PkBackendJob *job, GVariant *params, gpointer user
 	}
 
 	search = values[0];  //Fixme - support the possible multiple values (logical OR search)
+	if (g_str_has_prefix (search, "pattern:"))
+		search += strlen("pattern:");  // skip pattern
+
 	role = pk_backend_job_get_role(job);
 
 	pk_backend_job_set_status (job, PK_STATUS_ENUM_QUERY);
@@ -2835,6 +2885,7 @@ backend_find_packages_thread (PkBackendJob *job, GVariant *params, gpointer user
 	case PK_ROLE_ENUM_SEARCH_NAME:
 		zypp_build_pool (zypp, TRUE); // seems to be necessary?
 		q.addKind( ResKind::package );
+		q.addKind( ResKind::pattern );
 		q.addKind( ResKind::srcpackage );
 		q.addAttribute( sat::SolvAttr::name );
 		// Note: The query result is NOT sorted packages first, then srcpackage.
@@ -2844,6 +2895,7 @@ backend_find_packages_thread (PkBackendJob *job, GVariant *params, gpointer user
 	case PK_ROLE_ENUM_SEARCH_DETAILS:
 		zypp_build_pool (zypp, TRUE); // seems to be necessary?
 		q.addKind( ResKind::package );
+		q.addKind( ResKind::pattern );
 		//q.addKind( ResKind::srcpackage );
 		q.addAttribute( sat::SolvAttr::name );
 		q.addAttribute( sat::SolvAttr::description );
@@ -2853,6 +2905,7 @@ backend_find_packages_thread (PkBackendJob *job, GVariant *params, gpointer user
 	case PK_ROLE_ENUM_SEARCH_FILE: {
 		zypp_build_pool (zypp, TRUE);
 		q.addKind( ResKind::package );
+		q.addKind( ResKind::pattern );
 		q.addAttribute( sat::SolvAttr::name );
 		q.addAttribute( sat::SolvAttr::description );
 		q.addAttribute( sat::SolvAttr::filelist );
@@ -3146,6 +3199,10 @@ backend_get_packages_thread (PkBackendJob *job, GVariant *params, gpointer user_
 	for (ResPool::byKind_iterator it = pool.byKindBegin (ResKind::package); it != pool.byKindEnd (ResKind::package); ++it) {
 		v.push_back (it->satSolvable ());
 	}
+	/* Get also patterns */
+	for (ResPool::byKind_iterator it = pool.byKindBegin (ResKind::pattern); it != pool.byKindEnd (ResKind::pattern); ++it) {
+		v.push_back (it->satSolvable ());
+	}
 
 	zypp_emit_filtered_packages_in_list (job, _filters, v);
 
-- 
1.8.5.2



More information about the PackageKit mailing list