diff --git a/src/builder-manifest.c b/src/builder-manifest.c index fd2663b7..ed3253f6 100644 --- a/src/builder-manifest.c +++ b/src/builder-manifest.c @@ -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"); diff --git a/src/builder-module.c b/src/builder-module.c index 0a3853b5..03bf5ca1 100644 --- a/src/builder-module.c +++ b/src/builder-module.c @@ -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 * diff --git a/src/builder-options.c b/src/builder-options.c index d1b9b209..8c5ed710 100644 --- a/src/builder-options.c +++ b/src/builder-options.c @@ -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 * diff --git a/src/builder-source.c b/src/builder-source.c index c5edd720..1fef01d9 100644 --- a/src/builder-source.c +++ b/src/builder-source.c @@ -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 * diff --git a/src/builder-utils.c b/src/builder-utils.c index 4f5dda78..c9a185ae 100644 --- a/src/builder-utils.c +++ b/src/builder-utils.c @@ -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, ...) diff --git a/src/builder-utils.h b/src/builder-utils.h index 266069f2..fc1a18c4 100644 --- a/src/builder-utils.h +++ b/src/builder-utils.h @@ -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);