diff options
author | Alexander Larsson <alexl@redhat.com> | 2016-02-18 19:22:34 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2016-02-18 19:22:34 +0100 |
commit | d5d47aa458a909b6fc8dc9e0e804966417dbdf72 (patch) | |
tree | 2cbf5745757d0e18559a0035be39729cf60dfe42 /builder | |
parent | 6b6e4b213a8f8f6101f1726577def67af9c434a9 (diff) | |
download | xdg-app-d5d47aa458a909b6fc8dc9e0e804966417dbdf72.tar.gz |
builder: Support separating out locale data
Diffstat (limited to 'builder')
-rw-r--r-- | builder/builder-context.c | 14 | ||||
-rw-r--r-- | builder/builder-context.h | 3 | ||||
-rw-r--r-- | builder/builder-manifest.c | 86 | ||||
-rw-r--r-- | builder/builder-module.c | 110 | ||||
-rw-r--r-- | builder/xdg-app-builder-main.c | 40 |
5 files changed, 250 insertions, 3 deletions
diff --git a/builder/builder-context.c b/builder/builder-context.c index ed908a1..a15224e 100644 --- a/builder/builder-context.c +++ b/builder/builder-context.c @@ -51,6 +51,7 @@ struct BuilderContext { char **cleanup_platform; gboolean use_ccache; gboolean build_runtime; + gboolean separate_locales; }; typedef struct { @@ -332,6 +333,19 @@ builder_context_set_build_runtime (BuilderContext *self, } gboolean +builder_context_get_separate_locales (BuilderContext *self) +{ + return self->separate_locales; +} + +void +builder_context_set_separate_locales (BuilderContext *self, + gboolean separate_locales) +{ + self->separate_locales = !!separate_locales; +} + +gboolean builder_context_enable_ccache (BuilderContext *self, GError **error) { diff --git a/builder/builder-context.h b/builder/builder-context.h index b497c1c..df5a0a2 100644 --- a/builder/builder-context.h +++ b/builder/builder-context.h @@ -62,6 +62,9 @@ void builder_context_set_options (BuilderContext *self, gboolean builder_context_get_build_runtime (BuilderContext *self); void builder_context_set_build_runtime (BuilderContext *self, gboolean build_runtime); +gboolean builder_context_get_separate_locales(BuilderContext *self); +void builder_context_set_separate_locales(BuilderContext *self, + gboolean separate_locales); BuilderContext *builder_context_new (GFile *base_dir, GFile *app_dir); diff --git a/builder/builder-manifest.c b/builder/builder-manifest.c index b31cdf9..c23c222 100644 --- a/builder/builder-manifest.c +++ b/builder/builder-manifest.c @@ -47,6 +47,7 @@ struct BuilderManifest { char *sdk_commit; char *metadata; char *metadata_platform; + gboolean separate_locales; char **cleanup; char **cleanup_commands; char **cleanup_platform; @@ -96,6 +97,7 @@ enum { PROP_CLEANUP_COMMANDS, PROP_CLEANUP_PLATFORM, PROP_BUILD_RUNTIME, + PROP_SEPARATE_LOCALES, PROP_WRITABLE_SDK, PROP_APPSTREAM_COMPOSE, PROP_SDK_EXTENSIONS, @@ -228,6 +230,10 @@ builder_manifest_get_property (GObject *object, g_value_set_boolean (value, self->build_runtime); break; + case PROP_SEPARATE_LOCALES: + g_value_set_boolean (value, self->separate_locales); + break; + case PROP_WRITABLE_SDK: g_value_set_boolean (value, self->writable_sdk); break; @@ -383,6 +389,10 @@ builder_manifest_set_property (GObject *object, self->build_runtime = g_value_get_boolean (value); break; + case PROP_SEPARATE_LOCALES: + self->separate_locales = g_value_get_boolean (value); + break; + case PROP_WRITABLE_SDK: self->writable_sdk = g_value_get_boolean (value); break; @@ -572,6 +582,13 @@ builder_manifest_class_init (BuilderManifestClass *klass) FALSE, G_PARAM_READWRITE)); g_object_class_install_property (object_class, + PROP_SEPARATE_LOCALES, + g_param_spec_boolean ("separate-locales", + "", + "", + TRUE, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_WRITABLE_SDK, g_param_spec_boolean ("writable-sdk", "", @@ -654,6 +671,7 @@ static void builder_manifest_init (BuilderManifest *self) { self->appstream_compose = TRUE; + self->separate_locales = TRUE; } static JsonNode * @@ -917,6 +935,7 @@ builder_manifest_checksum (BuilderManifest *self, builder_cache_checksum_boolean (cache, self->writable_sdk); builder_cache_checksum_strv (cache, self->sdk_extensions); builder_cache_checksum_boolean (cache, self->build_runtime); + builder_cache_checksum_boolean (cache, self->separate_locales); if (self->build_options) builder_options_checksum (self->build_options, cache, context); @@ -1017,6 +1036,7 @@ builder_manifest_build (BuilderManifest *self, builder_context_set_global_cleanup (context, (const char **)self->cleanup); builder_context_set_global_cleanup_platform (context, (const char **)self->cleanup_platform); builder_context_set_build_runtime (context, self->build_runtime); + builder_context_set_separate_locales (context, self->separate_locales); g_print ("Starting build of %s\n", self->id ? self->id : "app"); for (l = self->modules; l != NULL; l = l->next) @@ -1503,6 +1523,7 @@ builder_manifest_finish (BuilderManifest *self, GFile *app_dir = builder_context_get_app_dir (context); g_autoptr(GFile) manifest_file = NULL; g_autoptr(GFile) debuginfo_dir = NULL; + g_autoptr(GFile) locale_parent_dir = NULL; g_autofree char *app_dir_path = g_file_get_path (app_dir); g_autofree char *json = NULL; g_autoptr(GPtrArray) args = NULL; @@ -1570,9 +1591,70 @@ builder_manifest_finish (BuilderManifest *self, if (self->build_runtime) - debuginfo_dir = g_file_resolve_relative_path (app_dir, "usr/lib/debug"); + { + debuginfo_dir = g_file_resolve_relative_path (app_dir, "usr/lib/debug"); + locale_parent_dir = g_file_resolve_relative_path (app_dir, "usr/share/runtime/locale"); + } else - debuginfo_dir = g_file_resolve_relative_path (app_dir, "files/lib/debug"); + { + debuginfo_dir = g_file_resolve_relative_path (app_dir, "files/lib/debug"); + locale_parent_dir = g_file_resolve_relative_path (app_dir, "files/share/runtime/locale"); + } + + if (self->separate_locales) + { + g_autoptr(GFile) metadata_file = NULL; + g_autofree char *extension_contents = NULL; + g_autoptr(GFileEnumerator) dir_enum = NULL; + g_autoptr(GFileOutputStream) output = NULL; + GFileInfo *next; + + metadata_file = g_file_get_child (app_dir, "metadata"); + + extension_contents = g_strdup_printf("\n" + "[Extension %s.Locale]\n" + "directory=share/runtime/locale\n" + "subdirectories=true\n", + self->id); + + output = g_file_append_to (metadata_file, G_FILE_CREATE_NONE, NULL, error); + if (output == NULL) + return FALSE; + + if (!g_output_stream_write_all (G_OUTPUT_STREAM (output), + extension_contents, strlen (extension_contents), + NULL, NULL, error)) + return FALSE; + + dir_enum = g_file_enumerate_children (locale_parent_dir, "standard::name,standard::type", + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, NULL); + + while (dir_enum != NULL && + (next = g_file_enumerator_next_file (dir_enum, NULL, NULL))) + { + g_autoptr(GFileInfo) child_info = next; + const char *name = g_file_info_get_name (child_info); + + if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY) + { + g_autoptr(GFile) metadata_locale_file = NULL; + g_autofree char *metadata_contents = NULL; + g_autofree char *filename = g_strdup_printf ("metadata.locale.%s", name); + + metadata_locale_file = g_file_get_child (app_dir, filename); + + metadata_contents = g_strdup_printf("[Runtime]\n" + "name=%s.Locale.%s\n", self->id, name); + if (!g_file_replace_contents (metadata_locale_file, + metadata_contents, strlen (metadata_contents), + NULL, FALSE, + G_FILE_CREATE_REPLACE_DESTINATION, + NULL, NULL, error)) + return FALSE; + } + } + } if (g_file_query_exists (debuginfo_dir, NULL)) { diff --git a/builder/builder-module.c b/builder/builder-module.c index 7f6807d..a1ff8a7 100644 --- a/builder/builder-module.c +++ b/builder/builder-module.c @@ -737,6 +737,103 @@ builder_module_handle_debuginfo (BuilderModule *self, return TRUE; } +static gboolean +migrate_locale_dir (GFile *source_dir, + GFile *separate_dir, + const char *subdir, + GError **error) +{ + g_autoptr(GFileEnumerator) dir_enum = NULL; + GFileInfo *next; + GError *temp_error = NULL; + + dir_enum = g_file_enumerate_children (source_dir, "standard::name,standard::type", + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, NULL); + if (!dir_enum) + return TRUE; + + while ((next = g_file_enumerator_next_file (dir_enum, NULL, &temp_error))) + { + g_autoptr(GFileInfo) child_info = next; + g_autoptr(GFile) child = NULL; + g_autoptr(GFile) locale_subdir = NULL; + + child = g_file_get_child (source_dir, g_file_info_get_name (child_info)); + + if (g_file_info_get_file_type (child_info) == G_FILE_TYPE_DIRECTORY) + { + g_autoptr(GFile) child = NULL; + const char *name = g_file_info_get_name (child_info); + g_autofree char *language = g_strdup (name); + g_autofree char *relative = NULL; + g_autofree char *target = NULL; + char *c; + + c = strchr (language, '@'); + if (c != NULL) + *c = 0; + c = strchr (language, '_'); + if (c != NULL) + *c = 0; + + /* We ship english and C locales always */ + if (strcmp (language, "C") == 0 || + strcmp (language, "en") == 0) + continue; + + child = g_file_get_child (source_dir, g_file_info_get_name (child_info)); + + relative = g_build_filename (language, subdir, name, NULL); + locale_subdir = g_file_resolve_relative_path (separate_dir, relative); + if (!gs_file_ensure_directory (locale_subdir, TRUE, + NULL, error)) + return FALSE; + + if (!xdg_app_cp_a (child, locale_subdir, + XDG_APP_CP_FLAGS_MERGE | XDG_APP_CP_FLAGS_MOVE, + NULL, error)) + return FALSE; + + target = g_build_filename ("../../share/runtime/locale", relative, NULL); + + if (!g_file_make_symbolic_link (child, target, + NULL, error)) + return FALSE; + + } + } + + if (temp_error != NULL) + { + g_propagate_error (error, temp_error); + return FALSE; + } + + return TRUE; +} + +static gboolean +migrate_locale_dirs (GFile *root_dir, + GError **error) +{ + g_autoptr(GFile) separate_dir = NULL; + g_autoptr(GFile) lib_locale_dir = NULL; + g_autoptr(GFile) share_locale_dir = NULL; + + lib_locale_dir = g_file_resolve_relative_path (root_dir, "lib/locale"); + share_locale_dir = g_file_resolve_relative_path (root_dir, "share/locale"); + separate_dir = g_file_resolve_relative_path (root_dir, "share/runtime/locale"); + + if (!migrate_locale_dir (lib_locale_dir, separate_dir, "lib", error)) + return FALSE; + + if (!migrate_locale_dir (share_locale_dir, separate_dir, "share", error)) + return FALSE; + + return TRUE; +} + gboolean builder_module_build (BuilderModule *self, BuilderCache *cache, @@ -985,6 +1082,19 @@ builder_module_build (BuilderModule *self, /* Post installation scripts */ + if (builder_context_get_separate_locales (context)) + { + g_autoptr(GFile) root_dir = NULL; + + if (builder_context_get_build_runtime (context)) + root_dir = g_file_get_child (app_dir, "usr"); + else + root_dir = g_file_get_child (app_dir, "files"); + + if (!migrate_locale_dirs (root_dir, error)) + return FALSE; + } + if (self->post_install) { for (i = 0; self->post_install[i] != NULL; i++) diff --git a/builder/xdg-app-builder-main.c b/builder/xdg-app-builder-main.c index 1166b28..390765e 100644 --- a/builder/xdg-app-builder-main.c +++ b/builder/xdg-app-builder-main.c @@ -91,6 +91,8 @@ usage (GOptionContext *context, const char *message) return 1; } +static const char skip_arg[] = "skip"; + static gboolean do_export (GError **error, gboolean runtime, @@ -124,7 +126,8 @@ do_export (GError **error, va_start (ap, runtime); while ((arg = va_arg (ap, const gchar *))) - g_ptr_array_add (args, g_strdup ((gchar *) arg)); + if (arg != skip_arg) + g_ptr_array_add (args, g_strdup ((gchar *) arg)); va_end (ap); g_ptr_array_add (args, NULL); @@ -157,6 +160,8 @@ main (int argc, g_autoptr(GFile) app_dir = NULL; g_autoptr(BuilderCache) cache = NULL; g_autofree char *cache_branch = NULL; + g_autoptr(GFileEnumerator) dir_enum = NULL; + GFileInfo *next = NULL; const char *platform_id = NULL; setlocale (LC_ALL, ""); @@ -347,6 +352,7 @@ main (int argc, builder_context_get_build_runtime (build_context), "--exclude=/lib/debug/*", "--include=/lib/debug/app", + builder_context_get_separate_locales (build_context) ? "--exclude=/share/runtime/locale/*/*" : skip_arg, opt_repo, app_dir_path, NULL)) { g_print ("Export failed: %s\n", error->message); @@ -369,6 +375,38 @@ main (int argc, } } + dir_enum = g_file_enumerate_children (app_dir, "standard::name,standard::type", + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, + NULL, NULL); + while (dir_enum != NULL && + (next = g_file_enumerator_next_file (dir_enum, NULL, NULL))) + { + g_autoptr(GFileInfo) child_info = next; + const char *name = g_file_info_get_name (child_info); + const char *language; + g_autofree char *metadata_arg = NULL; + g_autofree char *files_arg = NULL; + + if (!g_str_has_prefix (name, "metadata.locale.")) + continue; + language = name + strlen ("metadata.locale."); + + g_print ("exporting %s.Locale.%s to repo\n", builder_manifest_get_id (manifest), language); + + metadata_arg = g_strdup_printf ("--metadata=%s", name); + files_arg = g_strconcat (builder_context_get_build_runtime (build_context) ? "--files=usr" : "--files=files", + "/share/runtime/locale/", + language, NULL); + if (!do_export (&error, TRUE, + metadata_arg, + files_arg, + opt_repo, app_dir_path, NULL)) + { + g_print ("Export failed: %s\n", error->message); + return 1; + } + } + debuginfo_metadata = g_file_get_child (app_dir, "metadata.debuginfo"); if (g_file_query_exists (debuginfo_metadata, NULL)) { |