Skip to content

Commit

Permalink
cli-transaction: Better handling of EOL refs
Browse files Browse the repository at this point in the history
We remember what action we took for EOLs, and for sub-refs (ie .Locale)
we reuse that.

Also, we show if eol:ed refs are pinned (as that makes them not be
auto-uninstalled), and we list the apps that use the eol:ed runtime
ref.

Example run:
```
Looking for updates…
Info: (pinned) org.gnome.Sdk.Compat.i386 is end-of-life, with reason:
   The GNOME 3.34 runtime is no longer supported as of 14th August 2020. Please ask your application developer to migrate to a supported platform.
Info: org.gnome.Platform is end-of-life, with reason:
   The GNOME 3.32 runtime is no longer supported as of 11th March 2020. Please ask your application developer to migrate to a supported platform.
Applications using this runtime:
   org.gnome.HexGL
```
  • Loading branch information
alexlarsson committed Nov 16, 2020
1 parent 39333fd commit 7eb5f4d
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 22 deletions.
147 changes: 126 additions & 21 deletions app/flatpak-cli-transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ struct _FlatpakCliTransaction
gboolean non_default_arch;
GError *first_operation_error;

GHashTable *eol_actions;

int rows;
int cols;
int table_width;
Expand Down Expand Up @@ -641,49 +643,148 @@ basic_auth_start (FlatpakTransaction *transaction,
}


typedef enum {
EOL_UNDECIDED,
EOL_IGNORE, /* Don't do anything, we already printed a warning */
EOL_NO_REBASE, /* Choose to not rebase */
EOL_REBASE, /* Choose to rebase */
} EolAction;

