summaryrefslogtreecommitdiff
path: root/libappstream-builder/asb-package.c
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2014-06-17 11:52:49 +0100
committerRichard Hughes <richard@hughsie.com>2014-06-17 12:01:32 +0100
commit1284b3fa0addf21070c6d9ce697623a04862cdde (patch)
treea9ecf1b4d984e41e56179ebd6453288dd712843e /libappstream-builder/asb-package.c
parent0ec1dd10ee2281d4f6e102e4e8da8365332540b1 (diff)
downloadappstream-glib-1284b3fa0addf21070c6d9ce697623a04862cdde.tar.gz
Add libappstream-builder from the createrepo_as project
Diffstat (limited to 'libappstream-builder/asb-package.c')
-rw-r--r--libappstream-builder/asb-package.c780
1 files changed, 780 insertions, 0 deletions
diff --git a/libappstream-builder/asb-package.c b/libappstream-builder/asb-package.c
new file mode 100644
index 0000000..c61de78
--- /dev/null
+++ b/libappstream-builder/asb-package.c
@@ -0,0 +1,780 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2014 Richard Hughes <richard@hughsie.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
+ * @short_description: Object representing a package file.
+ * @stability: Unstable
+ *
+ * This object represents one package file.
+ */
+
+#include "config.h"
+
+#include <limits.h>
+
+#include "as-cleanup.h"
+#include "asb-package.h"
+#include "asb-plugin.h"
+
+typedef struct _AsbPackagePrivate AsbPackagePrivate;
+struct _AsbPackagePrivate
+{
+ gboolean enabled;
+ gchar **filelist;
+ gchar **deps;
+ gchar *filename;
+ gchar *basename;
+ gchar *name;
+ guint epoch;
+ gchar *version;
+ gchar *release;
+ gchar *arch;
+ gchar *url;
+ gchar *nevr;
+ gchar *evr;
+ gchar *license;
+ gchar *source;
+ GString *log;
+ GHashTable *configs;
+ GTimer *timer;
+ gdouble last_log;
+ GPtrArray *releases;
+ GHashTable *releases_hash;
+};
+
+G_DEFINE_TYPE_WITH_PRIVATE (AsbPackage, asb_package, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) (asb_package_get_instance_private (o))
+
+/**
+ * asb_package_finalize:
+ **/
+static void
+asb_package_finalize (GObject *object)
+{
+ AsbPackage *pkg = ASB_PACKAGE (object);
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+
+ g_strfreev (priv->filelist);
+ g_strfreev (priv->deps);
+ g_free (priv->filename);
+ g_free (priv->basename);
+ g_free (priv->name);
+ g_free (priv->version);
+ g_free (priv->release);
+ g_free (priv->arch);
+ g_free (priv->url);
+ g_free (priv->nevr);
+ g_free (priv->evr);
+ g_free (priv->license);
+ g_free (priv->source);
+ g_string_free (priv->log, TRUE);
+ g_timer_destroy (priv->timer);
+ g_hash_table_unref (priv->configs);
+ g_ptr_array_unref (priv->releases);
+ g_hash_table_unref (priv->releases_hash);
+
+ G_OBJECT_CLASS (asb_package_parent_class)->finalize (object);
+}
+
+/**
+ * asb_package_init:
+ **/
+static void
+asb_package_init (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ priv->enabled = TRUE;
+ priv->log = g_string_sized_new (1024);
+ priv->timer = g_timer_new ();
+ priv->configs = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_free);
+ priv->releases = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ priv->releases_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, (GDestroyNotify) g_object_unref);
+}
+
+/**
+ * asb_package_get_enabled:
+ * @pkg: A #AsbPackage
+ *
+ * Gets if the package is enabled.
+ *
+ * Returns: enabled status
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+asb_package_get_enabled (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->enabled;
+}
+
+/**
+ * asb_package_set_enabled:
+ * @pkg: A #AsbPackage
+ * @enabled: boolean
+ *
+ * Enables or disables the package.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_enabled (AsbPackage *pkg, gboolean enabled)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ priv->enabled = enabled;
+}
+
+/**
+ * asb_package_log_start:
+ * @pkg: A #AsbPackage
+ *
+ * Starts the log timer.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_log_start (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_timer_reset (priv->timer);
+}
+
+/**
+ * asb_package_log:
+ * @pkg: A #AsbPackage
+ * @log_level: a #AsbPackageLogLevel
+ * @fmt: Format string
+ * @...: varargs
+ *
+ * Logs a message.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_log (AsbPackage *pkg,
+ AsbPackageLogLevel log_level,
+ const gchar *fmt, ...)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ va_list args;
+ gdouble now;
+ _cleanup_free_ gchar *tmp;
+
+ va_start (args, fmt);
+ tmp = g_strdup_vprintf (fmt, args);
+ va_end (args);
+ if (g_getenv ("ASB_PROFILE") != NULL) {
+ now = g_timer_elapsed (priv->timer, NULL) * 1000;
+ g_string_append_printf (priv->log,
+ "%05.0f\t+%05.0f\t",
+ now, now - priv->last_log);
+ priv->last_log = now;
+ }
+ switch (log_level) {
+ case ASB_PACKAGE_LOG_LEVEL_INFO:
+ g_debug ("INFO: %s", tmp);
+ g_string_append_printf (priv->log, "INFO: %s\n", tmp);
+ break;
+ case ASB_PACKAGE_LOG_LEVEL_DEBUG:
+ g_debug ("DEBUG: %s", tmp);
+ if (g_getenv ("ASB_PROFILE") != NULL)
+ g_string_append_printf (priv->log, "DEBUG: %s\n", tmp);
+ break;
+ case ASB_PACKAGE_LOG_LEVEL_WARNING:
+ g_debug ("WARNING: %s", tmp);
+ g_string_append_printf (priv->log, "WARNING: %s\n", tmp);
+ break;
+ default:
+ g_debug ("%s", tmp);
+ g_string_append_printf (priv->log, "%s\n", tmp);
+ break;
+ }
+}
+
+/**
+ * asb_package_log_flush:
+ * @pkg: A #AsbPackage
+ * @error: A #GError or %NULL
+ *
+ * Flushes the log queue.
+ *
+ * Returns: %TRUE for success, %FALSE otherwise
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+asb_package_log_flush (AsbPackage *pkg, GError **error)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ _cleanup_free_ gchar *logfile;
+
+ /* overwrite old log */
+ logfile = g_strdup_printf ("%s/%s.log",
+ asb_package_get_config (pkg, "LogDir"),
+ asb_package_get_name (pkg));
+ return g_file_set_contents (logfile, priv->log->str, -1, error);
+}
+
+/**
+ * asb_package_get_filename:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the filename of the package.
+ *
+ * Returns: utf8 filename
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+asb_package_get_filename (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->filename;
+}
+
+/**
+ * asb_package_get_basename:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the package basename.
+ *
+ * Returns: utf8 string
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+asb_package_get_basename (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->basename;
+}
+
+/**
+ * asb_package_get_name:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the package name
+ *
+ * Returns: utf8 string
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+asb_package_get_name (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->name;
+}
+
+/**
+ * asb_package_get_url:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the package homepage URL
+ *
+ * Returns: utf8 string
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+asb_package_get_url (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->url;
+}
+
+/**
+ * asb_package_get_license:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the package license.
+ *
+ * Returns: utf8 string
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+asb_package_get_license (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->license;
+}
+
+/**
+ * asb_package_get_source:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the package source name.
+ *
+ * Returns: utf8 string
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+asb_package_get_source (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->source;
+}
+
+/**
+ * asb_package_get_filelist:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the package filelist.
+ *
+ * Returns: (transfer none) (element-type utf8): filelist
+ *
+ * Since: 0.1.0
+ **/
+gchar **
+asb_package_get_filelist (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->filelist;
+}
+
+/**
+ * asb_package_get_deps:
+ * @pkg: A #AsbPackage
+ *
+ * Get the package dependancy list.
+ *
+ * Returns: (transfer none) (element-type utf8): deplist
+ *
+ * Since: 0.1.0
+ **/
+gchar **
+asb_package_get_deps (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->deps;
+}
+
+/**
+ * asb_package_set_name:
+ * @pkg: A #AsbPackage
+ * @name: package name
+ *
+ * Sets the package name.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_name (AsbPackage *pkg, const gchar *name)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_free (priv->name);
+ priv->name = g_strdup (name);
+}
+
+/**
+ * asb_package_set_version:
+ * @pkg: A #AsbPackage
+ * @version: package version
+ *
+ * Sets the package version.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_version (AsbPackage *pkg, const gchar *version)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_free (priv->version);
+ priv->version = g_strdup (version);
+}
+
+/**
+ * asb_package_set_release:
+ * @pkg: A #AsbPackage
+ * @release: package release
+ *
+ * Sets the package release.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_release (AsbPackage *pkg, const gchar *release)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_free (priv->release);
+ priv->release = g_strdup (release);
+}
+
+/**
+ * asb_package_set_arch:
+ * @pkg: A #AsbPackage
+ * @arch: package architecture
+ *
+ * Sets the package architecture.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_arch (AsbPackage *pkg, const gchar *arch)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_free (priv->arch);
+ priv->arch = g_strdup (arch);
+}
+
+/**
+ * asb_package_set_epoch:
+ * @pkg: A #AsbPackage
+ * @epoch: epoch, or 0 for unset
+ *
+ * Sets the package epoch
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_epoch (AsbPackage *pkg, guint epoch)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ priv->epoch = epoch;
+}
+
+/**
+ * asb_package_set_url:
+ * @pkg: A #AsbPackage
+ * @url: homepage URL
+ *
+ * Sets the package URL.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_url (AsbPackage *pkg, const gchar *url)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_free (priv->url);
+ priv->url = g_strdup (url);
+}
+
+/**
+ * asb_package_set_license:
+ * @pkg: A #AsbPackage
+ * @license: license string
+ *
+ * Sets the package license.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_license (AsbPackage *pkg, const gchar *license)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_free (priv->license);
+ priv->license = g_strdup (license);
+}
+
+/**
+ * asb_package_set_source:
+ * @pkg: A #AsbPackage
+ * @source: source string, e.g. the srpm name
+ *
+ * Sets the package source name, which is usually the parent of a set of
+ * subpackages.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_source (AsbPackage *pkg, const gchar *source)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_free (priv->source);
+ priv->source = g_strdup (source);
+}
+
+/**
+ * asb_package_set_deps:
+ * @pkg: A #AsbPackage
+ * @deps: package deps
+ *
+ * Sets the package dependancies.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_deps (AsbPackage *pkg, gchar **deps)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_strfreev (priv->deps);
+ priv->deps = g_strdupv (deps);
+}
+
+/**
+ * asb_package_set_filelist:
+ * @pkg: A #AsbPackage
+ * @filelist: package filelist
+ *
+ * Sets the package filelist.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_filelist (AsbPackage *pkg, gchar **filelist)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_strfreev (priv->filelist);
+ priv->filelist = g_strdupv (filelist);
+}
+
+/**
+ * asb_package_get_nevr:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the package NEVR.
+ *
+ * Returns: utf8 string
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+asb_package_get_nevr (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ if (priv->nevr == NULL) {
+ if (priv->epoch == 0) {
+ priv->nevr = g_strdup_printf ("%s-%s-%s",
+ priv->name,
+ priv->version,
+ priv->release);
+ } else {
+ priv->nevr = g_strdup_printf ("%s-%i:%s-%s",
+ priv->name,
+ priv->epoch,
+ priv->version,
+ priv->release);
+ }
+ }
+ return priv->nevr;
+}
+
+/**
+ * asb_package_get_evr:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the package EVR.
+ *
+ * Returns: utf8 string
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+asb_package_get_evr (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ if (priv->evr == NULL) {
+ if (priv->epoch == 0) {
+ priv->evr = g_strdup_printf ("%s-%s",
+ priv->version,
+ priv->release);
+ } else {
+ priv->evr = g_strdup_printf ("%i:%s-%s",
+ priv->epoch,
+ priv->version,
+ priv->release);
+ }
+ }
+ return priv->evr;
+}
+
+/**
+ * asb_package_class_init:
+ **/
+static void
+asb_package_class_init (AsbPackageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = asb_package_finalize;
+}
+
+/**
+ * asb_package_open:
+ * @pkg: A #AsbPackage
+ * @filename: package filename
+ * @error: A #GError or %NULL
+ *
+ * Opens a package and parses the contents.
+ *
+ * Returns: %TRUE for success, %FALSE otherwise
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+asb_package_open (AsbPackage *pkg, const gchar *filename, GError **error)
+{
+ AsbPackageClass *klass = ASB_PACKAGE_GET_CLASS (pkg);
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+
+ /* cache here */
+ priv->filename = g_strdup (filename);
+ priv->basename = g_path_get_basename (filename);
+
+ /* call distro-specific method */
+ if (klass->open != NULL)
+ return klass->open (pkg, filename, error);
+ return TRUE;
+}
+
+/**
+ * asb_package_explode:
+ * @pkg: A #AsbPackage
+ * @dir: directory to explode into
+ * @glob: (element-type utf8): the glob list, or %NULL
+ * @error: A #GError or %NULL
+ *
+ * Decompresses a package into a directory, optionally using a glob list.
+ *
+ * Returns: %TRUE for success, %FALSE otherwise
+ *
+ * Since: 0.1.0
+ **/
+gboolean
+asb_package_explode (AsbPackage *pkg,
+ const gchar *dir,
+ GPtrArray *glob,
+ GError **error)
+{
+ AsbPackageClass *klass = ASB_PACKAGE_GET_CLASS (pkg);
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ if (klass->explode != NULL)
+ return klass->explode (pkg, dir, glob, error);
+ return asb_utils_explode (priv->filename, dir, glob, error);
+}
+
+/**
+ * asb_package_set_config:
+ * @pkg: A #AsbPackage
+ * @key: utf8 string
+ * @value: utf8 string
+ *
+ * Sets a config attribute on a package.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_set_config (AsbPackage *pkg, const gchar *key, const gchar *value)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_hash_table_insert (priv->configs, g_strdup (key), g_strdup (value));
+}
+
+/**
+ * asb_package_get_config:
+ * @pkg: A #AsbPackage
+ * @key: utf8 string
+ *
+ * Gets a config attribute from a package.
+ *
+ * Returns: utf8 string
+ *
+ * Since: 0.1.0
+ **/
+const gchar *
+asb_package_get_config (AsbPackage *pkg, const gchar *key)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return g_hash_table_lookup (priv->configs, key);
+}
+
+/**
+ * asb_package_get_releases:
+ * @pkg: A #AsbPackage
+ *
+ * Gets the releases of the package.
+ *
+ * Returns: (transfer none) (element-type AsRelease): the release data
+ *
+ * Since: 0.1.0
+ **/
+GPtrArray *
+asb_package_get_releases (AsbPackage *pkg)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return priv->releases;
+}
+
+/**
+ * asb_package_compare:
+ * @pkg1: A #AsbPackage
+ * @pkg2: A #AsbPackage
+ *
+ * Compares one package with another.
+ *
+ * Returns: -1 for <, 0 for the same and +1 for >
+ *
+ * Since: 0.1.0
+ **/
+gint
+asb_package_compare (AsbPackage *pkg1, AsbPackage *pkg2)
+{
+ AsbPackageClass *klass = ASB_PACKAGE_GET_CLASS (pkg1);
+ if (klass->compare != NULL)
+ return klass->compare (pkg1, pkg2);
+ return 0;
+}
+
+/**
+ * asb_package_get_release:
+ * @pkg: A #AsbPackage
+ * @version: package version
+ *
+ * Gets the release for a specific version.
+ *
+ * Returns: (transfer none): an #AsRelease, or %NULL for not found
+ *
+ * Since: 0.1.0
+ **/
+AsRelease *
+asb_package_get_release (AsbPackage *pkg, const gchar *version)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ return g_hash_table_lookup (priv->releases_hash, version);
+}
+
+/**
+ * asb_package_add_release:
+ * @pkg: A #AsbPackage
+ * @version: a package version
+ * @release: a package release
+ *
+ * Adds a (downstream) release to a package.
+ *
+ * Since: 0.1.0
+ **/
+void
+asb_package_add_release (AsbPackage *pkg,
+ const gchar *version,
+ AsRelease *release)
+{
+ AsbPackagePrivate *priv = GET_PRIVATE (pkg);
+ g_hash_table_insert (priv->releases_hash,
+ g_strdup (version),
+ g_object_ref (release));
+ g_ptr_array_add (priv->releases, g_object_ref (release));
+}