715 lines
19 KiB
Diff
715 lines
19 KiB
Diff
From b31fb56588c264d297ca04f36a7b3162d3db7736 Mon Sep 17 00:00:00 2001
|
|
From: Ikey Doherty <ikey@solus-project.com>
|
|
Date: Sun, 26 Jul 2015 16:01:47 +0100
|
|
Subject: [PATCH 1/2] builder: Implement support for Solus .pisi format
|
|
|
|
This format is employed by the Solus Operating System, and is implemented
|
|
in such a manner that it does not need to rely on executing the external
|
|
pisi program, which is Pythonic, thus slower.
|
|
|
|
This utilises code that is part of an ongoing rewrite of pisi, as such
|
|
in the future it would be refactored to use a 'libpisi'. As such no pretense
|
|
is held to support the "PiSi" format, which the Pythonic pisi is forked from,
|
|
as that support will not hold in the future in libpisi.
|
|
|
|
As of 25 Jun 2021, this patch adapted for appstream-glib 0.7.18 and .pisi format by:
|
|
Berk Çakar <berkcakar@pisilinux.org>
|
|
|
|
Signed-off-by: Ikey Doherty <ikey@solus-project.com>
|
|
---
|
|
meson.build | 6 ++++++
|
|
meson_options.txt | 1 +
|
|
libappstream-builder/meson.build | 8 ++++++++
|
|
libappstream-builder/asb-context.c | 7 +++++++
|
|
libappstream-builder/asb-package-pisi.c | 532 +++++++++++++++++++++++++++++++
|
|
libappstream-builder/asb-package-pisi.h | 60 ++++
|
|
5 files changed, 613 insertions(+)
|
|
create mode 100644 libappstream-builder/asb-package-pisi.c
|
|
create mode 100644 libappstream-builder/asb-package-pisi.h
|
|
|
|
--- a/meson.build
|
|
+++ b/meson.build
|
|
@@ -97,6 +97,12 @@ if get_option('rpm')
|
|
conf.set('HAVE_RPM', 1)
|
|
endif
|
|
|
|
+if get_option('pisi')
|
|
+ # dummy dependency for now...
|
|
+ pisi = dependency('libxml-2.0')
|
|
+ conf.set('HAVE_PISI', 1)
|
|
+endif
|
|
+
|
|
# support loading yaml files
|
|
if get_option('dep11')
|
|
yaml = dependency('yaml-0.1')
|
|
diff --git a/meson_options.txt b/meson_options.txt
|
|
index 518ed89..9d6d543 100644
|
|
--- a/meson_options.txt
|
|
+++ b/meson_options.txt
|
|
@@ -2,6 +2,7 @@ option('dep11', type : 'boolean', value : true, description : 'enable DEP-11')
|
|
option('builder', type : 'boolean', value : true, description : 'enable AppStream builder')
|
|
option('rpm', type : 'boolean', value : true, description : 'enable RPM support')
|
|
option('alpm', type : 'boolean', value : false, description : 'enable ALPM support')
|
|
+option('pisi', type : 'boolean', value : false, description : 'enable PiSi support')
|
|
option('fonts', type : 'boolean', value : true, description : 'enable font support')
|
|
option('stemmer', type : 'boolean', value : true, description : 'enable stemmer support')
|
|
option('man', type : 'boolean', value : true, description : 'generate man pages')
|
|
diff --git a/libappstream-builder/meson.build b/libappstream-builder/meson.build
|
|
index 79e8a74..bf85c5d 100644
|
|
--- a/libappstream-builder/meson.build
|
|
+++ b/libappstream-builder/meson.build
|
|
@@ -25,6 +25,10 @@ if get_option('alpm')
|
|
deps = deps + [alpm]
|
|
endif
|
|
|
|
+if get_option('pisi')
|
|
+ deps = deps + [pisi]
|
|
+endif
|
|
+
|
|
sources = [
|
|
'asb-app.c',
|
|
'asb-context.c',
|
|
@@ -45,6 +49,10 @@ if get_option('alpm')
|
|
sources = sources + ['asb-package-alpm.c']
|
|
endif
|
|
|
|
+if get_option('pisi')
|
|
+ sources = sources + ['asb-package-pisi.c']
|
|
+endif
|
|
+
|
|
top_build_incdir = include_directories('..')
|
|
|
|
asbuilder = static_library(
|
|
diff --git a/libappstream-builder/asb-context.c b/libappstream-builder/asb-context.c
|
|
index e2b83df..4fefadd 100644
|
|
--- a/libappstream-builder/asb-context.c
|
|
+++ b/libappstream-builder/asb-context.c
|
|
@@ -32,6 +32,9 @@
|
|
#ifdef HAVE_ALPM
|
|
#include "asb-package-alpm.h"
|
|
#endif
|
|
+#ifdef HAVE_PISI
|
|
+#include "asb-package-pisi.h"
|
|
+#endif
|
|
#include "asb-package-cab.h"
|
|
#include "asb-package-deb.h"
|
|
|
|
@@ -447,6 +452,10 @@ asb_context_add_filename (AsbContext *ctx, const gchar *filename, GError **error
|
|
if (g_str_has_suffix (filename, ".pkg.tar") ||
|
|
g_str_has_suffix (filename, ".pkg.tar.xz"))
|
|
pkg = asb_package_alpm_new ();
|
|
-#endif
|
|
+#endif
|
|
+#ifdef HAVE_PISI
|
|
+ if (g_str_has_suffix (filename, ".pisi"))
|
|
+ pkg = asb_package_pisi_new ();
|
|
+#endif
|
|
if (g_str_has_suffix (filename, ".cab"))
|
|
pkg = asb_package_cab_new ();
|
|
diff --git a/libappstream-builder/asb-package-pisi.c b/libappstream-builder/asb-package-pisi.c
|
|
new file mode 100644
|
|
index 0000000..cf6572c
|
|
--- /dev/null
|
|
+++ b/libappstream-builder/asb-package-pisi.c
|
|
@@ -0,0 +1,532 @@
|
|
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
|
+ *
|
|
+ * Copyright (C) 2015 Ikey Doherty <ikey@solus-project.com>
|
|
+ *
|
|
+ * Licensed under the GNU Lesser General Public License Version 2.1
|
|
+ *
|
|
+ * This library 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, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
+ */
|
|
+
|
|
+/**
|
|
+ * SECTION:asb-package-pisi
|
|
+ * @short_description: Object representing a .PISI package file.
|
|
+ * @stability: Unstable
|
|
+ *
|
|
+ * This object represents one .pisi package file.
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+
|
|
+#include "asb-package-pisi.h"
|
|
+#include "asb-plugin.h"
|
|
+
|
|
+#include <archive.h>
|
|
+#include <archive_entry.h>
|
|
+#include <libxml/xmlreader.h>
|
|
+#include <errno.h>
|
|
+#include <string.h>
|
|
+
|
|
+G_DEFINE_TYPE (AsbPackagePisi, asb_package_pisi, ASB_TYPE_PACKAGE)
|
|
+
|
|
+/**
|
|
+ * Storage for pisi metadata
|
|
+ */
|
|
+typedef struct pisi_meta_t {
|
|
+ gchar *name; /**<Binary package name */
|
|
+ gchar *source; /**<Distro source name */
|
|
+ gint release; /**<Release number */
|
|
+ gchar *version; /**<Package version */
|
|
+ gchar *url; /**<Upstream URL, i.e. homepage */
|
|
+ GSList *deps; /**<List of string-name dependencies */
|
|
+ GSList *licenses; /**<List of licenses (usually SPDX) */
|
|
+} pisi_meta_t;
|
|
+
|
|
+/**
|
|
+ * State tracking for metadata.xml traversal
|
|
+ */
|
|
+typedef struct meta_state_t {
|
|
+ gboolean in_name;
|
|
+ gboolean in_source;
|
|
+ gboolean in_packager;
|
|
+ gboolean in_url;
|
|
+ gboolean in_dep;
|
|
+ gboolean in_rundeps;
|
|
+ gboolean in_license;
|
|
+ gboolean in_package;
|
|
+ gboolean in_update;
|
|
+ gboolean in_version;
|
|
+ gboolean need_update;
|
|
+} meta_state_t;
|
|
+
|
|
+/**
|
|
+ * State tracking for files.xml traversal
|
|
+ */
|
|
+typedef struct file_state_t {
|
|
+ gboolean in_file;
|
|
+ gboolean in_path;
|
|
+} file_state_t;
|
|
+
|
|
+/**
|
|
+ * Complete binary .pisi representation
|
|
+ */
|
|
+typedef struct pisi_t {
|
|
+ pisi_meta_t *meta; /**<Metadata */
|
|
+ GPtrArray *files; /**<List of files (not directories) */
|
|
+} pisi_t;
|
|
+
|
|
+
|
|
+/**
|
|
+ * Process metadata.xml node
|
|
+ */
|
|
+gboolean process_meta_node(meta_state_t *self, pisi_meta_t *meta, xmlTextReaderPtr r);
|
|
+
|
|
+/**
|
|
+ * Examine a metadata file, returning the appropriate storage when complete
|
|
+ */
|
|
+pisi_meta_t *examine_metadata(const char *filename);
|
|
+
|
|
+/**
|
|
+ * Process a files.xml node
|
|
+ */
|
|
+gboolean process_file_node(file_state_t *self, GPtrArray *ret, xmlTextReaderPtr r);
|
|
+
|
|
+/**
|
|
+ * Examine a files xml file, returning the appropriate storage when complete
|
|
+ */
|
|
+GPtrArray *examine_files(const char *filename);
|
|
+
|
|
+/**
|
|
+ * Utility to free an pisi_meta_t
|
|
+ */
|
|
+void pisi_meta_free(pisi_meta_t *pisi);
|
|
+
|
|
+/**
|
|
+ * Free sources for an pisi_t
|
|
+ */
|
|
+void close_pisi(pisi_t *pisi);
|
|
+
|
|
+/**
|
|
+ * Open, and inspect, the archive identified by filename. This must be an
|
|
+ * .pisi file
|
|
+ */
|
|
+pisi_t *open_pisi(const char *filename);
|
|
+
|
|
+gboolean process_meta_node(meta_state_t *self, pisi_meta_t *meta, xmlTextReaderPtr r)
|
|
+{
|
|
+ const xmlChar *name = NULL;
|
|
+ int rel;
|
|
+ const xmlChar *val = NULL;
|
|
+
|
|
+ name = xmlTextReaderConstName(r);
|
|
+ if (!name) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (xmlStrEqual(name, BAD_CAST "Source")) {
|
|
+ self->in_source = !self->in_source;
|
|
+ } else if (xmlStrEqual(name, BAD_CAST "Package")) {
|
|
+ self->in_package = !self->in_package;
|
|
+ } else if (xmlStrEqual(name, BAD_CAST "Update")) {
|
|
+ self->in_update = !self->in_update;
|
|
+ if (self->in_update) {
|
|
+ xmlChar *attr = xmlTextReaderGetAttribute(r, BAD_CAST "release");
|
|
+ if (!attr) {
|
|
+ fprintf(stderr, "Malformed spec: No release ID\n");
|
|
+ return FALSE;
|
|
+ }
|
|
+ rel = atoi((const char*)attr);
|
|
+ if (rel > meta->release) {
|
|
+ meta->release = rel;
|
|
+ self->need_update = TRUE;
|
|
+ }
|
|
+ xmlFree(attr);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (self->in_source) {
|
|
+ if (xmlStrEqual(name, BAD_CAST "Name")) {
|
|
+ self->in_name = !self->in_name;
|
|
+ } else if (xmlStrEqual(name, BAD_CAST "Packager")) {
|
|
+ self->in_packager = !self->in_packager;
|
|
+ } else if (xmlStrEqual(name, BAD_CAST "Homepage")) {
|
|
+ self->in_url = !self->in_url;
|
|
+ }
|
|
+ if (self->in_name && !self->in_packager && !meta->source) {
|
|
+ val = xmlTextReaderConstValue(r);
|
|
+ if (!val) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ meta->source = g_strdup((gchar*)val);
|
|
+ } else if (self->in_url && !meta->url) {
|
|
+ val = xmlTextReaderConstValue(r);
|
|
+ if (!val) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ meta->url = g_strdup((gchar*)val);
|
|
+ }
|
|
+ } else if (self->in_package) {
|
|
+ if (xmlStrEqual(name, BAD_CAST "Name")) {
|
|
+ self->in_name = !self->in_name;
|
|
+ } else if (xmlStrEqual(name, BAD_CAST "License")) {
|
|
+ self->in_license = !self->in_license;
|
|
+ } else if (xmlStrEqual(name, BAD_CAST "RuntimeDependencies")) {
|
|
+ self->in_rundeps = !self->in_rundeps;
|
|
+ }
|
|
+ if (self->in_name && !self->in_update) {
|
|
+ val = xmlTextReaderConstValue(r);
|
|
+ if (!val) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ meta->name = g_strdup((gchar*)val);
|
|
+ } else if (self->in_license) {
|
|
+ val = xmlTextReaderConstValue(r);
|
|
+ if (!val) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ meta->licenses = g_slist_prepend(meta->licenses, g_strdup((gchar*)val));
|
|
+ } else if (self->in_rundeps) {
|
|
+ if (xmlStrEqual(name, BAD_CAST "Dependency")) {
|
|
+ self->in_dep = !self->in_dep;
|
|
+ }
|
|
+ val = xmlTextReaderConstValue(r);
|
|
+ if (self->in_dep && val) {
|
|
+ meta->deps = g_slist_prepend(meta->deps, g_strdup((gchar*)val));
|
|
+ }
|
|
+ } else if (self->in_update && self->need_update) {
|
|
+ /* invariably we'll hit here only once from sorted (default) high-to-low history in spec */
|
|
+ if (xmlStrEqual(name, BAD_CAST "Version")) {
|
|
+ self->in_version = !self->in_version;
|
|
+ }
|
|
+ if (self->in_version) {
|
|
+ val = xmlTextReaderConstValue(r);
|
|
+ if (!val) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ if (meta->version) {
|
|
+ g_free(meta->version);
|
|
+ }
|
|
+ meta->version = g_strdup((gchar*)val);
|
|
+ self->need_update = FALSE;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+pisi_meta_t *examine_metadata(const char *filename)
|
|
+{
|
|
+ xmlTextReaderPtr r = xmlReaderForFile(filename, NULL, 0);
|
|
+ int ret;
|
|
+ meta_state_t self = {0};
|
|
+ pisi_meta_t *meta = NULL;
|
|
+
|
|
+ meta = calloc(1, sizeof(pisi_meta_t));
|
|
+ if (!meta) {
|
|
+ fprintf(stderr, "OOM\n");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ while ((ret = xmlTextReaderRead(r)) > 0) {
|
|
+ if (!process_meta_node(&self, meta, r)) {
|
|
+ fprintf(stderr, "process_meta_node exited abnormally\n");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ xmlFreeTextReader(r);
|
|
+ return meta;
|
|
+}
|
|
+
|
|
+gboolean process_file_node(file_state_t *self, GPtrArray *ret, xmlTextReaderPtr r)
|
|
+{
|
|
+ const xmlChar *name = NULL;
|
|
+
|
|
+ name = xmlTextReaderConstName(r);
|
|
+ if (!name) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (xmlStrEqual(name, BAD_CAST "File")) {
|
|
+ self->in_file = !self->in_file;
|
|
+ } else if (self->in_file && xmlStrEqual(name, BAD_CAST "Path")) {
|
|
+ self->in_path = !self->in_path;
|
|
+ } else if (self->in_path) {
|
|
+ const xmlChar *val = xmlTextReaderConstValue(r);
|
|
+ gchar *tmp = NULL;
|
|
+ if (!val) {
|
|
+ return TRUE;
|
|
+ }
|
|
+ if (val[0] != '/') {
|
|
+ tmp = g_strdup_printf("/%s", (gchar*)val);
|
|
+ } else {
|
|
+ tmp = g_strdup((gchar*)val);
|
|
+ }
|
|
+ g_ptr_array_add(ret, tmp);
|
|
+ }
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+GPtrArray *examine_files(const char *filename)
|
|
+{
|
|
+ xmlTextReaderPtr r = xmlReaderForFile(filename, NULL, 0);
|
|
+ int ret;
|
|
+ file_state_t self = {0};
|
|
+ GPtrArray *arr = NULL;
|
|
+
|
|
+ arr = g_ptr_array_new_with_free_func(g_free);
|
|
+ if (!arr) {
|
|
+ fprintf(stderr, "OOM\n");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ while ((ret = xmlTextReaderRead(r)) > 0) {
|
|
+ if (!process_file_node(&self, arr, r)) {
|
|
+ fprintf(stderr, "process_file_node exited abnormally\n");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ g_ptr_array_add(arr, NULL);
|
|
+
|
|
+ xmlFreeTextReader(r);
|
|
+ return arr;
|
|
+}
|
|
+
|
|
+void pisi_meta_free(pisi_meta_t *pisi)
|
|
+{
|
|
+ if (!pisi) {
|
|
+ return;
|
|
+ }
|
|
+ if (pisi->name) {
|
|
+ g_free(pisi->name);
|
|
+ }
|
|
+ if (pisi->source) {
|
|
+ g_free(pisi->source);
|
|
+ }
|
|
+ if (pisi->version) {
|
|
+ g_free(pisi->version);
|
|
+ }
|
|
+ if (pisi->url) {
|
|
+ g_free(pisi->url);
|
|
+ }
|
|
+ if (pisi->deps) {
|
|
+ g_slist_free_full(pisi->deps, g_free);
|
|
+ }
|
|
+ if (pisi->licenses) {
|
|
+ g_slist_free_full(pisi->licenses, g_free);
|
|
+ }
|
|
+ free(pisi);
|
|
+}
|
|
+
|
|
+void close_pisi(pisi_t *pisi)
|
|
+{
|
|
+ if (pisi->meta) {
|
|
+ pisi_meta_free(pisi->meta);
|
|
+ }
|
|
+ if (pisi->files) {
|
|
+ g_ptr_array_unref(pisi->files);
|
|
+ }
|
|
+ free(pisi);
|
|
+}
|
|
+
|
|
+pisi_t *open_pisi(const char *filename)
|
|
+{
|
|
+ pisi_t *ret = NULL;
|
|
+ pisi_meta_t *meta = NULL;
|
|
+ GPtrArray *files = NULL;
|
|
+ struct archive *a = NULL;
|
|
+ struct archive_entry *entry = NULL;
|
|
+ int r;
|
|
+ char fname[PATH_MAX];
|
|
+ char template[] = "/tmp/solus-pisi-XXXXXX";
|
|
+ int fd;
|
|
+
|
|
+ a = archive_read_new();
|
|
+ archive_read_support_filter_all(a);
|
|
+ archive_read_support_format_all(a);
|
|
+
|
|
+ /* open 'er up */
|
|
+ r = archive_read_open_filename(a, filename, 10480);
|
|
+ if (r != ARCHIVE_OK) {
|
|
+ fprintf(stderr, "Unable to open archive\n");
|
|
+ goto clean;
|
|
+ }
|
|
+
|
|
+ while (archive_read_next_header(a, &entry) == ARCHIVE_OK) {
|
|
+ const char *name = archive_entry_pathname(entry);
|
|
+ gboolean filesxml = FALSE;
|
|
+
|
|
+ if ((filesxml = g_str_equal(name, "files.xml")) || g_str_equal(name, "metadata.xml")) {
|
|
+ strncpy(fname, template, sizeof(template));
|
|
+ fd = mkstemp(fname);
|
|
+ if (fd <= 0) {
|
|
+ fprintf(stderr, "Failed to open temporary file: %s\n", strerror(errno));
|
|
+ goto clean;
|
|
+ }
|
|
+
|
|
+ r = archive_read_data_into_fd(a, fd);
|
|
+ if (r != ARCHIVE_OK) {
|
|
+ fprintf(stderr, "Failed to extra file: %s\n", name);
|
|
+ close(fd);
|
|
+ (void)unlink(fname);
|
|
+ goto clean;
|
|
+ }
|
|
+
|
|
+ if (filesxml) {
|
|
+ files = examine_files(fname);
|
|
+ } else {
|
|
+ meta = examine_metadata(fname);
|
|
+ }
|
|
+ close(fd);
|
|
+ (void)unlink(fname);
|
|
+
|
|
+ } else {
|
|
+ archive_read_data_skip(a);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!meta) {
|
|
+ fprintf(stderr, "Failed to inspect metadata\n");
|
|
+ goto bail;
|
|
+ }
|
|
+ if (!files) {
|
|
+ fprintf(stderr, "Failed to inspect files\n");
|
|
+ goto bail;
|
|
+ }
|
|
+
|
|
+ ret = calloc(1, sizeof(pisi_t));
|
|
+ if (!ret) {
|
|
+ fprintf(stderr, "OOM\n");
|
|
+ goto bail;
|
|
+ }
|
|
+
|
|
+ ret->meta = meta;
|
|
+ ret->files = files;
|
|
+
|
|
+clean:
|
|
+ archive_read_free(a);
|
|
+
|
|
+ return ret;
|
|
+
|
|
+bail:
|
|
+ if (meta) {
|
|
+ pisi_meta_free(meta);
|
|
+ }
|
|
+ if (files) {
|
|
+ g_ptr_array_unref(files);
|
|
+ }
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * asb_package_pisi_init:
|
|
+ **/
|
|
+static void
|
|
+asb_package_pisi_init (AsbPackagePisi *pkg)
|
|
+{
|
|
+}
|
|
+
|
|
+
|
|
+/**
|
|
+ * asb_package_pisi_open:
|
|
+ **/
|
|
+static gboolean
|
|
+asb_package_pisi_open (AsbPackage *pkg, const gchar *filename, GError **error)
|
|
+{
|
|
+ pisi_t *pisi = NULL;
|
|
+ gchar *rel = NULL;
|
|
+ GSList *elem = NULL;
|
|
+
|
|
+ pisi = open_pisi(filename);
|
|
+ if (!pisi)
|
|
+ return FALSE;
|
|
+
|
|
+ asb_package_set_name (pkg, pisi->meta->name);
|
|
+ asb_package_set_source (pkg, pisi->meta->source);
|
|
+
|
|
+ rel = g_strdup_printf ("%d", pisi->meta->release);
|
|
+ asb_package_set_release (pkg, rel);
|
|
+ asb_package_set_version (pkg, pisi->meta->version);
|
|
+ asb_package_set_epoch (pkg, 1);
|
|
+ g_free(rel);
|
|
+
|
|
+ for (elem = pisi->meta->deps; elem; elem = elem->next) {
|
|
+ asb_package_add_dep (pkg, elem->data);
|
|
+ }
|
|
+ asb_package_set_filelist (pkg, (gchar**)pisi->files->pdata);
|
|
+
|
|
+ asb_package_set_license (pkg, pisi->meta->licenses->data);
|
|
+
|
|
+ close_pisi(pisi);
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * asb_package_pisi_explode:
|
|
+ **/
|
|
+static gboolean
|
|
+asb_package_pisi_explode (AsbPackage *pkg,
|
|
+ const gchar *dir,
|
|
+ GPtrArray *glob,
|
|
+ GError **error)
|
|
+{
|
|
+ const char *name = "install.tar.xz";
|
|
+ g_autofree gchar *tpath = NULL;
|
|
+
|
|
+ if (!asb_utils_explode (asb_package_get_filename (pkg),
|
|
+ dir, NULL, error)) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ tpath = g_build_filename(dir, name, NULL);
|
|
+ if (!g_file_test (tpath, G_FILE_TEST_EXISTS)) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ if (!asb_utils_explode (tpath, dir, glob, error)) {
|
|
+ return FALSE;
|
|
+ }
|
|
+
|
|
+ return TRUE;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * asb_package_pisi_class_init:
|
|
+ **/
|
|
+static void
|
|
+asb_package_pisi_class_init (AsbPackagePisiClass *klass)
|
|
+{
|
|
+ AsbPackageClass *package_class = ASB_PACKAGE_CLASS (klass);
|
|
+ package_class->open = asb_package_pisi_open;
|
|
+ package_class->explode = asb_package_pisi_explode;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * asb_package_pisi_new:
|
|
+ *
|
|
+ * Creates a new PISI package.
|
|
+ *
|
|
+ * Returns: a package
|
|
+ *
|
|
+ * Since: 0.1.0
|
|
+ **/
|
|
+AsbPackage *
|
|
+asb_package_pisi_new (void)
|
|
+{
|
|
+ AsbPackage *pkg;
|
|
+ pkg = g_object_new (ASB_TYPE_PACKAGE_PISI, NULL);
|
|
+ return ASB_PACKAGE (pkg);
|
|
+}
|
|
diff --git a/libappstream-builder/asb-package-pisi.h b/libappstream-builder/asb-package-pisi.h
|
|
new file mode 100644
|
|
index 0000000..08dd01d
|
|
--- /dev/null
|
|
+++ b/libappstream-builder/asb-package-pisi.h
|
|
@@ -0,0 +1,60 @@
|
|
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
|
|
+ *
|
|
+ * Copyright (C) 2015 Ikey Doherty <ikey@solus-project.com>
|
|
+ *
|
|
+ * Licensed under the GNU Lesser General Public License Version 2.1
|
|
+ *
|
|
+ * This library 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, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
+ */
|
|
+
|
|
+#ifndef ASB_PACKAGE_PISI_H
|
|
+#define ASB_PACKAGE_PISI_H
|
|
+
|
|
+#include <glib-object.h>
|
|
+
|
|
+#include <stdarg.h>
|
|
+#include <appstream-glib.h>
|
|
+
|
|
+#include "asb-package.h"
|
|
+
|
|
+#define ASB_TYPE_PACKAGE_PISI (asb_package_pisi_get_type())
|
|
+#define ASB_PACKAGE_PISI(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), ASB_TYPE_PACKAGE_PISI, AsbPackagePisi))
|
|
+#define ASB_PACKAGE_PISI_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST((cls), ASB_TYPE_PACKAGE_PISI, AsbPackagePisiClass))
|
|
+#define ASB_IS_PACKAGE_PISI(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), ASB_TYPE_PACKAGE_PISI))
|
|
+#define ASB_IS_PACKAGE_PISI_CLASS(cls) (G_TYPE_CHECK_CLASS_TYPE((cls), ASB_TYPE_PACKAGE_PISI))
|
|
+#define ASB_PACKAGE_PISI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), ASB_TYPE_PACKAGE_PISI, AsbPackagePisiClass))
|
|
+
|
|
+G_BEGIN_DECLS
|
|
+
|
|
+typedef struct _AsbPackagePisi AsbPackagePisi;
|
|
+typedef struct _AsbPackagePisiClass AsbPackagePisiClass;
|
|
+
|
|
+struct _AsbPackagePisi
|
|
+{
|
|
+ AsbPackage parent;
|
|
+};
|
|
+
|
|
+struct _AsbPackagePisiClass
|
|
+{
|
|
+ AsbPackageClass parent_class;
|
|
+};
|
|
+
|
|
+GType asb_package_pisi_get_type (void);
|
|
+
|
|
+AsbPackage *asb_package_pisi_new (void);
|
|
+
|
|
+G_END_DECLS
|
|
+
|
|
+#endif /* ASB_PACKAGE_PISI_H */
|
|
--
|
|
2.11.0
|