Upstream tag: 2.10.0 Upstream commit: 30e25418 Signed-off-by: Stephen Gallagher <sgallagh@redhat.com>
201 lines
5.6 KiB
C
201 lines
5.6 KiB
C
/*
|
|
* This file is part of libmodulemd
|
|
* Copyright 2018 Stephen Gallagher
|
|
*
|
|
* Fedora-License-Identifier: MIT
|
|
* SPDX-2.0-License-Identifier: MIT
|
|
* SPDX-3.0-License-Identifier: MIT
|
|
*
|
|
* This program is free software.
|
|
* For more information on the license, see COPYING.
|
|
* For more information on free software, see <https://www.gnu.org/philosophy/free-sw.en.html>.
|
|
*/
|
|
|
|
|
|
#include "modulemd.h"
|
|
#include "private/modulemd-module-index-private.h"
|
|
#include "private/modulemd-yaml.h"
|
|
|
|
#include <errno.h>
|
|
#include <glib.h>
|
|
#include <locale.h>
|
|
|
|
enum mmd_verbosity
|
|
{
|
|
MMD_QUIET = -1,
|
|
MMD_DEFAULT,
|
|
MMD_VERBOSE,
|
|
MMD_DEBUG
|
|
};
|
|
|
|
struct validator_options
|
|
{
|
|
enum mmd_verbosity verbosity;
|
|
gchar **filenames;
|
|
};
|
|
|
|
struct validator_options options = { 0, NULL };
|
|
|
|
static gboolean
|
|
print_version (const gchar *option_name,
|
|
const gchar *value,
|
|
gpointer data,
|
|
GError **error)
|
|
{
|
|
g_fprintf (stdout, "modulemd-validator %s\n", modulemd_get_version ());
|
|
exit (1);
|
|
}
|
|
|
|
static gboolean
|
|
set_verbosity (const gchar *option_name,
|
|
const gchar *value,
|
|
gpointer data,
|
|
GError **error)
|
|
{
|
|
g_autofree gchar *debugging_env = NULL;
|
|
if (g_strcmp0 ("-v", option_name) == 0 ||
|
|
g_strcmp0 ("--verbose", option_name) == 0)
|
|
{
|
|
if (options.verbosity < MMD_VERBOSE)
|
|
{
|
|
options.verbosity = MMD_VERBOSE;
|
|
}
|
|
}
|
|
else if (g_strcmp0 ("--debug", option_name) == 0)
|
|
{
|
|
if (options.verbosity < MMD_DEBUG)
|
|
{
|
|
options.verbosity = MMD_DEBUG;
|
|
const gchar *old_debug = g_getenv ("G_MESSAGES_DEBUG");
|
|
if (old_debug != NULL)
|
|
{
|
|
debugging_env =
|
|
g_strdup_printf ("%s,%s", old_debug, G_LOG_DOMAIN);
|
|
}
|
|
else
|
|
{
|
|
debugging_env = g_strdup (G_LOG_DOMAIN);
|
|
}
|
|
g_setenv ("G_MESSAGES_DEBUG", debugging_env, TRUE);
|
|
}
|
|
}
|
|
else if (g_strcmp0 ("-q", option_name) == 0 ||
|
|
g_strcmp0 ("--quiet", option_name) == 0)
|
|
{
|
|
options.verbosity = MMD_QUIET;
|
|
}
|
|
else
|
|
{
|
|
/* We shouldn't be called under any other circumstance */
|
|
g_set_error (error,
|
|
G_OPTION_ERROR,
|
|
G_OPTION_ERROR_FAILED,
|
|
"Called for unknown option \"%s\"",
|
|
option_name);
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// clang-format off
|
|
static GOptionEntry entries[] = {
|
|
{ "debug", 0, G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, set_verbosity, "Output debugging messages", NULL },
|
|
{ "quiet", 'q', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, set_verbosity, "Print no output", NULL },
|
|
{ "verbose", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, set_verbosity, "Be verbose", NULL },
|
|
{ "version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, print_version, "Print version number, then exit", NULL },
|
|
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &options.filenames, "Files to be validated", NULL },
|
|
{ NULL } };
|
|
// clang-format on
|
|
|
|
|
|
static gboolean
|
|
parse_file (const gchar *filename, GPtrArray **failures, GError **error)
|
|
{
|
|
g_autoptr (ModulemdModuleIndex) index = NULL;
|
|
|
|
if (options.verbosity >= MMD_VERBOSE)
|
|
{
|
|
g_fprintf (stdout, "Validating %s\n", filename);
|
|
}
|
|
|
|
index = modulemd_module_index_new ();
|
|
return modulemd_module_index_update_from_file_ext (
|
|
index, filename, TRUE, TRUE, failures, error);
|
|
}
|
|
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
const char *filename;
|
|
g_autoptr (GOptionContext) context = NULL;
|
|
g_autoptr (GError) error = NULL;
|
|
gsize num_invalid = 0;
|
|
gboolean ret;
|
|
g_autoptr (GPtrArray) failures = NULL;
|
|
ModulemdSubdocumentInfo *doc = NULL;
|
|
|
|
setlocale (LC_ALL, "");
|
|
|
|
context = g_option_context_new ("FILES - Simple modulemd YAML validator");
|
|
g_option_context_add_main_entries (context, entries, "modulemd-validator");
|
|
if (!g_option_context_parse (context, &argc, &argv, &error))
|
|
{
|
|
g_print ("option parsing failed: %s\n", error->message);
|
|
exit (1);
|
|
}
|
|
|
|
if (!(options.filenames && options.filenames[0]))
|
|
{
|
|
g_fprintf (stderr,
|
|
"At least one file must be specified on the command-line\n");
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
for (gsize i = 0; options.filenames[i]; i++)
|
|
{
|
|
filename = options.filenames[i];
|
|
|
|
ret = parse_file (filename, &failures, &error);
|
|
if (!ret)
|
|
{
|
|
num_invalid++;
|
|
if (options.verbosity >= MMD_DEFAULT)
|
|
{
|
|
g_fprintf (stderr, "%s failed to validate\n", filename);
|
|
|
|
if (error != NULL)
|
|
{
|
|
/* Unparseable content */
|
|
g_fprintf (stderr,
|
|
"%s could not be read in its entirety: %s\n",
|
|
filename,
|
|
error->message);
|
|
}
|
|
if (failures)
|
|
{
|
|
for (gsize j = 0; j < failures->len; j++)
|
|
{
|
|
doc = MODULEMD_SUBDOCUMENT_INFO (
|
|
g_ptr_array_index (failures, i));
|
|
g_printf (
|
|
"\nFailed subdocument (%s): \n%s\n",
|
|
modulemd_subdocument_info_get_gerror (doc)->message,
|
|
modulemd_subdocument_info_get_yaml (doc));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (options.verbosity >= MMD_DEFAULT)
|
|
{
|
|
g_printf ("%s validated successfully\n", filename);
|
|
}
|
|
}
|
|
g_clear_error (&error);
|
|
g_clear_pointer (&failures, g_ptr_array_unref);
|
|
}
|
|
|
|
return num_invalid;
|
|
}
|