libostree: new API ostree_repo_remote_list_refs

The new API permits to query a remote repository summary file and
retrieve the list of available refs.

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2015-07-22 12:16:51 +02:00 committed by Colin Walters
parent a917c96976
commit 133fb5ffdc
4 changed files with 90 additions and 28 deletions

View File

@ -259,6 +259,7 @@ ostree_repo_write_content_async
ostree_repo_write_content_finish ostree_repo_write_content_finish
ostree_repo_resolve_rev ostree_repo_resolve_rev
ostree_repo_list_refs ostree_repo_list_refs
ostree_repo_remote_list_refs
ostree_repo_load_variant ostree_repo_load_variant
ostree_repo_load_commit ostree_repo_load_commit
ostree_repo_load_variant_if_exists ostree_repo_load_variant_if_exists

View File

@ -578,6 +578,81 @@ ostree_repo_list_refs (OstreeRepo *self,
return ret; return ret;
} }
/**
* ostree_repo_remote_list_refs:
* @self: Repo
* @remote_name: Name of the remote.
* @out_all_refs: (out) (element-type utf8 utf8): Mapping from ref to checksum
* @cancellable: Cancellable
* @error: Error
*
*/
gboolean
ostree_repo_remote_list_refs (OstreeRepo *self,
const char *remote_name,
GHashTable **out_all_refs,
GCancellable *cancellable,
GError **error)
{
g_autoptr(GBytes) summary_bytes = NULL;
gboolean ret = FALSE;
g_autoptr(GHashTable) ret_all_refs = NULL;
if (!ostree_repo_remote_fetch_summary (self, remote_name,
&summary_bytes, NULL,
cancellable, error))
goto out;
if (summary_bytes == NULL)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
"Remote refs not available; server has no summary file\n");
goto out;
}
else
{
g_autoptr(GVariant) summary = NULL;
g_autoptr(GVariant) ref_map = NULL;
GVariantIter iter;
GVariant *child;
ret_all_refs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT,
summary_bytes, FALSE);
ref_map = g_variant_get_child_value (summary, 0);
g_variant_iter_init (&iter, ref_map);
while ((child = g_variant_iter_next_value (&iter)) != NULL)
{
const char *ref_name = NULL;
g_autoptr(GVariant) csum_v = NULL;
char tmp_checksum[65];
g_variant_get_child (child, 0, "&s", &ref_name);
if (ref_name != NULL)
{
g_variant_get_child (child, 1, "(t@aya{sv})", NULL, &csum_v, NULL);
ostree_checksum_inplace_from_bytes (ostree_checksum_bytes_peek (csum_v),
tmp_checksum);
g_hash_table_insert (ret_all_refs,
g_strdup (ref_name),
g_strdup (tmp_checksum));
}
g_variant_unref (child);
}
}
ret = TRUE;
ot_transfer_out_value (out_all_refs, &ret_all_refs);
out:
return ret;
}
gboolean gboolean
_ostree_repo_write_ref (OstreeRepo *self, _ostree_repo_write_ref (OstreeRepo *self,
const char *remote, const char *remote,

View File

@ -291,6 +291,12 @@ gboolean ostree_repo_list_refs (OstreeRepo *self,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
gboolean ostree_repo_remote_list_refs (OstreeRepo *self,
const char *remote_name,
GHashTable **out_all_refs,
GCancellable *cancellable,
GError **error);
gboolean ostree_repo_load_variant (OstreeRepo *self, gboolean ostree_repo_load_variant (OstreeRepo *self,
OstreeObjectType objtype, OstreeObjectType objtype,
const char *sha256, const char *sha256,

View File

@ -34,8 +34,8 @@ ot_remote_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError
GOptionContext *context; GOptionContext *context;
glnx_unref_object OstreeRepo *repo = NULL; glnx_unref_object OstreeRepo *repo = NULL;
const char *remote_name; const char *remote_name;
g_autoptr(GBytes) summary_bytes = NULL;
gboolean ret = FALSE; gboolean ret = FALSE;
g_autoptr(GHashTable) refs = NULL;
context = g_option_context_new ("NAME - List remote refs"); context = g_option_context_new ("NAME - List remote refs");
@ -51,39 +51,19 @@ ot_remote_builtin_refs (int argc, char **argv, GCancellable *cancellable, GError
remote_name = argv[1]; remote_name = argv[1];
if (!ostree_repo_remote_fetch_summary (repo, remote_name, if (!ostree_repo_remote_list_refs (repo, remote_name, &refs, cancellable, error))
&summary_bytes, NULL,
cancellable, error))
goto out; goto out;
if (summary_bytes == NULL)
{
g_print ("Remote refs not available; server has no summary file\n");
}
else else
{ {
g_autoptr(GVariant) summary = NULL; g_autoptr(GList) ordered_keys = NULL;
g_autoptr(GVariant) ref_map = NULL; GList *iter = NULL;
GVariantIter iter;
GVariant *child;
summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, ordered_keys = g_hash_table_get_keys (refs);
summary_bytes, FALSE); ordered_keys = g_list_sort (ordered_keys, (GCompareFunc) strcmp);
ref_map = g_variant_get_child_value (summary, 0); for (iter = ordered_keys; iter; iter = iter->next)
/* Ref map should already be sorted by ref name. */
g_variant_iter_init (&iter, ref_map);
while ((child = g_variant_iter_next_value (&iter)) != NULL)
{ {
const char *ref_name = NULL; g_print ("%s\n", (const char *) iter->data);
g_variant_get_child (child, 0, "&s", &ref_name);
if (ref_name != NULL)
g_print ("%s\n", ref_name);
g_variant_unref (child);
} }
} }