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);
|
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,
|
GCancellable *cancellable,
|
||||||
GError **error);
|
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
|
G_END_DECLS
|
||||||
|
@ -12,3 +12,11 @@ print "Package list: "
|
|||||||
for p in qr:
|
for p in qr:
|
||||||
print p.get_nevra()
|
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