Keep x-* properties in manifest.json

This add custom (de)serialization code for the source, module and manifest
objects so that properties starting with "x-" are kep and then put back
in the manifest.

We also add a checksum of the manifest to the "finish" phase so that
if you change them the manifest is re-generated.

Closes: #203
Approved by: TingPing
auto
Alexander Larsson 2018-08-15 17:18:15 +02:00 committed by Atomic Bot
parent e64943f2ff
commit fd802105c5
6 changed files with 240 additions and 35 deletions

View File

@ -1113,10 +1113,10 @@ builder_manifest_serialize_property (JsonSerializable *serializable,
}
else
{
return json_serializable_default_serialize_property (serializable,
property_name,
value,
pspec);
return builder_serializable_serialize_property (serializable,
property_name,
value,
pspec);
}
}
@ -1252,10 +1252,10 @@ builder_manifest_deserialize_property (JsonSerializable *serializable,
}
else
{
return json_serializable_default_deserialize_property (serializable,
property_name,
value,
pspec, property_node);
return builder_serializable_deserialize_property (serializable,
property_name,
value,
pspec, property_node);
}
}
@ -1264,7 +1264,28 @@ serializable_iface_init (JsonSerializableIface *serializable_iface)
{
serializable_iface->serialize_property = builder_manifest_serialize_property;
serializable_iface->deserialize_property = builder_manifest_deserialize_property;
serializable_iface->find_property = builder_serializable_find_property_with_error;
serializable_iface->find_property = builder_serializable_find_property;
serializable_iface->list_properties = builder_serializable_list_properties;
serializable_iface->set_property = builder_serializable_set_property;
serializable_iface->get_property = builder_serializable_get_property;
}
static char *
builder_manifest_serialize (BuilderManifest *self)
{
JsonNode *node;
JsonGenerator *generator;
char *json;
node = json_gobject_serialize (G_OBJECT (self));
generator = json_generator_new ();
json_generator_set_pretty (generator, TRUE);
json_generator_set_root (generator, node);
json = json_generator_to_data (generator, NULL);
g_object_unref (generator);
json_node_free (node);
return json;
}
const char *
@ -1747,6 +1768,7 @@ builder_manifest_checksum_for_finish (BuilderManifest *self,
BuilderContext *context)
{
GList *l;
g_autofree char *json = NULL;
builder_cache_checksum_str (cache, BUILDER_MANIFEST_CHECKSUM_FINISH_VERSION);
builder_cache_checksum_strv (cache, self->finish_args);
@ -1773,6 +1795,9 @@ builder_manifest_checksum_for_finish (BuilderManifest *self,
else
g_warning ("Can't load metadata file %s: %s", self->metadata, my_error->message);
}
json = builder_manifest_serialize (self);
builder_cache_checksum_str (cache, json);
}
static void
@ -2652,7 +2677,6 @@ maybe_format_extension_tag (const char *extension_tag)
return g_strdup ("");
}
gboolean
builder_manifest_finish (BuilderManifest *self,
BuilderCache *cache,
@ -2670,8 +2694,6 @@ builder_manifest_finish (BuilderManifest *self,
g_autoptr(GSubprocess) subp = NULL;
int i;
GList *l;
JsonNode *node;
JsonGenerator *generator;
builder_manifest_checksum_for_finish (self, cache, context);
if (!builder_cache_lookup (cache, "finish"))
@ -2874,13 +2896,7 @@ builder_manifest_finish (BuilderManifest *self,
!g_subprocess_wait_check (subp, NULL, error))
return FALSE;
node = json_gobject_serialize (G_OBJECT (self));
generator = json_generator_new ();
json_generator_set_pretty (generator, TRUE);
json_generator_set_root (generator, node);
json = json_generator_to_data (generator, NULL);
g_object_unref (generator);
json_node_free (node);
json = builder_manifest_serialize (self);
if (self->build_runtime)
manifest_file = g_file_resolve_relative_path (app_dir, "usr/manifest.json");

View File

@ -721,10 +721,10 @@ builder_module_serialize_property (JsonSerializable *serializable,
}
else
{
return json_serializable_default_serialize_property (serializable,
property_name,
value,
pspec);
return builder_serializable_serialize_property (serializable,
property_name,
value,
pspec);
}
}
@ -912,10 +912,10 @@ builder_module_deserialize_property (JsonSerializable *serializable,
}
else
{
return json_serializable_default_deserialize_property (serializable,
property_name,
value,
pspec, property_node);
return builder_serializable_deserialize_property (serializable,
property_name,
value,
pspec, property_node);
}
}
@ -924,7 +924,10 @@ serializable_iface_init (JsonSerializableIface *serializable_iface)
{
serializable_iface->serialize_property = builder_module_serialize_property;
serializable_iface->deserialize_property = builder_module_deserialize_property;
serializable_iface->find_property = builder_serializable_find_property_with_error;
serializable_iface->find_property = builder_serializable_find_property;
serializable_iface->list_properties = builder_serializable_list_properties;
serializable_iface->set_property = builder_serializable_set_property;
serializable_iface->get_property = builder_serializable_get_property;
}
const char *

