common: Make flatpak_split_partial_ref_arg more regular and capable

Instead of in-place editing we return proper new strings. We
also handle kinds, both the defaults and supporting app/ and runtime/
prefixes.
tingping/wmclass
Alexander Larsson 2016-10-14 12:08:37 +02:00
parent c23316cb5d
commit c3606392aa
8 changed files with 184 additions and 111 deletions

View File

@ -73,13 +73,16 @@ flatpak_builtin_info (int argc, char **argv, GCancellable *cancellable, GError *
FlatpakDir *dir = NULL;
g_autoptr(GError) lookup_error = NULL;
g_autoptr(GVariant) deploy_data = NULL;
char *name;
char *branch = NULL;
const char *commit = NULL;
const char *pref = NULL;
const char *default_branch = NULL;
const char *origin = NULL;
gboolean first = TRUE;
FlatpakKinds kinds;
FlatpakKinds kind = 0;
g_autofree char *id = NULL;
g_autofree char *arch = NULL;
g_autofree char *branch = NULL;
context = g_option_context_new (_("NAME [BRANCH] - Get info about installed app and/or runtime"));
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
@ -89,19 +92,20 @@ flatpak_builtin_info (int argc, char **argv, GCancellable *cancellable, GError *
if (argc < 2)
return usage_error (context, _("NAME must be specified"), error);
name = argv[1];
pref = argv[1];
if (argc >= 3)
branch = argv[2];
default_branch = argv[2];
if (argc > 3)
return usage_error (context, _("Too many arguments"), error);
if (!flatpak_split_partial_ref_arg (name, &opt_arch, &branch, error))
return FALSE;
kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);
if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, default_branch,
&kinds, &id, &arch, &branch, error))
return FALSE;
if (!opt_user && !opt_system)
opt_user = opt_system = TRUE;
@ -110,9 +114,9 @@ flatpak_builtin_info (int argc, char **argv, GCancellable *cancellable, GError *
user_dir = flatpak_dir_get_user ();
ref = flatpak_dir_find_installed_ref (user_dir,
name,
id,
branch,
opt_arch,
arch,
kinds, &kind,
&lookup_error);
if (ref)
@ -124,9 +128,9 @@ flatpak_builtin_info (int argc, char **argv, GCancellable *cancellable, GError *
system_dir = flatpak_dir_get_system ();
ref = flatpak_dir_find_installed_ref (system_dir,
name,
id,
branch,
opt_arch,
arch,
kinds, &kind,
lookup_error == NULL ? &lookup_error : NULL);
if (ref)

View File

@ -268,11 +268,14 @@ flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro
g_autoptr(GOptionContext) context = NULL;
g_autoptr(FlatpakDir) dir = NULL;
const char *repository;
char *name;
char *branch = NULL;
const char *pref = NULL;
const char *default_branch = NULL;
g_autofree char *ref = NULL;
FlatpakKinds kinds;
FlatpakKinds kind;
g_autofree char *id = NULL;
g_autofree char *arch = NULL;
g_autofree char *branch = NULL;
context = g_option_context_new (_("REPOSITORY NAME [BRANCH] - Install an application or runtime"));
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
@ -293,16 +296,17 @@ flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro
return usage_error (context, _("Too many arguments"), error);
repository = argv[1];
name = argv[2];
pref = argv[2];
if (argc >= 4)
branch = argv[3];
default_branch = argv[3];
kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);
if (!flatpak_split_partial_ref_arg (name, &opt_arch, &branch, error))
if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, default_branch,
&kinds, &id, &arch, &branch, error))
return FALSE;
ref = flatpak_dir_find_remote_ref (dir, repository, name, branch, opt_arch,
ref = flatpak_dir_find_remote_ref (dir, repository, id, branch, arch,
kinds, &kind, cancellable, error);
if (ref == NULL)
return FALSE;

View File

@ -45,10 +45,14 @@ flatpak_builtin_make_current_app (int argc, char **argv, GCancellable *cancellab
g_autoptr(GOptionContext) context = NULL;
g_autoptr(FlatpakDir) dir = NULL;
g_autoptr(GFile) deploy_base = NULL;
char *app;
char *branch = NULL;
const char *pref;
const char *default_branch = NULL;
g_autofree char *ref = NULL;
g_auto(GLnxLockFile) lock = GLNX_LOCK_FILE_INIT;
g_autofree char *id = NULL;
g_autofree char *arch = NULL;
g_autofree char *branch = NULL;
FlatpakKinds kinds;
context = g_option_context_new (_("APP BRANCH - Make branch of application current"));
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
@ -62,23 +66,20 @@ flatpak_builtin_make_current_app (int argc, char **argv, GCancellable *cancellab
if (argc > 3)
return usage_error (context, _("Too many arguments"), error);
app = argv[1];
pref = argv[1];
if (argc >= 3)
branch = argv[2];
default_branch = argv[2];
if (!flatpak_split_partial_ref_arg (app, &opt_arch, &branch, error))
if (!flatpak_split_partial_ref_arg (pref, FLATPAK_KINDS_APP, opt_arch, default_branch,
&kinds, &id, &arch, &branch, error))
return FALSE;
if (branch == NULL)
return usage_error (context, _("BRANCH must be specified"), error);
ref = flatpak_dir_find_installed_ref (dir,
app,
branch,
opt_arch,
FLATPAK_KINDS_APP, NULL,
error);
ref = flatpak_dir_find_installed_ref (dir, id, branch, arch, FLATPAK_KINDS_APP,
NULL, error);
if (ref == NULL)
return FALSE;
@ -88,12 +89,12 @@ flatpak_builtin_make_current_app (int argc, char **argv, GCancellable *cancellab
deploy_base = flatpak_dir_get_deploy_dir (dir, ref);
if (!g_file_query_exists (deploy_base, cancellable))
return flatpak_fail (error, _("App %s branch %s is not installed"), app, branch);
return flatpak_fail (error, _("App %s branch %s is not installed"), id, branch);
if (!flatpak_dir_make_current_ref (dir, ref, cancellable, error))
return FALSE;
if (!flatpak_dir_update_exports (dir, app, cancellable, error))
if (!flatpak_dir_update_exports (dir, id, cancellable, error))
return FALSE;
glnx_release_lock_file (&lock);

View File

@ -63,10 +63,14 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
g_autoptr(GOptionContext) context = NULL;
g_autoptr(FlatpakDeploy) app_deploy = NULL;
g_autofree char *app_ref = NULL;
char *app;
const char *pref;
int i;
int rest_argv_start, rest_argc;
g_autoptr(FlatpakContext) arg_context = NULL;
g_autofree char *id = NULL;
g_autofree char *arch = NULL;
g_autofree char *branch = NULL;
FlatpakKinds kinds;
context = g_option_context_new (_("APP [args...] - Run an app"));
g_option_context_set_translation_domain (context, GETTEXT_PACKAGE);
@ -93,24 +97,38 @@ flatpak_builtin_run (int argc, char **argv, GCancellable *cancellable, GError **
if (rest_argc == 0)
return usage_error (context, _("APP must be specified"), error);
app = argv[rest_argv_start];
pref = argv[rest_argv_start];
if (!flatpak_split_partial_ref_arg (app, &opt_arch, &opt_branch, error))
if (!flatpak_split_partial_ref_arg (pref, FLATPAK_KINDS_APP, opt_arch, opt_branch,
&kinds, &id, &arch, &branch, error))
return FALSE;
if (opt_branch == NULL && opt_arch == NULL)
if (branch == NULL || arch == NULL)
{
g_autofree char *current_ref = NULL;
g_autoptr(FlatpakDir) user_dir = flatpak_dir_get_user ();
g_autoptr(FlatpakDir) system_dir = flatpak_dir_get_system ();
app_ref = flatpak_dir_current_ref (user_dir, app, cancellable);
if (app_ref == NULL)
app_ref = flatpak_dir_current_ref (system_dir, app, cancellable);
current_ref = flatpak_dir_current_ref (user_dir, id, cancellable);
if (current_ref == NULL)
current_ref = flatpak_dir_current_ref (system_dir, id, cancellable);
if (current_ref)
{
g_auto(GStrv) parts = flatpak_decompose_ref (current_ref, NULL);
if (parts)
{
if (branch == NULL)
branch = g_strdup (parts[3]);
if (arch == NULL)
arch = g_strdup (parts[2]);
}
}
}
if (app_ref == NULL)
{
app_ref = flatpak_compose_ref (TRUE, app, opt_branch, opt_arch, error);
app_ref = flatpak_compose_ref (TRUE, id, branch, arch, error);
if (app_ref == NULL)
return FALSE;
}

View File

@ -54,13 +54,16 @@ flatpak_builtin_uninstall (int argc, char **argv, GCancellable *cancellable, GEr
{
g_autoptr(GOptionContext) context = NULL;
g_autoptr(FlatpakDir) dir = NULL;
char *name = NULL;
char *branch = NULL;
const char *pref = NULL;
const char *default_branch = NULL;
g_autofree char *ref = NULL;
FlatpakHelperUninstallFlags flags = 0;
g_autoptr(GPtrArray) related = NULL;
FlatpakKinds kinds;
FlatpakKinds kind;
g_autofree char *id = NULL;
g_autofree char *arch = NULL;
g_autofree char *branch = NULL;
int i;
context = g_option_context_new (_("NAME [BRANCH] - Uninstall an application"));
@ -75,21 +78,18 @@ flatpak_builtin_uninstall (int argc, char **argv, GCancellable *cancellable, GEr
if (argc > 3)
return usage_error (context, _("Too many arguments"), error);
name = argv[1];
pref = argv[1];
if (argc > 2)
branch = argv[2];
default_branch = argv[2];
kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);
if (!flatpak_split_partial_ref_arg (name, &opt_arch, &branch, error))
if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, default_branch,
&kinds, &id, &arch, &branch, error))
return FALSE;
ref = flatpak_dir_find_installed_ref (dir,
name,
branch,
opt_arch,
kinds, &kind,
error);
ref = flatpak_dir_find_installed_ref (dir, id, branch, arch,
kinds, &kind, error);
if (ref == NULL)
return FALSE;
@ -105,7 +105,7 @@ flatpak_builtin_uninstall (int argc, char **argv, GCancellable *cancellable, GEr
g_autoptr(GError) local_error = NULL;
g_autofree char *origin = NULL;
origin =flatpak_dir_get_origin (dir, ref, NULL, NULL);
origin = flatpak_dir_get_origin (dir, ref, NULL, NULL);
if (origin)
{
related = flatpak_dir_find_local_related (dir, ref, origin,

View File

@ -63,6 +63,9 @@ update_appstream (FlatpakDir *dir, const char *remote, GCancellable *cancellable
{
gboolean changed;
if (opt_arch == NULL)
opt_arch = (char *)flatpak_get_arch ();
if (remote == NULL)
{
g_auto(GStrv) remotes = NULL;
@ -215,11 +218,14 @@ flatpak_builtin_update (int argc,
{
g_autoptr(GOptionContext) context = NULL;
g_autoptr(FlatpakDir) dir = NULL;
char *name = NULL;
char *branch = NULL;
const char *pref = NULL;
const char *default_branch = NULL;
gboolean failed = FALSE;
gboolean found = FALSE;
FlatpakKinds kinds;
g_autofree char *id = NULL;
g_autofree char *arch = NULL;
g_autofree char *branch = NULL;
int i;
context = g_option_context_new (_("[NAME [BRANCH]] - Update an application or runtime"));
@ -229,22 +235,20 @@ flatpak_builtin_update (int argc,
return FALSE;
if (argc >= 2)
name = argv[1];
pref = argv[1];
if (argc >= 3)
branch = argv[2];
default_branch = argv[2];
if (argc > 3)
return usage_error (context, _("Too many arguments"), error);
if (opt_arch == NULL)
opt_arch = (char *)flatpak_get_arch ();
if (opt_appstream)
return update_appstream (dir, pref, cancellable, error);
kinds = flatpak_kinds_from_bools (opt_app, opt_runtime);
if (opt_appstream)
return update_appstream (dir, name, cancellable, error);
if (!flatpak_split_partial_ref_arg (name, &opt_arch, &branch, error))
if (!flatpak_split_partial_ref_arg (pref, kinds, opt_arch, default_branch,
&kinds, &id, &arch, &branch, error))
return FALSE;
if (kinds & FLATPAK_KINDS_APP)
@ -262,10 +266,10 @@ flatpak_builtin_update (int argc,
if (parts == NULL)
return FALSE;
if (name != NULL && strcmp (parts[1], name) != 0)
if (id != NULL && strcmp (parts[1], id) != 0)
continue;
if (strcmp (parts[2], opt_arch) != 0)
if (arch != NULL && strcmp (parts[2], arch) != 0)
continue;
if (branch != NULL && strcmp (parts[3], branch) != 0)
@ -294,10 +298,10 @@ flatpak_builtin_update (int argc,
if (parts == NULL)
return FALSE;
if (name != NULL && strcmp (parts[1], name) != 0)
if (id != NULL && strcmp (parts[1], id) != 0)
continue;
if (strcmp (parts[2], opt_arch) != 0)
if (arch != NULL && strcmp (parts[2], arch) != 0)
continue;
if (branch != NULL && strcmp (parts[3], branch) != 0)
@ -312,10 +316,10 @@ flatpak_builtin_update (int argc,
}
}
if (name && !found)
if (pref && !found)
{
g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED,
"%s not installed", name);
"%s not installed", pref);
return FALSE;
}

View File

@ -646,6 +646,26 @@ flatpak_decompose_ref (const char *full_ref,
return g_steal_pointer (&parts);
}
static const char *
next_element (const char **partial_ref)
{
const char *slash;
const char *end;
slash = (const char *)strchr (*partial_ref, '/');
if (slash != NULL)
{
end = slash;
*partial_ref = slash + 1;
}
else
{
end = *partial_ref + strlen (*partial_ref);
*partial_ref = end;
}
return end;
}
FlatpakKinds
flatpak_kinds_from_bools (gboolean app, gboolean runtime)
{
@ -664,56 +684,73 @@ flatpak_kinds_from_bools (gboolean app, gboolean runtime)
}
gboolean
flatpak_split_partial_ref_arg (char *partial_ref,
char **inout_arch,
char **inout_branch,
GError **error)
flatpak_split_partial_ref_arg (const char *partial_ref,
FlatpakKinds default_kinds,
const char *default_arch,
const char *default_branch,
FlatpakKinds *out_kinds,
char **out_id,
char **out_arch,
char **out_branch,
GError **error)
{
char *slash;
char *arch = NULL;
char *branch = NULL;
const char *id_start = NULL;
const char *id_end = NULL;
g_autofree char *id = NULL;
const char *arch_start = NULL;
const char *arch_end = NULL;
g_autofree char *arch = NULL;
const char *branch_start = NULL;
const char *branch_end = NULL;
g_autofree char *branch = NULL;
g_autoptr(GError) local_error = NULL;
FlatpakKinds kinds = 0;
if (partial_ref == NULL)
return TRUE;
slash = strchr (partial_ref, '/');
if (slash != NULL)
*slash = 0;
if (!flatpak_is_valid_name (partial_ref, &local_error))
return flatpak_fail (error, "Invalid name %s: %s", partial_ref, local_error->message);
if (slash == NULL)
goto out;
arch = slash + 1;
slash = strchr (arch, '/');
if (slash != NULL)
*slash = 0;
if (strlen (arch) == 0)
arch = NULL;
if (slash == NULL)
goto out;
branch = slash + 1;
if (strlen (branch) > 0)
if (g_str_has_prefix (partial_ref, "app/"))
{
if (!flatpak_is_valid_branch (branch, &local_error))
return flatpak_fail (error, "Invalid branch %s: %s", branch, local_error->message);
partial_ref += strlen ("app/");
kinds = FLATPAK_KINDS_APP;
}
else if (g_str_has_prefix (partial_ref, "runtime/"))
{
partial_ref += strlen ("runtime/");
kinds = FLATPAK_KINDS_RUNTIME;
}
else
branch = NULL;
kinds = default_kinds;
out:
id_start = partial_ref;
id_end = next_element (&partial_ref);
id = g_strndup (id_start, id_end - id_start);
if (*inout_arch == NULL)
*inout_arch = arch;
if (!flatpak_is_valid_name (id, &local_error))
return flatpak_fail (error, "Invalid id %s: %s", id, local_error->message);
if (*inout_branch == NULL)
*inout_branch = branch;
arch_start = partial_ref;
arch_end = next_element (&partial_ref);
if (arch_end != arch_start)
arch = g_strndup (arch_start, arch_end - arch_start);
else
arch = g_strdup (default_arch);
branch_start = partial_ref;
branch_end = next_element (&partial_ref);
if (branch_end != branch_start)
branch = g_strndup (branch_start, branch_end - branch_start);
else
branch = g_strdup (default_branch);
if (branch != NULL && !flatpak_is_valid_branch (branch, &local_error))
return flatpak_fail (error, "Invalid branch %s: %s", branch, local_error->message);
if (out_kinds)
*out_kinds = kinds;
if (out_id != NULL)
*out_id = g_steal_pointer (&id);
if (out_arch != NULL)
*out_arch = g_steal_pointer (&arch);
if (out_branch != NULL)
*out_branch = g_steal_pointer (&branch);
return TRUE;
}

View File

@ -91,10 +91,15 @@ char **flatpak_decompose_ref (const char *ref,
FlatpakKinds flatpak_kinds_from_bools (gboolean app, gboolean runtime);
gboolean flatpak_split_partial_ref_arg (char *partial_ref,
char **inout_arch,
char **inout_branch,
GError **error);
gboolean flatpak_split_partial_ref_arg (const char *partial_ref,
FlatpakKinds default_kinds,
const char *default_arch,
const char *default_branch,
FlatpakKinds *out_kinds,
char **out_id,
char **out_arch,
char **out_branch,
GError **error);
char * flatpak_compose_ref (gboolean app,
const char *name,