summaryrefslogtreecommitdiff
path: root/builder
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2016-02-18 19:22:34 +0100
committerAlexander Larsson <alexl@redhat.com>2016-02-18 19:22:34 +0100
commitd5d47aa458a909b6fc8dc9e0e804966417dbdf72 (patch)
tree2cbf5745757d0e18559a0035be39729cf60dfe42 /builder
parent6b6e4b213a8f8f6101f1726577def67af9c434a9 (diff)
downloadxdg-app-d5d47aa458a909b6fc8dc9e0e804966417dbdf72.tar.gz
builder: Support separating out locale data
Diffstat (limited to 'builder')
-rw-r--r--builder/builder-context.c14
-rw-r--r--builder/builder-context.h3
-rw-r--r--builder/builder-manifest.c86
-rw-r--r--builder/builder-module.c110
-rw-r--r--builder/xdg-app-builder-main.c40
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))
{