app: Improve checking for dependent apps in EOL messages

flatpak_dir_list_app_refs_with_runtime_extension() only works when the
runtime extension it is passed and the apps it returns are both
installed. Sometimes a end-of-life message is printed for a runtime that
is not installed but is being installed by the current transaction, or a
runtime that is installed but one of the apps that needs it is being
installed by the current transaction. To cover these cases, check the
operations in the current transaction when building informational
messages about EOL runtimes.
This commit is contained in:
Phaedrus Leeds
2022-06-21 14:19:31 -07:00
committed by Phaedrus Leeds
parent e739773056
commit ae0de69b17

View File

@@ -729,6 +729,49 @@ print_eol_info_message (FlatpakDir *dir,
}
}
static void
check_current_transaction_for_dependent_apps (GPtrArray *apps,
FlatpakTransaction *transaction,
FlatpakDecomposed *ref)
{
g_autoptr(FlatpakTransactionOperation) ref_op = NULL;
GPtrArray *related_ops;
ref_op = flatpak_transaction_get_operation_for_ref (transaction, NULL, flatpak_decomposed_get_ref (ref), NULL);
g_assert (ref_op != NULL);
/* Get the related ops to find any apps that use @ref as a runtime or extension */
related_ops = flatpak_transaction_operation_get_related_to_ops (ref_op);
if (related_ops == NULL)
return;
for (int i = 0; i < related_ops->len; i++)
{
FlatpakTransactionOperation *related_op = g_ptr_array_index (related_ops, i);
const char *related_op_ref = flatpak_transaction_operation_get_ref (related_op);
g_autoptr(FlatpakDecomposed) related_op_decomposed = flatpak_decomposed_new_from_ref (related_op_ref, NULL);
if (related_op_decomposed == NULL)
continue;
if (flatpak_decomposed_id_is_subref (related_op_decomposed))
continue;
/* Recurse in case @ref was a runtime extension. We need to check since a
* runtime can have a runtime extension in its related ops in the
* extra-data case, so if we recurse unconditionally it could be infinite
* recursion.
*/
if (flatpak_decomposed_is_runtime (related_op_decomposed))
{
GKeyFile *metadata = flatpak_transaction_operation_get_metadata (ref_op);
if (g_key_file_has_group (metadata, FLATPAK_METADATA_GROUP_EXTENSION_OF))
check_current_transaction_for_dependent_apps (apps, transaction, related_op_decomposed);
}
else if (!g_ptr_array_find_with_equal_func (apps, related_op_decomposed, (GEqualFunc)flatpak_decomposed_equal, NULL))
g_ptr_array_add (apps, g_steal_pointer (&related_op_decomposed));
}
}
static GPtrArray *
find_reverse_dep_apps (FlatpakTransaction *transaction,
FlatpakDir *dir,
@@ -767,6 +810,14 @@ find_reverse_dep_apps (FlatpakTransaction *transaction,
}
}
/* Also check the current transaction since it's possible the EOL ref
* and/or any app(s) that depend on it are not installed. It's also
* possible the current transaction updates one of the apps to a
* newer runtime but we don't handle that yet
* (https://github.com/flatpak/flatpak/issues/4832)
*/
check_current_transaction_for_dependent_apps (apps, transaction, ref);
return g_steal_pointer (&apps);
}