lib: Add diff API
This is a *third* implementation of rpm database diffs in the code, but it is now a public introspectable shared library API. Further commits will change the command line tools to use this, and then after that we'll further deduplicate the `db diff` from this code.
This commit is contained in:
parent
28ab27caf7
commit
3326e13481
@ -140,3 +140,136 @@ rpm_ostree_db_query (OstreeRepo *repo,
|
||||
|
||||
return query_all_packages_in_sack (rsack);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpm_ostree_db_diff:
|
||||
* @repo: An OSTree repository
|
||||
* @orig_ref: Original ref (branch or commit)
|
||||
* @new_ref: New ref (branch or commit)
|
||||
* @query: (allow-none): A query, currently must be %NULL
|
||||
* @out_removed: (out) (transfer container) (element-type RpmOstreePackage): Return location for removed packages
|
||||
* @out_added: (out) (transfer container) (element-type RpmOstreePackage): Return location for added packages
|
||||
* @out_modified_old: (out) (transfer container) (element-type RpmOstreePackage): Return location for modified old packages
|
||||
* @out_modified_new: (out) (transfer container) (element-type RpmOstreePackage): Return location for modified new packages
|
||||
*
|
||||
* Compute the RPM package delta between two commits. Currently you
|
||||
* must use %NULL for the @query parameter; in a future version this
|
||||
* function may allow looking at a subset of the packages.
|
||||
*
|
||||
* The @out_modified_old and @out_modified_new arrays will always be
|
||||
* the same length, and indicies will refer to the same base package
|
||||
* name. It is possible in RPM databases to have multiple packages
|
||||
* installed with the same name; in this case, the behavior will
|
||||
* depend on whether the package set is transitioning from 1 -> N or N
|
||||
* -> 1. In the former case, an arbitrary single instance of one of
|
||||
* the new packages will be in @out_modified_new. If the latter, then
|
||||
* multiple entries with the same name will be returned in
|
||||
* the array @out_modified_old, with each having a reference to the
|
||||
* single corresponding new package.
|
||||
*/
|
||||
gboolean
|
||||
rpm_ostree_db_diff (OstreeRepo *repo,
|
||||
const char *orig_ref,
|
||||
const char *new_ref,
|
||||
GVariant *query,
|
||||
GPtrArray **out_removed,
|
||||
GPtrArray **out_added,
|
||||
GPtrArray **out_modified_old,
|
||||
GPtrArray **out_modified_new,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
g_autoptr(RpmOstreeRefSack) orig_sack = NULL;
|
||||
g_autoptr(RpmOstreeRefSack) new_sack = NULL;
|
||||
_cleanup_hypackagelist_ HyPackageList orig_pkglist = NULL;
|
||||
_cleanup_hypackagelist_ HyPackageList new_pkglist = NULL;
|
||||
g_autoptr(GPtrArray) ret_removed = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
g_autoptr(GPtrArray) ret_added = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
g_autoptr(GPtrArray) ret_modified_old = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
g_autoptr(GPtrArray) ret_modified_new = g_ptr_array_new_with_free_func (g_object_unref);
|
||||
guint i;
|
||||
HyPackage pkg;
|
||||
|
||||
g_return_val_if_fail (query == NULL, FALSE);
|
||||
g_return_val_if_fail (out_removed != NULL && out_added != NULL &&
|
||||
out_modified_old != NULL && out_modified_new != NULL, FALSE);
|
||||
|
||||
orig_sack = get_refsack_for_commit (repo, orig_ref, cancellable, error);
|
||||
if (!orig_sack)
|
||||
goto out;
|
||||
|
||||
{ _cleanup_hyquery_ HyQuery query = hy_query_create (orig_sack->sack);
|
||||
hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
|
||||
orig_pkglist = hy_query_run (query);
|
||||
}
|
||||
|
||||
new_sack = get_refsack_for_commit (repo, new_ref, cancellable, error);
|
||||
if (!new_sack)
|
||||
goto out;
|
||||
|
||||
{ _cleanup_hyquery_ HyQuery query = hy_query_create (new_sack->sack);
|
||||
hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
|
||||
new_pkglist = hy_query_run (query);
|
||||
}
|
||||
|
||||
FOR_PACKAGELIST(pkg, new_pkglist, i)
|
||||
{
|
||||
_cleanup_hyquery_ HyQuery query = NULL;
|
||||
_cleanup_hypackagelist_ HyPackageList pkglist = NULL;
|
||||
guint count;
|
||||
HyPackage oldpkg;
|
||||
|
||||
query = hy_query_create (orig_sack->sack);
|
||||
hy_query_filter (query, HY_PKG_NAME, HY_EQ, hy_package_get_name (pkg));
|
||||
hy_query_filter (query, HY_PKG_EVR, HY_NEQ, hy_package_get_evr (pkg));
|
||||
hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
|
||||
pkglist = hy_query_run (query);
|
||||
|
||||
count = hy_packagelist_count (pkglist);
|
||||
if (count > 0)
|
||||
{
|
||||
/* See comment above about transitions from N -> 1 */
|
||||
oldpkg = hy_packagelist_get (pkglist, 0);
|
||||
|
||||
g_ptr_array_add (ret_modified_old, _rpm_ostree_package_new (orig_sack, oldpkg));
|
||||
g_ptr_array_add (ret_modified_new, _rpm_ostree_package_new (new_sack, pkg));
|
||||
}
|
||||
}
|
||||
|
||||
FOR_PACKAGELIST(pkg, orig_pkglist, i)
|
||||
{
|
||||
_cleanup_hyquery_ HyQuery query = NULL;
|
||||
_cleanup_hypackagelist_ HyPackageList pkglist = NULL;
|
||||
|
||||
query = hy_query_create (new_sack->sack);
|
||||
hy_query_filter (query, HY_PKG_NAME, HY_EQ, hy_package_get_name (pkg));
|
||||
hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
|
||||
pkglist = hy_query_run (query);
|
||||
|
||||
if (hy_packagelist_count (pkglist) == 0)
|
||||
g_ptr_array_add (ret_removed, _rpm_ostree_package_new (orig_sack, pkg));
|
||||
}
|
||||
|
||||
FOR_PACKAGELIST(pkg, new_pkglist, i)
|
||||
{
|
||||
_cleanup_hyquery_ HyQuery query = NULL;
|
||||
_cleanup_hypackagelist_ HyPackageList pkglist = NULL;
|
||||
|
||||
query = hy_query_create (orig_sack->sack);
|
||||
hy_query_filter (query, HY_PKG_NAME, HY_EQ, hy_package_get_name (pkg));
|
||||
hy_query_filter (query, HY_PKG_REPONAME, HY_EQ, HY_SYSTEM_REPO_NAME);
|
||||
pkglist = hy_query_run (query);
|
||||
|
||||
if (hy_packagelist_count (pkglist) == 0)
|
||||
g_ptr_array_add (ret_added, _rpm_ostree_package_new (new_sack, pkg));
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
*out_removed = g_steal_pointer (&ret_removed);
|
||||
*out_added = g_steal_pointer (&ret_added);
|
||||
*out_modified_old = g_steal_pointer (&ret_modified_old);
|
||||
*out_modified_new = g_steal_pointer (&ret_modified_new);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -31,4 +31,15 @@ _RPMOSTREE_EXTERN GPtrArray *rpm_ostree_db_query (OstreeRepo *repo
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
_RPMOSTREE_EXTERN gboolean rpm_ostree_db_diff (OstreeRepo *repo,
|
||||
const char *orig_ref,
|
||||
const char *new_ref,
|
||||
GVariant *query,
|
||||
GPtrArray **out_removed,
|
||||
GPtrArray **out_added,
|
||||
GPtrArray **out_modified_old,
|
||||
GPtrArray **out_modified_new,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
@ -12,3 +12,11 @@ print "Package list: "
|
||||
for p in qr:
|
||||
print p.get_nevra()
|
||||
|
||||
_,removed,added,modold,modnew = RpmOstree.db_diff(r, ref + '^', ref, None, None)
|
||||
for p in removed:
|
||||
print "D " + p.get_nevra()
|
||||
for p in added:
|
||||
print "A " + p.get_nevra()
|
||||
for o,n in zip(modold, modnew):
|
||||
print "M {0} {1} -> {2}".format(o.get_name(), o.get_evr(), n.get_evr())
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user