static gboolean
end_of_lifed_with_rebase (FlatpakTransaction *transaction,
const char *remote,
const char *ref,
const char *ref_str,
const char *reason,
const char *rebased_to_ref,
const char **previous_ids)
{
FlatpakCliTransaction *self = FLATPAK_CLI_TRANSACTION (transaction);
g_autoptr(FlatpakRef) rref = flatpak_ref_parse (ref, NULL);
g_autoptr(FlatpakDecomposed) ref = flatpak_decomposed_new_from_ref (ref_str, NULL);
g_autofree char *name = NULL;
EolAction action = EOL_UNDECIDED;
EolAction old_action = EOL_UNDECIDED;
gboolean can_rebase = rebased_to_ref != NULL && remote != NULL;
FlatpakInstallation *installation = flatpak_transaction_get_installation (transaction);
FlatpakDir *dir = flatpak_installation_get_dir (installation, NULL);

if (ref == NULL)
return FALSE; /* Shouldn't happen, the ref should be valid */

name = flatpak_decomposed_dup_id (ref);

self->did_interaction = TRUE;

if (rebased_to_ref)
g_print (_("Info: %s is end-of-life, in favor of %s\n"), flatpak_ref_get_name (rref), rebased_to_ref);
else if (reason)
g_print (_("Info: %s is end-of-life, with reason: %s\n"), flatpak_ref_get_name (rref), reason);
if (flatpak_decomposed_id_is_subref (ref))
{
GLNX_HASH_TABLE_FOREACH_KV (self->eol_actions, FlatpakDecomposed *, eoled_ref, gpointer, value)
{
guint old_eol_action = GPOINTER_TO_UINT (value);

if (flatpak_decomposed_id_is_subref_of (ref, eoled_ref))
{
old_action = old_eol_action; /* Do the same */
break;
}
}
}

if (rebased_to_ref && remote)
if (old_action != EOL_UNDECIDED)
{
if (self->disable_interaction ||
flatpak_yes_no_prompt (TRUE, _("Replace it with %s?"), rebased_to_ref))
switch (old_action)
{
g_autoptr(GError) error = NULL;
default:
case EOL_IGNORE:
if (!can_rebase)
action = EOL_IGNORE;
/* Else, ask if we want to rebase */
break;
case EOL_REBASE:
case EOL_NO_REBASE:
if (can_rebase)
action = old_action;
else
action = EOL_IGNORE;
}
}

if (self->disable_interaction)
g_print (_("Updating to rebased version\n"));
if (action == EOL_UNDECIDED)
{
gboolean is_pinned = flatpak_dir_ref_is_pinned (dir, flatpak_decomposed_get_ref (ref));
action = EOL_IGNORE;

if (rebased_to_ref)
if (is_pinned)
g_print (_("Info: (pinned) %s is end-of-life, in favor of %s\n"), name, rebased_to_ref);
else
g_print (_("Info: %s is end-of-life, in favor of %s\n"), name, rebased_to_ref);
else if (reason)
{
if (is_pinned)
g_print (_("Info: (pinned) %s is end-of-life, with reason:\n"), name);
else
g_print (_("Info: %s is end-of-life, with reason:\n"), name);
g_print (" %s\n", reason);
}

if (!flatpak_transaction_add_uninstall (transaction, ref, &error) ||
!flatpak_transaction_add_rebase (transaction, remote, rebased_to_ref, NULL, previous_ids, &error))
if (flatpak_decomposed_is_runtime (ref))
{
g_autoptr(GPtrArray) apps = flatpak_dir_list_app_refs_with_runtime (dir, ref, NULL, NULL);
if (apps && apps->len > 0)
{
g_propagate_prefixed_error (&self->first_operation_error,
g_error_copy (error),
_("Failed to rebase %s to %s: "),
flatpak_ref_get_name (rref), rebased_to_ref);
return FALSE;
g_print (_("Applications using this runtime:\n"));
g_print (" ");
for (int i = 0; i < apps->len; i++)
{
FlatpakDecomposed *app_ref = g_ptr_array_index (apps, i);
g_autofree char *id = flatpak_decomposed_dup_id (app_ref);
if (i != 0)
g_print (", ");
g_print ("%s", id);
}
g_print ("\n");
}
}

return TRUE;
if (rebased_to_ref && remote)
{
if (self->disable_interaction ||
flatpak_yes_no_prompt (TRUE, _("Replace it with %s?"), rebased_to_ref))
{
if (self->disable_interaction)
g_print (_("Updating to rebased version\n"));

action = EOL_REBASE;
}
else
action = EOL_NO_REBASE;
}
}
else
{
g_debug ("%s is end-of-life, using action from parent ren", name);
}

return FALSE;
/* Cache for later comparison and reuse */
g_hash_table_insert (self->eol_actions, flatpak_decomposed_ref (ref), GUINT_TO_POINTER (action));

if (action == EOL_REBASE)
{
g_autoptr(GError) error = NULL;

if (!flatpak_transaction_add_uninstall (transaction, ref_str, &error) ||
!flatpak_transaction_add_rebase (transaction, remote, rebased_to_ref, NULL, previous_ids, &error))
{
g_propagate_prefixed_error (&self->first_operation_error,
g_error_copy (error),
_("Failed to rebase %s to %s: "),
name, rebased_to_ref);
return FALSE;
}

return TRUE; /* skip update op, in favour of added uninstall */
}
else /* IGNORE or NO_REBASE */
return FALSE;
}

static int
Expand Down Expand Up @@ -1203,6 +1304,8 @@ flatpak_cli_transaction_finalize (GObject *object)

g_free (self->progress_msg);

g_hash_table_unref (self->eol_actions);

if (self->printer)
flatpak_table_printer_free (self->printer);

Expand All @@ -1212,6 +1315,8 @@ flatpak_cli_transaction_finalize (GObject *object)
static void
flatpak_cli_transaction_init (FlatpakCliTransaction *self)
{
self->eol_actions = g_hash_table_new_full ((GHashFunc)flatpak_decomposed_hash, (GEqualFunc)flatpak_decomposed_equal,
(GDestroyNotify)flatpak_decomposed_unref, NULL);
}

static gboolean flatpak_cli_transaction_run (FlatpakTransaction *transaction,
Expand Down
3 changes: 2 additions & 1 deletion tests/test-repo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,8 @@ ${FLATPAK} ${U} remote-ls -d -a test-repo > remote-ls-log
assert_file_has_content remote-ls-log "app/org\.test\.Hello/.*eol=Reason2"

${FLATPAK} ${U} update -y org.test.Hello > update-log
assert_file_has_content update-log "org\.test\.Hello.*Reason2"
assert_file_has_content update-log "org\.test\.Hello.*end-of-life"
assert_file_has_content update-log "Reason2"

${FLATPAK} ${U} info org.test.Hello > info-log
assert_file_has_content info-log "End-of-life: Reason2"
Expand Down

0 comments on commit 7eb5f4d

Please sign in to comment.