Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

validator: Reduce severity of release-time-missing on snapshot releases #650

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 98 additions & 28 deletions src/as-validator.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,53 @@ as_validator_finalize (GObject *object)
G_OBJECT_CLASS (as_validator_parent_class)->finalize (object);
}

/**
* _as_validator_add_issue:
**/
static void
_as_validator_add_issue (AsValidator *validator,
xmlNode *node,
const gchar *tag_final,
const AsIssueSeverity severity,
const gchar *explanation,
const gchar *buffer)
{
AsValidatorPrivate *priv = GET_PRIVATE (validator);
g_autofree gchar *location = NULL;
AsValidatorIssue *issue;
gchar *id_str;

issue = as_validator_issue_new ();
as_validator_issue_set_tag (issue, tag_final);
as_validator_issue_set_severity (issue, severity);
as_validator_issue_set_hint (issue, buffer);
as_validator_issue_set_explanation (issue, explanation);

/* update location information */
if (priv->current_fname != NULL)
as_validator_issue_set_filename (issue, priv->current_fname);

if (priv->current_cpt != NULL)
as_validator_issue_set_cid (issue, as_component_get_id (priv->current_cpt));

if (node != NULL)
as_validator_issue_set_line (issue, xmlGetLineNo (node));

location = as_validator_issue_get_location (issue);
id_str = g_strdup_printf ("%s/%s/%s", location, tag_final, buffer);
/* str ownership is transferred to the hashtable */
if (g_hash_table_insert (priv->issues, id_str, issue)) {
/* the issue is new, we can add it to our by-file listing */
const gchar *fname_key = priv->current_fname ? priv->current_fname : "";
GPtrArray *ilist = g_hash_table_lookup (priv->issues_per_file, fname_key);
if (ilist == NULL) {
ilist = g_ptr_array_new_with_free_func (g_object_unref);
g_hash_table_insert (priv->issues_per_file, g_strdup (fname_key), ilist);
}
g_ptr_array_add (ilist, g_object_ref (issue));
}
}