View File

@ -771,7 +771,8 @@ serializable_iface_init (JsonSerializableIface *serializable_iface)
{
serializable_iface->serialize_property = builder_options_serialize_property;
serializable_iface->deserialize_property = builder_options_deserialize_property;
serializable_iface->find_property = builder_serializable_find_property_with_error;
serializable_iface->find_property = builder_serializable_find_property;
serializable_iface->list_properties = builder_serializable_list_properties;
}
static GList *

View File

@ -228,13 +228,18 @@ builder_source_find_property (JsonSerializable *serializable,
{
if (strcmp (name, "type") == 0)
return NULL;
return builder_serializable_find_property_with_error (serializable, name);
return builder_serializable_find_property (serializable, name);
}
static void
serializable_iface_init (JsonSerializableIface *serializable_iface)
{
serializable_iface->serialize_property = builder_serializable_serialize_property;
serializable_iface->deserialize_property = builder_serializable_deserialize_property;
serializable_iface->find_property = builder_source_find_property;
serializable_iface->list_properties = builder_serializable_list_properties;
serializable_iface->set_property = builder_serializable_set_property;
serializable_iface->get_property = builder_serializable_get_property;
}
JsonNode *

View File

@ -2063,19 +2063,182 @@ builder_download_uri (SoupURI *uri,
return TRUE;
}
typedef struct {
GParamSpec *pspec;
JsonNode *data;
} BuilderXProperty;
static BuilderXProperty *
builder_x_property_new (const char *name)
{
BuilderXProperty *property = g_new0 (BuilderXProperty, 1);
property->pspec = g_param_spec_boxed (name, "", "", JSON_TYPE_NODE, G_PARAM_READWRITE | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB);
return property;
}
static void
builder_x_property_free (BuilderXProperty *prop)
{
g_param_spec_unref (prop->pspec);
if (prop->data)
json_node_unref (prop->data);
g_free (prop);
}
static const char *
builder_x_property_get_name (BuilderXProperty *prop)
{
return g_param_spec_get_name (prop->pspec);
}
GParamSpec *
builder_serializable_find_property_with_error (JsonSerializable *serializable,
const char *name)
builder_serializable_find_property (JsonSerializable *serializable,
const char *name)
{
GParamSpec *pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (serializable), name);
if (pspec == NULL &&
g_str_has_prefix (name, "x-"))
{
GHashTable *x_props = g_object_get_data (G_OBJECT (serializable), "flatpak-x-props");
BuilderXProperty *prop;
if (x_props == NULL)
{
x_props = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)builder_x_property_free);
g_object_set_data_full (G_OBJECT (serializable), "flatpak-x-props", x_props, (GDestroyNotify)g_hash_table_unref);
}
prop = g_hash_table_lookup (x_props, name);
if (prop == NULL)
{
prop = builder_x_property_new (name);
g_hash_table_insert (x_props, (char *)builder_x_property_get_name (prop), prop);
}
pspec = prop->pspec;
}
if (pspec == NULL &&
!g_str_has_prefix (name, "x-") &&
!g_str_has_prefix (name, "__") &&
!g_str_has_prefix (name, "//"))
g_warning ("Unknown property %s for type %s", name, g_type_name_from_instance ((GTypeInstance *)serializable));
return pspec;
}
GParamSpec **
builder_serializable_list_properties (JsonSerializable *serializable,
guint *n_pspecs)
{
GPtrArray *res = g_ptr_array_new ();
guint n_normal, i;
g_autofree GParamSpec **normal = NULL;
GHashTable *x_props;
normal = g_object_class_list_properties (G_OBJECT_GET_CLASS (serializable), &n_normal);
for (i = 0; i < n_normal; i++)
g_ptr_array_add (res, normal[i]);
x_props = g_object_get_data (G_OBJECT (serializable), "flatpak-x-props");
if (x_props)
{
GLNX_HASH_TABLE_FOREACH_V (x_props, BuilderXProperty *, prop)
{
g_ptr_array_add (res, prop->pspec);
}
}
if (n_pspecs)
*n_pspecs = res->len;
g_ptr_array_add (res, NULL);
return (GParamSpec **)g_ptr_array_free (res, FALSE);
}
gboolean
builder_serializable_deserialize_property (JsonSerializable *serializable,
const gchar *property_name,
GValue *value,
GParamSpec *pspec,
JsonNode *property_node)
{
GHashTable *x_props = g_object_get_data (G_OBJECT (serializable), "flatpak-x-props");
if (x_props)
{
BuilderXProperty *prop = g_hash_table_lookup (x_props, property_name);
if (prop)
{
g_value_set_boxed (value, property_node);
return TRUE;
}
}
return json_serializable_default_deserialize_property (serializable, property_name, value, pspec, property_node);
}
JsonNode *
builder_serializable_serialize_property (JsonSerializable *serializable,
const gchar *property_name,
const GValue *value,
GParamSpec *pspec)
{
GHashTable *x_props = g_object_get_data (G_OBJECT (serializable), "flatpak-x-props");
if (x_props)
{
BuilderXProperty *prop = g_hash_table_lookup (x_props, property_name);
if (prop)
return g_value_dup_boxed (value);
}
return json_serializable_default_serialize_property (serializable, property_name, value, pspec);
}
void
builder_serializable_set_property (JsonSerializable *serializable,
GParamSpec *pspec,
const GValue *value)
{
GHashTable *x_props = g_object_get_data (G_OBJECT (serializable), "flatpak-x-props");
if (x_props)
{
BuilderXProperty *prop = g_hash_table_lookup (x_props, g_param_spec_get_name (pspec));
if (prop)
{
prop->data = g_value_dup_boxed (value);
return;
}
}
g_object_set_property (G_OBJECT (serializable), pspec->name, value);
}
void
builder_serializable_get_property (JsonSerializable *serializable,
GParamSpec *pspec,
GValue *value)
{
GHashTable *x_props = g_object_get_data (G_OBJECT (serializable), "flatpak-x-props");
if (x_props)
{
BuilderXProperty *prop = g_hash_table_lookup (x_props, g_param_spec_get_name (pspec));
if (prop)
{
g_value_set_boxed (value, prop->data);
return;
}
}
g_object_get_property (G_OBJECT (serializable), pspec->name, value);
}
void
builder_set_term_title (const gchar *format,
...)

View File

@ -104,8 +104,25 @@ gboolean builder_verify_checksums (const char *name,
GChecksumType checksums_type[BUILDER_CHECKSUMS_LEN],
GError **error);
GParamSpec * builder_serializable_find_property_with_error (JsonSerializable *serializable,
const char *name);
GParamSpec * builder_serializable_find_property (JsonSerializable *serializable,
const char *name);
GParamSpec ** builder_serializable_list_properties (JsonSerializable *serializable,
guint *n_pspecs);
gboolean builder_serializable_deserialize_property (JsonSerializable *serializable,
const gchar *property_name,
GValue *value,
GParamSpec *pspec,
JsonNode *property_node);
JsonNode * builder_serializable_serialize_property (JsonSerializable *serializable,
const gchar *property_name,
const GValue *value,
GParamSpec *pspec);
void builder_serializable_get_property (JsonSerializable *serializable,
GParamSpec *pspec,
GValue *value);
void builder_serializable_set_property (JsonSerializable *serializable,
GParamSpec *pspec,
const GValue *value);
void builder_set_term_title (const gchar *format,
...) G_GNUC_PRINTF (1, 2);