<commit_before>/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 *
 * Copyright (C) 2014-2015 <NAME> <<EMAIL>>
 *
 * 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-task
 * @short_description: One specific task for building metadata.
 * @stability: Unstable
 *
 * Thsi object represents a single task, typically a package which is created
 * and then processed. Typically this is done in a number of threads.
 */

#include "config.h"

#include "asb-context-private.h"
#include "asb-task.h"
#include "asb-package.h"
#include "asb-utils.h"
#include "asb-plugin.h"
#include "asb-plugin-loader.h"

typedef struct
{
	AsbContext		*ctx;
	AsbPackage		*pkg;
	GPtrArray		*plugins_to_run;
	gchar			*filename;
	gchar			*tmpdir;
} AsbTaskPrivate;

G_DEFINE_TYPE_WITH_PRIVATE (AsbTask, asb_task, G_TYPE_OBJECT)

#define GET_PRIVATE(o) (asb_task_get_instance_private (o))

static void
asb_task_add_suitable_plugins (AsbTask *task)
{
	AsbPluginLoader *plugin_loader;
	AsbPlugin *plugin;
	AsbTaskPrivate *priv = GET_PRIVATE (task);
	gchar **filelist;
	guint i;
	guint j;

	filelist = asb_package_get_filelist (priv->pkg);
	if (filelist == NULL)
		return;
	plugin_loader = asb_context_get_plugin_loader (priv->ctx);
	for (i = 0; filelist[i] != NULL; i++) {
		plugin = asb_plugin_loader_match_fn (plugin_loader, filelist[i]);
		if (plugin == NULL)
			continue;

		/* check not already added */
		for (j = 0; j < priv->plugins_to_run->len; j++) {
			if (g_ptr_array_index (priv->plugins_to_run, j) == plugin)
				break;
		}

		/* add */
		if (j == priv->plugins_to_run->len)
			g_ptr_array_add (priv->plugins_to_run, plugin);
	}
}

static gboolean
asb_task_explode_extra_package (AsbTask *task,
				const gchar *pkg_name,
				gboolean require_same_srpm,
				GError **error)
{
	AsbTaskPrivate *priv = GET_PRIVATE (task);
	AsbPackage *pkg_extra;

	/* if not found, that's fine */
	pkg_extra = asb_context_find_by_pkgname (priv->ctx, pkg_name);
	if (pkg_extra == NULL)
		return TRUE;

	/* check it's from the same source package */
	if (!asb_package_ensure (pkg_extra,
				 ASB_PACKAGE_ENSURE_SOURCE,
				 error))
		return FALSE;
	if (require_same_srpm &&
	    (g_strcmp0 (asb_package_get_source (pkg_extra),
		        asb_package_get_source (priv->pkg)) != 0))
		return TRUE;
	g_debug ("decompressing extra pkg %s", asb_package_get_name (pkg_extra));
	asb_package_log (priv->pkg,
			 ASB_PACKAGE_LOG_LEVEL_DEBUG,
			 "Adding extra package %s for %s",
			 asb_package_get_name (pkg_extra),
			 asb_package_get_name (priv->pkg));
	if (!asb_package_ensure (pkg_extra,
				 ASB_PACKAGE_ENSURE_FILES |
				 ASB_PACKAGE_ENSURE_DEPS,
				 error))
		return FALSE;
	if (!asb_package_explode (pkg_extra, priv->tmpdir,
				  asb_context_get_file_globs (priv->ctx),
				  error))
		return FALSE;

	/* free resources */
	if (!asb_package_close (pkg_extra, error))
		return FALSE;
	asb_package_clear (pkg_extra,
			   ASB_PACKAGE_ENSURE_DEPS |
			   ASB_PACKAGE_ENSURE_FILES);

	return TRUE;
}

typedef struct {
	GPtrArray	*results;
	GHashTable	*results_hash;
} AsbTaskExtraDeps;