static void as_validator_add_issue (AsValidator *validator,
xmlNode *node,
const gchar *tag,
Expand All @@ -187,9 +234,6 @@ as_validator_add_issue (AsValidator *validator,
g_autofree gchar *tag_final = NULL;
const gchar *explanation;
AsIssueSeverity severity;
g_autofree gchar *location = NULL;
AsValidatorIssue *issue;
gchar *id_str;
const AsValidatorIssueTag *tag_data = g_hash_table_lookup (priv->issue_tags, tag);

if (tag_data == NULL) {
Expand All @@ -211,35 +255,53 @@ as_validator_add_issue (AsValidator *validator,
va_end (args);
}

issue = as_validator_issue_new ();
as_validator_issue_set_tag (issue, tag_final);
as_validator_issue_set_severity (issue, severity);
as_validator_issue_set_hint (issue, buffer);
as_validator_issue_set_explanation (issue, explanation);
_as_validator_add_issue(validator, node, tag_final, severity, explanation, buffer);
}

/* update location information */
if (priv->current_fname != NULL)
as_validator_issue_set_filename (issue, priv->current_fname);
static void as_validator_add_issue_at_severity (AsValidator *validator,
xmlNode *node,
const gchar *tag,
const AsIssueSeverity severity,
const gchar *format,
...) G_GNUC_PRINTF (5, 6);

if (priv->current_cpt != NULL)
as_validator_issue_set_cid (issue, as_component_get_id (priv->current_cpt));
/**
* as_validator_add_issue_with_severity:
**/
static void
as_validator_add_issue_at_severity (AsValidator *validator,
xmlNode *node,
const gchar *tag,
AsIssueSeverity severity,
const gchar *format,
...)
{
AsValidatorPrivate *priv = GET_PRIVATE (validator);
va_list args;
g_autofree gchar *buffer = NULL;
g_autofree gchar *tag_final = NULL;
const gchar *explanation;
const AsValidatorIssueTag *tag_data = g_hash_table_lookup (priv->issue_tags, tag);

if (node != NULL)
as_validator_issue_set_line (issue, xmlGetLineNo (node));
if (tag_data == NULL) {
/* we requested data about an invalid tag */
g_warning ("Validator invoked invalid issue tag: %s", tag);
severity = AS_ISSUE_SEVERITY_ERROR;
explanation = _("The emitted issue tag is unknown in the tag registry of AppStream. "
"This is a bug in the validator itself, please report this issue in our bugtracker.");
tag_final = g_strdup_printf ("__error__%s", tag);
} else {
tag_final = g_strdup (tag);
explanation = tag_data->explanation;
}

location = as_validator_issue_get_location (issue);
id_str = g_strdup_printf ("%s/%s/%s", location, tag_final, buffer);
/* str ownership is transferred to the hashtable */
if (g_hash_table_insert (priv->issues, id_str, issue)) {
/* the issue is new, we can add it to our by-file listing */
const gchar *fname_key = priv->current_fname ? priv->current_fname : "";
GPtrArray *ilist = g_hash_table_lookup (priv->issues_per_file, fname_key);
if (ilist == NULL) {
ilist = g_ptr_array_new_with_free_func (g_object_unref);
g_hash_table_insert (priv->issues_per_file, g_strdup (fname_key), ilist);
}
g_ptr_array_add (ilist, g_object_ref (issue));
if (format != NULL) {
va_start (args, format);
buffer = g_strdup_vprintf (format, args);
va_end (args);
}

_as_validator_add_issue(validator, node, tag_final, severity, explanation, buffer);
}

/**
Expand Down Expand Up @@ -2453,7 +2515,15 @@ as_validator_check_release (AsValidator *validator, xmlNode *node, AsFormatStyle
g_autofree gchar *timestamp = as_xml_get_prop_value (node, "timestamp");
if (timestamp == NULL) {
/* Neither timestamp, nor date property exists */
as_validator_add_issue (validator, node, "release-time-missing", "date");
if (rel_kind == AS_RELEASE_KIND_SNAPSHOT) {
as_validator_add_issue_at_severity (validator,
node,
"release-time-missing",
AS_ISSUE_SEVERITY_WARNING,
"date");
} else {
as_validator_add_issue (validator, node, "release-time-missing", "date");
}
} else {
/* check if the timestamp is both a number and higher than 3000. The 3000 is used to check that it is not a year */
if (!as_str_verify_integer (timestamp, 3000, G_MAXINT64))
Expand Down
50 changes: 50 additions & 0 deletions tests/test-validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,55 @@ test_validator_manyerrors_desktopapp (void)
g_assert_false (ret);
}

/**
* test_validator_snapshot_release:
*
* Allow snapshot releases to omit a release date.
*/
static void
test_validator_snapshot_release (void)
{
gboolean ret;
g_autoptr(GList) issues = NULL;
g_autoptr(AsValidator) validator = as_validator_new ();

const gchar *SAMPLE_XML = "<component>\n"
" <id>org.example.test</id>\n"
" <metadata_license>FSFAP</metadata_license>\n"
" <project_license>LGPL-2.1+</project_license>\n"
" <name>Test</name>\n"
" <summary>Another sample unittest</summary>\n"
" <releases>\n"
" <release type=\"snapshot\" version=\"1.0-rc2\"/>\n"
" <release type=\"snapshot\" date=\"18:49:09\" version=\"1.0-rc1\"/>\n"
" <release type=\"stable\" date=\"2024-08-15\" version=\"0.9\"/>\n"
" </releases>\n"
"</component>\n";

AsVResultCheck expected_results[] = {
{
"developer-info-missing", "",
-1,
AS_ISSUE_SEVERITY_INFO, },
{
"release-time-missing", "date",
8,
AS_ISSUE_SEVERITY_WARNING, },
{
"invalid-iso8601-date", "18:49:09",
9,
AS_ISSUE_SEVERITY_WARNING, },

{ NULL, NULL, 0, AS_ISSUE_SEVERITY_UNKNOWN }
};

ret = as_validator_validate_data (validator, SAMPLE_XML);

issues = as_validator_get_issues (validator);
_astest_check_validate_issues (issues, (AsVResultCheck *) &expected_results);
g_assert_false (ret);
}

/**
* test_validator_relationissues:
*
Expand Down Expand Up @@ -435,6 +484,7 @@ main (int argc, char **argv)
test_validator_manyerrors_desktopapp);
g_test_add_func ("/AppStream/Validate/RelationIssues", test_validator_relationissues);
g_test_add_func ("/AppStream/Validate/Overrides", test_validator_overrides);
g_test_add_func ("/AppStream/Validate/Snapshot", test_validator_snapshot_release);

ret = g_test_run ();
g_free (datadir);
Expand Down
Loading