Skip to content

Instantly share code, notes, and snippets.

@igor-raits
Last active January 7, 2019 16:08
Show Gist options
  • Select an option

  • Save igor-raits/e4d554c2a2263681f90c971adaf930e9 to your computer and use it in GitHub Desktop.

Select an option

Save igor-raits/e4d554c2a2263681f90c971adaf930e9 to your computer and use it in GitHub Desktop.
#include <locale.h>
#include <stdbool.h>
#include <glib.h>
#include <libsmartcols.h>
#include <solv/pool.h>
#include <solv/repo.h>
#include <solv/repo_solv.h>
#include <json-glib/json-glib.h>
#include <libsoup/soup.h>
enum {
COL_NAME,
COL_MAINTAINERS,
COL_NOTES,
};
static inline char *
join_keys (GHashTable *hash_table,
const char *separator)
{
unsigned int length = 0;
g_autofree char **strv = (char **)g_hash_table_get_keys_as_array (hash_table, &length);
return g_strjoinv (separator, strv);
}
int
main (void)
{
struct libscols_table *tb;
struct libscols_column *cl;
struct libscols_line *ln;
FILE *fp;
Queue q;
g_autoptr(GError) err = NULL;
setlocale (LC_ALL, "");
Pool *pool = pool_create ();
//pool_setdebuglevel (pool, 10);
//scols_init_debug (0xffff);
Repo *repo = repo_create (pool, "rawhide");
fp = fopen ("/var/cache/dnf/rawhide.solv", "rb");
repo_add_solv (repo, fp, 0);
fclose (fp);
Repodata *repodata = repo_add_repodata (repo, 0);
repodata_extend_block (repodata, repo->start, repo->end - repo->start);
fp = fopen ("/var/cache/dnf/rawhide-filenames.solvx", "rb");
repodata->state = REPODATA_LOADING;
repo_add_solv (repo, fp, REPO_USE_LOADING | REPO_EXTEND_SOLVABLES | REPO_LOCALPOOL);
repodata->state = REPODATA_AVAILABLE;
fclose (fp);
repodata_internalize (repodata);
pool_addfileprovides (pool);
pool_createwhatprovides (pool);
/* pkg → [err…] */
g_autoptr(GHashTable) to_fix = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify)g_hash_table_unref);
/* src → [pkg…] */
g_autoptr(GHashTable) smap = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify)g_hash_table_unref);
g_autoptr(JsonParser) json = json_parser_new_immutable ();
#if 0
g_autoptr(SoupSession) soup = soup_session_new ();
g_autoptr(SoupMessage) msg = soup_message_new ("GET", "https://src.fedoraproject.org/extras/pagure_owner_alias.json");
g_autoptr(GInputStream) stream = soup_session_send (soup, msg, NULL, &err);
#else
g_autoptr(GFile) file = g_file_new_for_path ("/var/tmp/pagure_owner_alias.json");
g_autoptr(GInputStream) stream = (GInputStream *)g_file_read (file, NULL, &err);
#endif
if (!stream)
goto err;
if (!json_parser_load_from_stream (json, stream, NULL, &err))
goto err;
JsonObject *root = json_node_get_object (json_parser_get_root (json));
JsonObject *owners = json_object_get_object_member (root, "rpms");
queue_init (&q);
pool_whatmatchesdep (pool,
SOLVABLE_REQUIRES,
pool_str2id (pool,
"/sbin/ldconfig",
1),
&q,
0);
for (int i = 0; i < q.count; i++)
{
Id p = q.elements[i];
Solvable *s = pool_id2solvable (pool, p);
Dataiterator di;
dataiterator_init (&di, pool, 0, p, SOLVABLE_FILELIST, "/etc/ld.so.conf.d/*", SEARCH_FILES | SEARCH_GLOB);
if (dataiterator_step (&di))
{
dataiterator_free (&di);
continue;
}
dataiterator_free (&di);
const char *name = pool_id2str (pool, s->name);
GHashTable *errors = g_hash_table_lookup (to_fix, name);
if (!errors)
{
errors = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (to_fix, g_strdup (name), errors);
}
g_hash_table_add (errors, "Uneeded /sbin/ldconfig");
const char *srcname;
if (solvable_lookup_void(s, SOLVABLE_SOURCENAME))
srcname = pool_id2str (pool, s->name);
else
srcname = solvable_lookup_str (s, SOLVABLE_SOURCENAME);
GHashTable *subpkgs = g_hash_table_lookup (smap, srcname);
if (!subpkgs)
{
subpkgs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_hash_table_insert (smap, g_strdup (srcname), subpkgs);
}
g_hash_table_add (subpkgs, g_strdup (name));
}
queue_free (&q);
tb = scols_new_table ();
cl =scols_table_new_column (tb, "NAME", 0, SCOLS_FL_TREE);
scols_column_set_cmpfunc (cl, scols_cmpstr_cells, NULL);
cl = scols_table_new_column (tb, "MAINTAINERS", 0, SCOLS_FL_WRAP | SCOLS_FL_NOEXTREMES);
scols_column_set_wrapfunc (cl,
scols_wrapnl_chunksize,
scols_wrapnl_nextchunk,
NULL);
scols_column_set_safechars (cl, "\n");
cl = scols_table_new_column (tb, "NOTES", 0, SCOLS_FL_WRAP);
scols_column_set_wrapfunc (cl,
scols_wrapnl_chunksize,
scols_wrapnl_nextchunk,
NULL);
scols_column_set_safechars (cl, "\n");
GHashTableIter iter;
g_hash_table_iter_init (&iter, smap);
gpointer key, value;
while (g_hash_table_iter_next (&iter, &key, &value))
{
const char *srcname = key;
ln = scols_table_new_line (tb, NULL);
scols_line_set_data (ln, COL_NAME, srcname);
JsonArray *owners_array = json_object_get_array_member (owners, srcname);
g_autoptr(GList) pkg_owners = NULL;
for (int i = 0; i < json_array_get_length (owners_array); i++)
/* It is fine to discard const here because we are not going
* to free that data and it is not going to outlive. */
pkg_owners = g_list_insert_sorted (pkg_owners,
(char *)json_array_get_string_element (owners_array, i),
(GCompareFunc)g_strcmp0);
pkg_owners = g_list_first (pkg_owners);
g_autoptr(GString) maintainers = g_string_new (pkg_owners->data);
for (GList *owner = pkg_owners->next; owner; owner = owner->next)
g_string_append_printf (maintainers, "\n%s", (const char *)owner->data);
scols_line_set_data (ln, COL_MAINTAINERS, maintainers->str);
GHashTable *subpkgs = value;
GHashTableIter siter;
g_hash_table_iter_init (&siter, subpkgs);
while (g_hash_table_iter_next (&siter, &key, &value))
{
const char *name = key;
GHashTable *errors = g_hash_table_lookup (to_fix, name);
g_autofree char *notes = join_keys (errors, "\n");
struct libscols_line *xln = scols_table_new_line (tb, ln);
scols_line_set_data (xln, COL_NAME, name);
scols_line_set_data (xln, COL_NOTES, notes);
}
}
scols_sort_table (tb, scols_table_get_column (tb, COL_NAME));
scols_print_table (tb);
scols_unref_table (tb);
err:
if (err)
printf ("%s\n", err->message);
pool_free (pool);
return EXIT_SUCCESS;
}
#include <locale.h>
#include <stdbool.h>
#include <glib.h>
#include <libsmartcols.h>
#include <solv/pool.h>
#include <solv/repo.h>
#include <solv/repo_solv.h>
#include <json-glib/json-glib.h>
#include <libsoup/soup.h>
enum {
COL_NAME,
COL_MAINTAINERS,
COL_NOTES,
};
static inline char *
join_keys (GHashTable *hash_table,
const char *separator)
{
unsigned int length = 0;
g_autofree char **strv = (char **)g_hash_table_get_keys_as_array (hash_table, &length);
return g_strjoinv (separator, strv);
}
int
main (void)
{
struct libscols_table *tb;
struct libscols_column *cl;
struct libscols_line *ln;
FILE *fp;
Queue q;
g_autoptr(GError) err = NULL;
setlocale (LC_ALL, "");
Pool *pool = pool_create ();
//pool_setdebuglevel (pool, 10);
scols_init_debug (0xffff);
Repo *repo = repo_create (pool, "rawhide");
fp = fopen ("/var/cache/dnf/rawhide.solv", "rb");
repo_add_solv (repo, fp, 0);
fclose (fp);
Repodata *repodata = repo_add_repodata (repo, 0);
repodata_extend_block (repodata, repo->start, repo->end - repo->start);
fp = fopen ("/var/cache/dnf/rawhide-filenames.solvx", "rb");
repodata->state = REPODATA_LOADING;
repo_add_solv (repo, fp, REPO_USE_LOADING | REPO_EXTEND_SOLVABLES | REPO_LOCALPOOL);
repodata->state = REPODATA_AVAILABLE;
fclose (fp);
repodata_internalize (repodata);
pool_addfileprovides (pool);
pool_createwhatprovides (pool);
/* pkg → [err…] */
g_autoptr(GHashTable) to_fix = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify)g_hash_table_unref);
/* src → [pkg…] */
g_autoptr(GHashTable) smap = g_hash_table_new_full (g_str_hash,
g_str_equal,
g_free,
(GDestroyNotify)g_hash_table_unref);
g_autoptr(JsonParser) json = json_parser_new_immutable ();
#if 0
g_autoptr(SoupSession) soup = soup_session_new ();
g_autoptr(SoupMessage) msg = soup_message_new ("GET", "https://src.fedoraproject.org/extras/pagure_owner_alias.json");
g_autoptr(GInputStream) stream = soup_session_send (soup, msg, NULL, &err);
#else
g_autoptr(GFile) file = g_file_new_for_path ("/var/tmp/pagure_owner_alias.json");
g_autoptr(GInputStream) stream = (GInputStream *)g_file_read (file, NULL, &err);
#endif
if (!stream)
goto err;
if (!json_parser_load_from_stream (json, stream, NULL, &err))
goto err;
JsonObject *root = json_node_get_object (json_parser_get_root (json));
JsonObject *owners = json_object_get_object_member (root, "rpms");
queue_init (&q);
pool_whatmatchesdep (pool,
SOLVABLE_REQUIRES,
pool_str2id (pool,
"/sbin/ldconfig",
1),
&q,
0);
for (int i = 0; i < q.count; i++)
{
Id p = q.elements[i];
Solvable *s = pool_id2solvable (pool, p);
Dataiterator di;
dataiterator_init (&di, pool, 0, p, SOLVABLE_FILELIST, "/etc/ld.so.conf.d/*", SEARCH_FILES | SEARCH_GLOB);
if (dataiterator_step (&di))
{
dataiterator_free (&di);
continue;
}
dataiterator_free (&di);
const char *name = pool_id2str (pool, s->name);
GHashTable *errors = g_hash_table_lookup (to_fix, name);
if (!errors)
{
errors = g_hash_table_new (g_str_hash, g_str_equal);
g_hash_table_insert (to_fix, g_strdup (name), errors);
}
g_hash_table_add (errors, "Uneeded /sbin/ldconfig");
const char *srcname;
if (solvable_lookup_void(s, SOLVABLE_SOURCENAME))
srcname = pool_id2str (pool, s->name);
else
srcname = solvable_lookup_str (s, SOLVABLE_SOURCENAME);
GHashTable *subpkgs = g_hash_table_lookup (smap, srcname);
if (!subpkgs)
{
subpkgs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
g_hash_table_insert (smap, g_strdup (srcname), subpkgs);
}
g_hash_table_add (subpkgs, g_strdup (name));
}
queue_free (&q);
tb = scols_new_table ();
cl =scols_table_new_column (tb, "NAME", 0, SCOLS_FL_TREE);
scols_column_set_cmpfunc (cl, scols_cmpstr_cells, NULL);
cl = scols_table_new_column (tb, "MAINTAINERS", 0, SCOLS_FL_WRAP | SCOLS_FL_NOEXTREMES);
scols_column_set_wrapfunc (cl,
scols_wrapnl_chunksize,
scols_wrapnl_nextchunk,
NULL);
scols_column_set_safechars (cl, "\n");
cl = scols_table_new_column (tb, "NOTES", 0, SCOLS_FL_WRAP);
scols_column_set_wrapfunc (cl,
scols_wrapnl_chunksize,
scols_wrapnl_nextchunk,
NULL);
scols_column_set_safechars (cl, "\n");
GHashTableIter iter;
g_hash_table_iter_init (&iter, smap);
gpointer key, value;
while (g_hash_table_iter_next (&iter, &key, &value))
{
const char *srcname = key;
ln = scols_table_new_line (tb, NULL);
scols_line_set_data (ln, COL_NAME, srcname);
JsonArray *owners_array = json_object_get_array_member (owners, srcname);
g_autoptr(GList) pkg_owners = NULL;
for (int i = 0; i < json_array_get_length (owners_array); i++)
/* It is fine to discard const here because we are not going
* to free that data and it is not going to outlive. */
pkg_owners = g_list_insert_sorted (pkg_owners,
(char *)json_array_get_string_element (owners_array, i),
(GCompareFunc)g_strcmp0);
pkg_owners = g_list_first (pkg_owners);
g_autoptr(GString) maintainers = g_string_new (pkg_owners->data);
for (GList *owner = pkg_owners->next; owner; owner = owner->next)
g_string_append_printf (maintainers, "\n%s", (const char *)owner->data);
scols_line_set_data (ln, COL_MAINTAINERS, maintainers->str);
GHashTable *subpkgs = value;
GHashTableIter siter;
g_hash_table_iter_init (&siter, subpkgs);
while (g_hash_table_iter_next (&siter, &key, &value))
{
const char *name = key;
GHashTable *errors = g_hash_table_lookup (to_fix, name);
g_autofree char *notes = join_keys (errors, "\n");
struct libscols_line *xln = scols_table_new_line (tb, ln);
scols_line_set_data (xln, COL_NAME, name);
scols_line_set_data (xln, COL_NOTES, notes);
}
}
scols_sort_table (tb, scols_table_get_column (tb, COL_NAME));
scols_print_table (tb);
scols_unref_table (tb);
err:
if (err)
printf ("%s\n", err->message);
pool_free (pool);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment