Add appdata-license field

This lets you modify the project_license field in the appdata file.
This is useful because appdata files from upstream generally only
contain license information for the app itself, whereas the
bundled app may contain other code with additional licenses.

Closes: #41
Approved by: alexlarsson
tingping/wmclass
Alexander Larsson 2017-09-28 16:29:50 +02:00 committed by Atomic Bot
parent 14df2dfc9a
commit 9f3e786c29
4 changed files with 108 additions and 1 deletions

View File

@ -93,7 +93,7 @@ AC_CHECK_FUNCS(fdwalk)
AC_CHECK_HEADER([sys/xattr.h], [], [AC_MSG_ERROR([You must have sys/xattr.h from glibc])])
AC_CHECK_HEADER([sys/capability.h], have_caps=yes, [AC_MSG_ERROR([sys/capability.h header not found])])
PKG_CHECK_MODULES(BASE, [glib-2.0 >= $GLIB_REQS gio-2.0 gio-unix-2.0 libsoup-2.4 ostree-1 >= $OSTREE_REQS json-glib-1.0])
PKG_CHECK_MODULES(BASE, [glib-2.0 >= $GLIB_REQS gio-2.0 gio-unix-2.0 libsoup-2.4 ostree-1 >= $OSTREE_REQS json-glib-1.0 libxml-2.0 >= 2.4])
dnl ************************
dnl *** check for libelf ***

View File

@ -207,6 +207,15 @@
<term><option>rename-icon</option> (string)</term>
<listitem><para>Any icon with this name will be renamed to a name based on id during the cleanup phase. Note that this is the icon name, not the full filenames, so it should not include a filename extension. </para></listitem>
</varlistentry>
<varlistentry>
<term><option>appdata-license</option> (string)</term>
<listitem><para>Replace the appdata
project_license field with this string. This is
useful as the upstream license is typically only
about the application itself, whereas the bundled
app can contain other licenses
too. </para></listitem>
</varlistentry>
<varlistentry>
<term><option>copy-icon</option> (boolean)</term>
<listitem><para>If rename-icon is set, keep a copy of the old icon file.</para></listitem>

View File

@ -34,6 +34,8 @@
#include "builder-post-process.h"
#include "builder-extension.h"
#include <libxml/parser.h>
#include "libglnx/libglnx.h"
#define LOCALES_SEPARATE_DIR "share/runtime/locale"
@ -83,6 +85,7 @@ struct BuilderManifest
char **tags;
char *rename_desktop_file;
char *rename_appdata_file;
char *appdata_license;
char *rename_icon;
gboolean copy_icon;
char *desktop_file_name_prefix;
@ -147,6 +150,7 @@ enum {
PROP_TAGS,
PROP_RENAME_DESKTOP_FILE,
PROP_RENAME_APPDATA_FILE,
PROP_APPDATA_LICENSE,
PROP_RENAME_ICON,
PROP_COPY_ICON,
PROP_DESKTOP_FILE_NAME_PREFIX,
@ -189,6 +193,7 @@ builder_manifest_finalize (GObject *object)
g_strfreev (self->tags);
g_free (self->rename_desktop_file);
g_free (self->rename_appdata_file);
g_free (self->appdata_license);
g_free (self->rename_icon);
g_free (self->desktop_file_name_prefix);
g_free (self->desktop_file_name_suffix);
@ -399,6 +404,10 @@ builder_manifest_get_property (GObject *object,
g_value_set_string (value, self->rename_appdata_file);
break;
case PROP_APPDATA_LICENSE:
g_value_set_string (value, self->appdata_license);
break;
case PROP_RENAME_ICON:
g_value_set_string (value, self->rename_icon);
break;
@ -621,6 +630,11 @@ builder_manifest_set_property (GObject *object,
self->rename_appdata_file = g_value_dup_string (value);
break;
case PROP_APPDATA_LICENSE:
g_free (self->appdata_license);
self->appdata_license = g_value_dup_string (value);
break;
case PROP_RENAME_ICON:
g_free (self->rename_icon);
self->rename_icon = g_value_dup_string (value);
@ -905,6 +919,13 @@ builder_manifest_class_init (BuilderManifestClass *klass)
"",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_APPDATA_LICENSE,
g_param_spec_string ("appdata-license",
"",
"",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property (object_class,
PROP_RENAME_ICON,
g_param_spec_string ("rename-icon",
@ -1543,6 +1564,7 @@ builder_manifest_checksum_for_cleanup (BuilderManifest *self,
builder_cache_checksum_strv (cache, self->cleanup_commands);
builder_cache_checksum_str (cache, self->rename_desktop_file);
builder_cache_checksum_str (cache, self->rename_appdata_file);
builder_cache_checksum_compat_str (cache, self->appdata_license);
builder_cache_checksum_str (cache, self->rename_icon);
builder_cache_checksum_boolean (cache, self->copy_icon);
builder_cache_checksum_str (cache, self->desktop_file_name_prefix);
@ -2028,6 +2050,62 @@ strcatv (char **strv1,
return retval;
}
static gboolean
rewrite_appdata (GFile *file,
const char *license,
GError **error)
{
g_autofree gchar *data = NULL;
gsize data_len;
g_autoptr(xmlDoc) doc = NULL;
xml_autofree xmlChar *xmlbuff = NULL;
int buffersize;
xmlNode *root_element, *component_node;
if (!g_file_load_contents (file, NULL, &data, &data_len, NULL, error))
return FALSE;
doc = xmlReadMemory (data, data_len, NULL, NULL, 0);
if (doc == NULL)
return flatpak_fail (error, _("Error parsing appstream"));
root_element = xmlDocGetRootElement (doc);
for (component_node = root_element; component_node; component_node = component_node->next)
{
xmlNode *sub_node = NULL;
xmlNode *license_node = NULL;
if (component_node->type != XML_ELEMENT_NODE ||
strcmp ((char *)component_node->name, "component") != 0)
continue;
for (sub_node = component_node->children; sub_node; sub_node = sub_node->next)
{
if (sub_node->type != XML_ELEMENT_NODE ||
strcmp ((char *)sub_node->name, "project_license") != 0)
continue;
license_node = sub_node;
break;
}
if (license_node)
xmlNodeSetContent(license_node, (xmlChar *)license);
else
xmlNewChild(component_node, NULL, (xmlChar *)"project_license", (xmlChar *)license);
}
xmlDocDumpFormatMemory (doc, &xmlbuff, &buffersize, 1);
if (!g_file_set_contents (flatpak_file_get_path_cached (file),
(gchar *)xmlbuff, buffersize,
error))
return FALSE;
return TRUE;
}
gboolean
builder_manifest_cleanup (BuilderManifest *self,
BuilderCache *cache,
@ -2120,6 +2198,12 @@ builder_manifest_cleanup (BuilderManifest *self,
return FALSE;
}
if (self->appdata_license != NULL && self->appdata_license[0] != 0)
{
if (!rewrite_appdata (appdata_file, self->appdata_license, error))
return FALSE;
}
if (self->rename_desktop_file != NULL)
{
g_autoptr(GFile) applications_dir = g_file_resolve_relative_path (app_root, "share/applications");

View File

@ -25,6 +25,8 @@
#include <libsoup/soup.h>
#include <json-glib/json-glib.h>
#include <libxml/tree.h>
G_BEGIN_DECLS
typedef struct BuilderUtils BuilderUtils;
@ -75,6 +77,18 @@ GParamSpec * builder_serializable_find_property_with_error (JsonSerializable *se
void builder_set_term_title (const gchar *format,
...) G_GNUC_PRINTF (1, 2);
static inline void
xml_autoptr_cleanup_generic_free (void *p)
{
void **pp = (void**)p;
if (*pp)
xmlFree (*pp);
}
#define xml_autofree _GLIB_CLEANUP(xml_autoptr_cleanup_generic_free)
G_DEFINE_AUTOPTR_CLEANUP_FUNC (xmlDoc, xmlFreeDoc)
G_END_DECLS
#endif /* __BUILDER_UTILS_H__ */