forked from Mirrors/flatpak-builder
commit
cd3289e0cb
|
@ -25,6 +25,7 @@ _xdg-app() {
|
|||
[GENERAL]='--help --verbose --version'
|
||||
[MODE]='--user --system'
|
||||
[ARCH]='--arch'
|
||||
[ADD_REMOTE]='--no-gpg-verify --if-not-exists --title'
|
||||
[LIST_REMOTES]='--show-urls'
|
||||
[REPO_CONTENTS]='--show-details --runtimes --apps --update'
|
||||
[UNINSTALL]='--keep-ref'
|
||||
|
@ -33,7 +34,8 @@ _xdg-app() {
|
|||
[BUILD]='--runtime --network --x11'
|
||||
[BUILD_FINISH]='--command --allow'
|
||||
[BUILD_EXPORT]='--subject --body'
|
||||
[ARG]='--arch --command --branch --var --allow --forbid --subject --body --runtime'
|
||||
[REPO_UPDATE]='--title'
|
||||
[ARG]='--arch --command --branch --var --allow --forbid --subject --body --title --runtime'
|
||||
)
|
||||
|
||||
if __contains_word "--user" ${COMP_WORDS[*]}; then
|
||||
|
@ -56,7 +58,7 @@ _xdg-app() {
|
|||
--allow|--forbid)
|
||||
comps='x11 wayland ipc pulseaudio system-dbus session-dbus network host-fs homedir'
|
||||
;;
|
||||
--branch|--subject|--body)
|
||||
--branch|--subject|--body|--title)
|
||||
comps=''
|
||||
;;
|
||||
esac
|
||||
|
@ -152,6 +154,12 @@ _xdg-app() {
|
|||
if [ "$verb" = "build-export" ]; then
|
||||
comps="$comps ${OPTS[BUILD_EXPORT]}"
|
||||
fi
|
||||
if [ "$verb" = "repo-update" ]; then
|
||||
comps="$comps ${OPTS[REPO_UPDATE]}"
|
||||
fi
|
||||
if [ "$verb" = "add-remote" ]; then
|
||||
comps="$comps ${OPTS[ADD_REMOTE]}"
|
||||
fi
|
||||
|
||||
else
|
||||
case "$verb" in
|
||||
|
|
|
@ -68,6 +68,15 @@
|
|||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--title=TITLE</option></term>
|
||||
|
||||
<listitem><para>
|
||||
A title for the repository, e.g. for display in a UI.
|
||||
The title is stored in the repository summary.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-v</option></term>
|
||||
<term><option>--verbose</option></term>
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "libgsystem.h"
|
||||
|
||||
#include "xdg-app-builtins.h"
|
||||
#include "xdg-app-utils.h"
|
||||
|
||||
static gboolean opt_no_gpg_verify;
|
||||
static gboolean opt_if_not_exists;
|
||||
|
@ -26,6 +27,8 @@ xdg_app_builtin_add_remote (int argc, char **argv, GCancellable *cancellable, GE
|
|||
gboolean ret = FALSE;
|
||||
gs_unref_object XdgAppDir *dir = NULL;
|
||||
gs_unref_variant_builder GVariantBuilder *optbuilder = NULL;
|
||||
gs_unref_hashtable GHashTable *refs = NULL;
|
||||
gs_free char *title = NULL;
|
||||
const char *remote_name;
|
||||
const char *remote_url;
|
||||
|
||||
|
@ -45,14 +48,24 @@ xdg_app_builtin_add_remote (int argc, char **argv, GCancellable *cancellable, GE
|
|||
|
||||
optbuilder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
|
||||
|
||||
if (!ostree_repo_load_summary (remote_url, &refs, &title, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (opt_no_gpg_verify)
|
||||
g_variant_builder_add (optbuilder, "{s@v}",
|
||||
"gpg-verify",
|
||||
g_variant_new_variant (g_variant_new_boolean (FALSE)));
|
||||
|
||||
if (opt_title)
|
||||
{
|
||||
g_free (title);
|
||||
title = g_strdup (opt_title);
|
||||
}
|
||||
|
||||
if (title)
|
||||
g_variant_builder_add (optbuilder, "{s@v}",
|
||||
"xa.title",
|
||||
g_variant_new_variant (g_variant_new_string (opt_title)));
|
||||
g_variant_new_variant (g_variant_new_string (title)));
|
||||
|
||||
if (!ostree_repo_remote_change (xdg_app_dir_get_repo (dir), NULL,
|
||||
opt_if_not_exists ? OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS :
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "libgsystem.h"
|
||||
#include <libsoup/soup.h>
|
||||
|
||||
#include "xdg-app-builtins.h"
|
||||
#include "xdg-app-utils.h"
|
||||
|
@ -24,58 +23,15 @@ static GOptionEntry options[] = {
|
|||
{ NULL }
|
||||
};
|
||||
|
||||
static gboolean
|
||||
load_contents (const char *uri, GBytes **contents, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_free char *scheme = NULL;
|
||||
|
||||
scheme = g_uri_parse_scheme (uri);
|
||||
if (strcmp (scheme, "file") == 0)
|
||||
{
|
||||
char *buffer;
|
||||
gsize length;
|
||||
gs_unref_object GFile *file = NULL;
|
||||
|
||||
g_debug ("Loading summary %s using GIO", uri);
|
||||
file = g_file_new_for_uri (uri);
|
||||
if (!g_file_load_contents (file, cancellable, &buffer, &length, NULL, NULL))
|
||||
goto out;
|
||||
|
||||
*contents = g_bytes_new_take (buffer, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
gs_unref_object SoupSession *session = NULL;
|
||||
gs_unref_object SoupMessage *msg = NULL;
|
||||
|
||||
g_debug ("Loading summary %s using libsoup", uri);
|
||||
session = soup_session_new ();
|
||||
msg = soup_message_new ("GET", uri);
|
||||
soup_session_send_message (session, msg);
|
||||
|
||||
if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
|
||||
goto out;
|
||||
|
||||
*contents = g_bytes_new (msg->response_body->data, msg->response_body->length);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
g_debug ("Received %ld bytes", g_bytes_get_size (*contents));
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
GOptionContext *context;
|
||||
gs_unref_object XdgAppDir *dir = NULL;
|
||||
gs_unref_object OstreeRepo *repo = NULL;
|
||||
OstreeRepo *repo = NULL;
|
||||
gs_unref_hashtable GHashTable *refs = NULL;
|
||||
gs_free char *title = NULL;
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
gpointer value;
|
||||
|
@ -83,7 +39,6 @@ xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable,
|
|||
int i;
|
||||
const char *repository;
|
||||
gs_free char *url = NULL;
|
||||
gs_free char *summary_url = NULL;
|
||||
gs_unref_bytes GBytes *bytes = NULL;
|
||||
|
||||
context = g_option_context_new (" REPOSITORY - Show available runtimes and applications");
|
||||
|
@ -103,43 +58,8 @@ xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable,
|
|||
if (!ostree_repo_remote_get_url (repo, repository, &url, error))
|
||||
goto out;
|
||||
|
||||
summary_url = g_build_filename (url, "summary", NULL);
|
||||
if (load_contents (summary_url, &bytes, cancellable, NULL))
|
||||
{
|
||||
gs_unref_variant GVariant *summary;
|
||||
gs_unref_variant GVariant *ref_list;
|
||||
int n;
|
||||
|
||||
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, bytes, FALSE);
|
||||
ref_list = g_variant_get_child_value (summary, 0);
|
||||
n = g_variant_n_children (ref_list);
|
||||
g_debug ("Summary contains %d refs", n);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
gs_unref_variant GVariant *ref = NULL;
|
||||
gs_unref_variant GVariant *csum_v = NULL;
|
||||
char *refname;
|
||||
char *checksum;
|
||||
|
||||
ref = g_variant_get_child_value (ref_list, i);
|
||||
g_variant_get (ref, "(&s(t@aya{sv}))", &refname, NULL, &csum_v, NULL);
|
||||
|
||||
if (!ostree_validate_rev (refname, error))
|
||||
goto out;
|
||||
|
||||
checksum = ostree_checksum_from_bytes_v (csum_v);
|
||||
g_debug ("%s summary: %s -> %s\n", repository, refname, checksum);
|
||||
g_hash_table_insert (refs, g_strdup (refname), checksum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
g_printerr ("Failed to load summary file for remote %s, listing local refs\n", repository);
|
||||
if (!ostree_repo_list_refs (repo, NULL, &refs, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
if (!ostree_repo_load_summary (url, &refs, &title, cancellable, error))
|
||||
goto out;
|
||||
|
||||
names = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
|
@ -212,7 +132,7 @@ xdg_app_builtin_repo_contents (int argc, char **argv, GCancellable *cancellable,
|
|||
break;
|
||||
}
|
||||
|
||||
if (found)
|
||||
if (!found)
|
||||
g_ptr_array_add (names, name);
|
||||
else
|
||||
g_free (name);
|
||||
|
|
|
@ -10,6 +10,13 @@
|
|||
#include "xdg-app-builtins.h"
|
||||
#include "xdg-app-utils.h"
|
||||
|
||||
static char *opt_title;
|
||||
|
||||
static GOptionEntry options[] = {
|
||||
{ "title", 0, 0, G_OPTION_ARG_STRING, &opt_title, "A nice name to use for this repository", "TITLE" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
gboolean
|
||||
xdg_app_builtin_repo_update (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
|
@ -19,10 +26,11 @@ xdg_app_builtin_repo_update (int argc, char **argv, GCancellable *cancellable, G
|
|||
gs_unref_object GFile *repofile = NULL;
|
||||
gs_unref_object OstreeRepo *repo = NULL;
|
||||
const char *location;
|
||||
GVariant *extra = NULL;
|
||||
|
||||
context = g_option_context_new ("LOCATION - Update repository metadata");
|
||||
|
||||
if (!xdg_app_option_context_parse (context, NULL, &argc, &argv, XDG_APP_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
|
||||
if (!xdg_app_option_context_parse (context, options, &argc, &argv, XDG_APP_BUILTIN_FLAG_NO_DIR, NULL, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (argc < 2)
|
||||
|
@ -39,7 +47,16 @@ xdg_app_builtin_repo_update (int argc, char **argv, GCancellable *cancellable, G
|
|||
if (!ostree_repo_open (repo, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!ostree_repo_regenerate_summary (repo, NULL, cancellable, error))
|
||||
if (opt_title)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_add (&builder, "{sv}", "xa.title", g_variant_new_string (opt_title));
|
||||
extra = g_variant_builder_end (&builder);
|
||||
}
|
||||
|
||||
if (!ostree_repo_regenerate_summary (repo, extra, cancellable, error))
|
||||
goto out;
|
||||
|
||||
/* TODO: appstream data */
|
||||
|
|
107
xdg-app-utils.c
107
xdg-app-utils.c
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include "libgsystem.h"
|
||||
#include <libsoup/soup.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
@ -343,3 +344,109 @@ xdg_app_remove_dangling_symlinks (GFile *dir,
|
|||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
load_contents (const char *uri, GBytes **contents, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_free char *scheme = NULL;
|
||||
|
||||
scheme = g_uri_parse_scheme (uri);
|
||||
if (strcmp (scheme, "file") == 0)
|
||||
{
|
||||
char *buffer;
|
||||
gsize length;
|
||||
gs_unref_object GFile *file = NULL;
|
||||
|
||||
g_debug ("Loading summary %s using GIO", uri);
|
||||
file = g_file_new_for_uri (uri);
|
||||
if (!g_file_load_contents (file, cancellable, &buffer, &length, NULL, NULL))
|
||||
goto out;
|
||||
|
||||
*contents = g_bytes_new_take (buffer, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
gs_unref_object SoupSession *session = NULL;
|
||||
gs_unref_object SoupMessage *msg = NULL;
|
||||
|
||||
g_debug ("Loading summary %s using libsoup", uri);
|
||||
session = soup_session_new ();
|
||||
msg = soup_message_new ("GET", uri);
|
||||
soup_session_send_message (session, msg);
|
||||
|
||||
if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
|
||||
goto out;
|
||||
|
||||
*contents = g_bytes_new (msg->response_body->data, msg->response_body->length);
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
g_debug ("Received %ld bytes", g_bytes_get_size (*contents));
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
gboolean
|
||||
ostree_repo_load_summary (const char *repository_url,
|
||||
GHashTable **refs,
|
||||
gchar **title,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
gs_free char *summary_url = NULL;
|
||||
gs_unref_bytes GBytes *bytes = NULL;
|
||||
gs_unref_hashtable GHashTable *local_refs = NULL;
|
||||
gs_free char *local_title = NULL;
|
||||
|
||||
summary_url = g_build_filename (repository_url, "summary", NULL);
|
||||
if (load_contents (summary_url, &bytes, cancellable, NULL))
|
||||
{
|
||||
gs_unref_variant GVariant *summary;
|
||||
gs_unref_variant GVariant *ref_list;
|
||||
gs_unref_variant GVariant *extensions;
|
||||
GVariantDict dict;
|
||||
int i, n;
|
||||
|
||||
local_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, bytes, FALSE);
|
||||
ref_list = g_variant_get_child_value (summary, 0);
|
||||
extensions = g_variant_get_child_value (summary, 1);
|
||||
|
||||
n = g_variant_n_children (ref_list);
|
||||
g_debug ("Summary contains %d refs", n);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
gs_unref_variant GVariant *ref = NULL;
|
||||
gs_unref_variant GVariant *csum_v = NULL;
|
||||
char *refname;
|
||||
char *checksum;
|
||||
|
||||
ref = g_variant_get_child_value (ref_list, i);
|
||||
g_variant_get (ref, "(&s(t@aya{sv}))", &refname, NULL, &csum_v, NULL);
|
||||
|
||||
if (!ostree_validate_rev (refname, error))
|
||||
goto out;
|
||||
|
||||
checksum = ostree_checksum_from_bytes_v (csum_v);
|
||||
g_debug ("\t%s -> %s", refname, checksum);
|
||||
g_hash_table_insert (local_refs, g_strdup (refname), checksum);
|
||||
}
|
||||
|
||||
g_variant_dict_init (&dict, extensions);
|
||||
g_variant_dict_lookup (&dict, "xa.title", "s", &local_title);
|
||||
g_debug ("Summary title: %s", local_title);
|
||||
g_variant_dict_end (&dict);
|
||||
}
|
||||
|
||||
*refs = g_hash_table_ref (local_refs);
|
||||
*title = g_strdup (local_title);
|
||||
|
||||
ret = TRUE;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __XDG_APP_UTILS_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <ostree.h>
|
||||
|
||||
const char * xdg_app_get_arch (void);
|
||||
|
||||
|
@ -33,6 +34,12 @@ gboolean xdg_app_remove_dangling_symlinks (GFile *dir,
|
|||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
gboolean ostree_repo_load_summary (const char *repository_url,
|
||||
GHashTable **refs,
|
||||
gchar **title,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2,43,1)
|
||||
static inline gboolean
|
||||
g_strv_contains (const gchar * const *strv,
|
||||
|
|
Loading…
Reference in New Issue