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

cli: Add "get-latest-version" util command #503

Open
wants to merge 2 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
27 changes: 26 additions & 1 deletion tools/appstreamcli.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,26 @@ as_client_run_is_satisfied (const gchar *command, char **argv, int argc)
optn_no_cache);
}

/**
* as_client_run_get_latest_version:
*
* Get the latest version specified in an AppData file.
*/
static int
as_client_run_get_latest_version (const gchar *command, char **argv, int argc)
{
const gchar *fname = NULL;

if (argc > 2)
fname = argv[2];
if (argc > 3) {
as_client_print_help_hint (command, argv[3]);
return 1;
}

return ascli_get_latest_version_file (fname);
}

/**
* as_client_run_put:
*
Expand Down Expand Up @@ -1340,9 +1360,14 @@ as_client_run (char **argv, int argc)
as_client_run_check_license);
ascli_add_cmd (commands,
2, "is-satisfied", NULL, "FILE|COMPONENT-ID",
/* TRANSLATORS: `appstreamcli `check-license` command description. */
/* TRANSLATORS: `appstreamcli `is-satisfied` command description. */
_("Check if requirements of a component (via its ID or MetaInfo file) are satisfied on this system."),
as_client_run_is_satisfied);
ascli_add_cmd (commands,
2, "get-latest-version", NULL, "FILE",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if this should be called metainfo-latest-version or something, to make clear we're not querying the latest AppStream version... But the confusion potential is probably not that high...

/* TRANSLATORS: `appstreamcli get-latest-version command description. */
_("Get the latest version from the AppData file"),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_("Get the latest version from the AppData file"),
_("Get the latest version from the MetaInfo file"),

(the file format is called MetaInfo, AppData is an ancient name from an early draft)

as_client_run_get_latest_version);

ascli_add_cmd (commands,
3, "install", NULL, "COMPONENT-ID",
Expand Down
66 changes: 66 additions & 0 deletions tools/ascli-actions-mdata.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,3 +739,69 @@ ascli_check_is_satisfied (const gchar *fname_or_cid, const gchar *cachepath, gbo

return res? ASCLI_EXIT_CODE_SUCCESS : ASCLI_EXIT_CODE_FAILED;
}

gint
ascli_get_latest_version_file (const gchar *fname)
{
g_autoptr(AsMetadata) metad = NULL;
g_autoptr(AsComponent) cpt = NULL;
g_autoptr(GFile) infile = NULL;
g_autoptr(GError) error = NULL;

if (fname == NULL) {
ascli_print_stderr (_("You need to specify an input file."));
return 1;
}

/* load input file */
infile = g_file_new_for_path (fname);
if (!g_file_query_exists (infile, NULL)) {
ascli_print_stderr (_("Metadata file '%s' does not exist."), fname);
return 2;
}

metad = as_metadata_new ();
as_metadata_set_locale (metad, "ALL");

if ((g_str_has_suffix (fname, ".yml.gz")) ||
(g_str_has_suffix (fname, ".yaml.gz")) ||
(g_str_has_suffix (fname, ".yml")) ||
(g_str_has_suffix (fname, ".yaml"))) {
/* if we have YAML, we also automatically assume a catalog style */
as_metadata_set_format_style (metad, AS_FORMAT_STYLE_CATALOG);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make any sense to read this for CATALOG data? Since catalog files contain many components, you would currently just get a random version, so I don't think that makes sense.
I think it would be better if this code would just error-out in that case and limit itself to metainfo files.
The added benefit of that would be that this code would be much smaller then too ;-)

} else if (g_str_has_suffix (fname, ".metainfo.xml") || g_str_has_suffix (fname, ".appdata.xml")) {
as_metadata_set_format_style (metad, AS_FORMAT_STYLE_METAINFO);
} else {
as_metadata_set_format_style (metad, AS_FORMAT_STYLE_CATALOG);
}

as_metadata_parse_file (metad,
infile,
AS_FORMAT_KIND_UNKNOWN,
&error);
if (error != NULL) {
g_printerr ("%s\n", error->message);
return 3;
}

cpt = g_object_ref (as_metadata_get_component (metad));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: You don't need to reference the AsComponent here, as it is held for the duration of AsMetadata's life. That said, it also doesn't really hurt either.


if (as_component_get_releases (cpt)->len > 0) {
GPtrArray *releases = as_component_get_releases (cpt);
AsRelease *release_newest = NULL;

for (guint i = 0; i < releases->len; i++) {
AsRelease *release_tmp = g_ptr_array_index (releases, i);
if (release_newest == NULL ||
as_release_get_timestamp (release_tmp) > as_release_get_timestamp (release_newest))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not always have a timestamp (e.g. for development versions / unreleased ones).
Since the release entries must be sorted highest to lowest, we could cheat here and just pick the first release entry, or we could go the extra mile of comparing version numbers if one of the releases has no timestamp...

Is it common that there are sorting errors with release elements? (appstreamcli validate should throw an error for that).

release_newest = release_tmp;
}

g_print ("%s\n", as_release_get_version (release_newest));
} else {
ascli_print_stderr (_("No releases information available in '%s'."), fname);
return 4;
}

return ASCLI_EXIT_CODE_SUCCESS;
}
2 changes: 2 additions & 0 deletions tools/ascli-actions-mdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ gint ascli_check_is_satisfied (const gchar *fname_or_cid,
const gchar *cachepath,
gboolean no_cache);

gint ascli_get_latest_version_file (const gchar *fname);


G_END_DECLS

Expand Down