app: Add new extra-languages key

If xa.languages is set, use these, and no others. Otherwise, take the union
of xa.extra-languages, and the system default locales for system repos;
xa.extra-languages for user repo and the langs based on the user's locale

Fixes https://github.com/flatpak/flatpak/issues/3043
This commit is contained in:
Mazen Asef
2019-08-16 11:33:35 -03:00
parent 1678d0cb9f
commit a0666034db
8 changed files with 155 additions and 32 deletions

View File

@@ -69,10 +69,6 @@ parse_lang (const char *value, GError **error)
g_auto(GStrv) strs = NULL;
int i;
if (strcmp (value, "*") == 0 ||
strcmp (value, "*all*") == 0)
return g_strdup ("");
strs = g_strsplit (value, ";", 0);
for (i = 0; strs[i]; i++)
{
@@ -86,12 +82,28 @@ parse_lang (const char *value, GError **error)
return g_strdup (value);
}
static char *
parse_special_lang (const char *value, GError **error)
{
if (strcmp (value, "*") == 0 ||
strcmp (value, "*all*") == 0)
return g_strdup ("");
return parse_lang (value, error);
}
static char *
print_lang (const char *value)
{
return g_strdup (value);
}
static char *
print_special_lang (const char *value)
{
if (*value == 0)
return g_strdup ("*all*");
return g_strdup (value);
return print_lang (value);
}
static char *
@@ -111,7 +123,8 @@ typedef struct
} ConfigKey;
ConfigKey keys[] = {
{ "languages", parse_lang, print_lang, get_lang_default },
{ "languages", parse_special_lang, print_special_lang, get_lang_default },
{ "extra-languages", parse_lang, print_lang, NULL },
};
static ConfigKey *

View File

@@ -14047,17 +14047,37 @@ sort_strv (char **strv)
return strv;
}
static char **
flatpak_dir_get_config_strv (FlatpakDir *self, char *key)
{
GKeyFile *config = flatpak_dir_get_repo_config (self);
g_auto(GStrv) lang = NULL;
if (config)
{
if (g_key_file_has_key (config, "core", key, NULL))
{
lang = g_key_file_get_string_list (config, "core", key, NULL, NULL);
return g_steal_pointer (&lang);
}
}
return NULL;
}
char **
flatpak_dir_get_default_locale_languages (FlatpakDir *self)
{
g_autoptr(GPtrArray) langs = g_ptr_array_new_with_free_func (g_free);
g_autoptr(GDBusProxy) localed_proxy = NULL;
g_autoptr(GDBusProxy) accounts_proxy = NULL;
g_auto(GStrv) extra_languages = NULL;
extra_languages = flatpak_dir_get_config_strv (self, "xa.extra-languages");
if (flatpak_dir_is_user (self))
return flatpak_get_current_locale_langs ();
return sort_strv (flatpak_strv_merge (extra_languages, flatpak_get_current_locale_langs ()));
/* First get the system default locales */
/* Then get the system default locales */
localed_proxy = get_localed_dbus_proxy ();
if (localed_proxy != NULL)
get_locale_langs_from_localed_dbus (localed_proxy, langs);
@@ -14068,27 +14088,23 @@ flatpak_dir_get_default_locale_languages (FlatpakDir *self)
if (accounts_proxy != NULL)
get_locale_langs_from_accounts_dbus (accounts_proxy, langs);
/* If none were found, fall back to using all languages */
if (langs->len == 0)
return g_new0 (char *, 1);
g_ptr_array_sort (langs, flatpak_strcmp0_ptr);
g_ptr_array_add (langs, NULL);
return (char **) g_ptr_array_free (g_steal_pointer (&langs), FALSE);
return sort_strv (flatpak_strv_merge (extra_languages, (char **) langs->pdata));
}
char **
flatpak_dir_get_locale_languages (FlatpakDir *self)
{
GKeyFile *config = flatpak_dir_get_repo_config (self);
char **langs = NULL;
if (config)
{
char **langs = g_key_file_get_string_list (config, "core", "xa.languages", NULL, NULL);
if (langs)
return sort_strv (langs);
}
/* Fetch the list of languages specified by xa.languages - if this key is empty,
* this would mean that all languages are accepted. You can read the man for the
* flatpak-config section for more info.
*/
langs = flatpak_dir_get_config_strv (self, "xa.languages");
if (langs)
return sort_strv (langs);
return flatpak_dir_get_default_locale_languages (self);
}

View File

