mirror of
https://github.com/flatpak/flatpak.git
synced 2026-03-17 06:29:21 -04:00
builder: Add support for defining extensions in flatpak-builder
This takes a list of properties and generate finish arguments. Additionally you can specify "bundle": true, which causes f-b to emit an actual extension implementation, similar to e.g. the locale and debuginfo extension.
This commit is contained in:
@@ -8,6 +8,8 @@ flatpak_builder_SOURCES = \
|
||||
builder/builder-manifest.h \
|
||||
builder/builder-options.c \
|
||||
builder/builder-options.h \
|
||||
builder/builder-extension.c \
|
||||
builder/builder-extension.h \
|
||||
builder/builder-module.c \
|
||||
builder/builder-module.h \
|
||||
builder/builder-post-process.c \
|
||||
|
||||
425
builder/builder-extension.c
Normal file
425
builder/builder-extension.c
Normal file
@@ -0,0 +1,425 @@
|
||||
/* builder-extension.c
|
||||
*
|
||||
* Copyright (C) 2015 Red Hat, Inc
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Alexander Larsson <alexl@redhat.com>
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/statfs.h>
|
||||
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
#include "libglnx/libglnx.h"
|
||||
|
||||
#include "flatpak-utils.h"
|
||||
#include "flatpak-run.h"
|
||||
#include "builder-utils.h"
|
||||
#include "builder-extension.h"
|
||||
|
||||
struct BuilderExtension
|
||||
{
|
||||
GObject parent;
|
||||
|
||||
char *name;
|
||||
char *directory;
|
||||
gboolean bundle;
|
||||
gboolean autodelete;
|
||||
gboolean no_autodownload;
|
||||
gboolean subdirectories;
|
||||
char *add_ld_path;
|
||||
char *download_if;
|
||||
char *enable_if;
|
||||
char *merge_dirs;
|
||||
char *subdirectory_suffix;
|
||||
char *version;
|
||||
char *versions;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
} BuilderExtensionClass;
|
||||
|
||||
G_DEFINE_TYPE (BuilderExtension, builder_extension, G_TYPE_OBJECT);
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_DIRECTORY,
|
||||
PROP_BUNDLE,
|
||||
PROP_AUTODELETE,
|
||||
PROP_ADD_LD_PATH,
|
||||
PROP_DOWNLOAD_IF,
|
||||
PROP_ENABLE_IF,
|
||||
PROP_MERGE_DIRS,
|
||||
PROP_NO_AUTODOWNLOAD,
|
||||
PROP_SUBDIRECTORIES,
|
||||
PROP_SUBDIRECTORY_SUFFIX,
|
||||
PROP_VERSION,
|
||||
PROP_VERSIONS,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
static void
|
||||
builder_extension_finalize (GObject *object)
|
||||
{
|
||||
BuilderExtension *self = (BuilderExtension *) object;
|
||||
|
||||
g_free (self->name);
|
||||
g_free (self->directory);
|
||||
g_free (self->add_ld_path);
|
||||
g_free (self->download_if);
|
||||
g_free (self->enable_if);
|
||||
g_free (self->merge_dirs);
|
||||
g_free (self->subdirectory_suffix);
|
||||
g_free (self->version);
|
||||
g_free (self->versions);
|
||||
|
||||
G_OBJECT_CLASS (builder_extension_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
builder_extension_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BuilderExtension *self = BUILDER_EXTENSION (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DIRECTORY:
|
||||
g_value_set_string (value, self->directory);
|
||||
break;
|
||||
|
||||
case PROP_BUNDLE:
|
||||
g_value_set_boolean (value, self->bundle);
|
||||
break;
|
||||
|
||||
case PROP_AUTODELETE:
|
||||
g_value_set_boolean (value, self->autodelete);
|
||||
break;
|
||||
|
||||
case PROP_NO_AUTODOWNLOAD:
|
||||
g_value_set_boolean (value, self->autodelete);
|
||||
break;
|
||||
|
||||
case PROP_SUBDIRECTORIES:
|
||||
g_value_set_boolean (value, self->autodelete);
|
||||
break;
|
||||
|
||||
case PROP_ADD_LD_PATH:
|
||||
g_value_set_string (value, self->add_ld_path);
|
||||
break;
|
||||
|
||||
case PROP_DOWNLOAD_IF:
|
||||
g_value_set_string (value, self->download_if);
|
||||
break;
|
||||
|
||||
case PROP_ENABLE_IF:
|
||||
g_value_set_string (value, self->enable_if);
|
||||
break;
|
||||
|
||||
case PROP_MERGE_DIRS:
|
||||
g_value_set_string (value, self->merge_dirs);
|
||||
break;
|
||||
|
||||
case PROP_SUBDIRECTORY_SUFFIX:
|
||||
g_value_set_string (value, self->subdirectory_suffix);
|
||||
break;
|
||||
|
||||
case PROP_VERSION:
|
||||
g_value_set_string (value, self->version);
|
||||
break;
|
||||
|
||||
case PROP_VERSIONS:
|
||||
g_value_set_string (value, self->versions);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
builder_extension_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
BuilderExtension *self = BUILDER_EXTENSION (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DIRECTORY:
|
||||
g_clear_pointer (&self->directory, g_free);
|
||||
self->directory = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_BUNDLE:
|
||||
self->bundle = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_AUTODELETE:
|
||||
self->autodelete = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_NO_AUTODOWNLOAD:
|
||||
self->no_autodownload = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_SUBDIRECTORIES:
|
||||
self->subdirectories = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_ADD_LD_PATH:
|
||||
g_clear_pointer (&self->add_ld_path, g_free);
|
||||
self->add_ld_path = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_DOWNLOAD_IF:
|
||||
g_clear_pointer (&self->download_if, g_free);
|
||||
self->download_if = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_ENABLE_IF:
|
||||
g_clear_pointer (&self->enable_if, g_free);
|
||||
self->enable_if = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_MERGE_DIRS:
|
||||
g_clear_pointer (&self->merge_dirs, g_free);
|
||||
self->merge_dirs = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_SUBDIRECTORY_SUFFIX:
|
||||
g_clear_pointer (&self->subdirectory_suffix, g_free);
|
||||
self->subdirectory_suffix = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_VERSION:
|
||||
g_clear_pointer (&self->version, g_free);
|
||||
self->version = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
case PROP_VERSIONS:
|
||||
g_clear_pointer (&self->versions, g_free);
|
||||
self->versions = g_value_dup_string (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
builder_extension_class_init (BuilderExtensionClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->finalize = builder_extension_finalize;
|
||||
object_class->get_property = builder_extension_get_property;
|
||||
object_class->set_property = builder_extension_set_property;
|
||||
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DIRECTORY,
|
||||
g_param_spec_string ("directory",
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_BUNDLE,
|
||||
g_param_spec_boolean ("bundle",
|
||||
"",
|
||||
"",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_AUTODELETE,
|
||||
g_param_spec_boolean ("autodelete",
|
||||
"",
|
||||
"",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_NO_AUTODOWNLOAD,
|
||||
g_param_spec_boolean ("no-autodownload",
|
||||
"",
|
||||
"",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SUBDIRECTORIES,
|
||||
g_param_spec_boolean ("subdirectories",
|
||||
"",
|
||||
"",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ADD_LD_PATH,
|
||||
g_param_spec_string ("add-ld-path",
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_DOWNLOAD_IF,
|
||||
g_param_spec_string ("download-if",
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ENABLE_IF,
|
||||
g_param_spec_string ("enable-if",
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MERGE_DIRS,
|
||||
g_param_spec_string ("merge-dirs",
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SUBDIRECTORY_SUFFIX,
|
||||
g_param_spec_string ("subdirectory-suffix",
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_VERSION,
|
||||
g_param_spec_string ("version",
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_VERSIONS,
|
||||
g_param_spec_string ("versions",
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE));
|
||||
}
|
||||
|
||||
static void
|
||||
builder_extension_init (BuilderExtension *self)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
builder_extension_set_name (BuilderExtension *self,
|
||||
const char *name)
|
||||
{
|
||||
g_free (self->name);
|
||||
self->name = g_strdup (name);
|
||||
}
|
||||
|
||||
const char *
|
||||
builder_extension_get_name (BuilderExtension *self)
|
||||
{
|
||||
return self->name;
|
||||
}
|
||||
|
||||
|
||||
gboolean
|
||||
builder_extension_is_bundled (BuilderExtension *self)
|
||||
{
|
||||
return self->bundle;
|
||||
}
|
||||
|
||||
const char *
|
||||
builder_extension_get_directory (BuilderExtension *self)
|
||||
{
|
||||
return self->directory;
|
||||
}
|
||||
|
||||
static void
|
||||
add_arg (BuilderExtension *self,
|
||||
GPtrArray *args,
|
||||
const char *key,
|
||||
const char *value)
|
||||
{
|
||||
if (value == NULL)
|
||||
return;
|
||||
g_ptr_array_add (args,
|
||||
g_strdup_printf ("--extension=%s=%s=%s", self->name, key, value));
|
||||
}
|
||||
|
||||
static void
|
||||
add_argb (BuilderExtension *self,
|
||||
GPtrArray *args,
|
||||
const char *key,
|
||||
gboolean val)
|
||||
{
|
||||
if (val)
|
||||
add_arg (self, args, key, "true");
|
||||
}
|
||||
|
||||
void
|
||||
builder_extension_add_finish_args (BuilderExtension *self,
|
||||
GPtrArray *args)
|
||||
{
|
||||
if (self->directory == NULL)
|
||||
{
|
||||
g_warning ("No directory specified for extension '%s'", self->name);
|
||||
return;
|
||||
}
|
||||
|
||||
add_arg (self, args, FLATPAK_METADATA_KEY_DIRECTORY, self->directory);
|
||||
add_argb (self, args, FLATPAK_METADATA_KEY_AUTODELETE, self->autodelete);
|
||||
add_argb (self, args, FLATPAK_METADATA_KEY_NO_AUTODOWNLOAD, self->no_autodownload);
|
||||
add_argb (self, args, FLATPAK_METADATA_KEY_SUBDIRECTORIES, self->subdirectories);
|
||||
add_arg (self, args, FLATPAK_METADATA_KEY_ADD_LD_PATH, self->add_ld_path);
|
||||
add_arg (self, args, FLATPAK_METADATA_KEY_DOWNLOAD_IF, self->download_if);
|
||||
add_arg (self, args, FLATPAK_METADATA_KEY_ENABLE_IF, self->enable_if);
|
||||
add_arg (self, args, FLATPAK_METADATA_KEY_MERGE_DIRS, self->merge_dirs);
|
||||
add_arg (self, args, FLATPAK_METADATA_KEY_SUBDIRECTORY_SUFFIX, self->subdirectory_suffix);
|
||||
add_arg (self, args, FLATPAK_METADATA_KEY_VERSION, self->version);
|
||||
add_arg (self, args, FLATPAK_METADATA_KEY_VERSIONS, self->versions);
|
||||
}
|
||||
|
||||
void
|
||||
builder_extension_checksum (BuilderExtension *self,
|
||||
BuilderCache *cache,
|
||||
BuilderContext *context)
|
||||
{
|
||||
builder_cache_checksum_str (cache, BUILDER_EXTENSION_CHECKSUM_VERSION);
|
||||
builder_cache_checksum_str (cache, self->name);
|
||||
builder_cache_checksum_str (cache, self->directory);
|
||||
builder_cache_checksum_boolean (cache, self->bundle);
|
||||
builder_cache_checksum_boolean (cache, self->autodelete);
|
||||
builder_cache_checksum_boolean (cache, self->no_autodownload);
|
||||
builder_cache_checksum_boolean (cache, self->subdirectories);
|
||||
builder_cache_checksum_str (cache, self->add_ld_path);
|
||||
builder_cache_checksum_str (cache, self->download_if);
|
||||
builder_cache_checksum_str (cache, self->enable_if);
|
||||
builder_cache_checksum_str (cache, self->merge_dirs);
|
||||
builder_cache_checksum_str (cache, self->subdirectory_suffix);
|
||||
builder_cache_checksum_str (cache, self->version);
|
||||
builder_cache_checksum_str (cache, self->versions);
|
||||
}
|
||||
59
builder/builder-extension.h
Normal file
59
builder/builder-extension.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright © 2017 Red Hat, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Authors:
|
||||
* Alexander Larsson <alexl@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef __BUILDER_EXTENSION_H__
|
||||
#define __BUILDER_EXTENSION_H__
|
||||
|
||||
#include <json-glib/json-glib.h>
|
||||
|
||||
#include "builder-context.h"
|
||||
#include "builder-cache.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct BuilderExtension BuilderExtension;
|
||||
|
||||
#define BUILDER_TYPE_EXTENSION (builder_extension_get_type ())
|
||||
#define BUILDER_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), BUILDER_TYPE_EXTENSION, BuilderExtension))
|
||||
#define BUILDER_IS_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), BUILDER_TYPE_EXTENSION))
|
||||
|
||||
/* Bump this if format changes in incompatible ways to force rebuild */
|
||||
#define BUILDER_EXTENSION_CHECKSUM_VERSION "1"
|
||||
|
||||
GType builder_extension_get_type (void);
|
||||
|
||||
void builder_extension_set_name (BuilderExtension *self,
|
||||
const char *name);
|
||||
const char * builder_extension_get_name (BuilderExtension *self);
|
||||
|
||||
gboolean builder_extension_is_bundled (BuilderExtension *self);
|
||||
const char * builder_extension_get_directory (BuilderExtension *self);
|
||||
|
||||
void builder_extension_add_finish_args (BuilderExtension *self,
|
||||
GPtrArray *args);
|
||||
void builder_extension_checksum (BuilderExtension *self,
|
||||
BuilderCache *cache,
|
||||
BuilderContext *context);
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (BuilderExtension, g_object_unref)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __BUILDER_EXTENSION_H__ */
|
||||
@@ -170,6 +170,7 @@ do_export (BuilderContext *build_context,
|
||||
gboolean runtime,
|
||||
const gchar *location,
|
||||
const gchar *directory,
|
||||
char **exclude_dirs,
|
||||
const gchar *branch,
|
||||
const gchar *collection_id,
|
||||
...)
|
||||
@@ -212,6 +213,12 @@ do_export (BuilderContext *build_context,
|
||||
g_ptr_array_add (args, g_strdup ((gchar *) arg));
|
||||
va_end (ap);
|
||||
|
||||
if (exclude_dirs)
|
||||
{
|
||||
for (i = 0; exclude_dirs[i] != NULL; i++)
|
||||
g_ptr_array_add (args, g_strdup_printf ("--exclude=/%s/*", exclude_dirs[i]));
|
||||
}
|
||||
|
||||
/* Mandatory positional arguments. */
|
||||
g_ptr_array_add (args, g_strdup (location));
|
||||
g_ptr_array_add (args, g_strdup (directory));
|
||||
@@ -740,12 +747,14 @@ main (int argc,
|
||||
{
|
||||
g_autoptr(GFile) debuginfo_metadata = NULL;
|
||||
g_autoptr(GFile) sourcesinfo_metadata = NULL;
|
||||
g_auto(GStrv) exclude_dirs = builder_manifest_get_exclude_dirs (manifest);
|
||||
GList *l;
|
||||
|
||||
g_print ("Exporting %s to repo\n", builder_manifest_get_id (manifest));
|
||||
|
||||
if (!do_export (build_context, &error,
|
||||
FALSE,
|
||||
opt_repo, app_dir_path, builder_manifest_get_branch (manifest),
|
||||
opt_repo, app_dir_path, exclude_dirs, builder_manifest_get_branch (manifest),
|
||||
builder_manifest_get_collection_id (manifest),
|
||||
"--exclude=/lib/debug/*",
|
||||
"--include=/lib/debug/app",
|
||||
@@ -778,7 +787,7 @@ main (int argc,
|
||||
files_arg = g_strconcat (builder_context_get_build_runtime (build_context) ? "--files=usr" : "--files=files",
|
||||
"/share/runtime/locale/", NULL);
|
||||
if (!do_export (build_context, &error, TRUE,
|
||||
opt_repo, app_dir_path, builder_manifest_get_branch (manifest),
|
||||
opt_repo, app_dir_path, NULL, builder_manifest_get_branch (manifest),
|
||||
builder_manifest_get_collection_id (manifest),
|
||||
metadata_arg,
|
||||
files_arg,
|
||||
@@ -797,7 +806,7 @@ main (int argc,
|
||||
g_print ("Exporting %s to repo\n", debug_id);
|
||||
|
||||
if (!do_export (build_context, &error, TRUE,
|
||||
opt_repo, app_dir_path, builder_manifest_get_branch (manifest),
|
||||
opt_repo, app_dir_path, NULL, builder_manifest_get_branch (manifest),
|
||||
builder_manifest_get_collection_id (manifest),
|
||||
"--metadata=metadata.debuginfo",
|
||||
builder_context_get_build_runtime (build_context) ? "--files=usr/lib/debug" : "--files=files/lib/debug",
|
||||
@@ -808,6 +817,35 @@ main (int argc,
|
||||
}
|
||||
}
|
||||
|
||||
for (l = builder_manifest_get_add_extensions (manifest); l != NULL; l = l->next)
|
||||
{
|
||||
BuilderExtension *e = l->data;
|
||||
const char *extension_id = NULL;
|
||||
g_autofree char *metadata_arg = NULL;
|
||||
g_autofree char *files_arg = NULL;
|
||||
|
||||
if (!builder_extension_is_bundled (e))
|
||||
continue;
|
||||
|
||||
extension_id = builder_extension_get_name (e);
|
||||
g_print ("Exporting %s to repo\n", extension_id);
|
||||
|
||||
metadata_arg = g_strdup_printf ("--metadata=metadata.%s", extension_id);
|
||||
files_arg = g_strdup_printf ("--files=%s/%s",
|
||||
builder_context_get_build_runtime (build_context) ? "usr" : "files",
|
||||
builder_extension_get_directory (e));
|
||||
|
||||
if (!do_export (build_context, &error, TRUE,
|
||||
opt_repo, app_dir_path, NULL, builder_manifest_get_branch (manifest),
|
||||
builder_manifest_get_collection_id (manifest),
|
||||
metadata_arg, files_arg,
|
||||
NULL))
|
||||
{
|
||||
g_printerr ("Export failed: %s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Export sources extensions */
|
||||
sourcesinfo_metadata = g_file_get_child (app_dir, "metadata.sources");
|
||||
if (g_file_query_exists (sourcesinfo_metadata, NULL))
|
||||
@@ -816,7 +854,7 @@ main (int argc,
|
||||
g_print ("Exporting %s to repo\n", sources_id);
|
||||
|
||||
if (!do_export (build_context, &error, TRUE,
|
||||
opt_repo, app_dir_path, builder_manifest_get_branch (manifest),
|
||||
opt_repo, app_dir_path, NULL, builder_manifest_get_branch (manifest),
|
||||
builder_manifest_get_collection_id (manifest),
|
||||
"--metadata=metadata.sources",
|
||||
"--files=sources",
|
||||
@@ -835,7 +873,7 @@ main (int argc,
|
||||
g_print ("Exporting %s to repo\n", platform_id);
|
||||
|
||||
if (!do_export (build_context, &error, TRUE,
|
||||
opt_repo, app_dir_path, builder_manifest_get_branch (manifest),
|
||||
opt_repo, app_dir_path, NULL, builder_manifest_get_branch (manifest),
|
||||
builder_manifest_get_collection_id (manifest),
|
||||
"--metadata=metadata.platform",
|
||||
"--files=platform",
|
||||
@@ -868,7 +906,7 @@ main (int argc,
|
||||
metadata_arg = g_strdup_printf ("--metadata=%s", name);
|
||||
files_arg = g_strconcat ("--files=platform/share/runtime/locale/", NULL);
|
||||
if (!do_export (build_context, &error, TRUE,
|
||||
opt_repo, app_dir_path, builder_manifest_get_branch (manifest),
|
||||
opt_repo, app_dir_path, NULL, builder_manifest_get_branch (manifest),
|
||||
builder_manifest_get_collection_id (manifest),
|
||||
metadata_arg,
|
||||
files_arg,
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "builder-utils.h"
|
||||
#include "flatpak-utils.h"
|
||||
#include "builder-post-process.h"
|
||||
#include "builder-extension.h"
|
||||
|
||||
#include "libglnx/libglnx.h"
|
||||
|
||||
@@ -95,6 +96,7 @@ struct BuilderManifest
|
||||
BuilderOptions *build_options;
|
||||
GList *modules;
|
||||
GList *expanded_modules;
|
||||
GList *add_extensions;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
@@ -149,6 +151,7 @@ enum {
|
||||
PROP_DESKTOP_FILE_NAME_PREFIX,
|
||||
PROP_DESKTOP_FILE_NAME_SUFFIX,
|
||||
PROP_COLLECTION_ID,
|
||||
PROP_ADD_EXTENSIONS,
|
||||
LAST_PROP
|
||||
};
|
||||
|
||||
@@ -174,6 +177,7 @@ builder_manifest_finalize (GObject *object)
|
||||
g_free (self->command);
|
||||
g_clear_object (&self->build_options);
|
||||
g_list_free_full (self->modules, g_object_unref);
|
||||
g_list_free_full (self->add_extensions, g_object_unref);
|
||||
g_list_free (self->expanded_modules);
|
||||
g_strfreev (self->cleanup);
|
||||
g_strfreev (self->cleanup_commands);
|
||||
@@ -322,6 +326,10 @@ builder_manifest_get_property (GObject *object,
|
||||
g_value_set_pointer (value, self->modules);
|
||||
break;
|
||||
|
||||
case PROP_ADD_EXTENSIONS:
|
||||
g_value_set_pointer (value, self->add_extensions);
|
||||
break;
|
||||
|
||||
case PROP_CLEANUP:
|
||||
g_value_set_boxed (value, self->cleanup);
|
||||
break;
|
||||
@@ -518,6 +526,12 @@ builder_manifest_set_property (GObject *object,
|
||||
self->modules = g_value_get_pointer (value);
|
||||
break;
|
||||
|
||||
case PROP_ADD_EXTENSIONS:
|
||||
g_list_free_full (self->add_extensions, g_object_unref);
|
||||
/* NOTE: This takes ownership of the list! */
|
||||
self->add_extensions = g_value_get_pointer (value);
|
||||
break;
|
||||
|
||||
case PROP_CLEANUP:
|
||||
tmp = self->cleanup;
|
||||
self->cleanup = g_strdupv (g_value_get_boxed (value));
|
||||
@@ -772,6 +786,12 @@ builder_manifest_class_init (BuilderManifestClass *klass)
|
||||
"",
|
||||
"",
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ADD_EXTENSIONS,
|
||||
g_param_spec_pointer ("add-extensions",
|
||||
"",
|
||||
"",
|
||||
G_PARAM_READWRITE));
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_CLEANUP,
|
||||
g_param_spec_boxed ("cleanup",
|
||||
@@ -956,6 +976,31 @@ builder_manifest_serialize_property (JsonSerializable *serializable,
|
||||
json_array_unref (array);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
else if (strcmp (property_name, "add-extensions") == 0)
|
||||
{
|
||||
BuilderManifest *self = BUILDER_MANIFEST (serializable);
|
||||
JsonNode *retval = NULL;
|
||||
|
||||
if (self->add_extensions)
|
||||
{
|
||||
JsonObject *object;
|
||||
GList *l;
|
||||
|
||||
object = json_object_new ();
|
||||
|
||||
for (l = self->add_extensions; l != NULL; l = l->next)
|
||||
{
|
||||
BuilderExtension *e = l->data;
|
||||
JsonNode *child = json_gobject_serialize (G_OBJECT (e));
|
||||
json_object_set_member (object, (char *) builder_extension_get_name (e), child);
|
||||
}
|
||||
|
||||
retval = json_node_init_object (json_node_alloc (), object);
|
||||
json_object_unref (object);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
@@ -967,6 +1012,14 @@ builder_manifest_serialize_property (JsonSerializable *serializable,
|
||||
}
|
||||
}
|
||||
|
||||
static gint
|
||||
sort_extension (gconstpointer a,
|
||||
gconstpointer b)
|
||||
{
|
||||
return strcmp (builder_extension_get_name (BUILDER_EXTENSION (a)),
|
||||
builder_extension_get_name (BUILDER_EXTENSION (b)));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
builder_manifest_deserialize_property (JsonSerializable *serializable,
|
||||
const gchar *property_name,
|
||||
@@ -1044,6 +1097,48 @@ builder_manifest_deserialize_property (JsonSerializable *serializable,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else if (strcmp (property_name, "add-extensions") == 0)
|
||||
{
|
||||
if (JSON_NODE_TYPE (property_node) == JSON_NODE_NULL)
|
||||
{
|
||||
g_value_set_pointer (value, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
else if (JSON_NODE_TYPE (property_node) == JSON_NODE_OBJECT)
|
||||
{
|
||||
JsonObject *object = json_node_get_object (property_node);
|
||||
g_autoptr(GHashTable) hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
|
||||
g_autoptr(GList) members = NULL;
|
||||
GList *extensions;
|
||||
GList *l;
|
||||
|
||||
members = json_object_get_members (object);
|
||||
for (l = members; l != NULL; l = l->next)
|
||||
{
|
||||
const char *member_name = l->data;
|
||||
JsonNode *val;
|
||||
GObject *extension;
|
||||
|
||||
val = json_object_get_member (object, member_name);
|
||||
extension = json_gobject_deserialize (BUILDER_TYPE_EXTENSION, val);
|
||||
if (extension == NULL)
|
||||
return FALSE;
|
||||
|
||||
builder_extension_set_name (BUILDER_EXTENSION (extension), member_name);
|
||||
g_hash_table_insert (hash, (char *)builder_extension_get_name (BUILDER_EXTENSION (extension)), extension);
|
||||
}
|
||||
|
||||
extensions = g_hash_table_get_values (hash);
|
||||
g_hash_table_steal_all (hash);
|
||||
|
||||
extensions = g_list_sort (extensions, sort_extension);
|
||||
g_value_set_pointer (value, extensions);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
@@ -1122,6 +1217,12 @@ builder_manifest_get_modules (BuilderManifest *self)
|
||||
return self->modules;
|
||||
}
|
||||
|
||||
GList *
|
||||
builder_manifest_get_add_extensions (BuilderManifest *self)
|
||||
{
|
||||
return self->add_extensions;
|
||||
}
|
||||
|
||||
static const char *
|
||||
builder_manifest_get_runtime_version (BuilderManifest *self)
|
||||
{
|
||||
@@ -1459,11 +1560,19 @@ builder_manifest_checksum_for_finish (BuilderManifest *self,
|
||||
BuilderCache *cache,
|
||||
BuilderContext *context)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
builder_cache_checksum_str (cache, BUILDER_MANIFEST_CHECKSUM_FINISH_VERSION);
|
||||
builder_cache_checksum_strv (cache, self->finish_args);
|
||||
builder_cache_checksum_str (cache, self->command);
|
||||
builder_cache_checksum_compat_strv (cache, self->inherit_extensions);
|
||||
|
||||
for (l = self->add_extensions; l != NULL; l = l->next)
|
||||
{
|
||||
BuilderExtension *e = l->data;
|
||||
builder_extension_checksum (e, cache, context);
|
||||
}
|
||||
|
||||
if (self->metadata)
|
||||
{
|
||||
GFile *base_dir = builder_context_get_base_dir (context);
|
||||
@@ -2209,6 +2318,7 @@ builder_manifest_finish (BuilderManifest *self,
|
||||
g_autoptr(GPtrArray) args = NULL;
|
||||
g_autoptr(GSubprocess) subp = NULL;
|
||||
int i;
|
||||
GList *l;
|
||||
JsonNode *node;
|
||||
JsonGenerator *generator;
|
||||
|
||||
@@ -2375,6 +2485,9 @@ builder_manifest_finish (BuilderManifest *self,
|
||||
g_ptr_array_add (args, g_strdup (self->finish_args[i]));
|
||||
}
|
||||
|
||||
for (l = self->add_extensions; l != NULL; l = l->next)
|
||||
builder_extension_add_finish_args (l->data, args);
|
||||
|
||||
g_ptr_array_add (args, g_file_get_path (app_dir));
|
||||
g_ptr_array_add (args, NULL);
|
||||
|
||||
@@ -2519,6 +2632,30 @@ builder_manifest_finish (BuilderManifest *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
for (l = self->add_extensions; l != NULL; l = l->next)
|
||||
{
|
||||
BuilderExtension *e = l->data;
|
||||
g_autofree char *extension_metadata_name = NULL;
|
||||
g_autoptr(GFile) metadata_extension_file = NULL;
|
||||
g_autofree char *metadata_contents = NULL;
|
||||
|
||||
if (!builder_extension_is_bundled (e))
|
||||
continue;
|
||||
|
||||
extension_metadata_name = g_strdup_printf ("metadata.%s", builder_extension_get_name (e));
|
||||
metadata_extension_file = g_file_get_child (app_dir, extension_metadata_name);
|
||||
metadata_contents = g_strdup_printf ("[Runtime]\n"
|
||||
"name=%s\n"
|
||||
"\n"
|
||||
"[ExtensionOf]\n"
|
||||
"ref=%s\n",
|
||||
builder_extension_get_name (e), ref);
|
||||
if (!g_file_set_contents (flatpak_file_get_path_cached (metadata_extension_file),
|
||||
metadata_contents, strlen (metadata_contents), error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!builder_context_disable_rofiles (context, error))
|
||||
return FALSE;
|
||||
|
||||
@@ -3173,3 +3310,23 @@ builder_manifest_run (BuilderManifest *self,
|
||||
/* Not reached */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char **
|
||||
builder_manifest_get_exclude_dirs (BuilderManifest *self)
|
||||
{
|
||||
g_autoptr(GPtrArray) dirs = NULL;
|
||||
GList *l;
|
||||
|
||||
dirs = g_ptr_array_new ();
|
||||
|
||||
for (l = self->add_extensions; l != NULL; l = l->next)
|
||||
{
|
||||
BuilderExtension *e = l->data;
|
||||
|
||||
if (builder_extension_is_bundled (e))
|
||||
g_ptr_array_add (dirs, g_strdup (builder_extension_get_directory (e)));
|
||||
}
|
||||
g_ptr_array_add (dirs, NULL);
|
||||
|
||||
return (char **)g_ptr_array_free (g_steal_pointer (&dirs), FALSE);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "builder-options.h"
|
||||
#include "builder-module.h"
|
||||
#include "builder-cache.h"
|
||||
#include "builder-extension.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -56,6 +57,7 @@ const char * builder_manifest_get_id_platform (BuilderManifest *self);
|
||||
char * builder_manifest_get_locale_id_platform (BuilderManifest *self);
|
||||
BuilderOptions *builder_manifest_get_build_options (BuilderManifest *self);
|
||||
GList * builder_manifest_get_modules (BuilderManifest *self);
|
||||
GList * builder_manifest_get_add_extensions (BuilderManifest *self);
|
||||
const char * builder_manifest_get_branch (BuilderManifest *self);
|
||||
void builder_manifest_set_default_branch (BuilderManifest *self,
|
||||
const char *default_branch);
|
||||
@@ -63,6 +65,9 @@ const char * builder_manifest_get_collection_id (BuilderManifest *self);
|
||||
void builder_manifest_set_default_collection_id (BuilderManifest *self,
|
||||
const char *default_collection_id);
|
||||
|
||||
|
||||
char ** builder_manifest_get_exclude_dirs (BuilderManifest *self);
|
||||
|
||||
gboolean builder_manifest_start (BuilderManifest *self,
|
||||
gboolean allow_missing_runtimes,
|
||||
BuilderContext *context,
|
||||
|
||||
@@ -169,6 +169,10 @@
|
||||
String members in the array are interpreted as the name of a separate json file that contains a module.
|
||||
See below for details.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>add-extensions</option> (objects)</term>
|
||||
<listitem><para>This is a dictionary of extension objects. The key is the name of the extension. See below for details.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>cleanup</option> (array of strings)</term>
|
||||
<listitem><para>An array of file patterns that should be removed at the end.
|
||||
@@ -276,6 +280,36 @@
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Extension</title>
|
||||
<para>
|
||||
Extension define extension points in the app/runtime that can be implemented by extensions, supplying extra files
|
||||
which are available during runtime..
|
||||
</para>
|
||||
<para>
|
||||
These are the properties that are accepted:
|
||||
</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>directory</option> (string)</term>
|
||||
<listitem><para>The directory where the extension is mounted.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>bundle</option> (boolean)</term>
|
||||
<listitem><para>If this is true, then the data
|
||||
created in the extension directory is omitted from
|
||||
the result, and instead packaged in a separate
|
||||
extension..</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<para>
|
||||
Additionally the standard flatpak extension properies
|
||||
are supported, and put directly into the metadata file:
|
||||
autodelete, no-autodownload, subdirectories,
|
||||
add-ld-path, download-if, enable-if, merge-dirs,
|
||||
subdirectory-suffix, version, versions.
|
||||
</para>
|
||||
</refsect2>
|
||||
<refsect2>
|
||||
<title>Module</title>
|
||||
<para>
|
||||
|
||||
Reference in New Issue
Block a user