mirror of
https://github.com/flatpak/flatpak.git
synced 2026-05-19 06:11:47 -04:00
uninstall: Support multiple REFs
This commit is contained in:
@@ -49,79 +49,105 @@ static GOptionEntry options[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static gboolean
|
||||
looks_like_branch (const char *branch)
|
||||
{
|
||||
/* In particular, / is not a valid branch char, so
|
||||
this lets us distinguish full or partial refs as
|
||||
non-branches. */
|
||||
if (!flatpak_is_valid_branch (branch, NULL))
|
||||
return FALSE;
|
||||
|
||||
/* Dots are allowed in branches, but not really used much, while
|
||||
they are required for app ids, so thats a good check to
|
||||
distinguish the two */
|
||||
if (strchr (branch, '.') != NULL)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
flatpak_builtin_uninstall (int argc, char **argv, GCancellable *cancellable, GError **error)
|
||||
{
|
||||
g_autoptr(GOptionContext) context = NULL;
|
||||
g_autoptr(FlatpakDir) dir = NULL;
|
||||
const char *pref = NULL;
|
||||
char **prefs = NULL;
|
||||
int i, j, n_prefs;
|
||||
const char *default_branch = NULL;
|
||||
g_autofree char *ref = NULL;
|
||||
FlatpakHelperUninstallFlags flags = 0;
|
||||
g_autoptr(GPtrArray) related = NULL;
|
||||
FlatpakKinds kinds;
|
||||
FlatpakKinds kind;
|
||||
g_autofree char *id = NULL;
|
||||
g_autofree char *arch = NULL;
|
||||
g_autofree char *branch = NULL;
|
||||
int i;
|
||||
g_autoptr(GHashTable) uninstall_refs_hash = NULL;
|
||||
g_autoptr(GPtrArray) uninstall_refs = NULL;
|
||||
|
||||
context = g_option_context_new (_("NAME [BRANCH] - Uninstall an application"));
|
||||
context = g_option_context_new (_("REF... - Uninstall an application"));
|
||||
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
|
||||
|
||||
if (!flatpak_option_context_parse (context, options, &argc, &argv, 0, &dir, cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (argc < 2)
|
||||
return usage_error (context, _("NAME must be specified"), error);
|
||||
return usage_error (context, _("Must specify at least one REF"), error);
|
||||
|
||||
if (argc > 3)
|
||||
return usage_error (context, _("Too many arguments"), error);
|
||||
prefs = &argv[1];
|
||||
n_prefs = argc - 1;
|
||||
|
||||
pref = argv[1];
|
||||
if (argc > 2)
|
||||
default_branch = argv[2];
|
||||
/* Backwards compat for old "REPOSITORY NAME [BRANCH]" argument version */
|
||||
if (argc == 3 && looks_like_branch (argv[2]))
|
||||
{
|
||||
default_branch = argv[2];
|
||||
n_prefs = 1;
|
||||
}
|
||||
|
||||
kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);
|
||||
uninstall_refs = g_ptr_array_new_with_free_func (g_free);
|
||||
uninstall_refs_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
|
||||
|
||||
if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, default_branch,
|
||||
&kinds, &id, &arch, &branch, error))
|
||||
return FALSE;
|
||||
|
||||
ref = flatpak_dir_find_installed_ref (dir, id, branch, arch,
|
||||
kinds, &kind, error);
|
||||
if (ref == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* TODO: when removing runtimes, look for apps that use it, require --force */
|
||||
|
||||
if (opt_keep_ref)
|
||||
flags |= FLATPAK_HELPER_UNINSTALL_FLAGS_KEEP_REF;
|
||||
if (opt_force_remove)
|
||||
flags |= FLATPAK_HELPER_UNINSTALL_FLAGS_FORCE_REMOVE;
|
||||
|
||||
if (!opt_no_related)
|
||||
for (j = 0; j < n_prefs; j++)
|
||||
{
|
||||
const char *pref = NULL;
|
||||
FlatpakKinds matched_kinds;
|
||||
g_autofree char *id = NULL;
|
||||
g_autofree char *arch = NULL;
|
||||
g_autofree char *branch = NULL;
|
||||
g_autoptr(GError) local_error = NULL;
|
||||
g_autofree char *origin = NULL;
|
||||
|
||||
pref = prefs[j];
|
||||
|
||||
if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, default_branch,
|
||||
&matched_kinds, &id, &arch, &branch, error))
|
||||
return FALSE;
|
||||
|
||||
ref = flatpak_dir_find_installed_ref (dir, id, branch, arch,
|
||||
kinds, &kind, error);
|
||||
if (ref == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (g_hash_table_insert (uninstall_refs_hash, g_strdup (ref), NULL))
|
||||
g_ptr_array_add (uninstall_refs, g_strdup (ref));
|
||||
|
||||
/* TODO: when removing runtimes, look for apps that use it, require --force */
|
||||
|
||||
if (opt_no_related)
|
||||
continue;
|
||||
|
||||
origin = flatpak_dir_get_origin (dir, ref, NULL, NULL);
|
||||
if (origin)
|
||||
if (origin == NULL)
|
||||
continue;
|
||||
|
||||
related = flatpak_dir_find_local_related (dir, ref, origin,
|
||||
NULL, &local_error);
|
||||
if (related == NULL)
|
||||
{
|
||||
related = flatpak_dir_find_local_related (dir, ref, origin,
|
||||
NULL, &local_error);
|
||||
if (related == NULL)
|
||||
g_printerr (_("Warning: Problem looking for related refs: %s\n"),
|
||||
local_error->message);
|
||||
g_printerr (_("Warning: Problem looking for related refs: %s\n"),
|
||||
local_error->message);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!flatpak_dir_uninstall (dir, ref, flags,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
|
||||
if (related != NULL)
|
||||
{
|
||||
for (i = 0; i < related->len; i++)
|
||||
{
|
||||
FlatpakRelated *rel = g_ptr_array_index (related, i);
|
||||
@@ -132,15 +158,26 @@ flatpak_builtin_uninstall (int argc, char **argv, GCancellable *cancellable, GEr
|
||||
continue;
|
||||
|
||||
parts = g_strsplit (rel->ref, "/", 0);
|
||||
g_print (_("Uninstalling related: %s\n"), parts[1]);
|
||||
|
||||
if (!flatpak_dir_uninstall (dir, rel->ref, flags,
|
||||
cancellable, &local_error))
|
||||
g_printerr (_("Warning: Failed to uninstall related ref: %s\n"),
|
||||
rel->ref);
|
||||
if (g_hash_table_insert (uninstall_refs_hash, g_strdup (rel->ref), NULL))
|
||||
g_ptr_array_add (uninstall_refs, g_strdup (rel->ref));
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_keep_ref)
|
||||
flags |= FLATPAK_HELPER_UNINSTALL_FLAGS_KEEP_REF;
|
||||
if (opt_force_remove)
|
||||
flags |= FLATPAK_HELPER_UNINSTALL_FLAGS_FORCE_REMOVE;
|
||||
|
||||
for (i = 0; i < uninstall_refs->len; i++)
|
||||
{
|
||||
const char *ref = (char *)g_ptr_array_index (uninstall_refs, i);
|
||||
g_print ("uninstalling %s\n", ref);
|
||||
if (!flatpak_dir_uninstall (dir, ref, flags,
|
||||
cancellable, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -152,7 +189,6 @@ flatpak_complete_uninstall (FlatpakCompletion *completion)
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_auto(GStrv) refs = NULL;
|
||||
FlatpakKinds kinds;
|
||||
int i;
|
||||
|
||||
context = g_option_context_new ("");
|
||||
if (!flatpak_option_context_parse (context, options, &completion->argc, &completion->argv, 0, &dir, NULL, NULL))
|
||||
@@ -163,37 +199,11 @@ flatpak_complete_uninstall (FlatpakCompletion *completion)
|
||||
switch (completion->argc)
|
||||
{
|
||||
case 0:
|
||||
case 1: /* NAME */
|
||||
default: /* REF */
|
||||
flatpak_complete_options (completion, global_entries);
|
||||
flatpak_complete_options (completion, options);
|
||||
flatpak_complete_options (completion, user_entries);
|
||||
|
||||
refs = flatpak_dir_find_installed_refs (dir, NULL, NULL, opt_arch,
|
||||
kinds, &error);
|
||||
if (refs == NULL)
|
||||
flatpak_completion_debug ("find installed refs error: %s", error->message);
|
||||
for (i = 0; refs != NULL && refs[i] != NULL; i++)
|
||||
{
|
||||
g_auto(GStrv) parts = flatpak_decompose_ref (refs[i], NULL);
|
||||
if (parts)
|
||||
flatpak_complete_word (completion, "%s ", parts[1]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /* Branch */
|
||||
refs = flatpak_dir_find_installed_refs (dir, completion->argv[1], NULL, opt_arch,
|
||||
kinds, &error);
|
||||
if (refs == NULL)
|
||||
flatpak_completion_debug ("find installed refs error: %s", error->message);
|
||||
for (i = 0; refs != NULL && refs[i] != NULL; i++)
|
||||
{
|
||||
g_auto(GStrv) parts = flatpak_decompose_ref (refs[i], NULL);
|
||||
if (parts)
|
||||
flatpak_complete_word (completion, "%s ", parts[3]);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
flatpak_complete_partial_ref (completion, kinds, opt_arch, dir, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,8 +32,7 @@
|
||||
<cmdsynopsis>
|
||||
<command>flatpak uninstall</command>
|
||||
<arg choice="opt" rep="repeat">OPTION</arg>
|
||||
<arg choice="plain">NAME</arg>
|
||||
<arg choice="opt">BRANCH</arg>
|
||||
<arg choice="opt" rep="repeat">REF</arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
@@ -41,12 +40,17 @@
|
||||
<title>Description</title>
|
||||
|
||||
<para>
|
||||
Uninstalls an application or runtime. The <arg choice="plain">NAME</arg>,
|
||||
<arg choice="plain">ARCH</arg> and <arg choice="plain">BRANCH</arg>
|
||||
arguments must identify an installed application.
|
||||
If <arg choice="plain">BRANCH</arg> is not specified, it defaults
|
||||
to whatever is installed, unless there are multiple versions, then you
|
||||
have to specify a branch.
|
||||
Uninstalls an application or runtime. <arg choice="plain">REF</arg> is a reference to the
|
||||
application or runtime to install. If no <arg choice="plain">REF</arg> is given, everything
|
||||
is updated.
|
||||
</para>
|
||||
<para>
|
||||
Each <arg choice="plain">REF</arg> arguments is a full or partial indentifier in the
|
||||
flatpak ref format, which looks like "(app|runtime)/ID/ARCH/BRANCH". All elements
|
||||
except ID are optional and can be left out, including the slashes,
|
||||
so most of the time you need only specify ID. Any part left out will be matched
|
||||
against what is installed, and if there are multiple matches an error message
|
||||
will list the alternatives.
|
||||
</para>
|
||||
<para>
|
||||
By default this looks for both installed apps and runtime
|
||||
|
||||
Reference in New Issue
Block a user