@@ -1648,6 +1648,33 @@ flatpak_installation_get_config (FlatpakInstallation *self,
return flatpak_dir_get_config (dir, key, error);
}
/**
* flatpak_installation_get_default_languages:
* @self: a #FlatpakInstallation
* @error: return location for a #GError
*
* Get the default languages used by the installation to decide which
* subpaths to install of locale extensions. This list may also be used
* by frontends like GNOME Software to decide which language-specific apps
* to display. An empty array means that all languages should be installed.
*
* Returns: (array zero-terminated=1) (element-type utf8) (transfer full):
* A possibly empty array of locale strings, or %NULL on error.
* Since: 1.5.0
*/
char **
flatpak_installation_get_default_languages (FlatpakInstallation *self,
GError **error)
{
g_autoptr(FlatpakDir) dir = NULL;
dir = flatpak_installation_get_dir (self, error);
if (dir == NULL)
return NULL;
return flatpak_dir_get_locale_languages (dir);
}
/**
* flatpak_installation_get_min_free_space_bytes:
* @self: a #FlatpakInstallation

View File

@@ -296,6 +296,8 @@ FLATPAK_EXTERN char * flatpak_installation_get_config (FlatpakIns
const char *key,
GCancellable *cancellable,
GError **error);
FLATPAK_EXTERN char ** flatpak_installation_get_default_languages (FlatpakInstallation *self,
GError **error);
FLATPAK_EXTERN char * flatpak_installation_load_app_overrides (FlatpakInstallation *self,
const char *app_id,
GCancellable *cancellable,

View File

@@ -62,7 +62,15 @@
The languages that are included when installing Locale extensions.
The value is a semicolon-separated list of two-letter language codes,
or one of the special values * or all. If this key is unset, flatpak
defaults to including just the current locale.
defaults to including the extra-languages key and the current locale.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>extra-languages</varname></term>
<listitem><para>
This key is used when languages is not set, and it defines extra locale
extensions on top of the system configured languages. The value is a
semicolon-separated list of two-letter language codes.
</para></listitem>
</varlistentry>
</variablelist>

View File

@@ -47,6 +47,7 @@ flatpak_installation_remove_remote
flatpak_installation_update_remote_sync
flatpak_installation_cleanup_local_refs_sync
flatpak_installation_get_config
flatpak_installation_get_default_languages
flatpak_installation_prune_local_repo
flatpak_installation_remove_local_ref_sync
flatpak_installation_set_config_sync

View File

@@ -1120,8 +1120,7 @@ handle_configure (FlatpakSystemHelper *object,
return TRUE;
}
/* We only support this for now */
if (strcmp (arg_key, "languages") != 0)
if ((strcmp (arg_key, "languages") != 0) && (strcmp (arg_key, "extra-languages") != 0))
{
g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS,
"Unsupported key: %s", arg_key);

View File

@@ -237,6 +237,69 @@ test_installation_config (void)
g_assert_no_error (error);
}
static void
configure_languages (void)
{
char *argv[] = { "flatpak", "config", "--user", "--set", "languages", "de", NULL };
run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}
static void
clean_languages (void)
{
char *argv[] = { "flatpak", "config", "--user", "--unset", "languages", NULL };
run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}
static void
test_languages_config (void)
{
g_autoptr(FlatpakInstallation) inst = NULL;
g_autofree char *path = NULL;
g_autoptr(GFile) file = NULL;
g_autoptr(GError) error = NULL;
g_auto(GStrv) value = NULL;
gboolean res;
clean_languages ();
path = g_build_filename (g_get_user_data_dir (), "flatpak", NULL);
file = g_file_new_for_path (path);
inst = flatpak_installation_new_for_path (file, TRUE, NULL, &error);
g_assert_no_error (error);
g_assert_nonnull (inst);
value = flatpak_installation_get_default_languages (inst, &error);
g_assert_no_error (error);
g_assert_cmpstr (value[0], ==, "en");
res = flatpak_installation_set_config_sync (inst, "extra-languages", "en;pt", NULL, &error);
g_assert_no_error (error);
g_assert_true (res);
value = flatpak_installation_get_default_languages (inst, &error);
g_assert_no_error (error);
g_assert_cmpstr (value[0], ==, "en");
g_assert_cmpstr (value[1], ==, "pt");
g_assert_null (value[2]);
g_clear_pointer (&value, g_free);
res = flatpak_installation_set_config_sync (inst, "languages", "ar;es", NULL, &error);
g_assert_no_error (error);
g_assert_true (res);
value = flatpak_installation_get_default_languages (inst, &error);
g_assert_no_error (error);
g_assert_cmpstr (value[0], ==, "ar");
g_assert_cmpstr (value[1], ==, "es");
g_assert_null (value[2]);
g_clear_pointer (&value, g_free);
configure_languages ();
}
static void
test_arches (void)
{
@@ -1829,14 +1892,6 @@ setup_multiple_installations (void)
add_extra_installation ("extra-installation-3", NULL, NULL, NULL);
}
static void
configure_languages (void)
{
char *argv[] = { "flatpak", "config", "--user", "--set", "languages", "de", NULL };
run_test_subprocess (argv, RUN_TEST_SUBPROCESS_DEFAULT);
}
static void
setup_repo (void)
{
@@ -1968,6 +2023,7 @@ global_setup (void)
g_assert_cmpstr (g_get_user_runtime_dir (), ==, flatpak_runtimedir);
g_setenv ("FLATPAK_SYSTEM_HELPER_ON_SESSION", "1", TRUE);
g_setenv ("LANGUAGE", "en", TRUE);
test_bus = g_test_dbus_new (G_TEST_DBUS_NONE);
@@ -3635,6 +3691,7 @@ main (int argc, char *argv[])
g_test_add_func ("/library/system-installation", test_system_installation);
g_test_add_func ("/library/multiple-system-installation", test_multiple_system_installations);
g_test_add_func ("/library/installation-config", test_installation_config);
g_test_add_func ("/library/languages-config", test_languages_config);
g_test_add_func ("/library/arches", test_arches);
g_test_add_func ("/library/ref", test_ref);
g_test_add_func ("/library/list-remotes", test_list_remotes);