Merge branch 'moskalets/gapplication/add-version' into 'main'

gapplication: add GApplication:version property

Closes #3198

See merge request GNOME/glib!3889
This commit is contained in:
Philip Withnall 2024-02-09 10:04:15 +00:00
commit 0701943d9f
4 changed files with 145 additions and 1 deletions

View File

@ -227,6 +227,7 @@ struct _GApplicationPrivate
{
GApplicationFlags flags;
gchar *id;
gchar *version;
gchar *resource_path;
GActionGroup *actions;
@ -264,6 +265,7 @@ enum
{
PROP_NONE,
PROP_APPLICATION_ID,
PROP_VERSION,
PROP_FLAGS,
PROP_RESOURCE_BASE_PATH,
PROP_IS_REGISTERED,
@ -478,11 +480,13 @@ g_application_pack_option_entries (GApplication *application,
static GVariantDict *
g_application_parse_command_line (GApplication *application,
gchar ***arguments,
gboolean *print_version,
GError **error)
{
gboolean become_service = FALSE;
gchar *app_id = NULL;
gboolean replace = FALSE;
gboolean version = FALSE;
GVariantDict *dict = NULL;
GOptionContext *context;
GOptionGroup *gapplication_group;
@ -564,6 +568,17 @@ g_application_parse_command_line (GApplication *application,
g_option_group_add_entries (gapplication_group, entries);
}
if (application->priv->version)
{
GOptionEntry entries[] = {
{ "version", '\0', 0, G_OPTION_ARG_NONE, &version,
N_("Print the application version"), NULL },
G_OPTION_ENTRY_NULL
};
g_option_group_add_entries (gapplication_group, entries);
}
/* Allow replacing if the application allows it */
if (application->priv->flags & G_APPLICATION_ALLOW_REPLACEMENT)
{
@ -580,6 +595,8 @@ g_application_parse_command_line (GApplication *application,
if (!g_option_context_parse_strv (context, arguments, error))
goto out;
*print_version = version;
/* Check for --gapplication-service */
if (become_service)
application->priv->flags |= G_APPLICATION_IS_SERVICE;
@ -1101,8 +1118,9 @@ g_application_real_local_command_line (GApplication *application,
GError *error = NULL;
GVariantDict *options;
gint n_args;
gboolean print_version = FALSE;
options = g_application_parse_command_line (application, arguments, &error);
options = g_application_parse_command_line (application, arguments, &print_version, &error);
if (!options)
{
g_printerr ("%s\n", error->message);
@ -1111,6 +1129,21 @@ g_application_real_local_command_line (GApplication *application,
return TRUE;
}
/* Exit quickly with --version? */
if (print_version)
{
const char *prgname = g_get_prgname ();
g_assert (application->priv->version != NULL);
if (prgname != NULL)
g_print ("%s %s\n", prgname, application->priv->version);
else
g_print ("%s\n", application->priv->version);
*exit_status = EXIT_SUCCESS;
return TRUE;
}
g_signal_emit (application, g_application_signals[SIGNAL_HANDLE_LOCAL_OPTIONS], 0, options, exit_status);
if (*exit_status >= 0)
@ -1236,6 +1269,10 @@ g_application_set_property (GObject *object,
g_value_get_string (value));
break;
case PROP_VERSION:
g_application_set_version (application, g_value_get_string (value));
break;
case PROP_FLAGS:
g_application_set_flags (application, g_value_get_flags (value));
break;
@ -1306,6 +1343,11 @@ g_application_get_property (GObject *object,
g_application_get_application_id (application));
break;
case PROP_VERSION:
g_value_set_string (value,
g_application_get_version (application));
break;
case PROP_FLAGS:
g_value_set_flags (value,
g_application_get_flags (application));
@ -1401,6 +1443,7 @@ g_application_finalize (GObject *object)
g_free (application->priv->parameter_string);
g_free (application->priv->summary);
g_free (application->priv->description);
g_free (application->priv->version);
g_slist_free_full (application->priv->option_strings, g_free);
@ -1496,6 +1539,18 @@ g_application_class_init (GApplicationClass *class)
NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
/**
* GApplication:version:
*
* The human-readable version number of the application.
*
* Since: 2.80
*/
g_object_class_install_property (object_class, PROP_VERSION,
g_param_spec_string ("version", NULL, NULL,
NULL, G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY));
/**
* GApplication:flags:
*
@ -1887,6 +1942,50 @@ g_application_set_application_id (GApplication *application,
}
}
/**
* g_application_get_version:
* @application: a #GApplication
*
* Gets the version of @application.
*
* Returns: (nullable): the version of @application
*
* Since: 2.80
**/
const gchar *
g_application_get_version (GApplication *application)
{
g_return_val_if_fail (G_IS_APPLICATION (application), NULL);
return application->priv->version;
}
/**
* g_application_set_version
* @application: a #GApplication
* @version: the version of @application
*
* Sets the version number of @application. This will be used to implement
* a `--version` command line argument
*
* The application version can only be modified if @application has not yet
* been registered.
*
* Since: 2.80
**/
void
g_application_set_version (GApplication *application,
const gchar *version)
{
g_return_if_fail (G_IS_APPLICATION (application));
g_return_if_fail (version != NULL);
g_return_if_fail (!application->priv->is_registered);
if (g_set_str (&application->priv->version, version))
g_object_notify (G_OBJECT (application), "version");
}
/**
* g_application_get_flags:
* @application: a #GApplication

View File

@ -139,6 +139,12 @@ GIO_AVAILABLE_IN_ALL
void g_application_set_application_id (GApplication *application,
const gchar *application_id);
GIO_AVAILABLE_IN_2_80
const gchar * g_application_get_version (GApplication *application);
GIO_AVAILABLE_IN_2_80
void g_application_set_version (GApplication *application,
const gchar *version);
GIO_AVAILABLE_IN_2_34
GDBusConnection * g_application_get_dbus_connection (GApplication *application);
GIO_AVAILABLE_IN_2_34

View File

@ -34,6 +34,7 @@ main (int argc, char **argv)
G_APPLICATION_HANDLES_COMMAND_LINE);
g_signal_connect (app, "command-line", G_CALLBACK (command_line), NULL);
g_application_set_inactivity_timeout (app, 10000);
g_application_set_version (app, "2.3");
status = g_application_run (app, argc, argv);

View File

@ -369,6 +369,7 @@ properties (void)
GDBusConnection *c;
GObject *app;
gchar *id;
gchar *version;
GApplicationFlags flags;
gboolean registered;
guint timeout;
@ -381,20 +382,25 @@ properties (void)
app = g_object_new (G_TYPE_APPLICATION,
"application-id", "org.gtk.TestApplication",
"version", "1.0",
NULL);
g_object_get (app,
"application-id", &id,
"version", &version,
"flags", &flags,
"is-registered", &registered,
"inactivity-timeout", &timeout,
NULL);
g_assert_cmpstr (id, ==, "org.gtk.TestApplication");
g_assert_cmpstr (version, ==, "1.0");
g_assert_cmpint (flags, ==, G_APPLICATION_DEFAULT_FLAGS);
g_assert (!registered);
g_assert_cmpint (timeout, ==, 0);
g_clear_pointer (&version, g_free);
ret = g_application_register (G_APPLICATION (app), NULL, &error);
g_assert (ret);
g_assert_no_error (error);
@ -1085,6 +1091,37 @@ test_api (void)
g_object_unref (app);
}
static void
test_version (void)
{
GApplication *app;
gchar *version = NULL;
gchar *version_orig = NULL;
app = g_application_new ("org.gtk.TestApplication", 0);
version_orig = "1.2";
g_object_set (G_OBJECT (app), "version", version_orig, NULL);
g_object_get (app, "version", &version, NULL);
g_assert_cmpstr (version, ==, version_orig);
g_free (version);
/* test attempting to set the same version again */
version_orig = "1.2";
g_object_set (G_OBJECT (app), "version", version_orig, NULL);
g_object_get (app, "version", &version, NULL);
g_assert_cmpstr (version, ==, version_orig);
g_free (version);
version_orig = "2.4";
g_object_set (G_OBJECT (app), "version", version_orig, NULL);
g_object_get (app, "version", &version, NULL);
g_assert_cmpstr (version, ==, version_orig);
g_free (version);
g_object_unref (app);
}
/* Check that G_APPLICATION_ALLOW_REPLACEMENT works. To do so, we launch
* a GApplication in this process that allows replacement, and then
* launch a subprocess with --gapplication-replace. We have to do our
@ -1830,6 +1867,7 @@ main (int argc, char **argv)
g_test_add_func ("/gapplication/test-handle-local-options2", test_handle_local_options_failure);
g_test_add_func ("/gapplication/test-handle-local-options3", test_handle_local_options_passthrough);
g_test_add_func ("/gapplication/api", test_api);
g_test_add_func ("/gapplication/version", test_version);
g_test_add_data_func ("/gapplication/replace", GINT_TO_POINTER (TRUE), test_replace);
g_test_add_data_func ("/gapplication/no-replace", GINT_TO_POINTER (FALSE), test_replace);
g_test_add_func ("/gapplication/dbus/activate", test_dbus_activate);