forked from Mirrors/flatpak-builder
Add support for subpath limited installs
This allows you to install e.g. org.freedesktop.Platform.Locale but only the /sv subdir, and replaces using separate branches for each locale.tingping/wmclass
parent
545a699698
commit
3cc45ccf13
|
@ -36,6 +36,7 @@
|
|||
|
||||
static char *opt_arch;
|
||||
static char **opt_gpg_file;
|
||||
static char **opt_subpaths;
|
||||
static gboolean opt_no_pull;
|
||||
static gboolean opt_no_deploy;
|
||||
static gboolean opt_runtime;
|
||||
|
@ -50,6 +51,7 @@ static GOptionEntry options[] = {
|
|||
{ "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, "Look for app with the specified name", },
|
||||
{ "bundle", 0, 0, G_OPTION_ARG_NONE, &opt_bundle, "Install from local bundle file", },
|
||||
{ "gpg-file", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_gpg_file, "Check bundle signatures with GPG key from FILE (- for stdin)", "FILE" },
|
||||
{ "subpath", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_subpaths, "Only install this subpath", "path" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -286,7 +288,7 @@ xdg_app_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro
|
|||
|
||||
if (!opt_no_pull)
|
||||
{
|
||||
if (!xdg_app_dir_pull (dir, repository, ref, NULL,
|
||||
if (!xdg_app_dir_pull (dir, repository, ref, opt_subpaths, NULL,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -306,6 +308,10 @@ xdg_app_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro
|
|||
if (!xdg_app_dir_set_origin (dir, ref, repository, cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!xdg_app_dir_set_subpaths (dir, ref, (const char **)opt_subpaths,
|
||||
cancellable, error))
|
||||
goto out;
|
||||
|
||||
if (!xdg_app_dir_deploy (dir, ref, NULL, cancellable, error))
|
||||
goto out;
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
static char *opt_arch;
|
||||
static char *opt_commit;
|
||||
static char **opt_subpaths;
|
||||
static gboolean opt_force_remove;
|
||||
static gboolean opt_no_pull;
|
||||
static gboolean opt_no_deploy;
|
||||
|
@ -49,6 +50,7 @@ static GOptionEntry options[] = {
|
|||
{ "runtime", 0, 0, G_OPTION_ARG_NONE, &opt_runtime, "Look for runtime with the specified name", },
|
||||
{ "app", 0, 0, G_OPTION_ARG_NONE, &opt_app, "Look for app with the specified name", },
|
||||
{ "appstream", 0, 0, G_OPTION_ARG_NONE, &opt_appstream, "Update appstream for remote", },
|
||||
{ "subpath", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &opt_subpaths, "Only update this subpath", "path" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -75,6 +77,7 @@ do_update (XdgAppDir* dir,
|
|||
{
|
||||
g_autofree char *ref = NULL;
|
||||
g_autofree char *repository = NULL;
|
||||
g_auto(GStrv) subpaths = NULL;
|
||||
gboolean was_updated = FALSE;
|
||||
gboolean is_app;
|
||||
g_auto(GLnxLockFile) lock = GLNX_LOCK_FILE_INIT;
|
||||
|
@ -92,10 +95,14 @@ do_update (XdgAppDir* dir,
|
|||
if (repository == NULL)
|
||||
return FALSE;
|
||||
|
||||
subpaths = xdg_app_dir_get_subpaths (dir, ref, cancellable, error);
|
||||
if (subpaths == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!opt_no_pull)
|
||||
{
|
||||
if (!xdg_app_dir_pull (dir, repository, ref, NULL,
|
||||
cancellable, error))
|
||||
if (!xdg_app_dir_pull (dir, repository, ref, opt_subpaths ? opt_subpaths : subpaths,
|
||||
NULL, cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -521,6 +521,80 @@ xdg_app_dir_set_origin (XdgAppDir *self,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
char **
|
||||
xdg_app_dir_get_subpaths (XdgAppDir *self,
|
||||
const char *ref,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GFile) deploy_base = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autofree char *data = NULL;
|
||||
g_autoptr(GError) my_error = NULL;
|
||||
g_autoptr(GPtrArray) subpaths = NULL;
|
||||
g_auto(GStrv) lines = NULL;
|
||||
int i;
|
||||
|
||||
deploy_base = xdg_app_dir_get_deploy_dir (self, ref);
|
||||
if (!g_file_query_exists (deploy_base, cancellable))
|
||||
{
|
||||
xdg_app_fail (error, "%s is not installed", ref);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
file = g_file_get_child (deploy_base, "subpaths");
|
||||
if (!g_file_load_contents (file, cancellable, &data, NULL, NULL, &my_error))
|
||||
{
|
||||
if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
|
||||
data = g_strdup ("");
|
||||
else
|
||||
g_propagate_error (error, g_steal_pointer (&my_error));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lines = g_strsplit (data, "\n", 0);
|
||||
|
||||
subpaths = g_ptr_array_new ();
|
||||
for (i = 0; lines[i] != NULL; i++)
|
||||
{
|
||||
lines[i] = g_strstrip (lines[i]);
|
||||
if (lines[i][0] == '/')
|
||||
g_ptr_array_add (subpaths, g_strdup (lines[i]));
|
||||
}
|
||||
|
||||
g_ptr_array_add (subpaths, NULL);
|
||||
return (char **)g_ptr_array_free (subpaths, FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
xdg_app_dir_set_subpaths (XdgAppDir *self,
|
||||
const char *ref,
|
||||
const char **subpaths,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GFile) deploy_base = NULL;
|
||||
g_autoptr(GFile) file = NULL;
|
||||
g_autofree char *data = NULL;
|
||||
|
||||
deploy_base = xdg_app_dir_get_deploy_dir (self, ref);
|
||||
if (!g_file_query_exists (deploy_base, cancellable))
|
||||
{
|
||||
xdg_app_fail (error, "%s is not installed", ref);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
data = g_strjoinv ("\n", (char **)subpaths);
|
||||
|
||||
file = g_file_get_child (deploy_base, "subpaths");
|
||||
if (!g_file_replace_contents (file, data, strlen (data), NULL, FALSE,
|
||||
G_FILE_CREATE_NONE, NULL, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
xdg_app_dir_ensure_path (XdgAppDir *self,
|
||||
GCancellable *cancellable,
|
||||
|
@ -690,7 +764,7 @@ xdg_app_dir_update_appstream (XdgAppDir *self,
|
|||
if (!ostree_repo_resolve_rev (self->repo, remote_and_branch, TRUE, &old_checksum, error))
|
||||
return FALSE;
|
||||
|
||||
if (!xdg_app_dir_pull (self, remote, branch, progress,
|
||||
if (!xdg_app_dir_pull (self, remote, branch, NULL, progress,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
|
@ -785,10 +859,45 @@ xdg_app_dir_update_appstream (XdgAppDir *self,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* This is a copy of ostree_repo_pull_one_dir that always disables
|
||||
static deltas if subdir is used */
|
||||
static gboolean
|
||||
repo_pull_one_dir (OstreeRepo *self,
|
||||
const char *remote_name,
|
||||
const char *dir_to_pull,
|
||||
char **refs_to_fetch,
|
||||
OstreeRepoPullFlags flags,
|
||||
OstreeAsyncProgress *progress,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
||||
|
||||
if (dir_to_pull)
|
||||
{
|
||||
g_variant_builder_add (&builder, "{s@v}", "subdir",
|
||||
g_variant_new_variant (g_variant_new_string (dir_to_pull)));
|
||||
g_variant_builder_add (&builder, "{s@v}", "disable-static-deltas",
|
||||
g_variant_new_variant (g_variant_new_boolean (TRUE)));
|
||||
}
|
||||
|
||||
g_variant_builder_add (&builder, "{s@v}", "flags",
|
||||
g_variant_new_variant (g_variant_new_int32 (flags)));
|
||||
if (refs_to_fetch)
|
||||
g_variant_builder_add (&builder, "{s@v}", "refs",
|
||||
g_variant_new_variant (g_variant_new_strv ((const char *const*) refs_to_fetch, -1)));
|
||||
|
||||
return ostree_repo_pull_with_options (self, remote_name, g_variant_builder_end (&builder),
|
||||
progress, cancellable, error);
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
xdg_app_dir_pull (XdgAppDir *self,
|
||||
const char *repository,
|
||||
const char *ref,
|
||||
char **subpaths,
|
||||
OstreeAsyncProgress *progress,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
|
@ -825,13 +934,46 @@ xdg_app_dir_pull (XdgAppDir *self,
|
|||
refs[0] = ref;
|
||||
refs[1] = NULL;
|
||||
|
||||
if (!ostree_repo_pull (self->repo, repository,
|
||||
(char **)refs, OSTREE_REPO_PULL_FLAGS_NONE,
|
||||
progress,
|
||||
cancellable, error))
|
||||
if (subpaths == NULL || subpaths[0] == NULL)
|
||||
{
|
||||
g_prefix_error (error, "While pulling %s from remote %s: ", ref, repository);
|
||||
goto out;
|
||||
if (!ostree_repo_pull (self->repo, repository,
|
||||
(char **)refs, OSTREE_REPO_PULL_FLAGS_NONE,
|
||||
progress,
|
||||
cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "While pulling %s from remote %s: ", ref, repository);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!repo_pull_one_dir (self->repo, repository,
|
||||
"/metadata",
|
||||
(char **)refs, OSTREE_REPO_PULL_FLAGS_NONE,
|
||||
progress,
|
||||
cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "While pulling %s from remote %s, metadata: ",
|
||||
ref, repository);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; subpaths[i] != NULL; i++)
|
||||
{
|
||||
g_autofree char *subpath = g_build_filename ("/files", subpaths[i], NULL);
|
||||
if (!repo_pull_one_dir (self->repo, repository,
|
||||
subpath,
|
||||
(char **)refs, OSTREE_REPO_PULL_FLAGS_NONE,
|
||||
progress,
|
||||
cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "While pulling %s from remote %s, subpath %s: ",
|
||||
ref, repository, subpaths[i]);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
@ -1916,6 +2058,7 @@ xdg_app_dir_deploy (XdgAppDir *self,
|
|||
g_autoptr(GFile) export = NULL;
|
||||
g_autoptr(OstreeAsyncProgress) progress = NULL;
|
||||
g_autoptr(GKeyFile) keyfile = NULL;
|
||||
g_auto(GStrv) subpaths = NULL;
|
||||
|
||||
if (!xdg_app_dir_ensure_repo (self, cancellable, error))
|
||||
return FALSE;
|
||||
|
@ -1969,20 +2112,73 @@ xdg_app_dir_deploy (XdgAppDir *self,
|
|||
if (file_info == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!ostree_repo_checkout_tree (self->repo,
|
||||
OSTREE_REPO_CHECKOUT_MODE_USER,
|
||||
OSTREE_REPO_CHECKOUT_OVERWRITE_NONE,
|
||||
checkoutdir,
|
||||
OSTREE_REPO_FILE (root), file_info,
|
||||
cancellable, error))
|
||||
{
|
||||
g_autofree char *rootpath = NULL;
|
||||
g_autofree char *checkoutpath = NULL;
|
||||
subpaths = xdg_app_dir_get_subpaths (self, ref, cancellable, error);
|
||||
if (subpaths == NULL)
|
||||
return FALSE;
|
||||
|
||||
rootpath = g_file_get_path (root);
|
||||
checkoutpath = g_file_get_path (checkoutdir);
|
||||
g_prefix_error (error, "While trying to checkout %s into %s: ", rootpath, checkoutpath);
|
||||
return FALSE;
|
||||
if (*subpaths == NULL)
|
||||
{
|
||||
if (!ostree_repo_checkout_tree (self->repo,
|
||||
OSTREE_REPO_CHECKOUT_MODE_USER,
|
||||
OSTREE_REPO_CHECKOUT_OVERWRITE_NONE,
|
||||
checkoutdir,
|
||||
OSTREE_REPO_FILE (root), file_info,
|
||||
cancellable, error))
|
||||
{
|
||||
g_autofree char *rootpath = NULL;
|
||||
g_autofree char *checkoutpath = NULL;
|
||||
|
||||
rootpath = g_file_get_path (root);
|
||||
checkoutpath = g_file_get_path (checkoutdir);
|
||||
g_prefix_error (error, "While trying to checkout %s into %s: ", rootpath, checkoutpath);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OstreeRepoCheckoutOptions options = { 0, };
|
||||
g_autofree char *checkoutdirpath = g_file_get_path (checkoutdir);
|
||||
g_autoptr(GFile) files = g_file_get_child (checkoutdir, "files");
|
||||
int i;
|
||||
|
||||
if (!g_file_make_directory_with_parents (files, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
options.mode = OSTREE_REPO_CHECKOUT_MODE_USER;
|
||||
options.overwrite_mode = OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES;
|
||||
options.subpath = "/metadata";
|
||||
|
||||
access ("checkout metadata", 0);
|
||||
if (!ostree_repo_checkout_tree_at (self->repo, &options,
|
||||
AT_FDCWD, checkoutdirpath,
|
||||
checksum,
|
||||
cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "While trying to checkout metadata subpath: ");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; subpaths[i] != NULL; i++)
|
||||
{
|
||||
g_autofree char *subpath = g_build_filename ("/files", subpaths[i], NULL);
|
||||
g_autofree char *dstpath = g_build_filename (checkoutdirpath, "/files", subpaths[i], NULL);
|
||||
g_autofree char *dstpath_parent = g_path_get_dirname (dstpath);
|
||||
if (g_mkdir_with_parents (dstpath_parent, 0755))
|
||||
{
|
||||
glnx_set_error_from_errno (error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
options.subpath = subpath;
|
||||
if (!ostree_repo_checkout_tree_at (self->repo, &options,
|
||||
AT_FDCWD, dstpath,
|
||||
checksum,
|
||||
cancellable, error))
|
||||
{
|
||||
g_prefix_error (error, "While trying to checkout metadata subpath: ");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dotref = g_file_resolve_relative_path (checkoutdir, "files/.ref");
|
||||
|
|
|
@ -88,6 +88,15 @@ gboolean xdg_app_dir_set_origin (XdgAppDir *self,
|
|||
const char *remote,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
char ** xdg_app_dir_get_subpaths (XdgAppDir *self,
|
||||
const char *ref,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
gboolean xdg_app_dir_set_subpaths (XdgAppDir *self,
|
||||
const char *ref,
|
||||
const char **subpaths,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
GFile * xdg_app_dir_get_exports_dir (XdgAppDir *self);
|
||||
GFile * xdg_app_dir_get_removed_dir (XdgAppDir *self);
|
||||
GFile * xdg_app_dir_get_if_deployed (XdgAppDir *self,
|
||||
|
@ -144,6 +153,7 @@ gboolean xdg_app_dir_update_appstream(XdgAppDir *self,
|
|||
gboolean xdg_app_dir_pull (XdgAppDir *self,
|
||||
const char *repository,
|
||||
const char *ref,
|
||||
char **subpaths,
|
||||
OstreeAsyncProgress *progress,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
|
|
@ -104,6 +104,15 @@
|
|||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--subpath=PATH</option></term>
|
||||
|
||||
<listitem><para>
|
||||
Install only a subpath of the ref. This is mainly used to install a subset of locales.
|
||||
This can be added multiple times to install multiple subpaths.,
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--no-deploy</option></term>
|
||||
|
||||
|
|
|
@ -111,6 +111,16 @@
|
|||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--subpath=PATH</option></term>
|
||||
|
||||
<listitem><para>
|
||||
Install only a subpath of the ref. This is mainly used to install a subset of locales.
|
||||
This can be added multiple times to install multiple subpaths.
|
||||
If this is not specified the subpaths specified at install time are reused.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--commit=COMMIT</option></term>
|
||||
|
||||
|
|
|
@ -290,6 +290,7 @@ get_ref (XdgAppInstallation *self,
|
|||
g_autoptr(GFile) deploy_subdir = NULL;
|
||||
g_autofree char *deploy_path = NULL;
|
||||
g_autofree char *latest_commit = NULL;
|
||||
g_auto(GStrv) subpaths = NULL;
|
||||
gboolean is_current = FALSE;
|
||||
guint64 installed_size = 0;
|
||||
|
||||
|
@ -297,6 +298,8 @@ get_ref (XdgAppInstallation *self,
|
|||
|
||||
origin = xdg_app_dir_get_origin (priv->dir, full_ref, NULL, NULL);
|
||||
commit = xdg_app_dir_read_active (priv->dir, full_ref, cancellable);
|
||||
subpaths = xdg_app_dir_get_subpaths (priv->dir, full_ref, cancellable, NULL);
|
||||
|
||||
deploy_dir = xdg_app_dir_get_deploy_dir (priv->dir, full_ref);
|
||||
if (deploy_dir && commit)
|
||||
{
|
||||
|
@ -323,7 +326,7 @@ get_ref (XdgAppInstallation *self,
|
|||
return xdg_app_installed_ref_new (full_ref,
|
||||
commit,
|
||||
latest_commit,
|
||||
origin,
|
||||
origin, subpaths,
|
||||
deploy_path,
|
||||
installed_size,
|
||||
is_current);
|
||||
|
@ -992,7 +995,7 @@ xdg_app_installation_install (XdgAppInstallation *self,
|
|||
g_object_set_data (G_OBJECT (ostree_progress), "last_progress", GUINT_TO_POINTER(0));
|
||||
}
|
||||
|
||||
if (!xdg_app_dir_pull (dir_clone, remote_name, ref,
|
||||
if (!xdg_app_dir_pull (dir_clone, remote_name, ref, NULL,
|
||||
ostree_progress, cancellable, error))
|
||||
goto out;
|
||||
|
||||
|
@ -1088,6 +1091,7 @@ xdg_app_installation_update (XdgAppInstallation *self,
|
|||
XdgAppInstalledRef *result = NULL;
|
||||
gboolean was_updated = FALSE;
|
||||
g_auto(GLnxLockFile) lock = GLNX_LOCK_FILE_INIT;
|
||||
g_auto(GStrv) subpaths = NULL;
|
||||
|
||||
ref = xdg_app_compose_ref (kind == XDG_APP_REF_KIND_APP, name, branch, arch, error);
|
||||
if (ref == NULL)
|
||||
|
@ -1106,6 +1110,10 @@ xdg_app_installation_update (XdgAppInstallation *self,
|
|||
if (remote_name == NULL)
|
||||
return NULL;
|
||||
|
||||
subpaths = xdg_app_dir_get_subpaths (priv->dir, ref, cancellable, error);
|
||||
if (subpaths == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Pull, prune, etc are not threadsafe, so we work on a copy */
|
||||
dir_clone = xdg_app_dir_clone (priv->dir);
|
||||
|
||||
|
@ -1122,7 +1130,7 @@ xdg_app_installation_update (XdgAppInstallation *self,
|
|||
|
||||
if ((flags & XDG_APP_UPDATE_FLAGS_NO_PULL) == 0)
|
||||
{
|
||||
if (!xdg_app_dir_pull (dir_clone, remote_name, ref,
|
||||
if (!xdg_app_dir_pull (dir_clone, remote_name, ref, subpaths,
|
||||
ostree_progress, cancellable, error))
|
||||
goto out;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ XdgAppInstalledRef *xdg_app_installed_ref_new (const char *full_ref,
|
|||
const char *commit,
|
||||
const char *latest_commit,
|
||||
const char *origin,
|
||||
char **subpaths,
|
||||
const char *deploy_dir,
|
||||
guint64 installed_size,
|
||||
gboolean current);
|
||||
|
|
|
@ -44,6 +44,7 @@ struct _XdgAppInstalledRefPrivate
|
|||
char *origin;
|
||||
char *latest_commit;
|
||||
char *deploy_dir;
|
||||
char **subpaths;
|
||||
guint64 installed_size;
|
||||
};
|
||||
|
||||
|
@ -56,7 +57,8 @@ enum {
|
|||
PROP_ORIGIN,
|
||||
PROP_LATEST_COMMIT,
|
||||
PROP_DEPLOY_DIR,
|
||||
PROP_INSTALLED_SIZE
|
||||
PROP_INSTALLED_SIZE,
|
||||
PROP_SUBPATHS
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -67,6 +69,7 @@ xdg_app_installed_ref_finalize (GObject *object)
|
|||
|
||||
g_free (priv->origin);
|
||||
g_free (priv->deploy_dir);
|
||||
g_strfreev (priv->subpaths);
|
||||
|
||||
G_OBJECT_CLASS (xdg_app_installed_ref_parent_class)->finalize (object);
|
||||
}
|
||||
|
@ -105,6 +108,11 @@ xdg_app_installed_ref_set_property (GObject *object,
|
|||
priv->deploy_dir = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_SUBPATHS:
|
||||
g_clear_pointer (&priv->subpaths, g_strfreev);
|
||||
priv->subpaths = g_strdupv (g_value_get_boxed (value));
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -142,6 +150,10 @@ xdg_app_installed_ref_get_property (GObject *object,
|
|||
g_value_set_string (value, priv->deploy_dir);
|
||||
break;
|
||||
|
||||
case PROP_SUBPATHS:
|
||||
g_value_set_boxed (value, priv->subpaths);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -192,6 +204,13 @@ xdg_app_installed_ref_class_init (XdgAppInstalledRefClass *klass)
|
|||
"Where the application is installed",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SUBPATHS,
|
||||
g_param_spec_boxed ("subpaths",
|
||||
"",
|
||||
"",
|
||||
G_TYPE_STRV,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -319,6 +338,7 @@ xdg_app_installed_ref_new (const char *full_ref,
|
|||
const char *commit,
|
||||
const char *latest_commit,
|
||||
const char *origin,
|
||||
char **subpaths,
|
||||
const char *deploy_dir,
|
||||
guint64 installed_size,
|
||||
gboolean is_current)
|
||||
|
@ -332,6 +352,10 @@ xdg_app_installed_ref_new (const char *full_ref,
|
|||
if (strcmp (parts[0], "app") != 0)
|
||||
kind = XDG_APP_REF_KIND_RUNTIME;
|
||||
|
||||
/* Canonicalize the "no subpaths" case */
|
||||
if (subpaths && *subpaths == NULL)
|
||||
subpaths = NULL;
|
||||
|
||||
ref = g_object_new (XDG_APP_TYPE_INSTALLED_REF,
|
||||
"kind", kind,
|
||||
"name", parts[1],
|
||||
|
@ -340,6 +364,7 @@ xdg_app_installed_ref_new (const char *full_ref,
|
|||
"commit", commit,
|
||||
"latest-commit", latest_commit,
|
||||
"origin", origin,
|
||||
"subpaths", subpaths,
|
||||
"is-current", is_current,
|
||||
"installed-size", installed_size,
|
||||
"deploy-dir", deploy_dir,
|
||||
|
|
|
@ -48,12 +48,13 @@ typedef struct {
|
|||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(XdgAppInstalledRef, g_object_unref)
|
||||
#endif
|
||||
|
||||
XDG_APP_EXTERN const char *xdg_app_installed_ref_get_origin (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN guint64 xdg_app_installed_ref_get_installed_size (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN const char *xdg_app_installed_ref_get_deploy_dir (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN const char *xdg_app_installed_ref_get_latest_commit (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN gboolean xdg_app_installed_ref_get_is_current (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN GBytes *xdg_app_installed_ref_load_metadata (XdgAppInstalledRef *self,
|
||||
XDG_APP_EXTERN const char *xdg_app_installed_ref_get_origin (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN const char **xdg_app_installed_ref_get_subpaths (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN guint64 xdg_app_installed_ref_get_installed_size (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN const char *xdg_app_installed_ref_get_deploy_dir (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN const char *xdg_app_installed_ref_get_latest_commit (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN gboolean xdg_app_installed_ref_get_is_current (XdgAppInstalledRef *self);
|
||||
XDG_APP_EXTERN GBytes *xdg_app_installed_ref_load_metadata (XdgAppInstalledRef *self,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
|
|
Loading…
Reference in New Issue