static void
asb_task_extra_deps_free (AsbTaskExtraDeps *extra_deps)
{
	g_ptr_array_unref (extra_deps->results);
	g_hash_table_unref (extra_deps->results_hash);
	g_slice_free (AsbTaskExtraDeps, extra_deps);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC(AsbTaskExtraDeps, asb_task_extra_deps_free);

static gboolean
asb_task_get_extra_deps_recursive (AsbTask *task,
                                   const gchar *dep,
                                   AsbTaskExtraDeps *extra_deps,
                                   GError **error)
{
	AsbTaskPrivate *priv = GET_PRIVATE (task);
	AsbPackage *subpkg;
	GPtrArray *subpkg_deps;

	subpkg = asb_context_find_by_pkgname (priv->ctx, dep);
	if (subpkg == NULL)
		return TRUE;

	if (!asb_package_ensure (subpkg,
				 ASB_PACKAGE_ENSURE_DEPS,
				 error))
		return FALSE;

	subpkg_deps = asb_package_get_deps (subpkg);
	for (guint i = 0; i < subpkg_deps->len; i++) {
		const gchar *subpkg_dep = g_ptr_array_index (subpkg_deps, i);

		/* same as the parent? */
		if (g_strcmp0 (subpkg_dep, dep) == 0)
			continue;

		/* already processed? */
		if (g_hash_table_lookup (extra_deps->results_hash, subpkg_dep) != NULL)
			continue;

		/* process recursively */
		g_hash_table_insert (extra_deps->results_hash,
				     g_strdup (subpkg_dep),
				     GINT_TO_POINTER (1));
		if (!asb_task_get_extra_deps_recursive (task, subpkg_dep, extra_deps, error))
			return FALSE;

		/* add to results */
		g_ptr_array_add (extra_deps->results, g_strdup (subpkg_dep));
	}

	return TRUE;
}

static gboolean
asb_task_add_extra_deps (AsbTask *task, GError **error)
{
	AsbTaskPrivate *priv = GET_PRIVATE (task);<commit_msg>Revert "trivial: Prevent recusion when a package lists itself as a dep"<commit_after>/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 *
 * Copyright (C) 2014-2015 <NAME> <<EMAIL>>
 *
 * 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-task
 * @short_description: One specific task for building metadata.
 * @stability: Unstable
 *
 * Thsi object represents a single task, typically a package which is created
 * and then processed. Typically this is done in a number of threads.
 */

#include "config.h"

#include "asb-context-private.h"
#include "asb-task.h"
#include "asb-package.h"
#include "asb-utils.h"
#include "asb-plugin.h"
#include "asb-plugin-loader.h"

typedef struct
{
	AsbContext		*ctx;
	AsbPackage		*pkg;
	GPtrArray		*plugins_to_run;
	gchar			*filename;
	gchar			*tmpdir;
} AsbTaskPrivate;

G_DEFINE_TYPE_WITH_PRIVATE (AsbTask, asb_task, G_TYPE_OBJECT)

#define GET_PRIVATE(o) (asb_task_get_instance_private (o))

static void
asb_task_add_suitable_plugins (AsbTask *task)
{
	AsbPluginLoader *plugin_loader;
	AsbPlugin *plugin;
	AsbTaskPrivate *priv = GET_PRIVATE (task);
	gchar **filelist;
	guint i;
	guint j;

	filelist = asb_package_get_filelist (priv->pkg);
	if (filelist == NULL)
		return;
	plugin_loader = asb_context_get_plugin_loader (priv->ctx);
	for (i = 0; filelist[i] != NULL; i++) {
		plugin = asb_plugin_loader_match_fn (plugin_loader, filelist[i]);
		if (plugin == NULL)
			continue;

		/* check not already added */
		for (j = 0; j < priv->plugins_to_run->len; j++) {
			if (g_ptr_array_index (priv->plugins_to_run, j) == plugin)
				break;
		}

		/* add */
		if (j == priv->plugins_to_run->len)
			g_ptr_array_add (priv->plugins_to_run, plugin);
	}
}

static gboolean
asb_task_explode_extra_package (AsbTask *task,
				const gchar *pkg_name,
				gboolean require_same_srpm,
				GError **error)
{
	AsbTaskPrivate *priv = GET_PRIVATE (task);
	AsbPackage *pkg_extra;

	/* if not found, that's fine */
	pkg_extra = asb_context_find_by_pkgname (priv->ctx, pkg_name);
	if (pkg_extra == NULL)
		return TRUE;

	/* check it's from the same source package */
	if (!asb_package_ensure (pkg_extra,
				 ASB_PACKAGE_ENSURE_SOURCE,
				 error))
		return FALSE;
	if (require_same_srpm &&
	    (g_strcmp0 (asb_package_get_source (pkg_extra),
		        asb_package_get_source (priv->pkg)) != 0))
		return TRUE;
	g_debug ("decompressing extra pkg %s", asb_package_get_name (pkg_extra));
	asb_package_log (priv->pkg,
			 ASB_PACKAGE_LOG_LEVEL_DEBUG,
			 "Adding extra package %s for %s",
			 asb_package_get_name (pkg_extra),
			 asb_package_get_name (priv->pkg));
	if (!asb_package_ensure (pkg_extra,
				 ASB_PACKAGE_ENSURE_FILES |
				 ASB_PACKAGE_ENSURE_DEPS,
				 error))
		return FALSE;
	if (!asb_package_explode (pkg_extra, priv->tmpdir,
				  asb_context_get_file_globs (priv->ctx),
				  error))
		return FALSE;

	/* free resources */
	if (!asb_package_close (pkg_extra, error))
		return FALSE;
	asb_package_clear (pkg_extra,
			   ASB_PACKAGE_ENSURE_DEPS |
			   ASB_PACKAGE_ENSURE_FILES);

	return TRUE;
}

typedef struct {
	GPtrArray	*results;
	GHashTable	*results_hash;
} AsbTaskExtraDeps;

static void
asb_task_extra_deps_free (AsbTaskExtraDeps *extra_deps)
{
	g_ptr_array_unref (extra_deps->results);
	g_hash_table_unref (extra_deps->results_hash);
	g_slice_free (AsbTaskExtraDeps, extra_deps);
}

G_DEFINE_AUTOPTR_CLEANUP_FUNC(AsbTaskExtraDeps, asb_task_extra_deps_free);

static gboolean
asb_task_get_extra_deps_recursive (AsbTask *task,
                                   const gchar *dep,
                                   AsbTaskExtraDeps *extra_deps,
                                   GError **error)
{
	AsbTaskPrivate *priv = GET_PRIVATE (task);
	AsbPackage *subpkg;
	GPtrArray *subpkg_deps;

	subpkg = asb_context_find_by_pkgname (priv->ctx, dep);
	if (subpkg == NULL)
		return TRUE;

	if (!asb_package_ensure (subpkg,
				 ASB_PACKAGE_ENSURE_DEPS,
				 error))
		return FALSE;

	subpkg_deps = asb_package_get_deps (subpkg);
	for (guint i = 0; i < subpkg_deps->len; i++) {
		const gchar *subpkg_dep = g_ptr_array_index (subpkg_deps, i);

		/* already processed? */
		if (g_hash_table_lookup (extra_deps->results_hash, subpkg_dep) != NULL)
			continue;

		/* process recursively */
		g_hash_table_insert (extra_deps->results_hash,
				     g_strdup (subpkg_dep),
				     GINT_TO_POINTER (1));
		if (!asb_task_get_extra_deps_recursive (task, subpkg_dep, extra_deps, error))
			return FALSE;

		/* add to results */
		g_ptr_array_add (extra_deps->results, g_strdup (subpkg_dep));
	}

	return TRUE;
}

static gboolean
asb_task_add_extra_deps (AsbTask *task, GError **error)
{
	AsbTaskPrivate *priv = GET_PRIVATE (task);
{'fraction_non_alphanumeric': 0.10290623286419302, 'fraction_numerical': 0.005849022116614878, 'mean_word_length': 4.035895075931891, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 51, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5301426', 'n_tokens_mistral': 4258, 'n_tokens_neox': 3912, 'n_words': 1018}