diff --git a/app/flatpak-builtins-install.c b/app/flatpak-builtins-install.c
index 377b80be..54899622 100644
--- a/app/flatpak-builtins-install.c
+++ b/app/flatpak-builtins-install.c
@@ -54,6 +54,7 @@ static gboolean opt_from;
static gboolean opt_yes;
static gboolean opt_reinstall;
static gboolean opt_noninteractive;
+static gboolean opt_or_update;
static GOptionEntry options[] = {
{ "arch", 0, 0, G_OPTION_ARG_STRING, &opt_arch, N_("Arch to install for"), N_("ARCH") },
@@ -71,6 +72,7 @@ static GOptionEntry options[] = {
{ "assumeyes", 'y', 0, G_OPTION_ARG_NONE, &opt_yes, N_("Automatically answer yes for all questions"), NULL },
{ "reinstall", 0, 0, G_OPTION_ARG_NONE, &opt_reinstall, N_("Uninstall first if already installed"), NULL },
{ "noninteractive", 0, 0, G_OPTION_ARG_NONE, &opt_noninteractive, N_("Produce minimal output and don't ask questions"), NULL },
+ { "or-update", 0, 0, G_OPTION_ARG_NONE, &opt_or_update, N_("Update install if already installed"), NULL },
{ NULL }
};
@@ -502,13 +504,21 @@ flatpak_builtin_install (int argc, char **argv, GCancellable *cancellable, GErro
if (!flatpak_resolve_matching_refs (remote, dir, opt_yes, refs, id, &ref, error))
return FALSE;
- if (!flatpak_transaction_add_install (transaction, remote, ref, (const char **) opt_subpaths, error))
+ if (!flatpak_transaction_add_install (transaction, remote, ref, (const char **) opt_subpaths, &local_error))
{
- if (!g_error_matches (*error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
- return FALSE;
+ if (!g_error_matches (local_error, FLATPAK_ERROR, FLATPAK_ERROR_ALREADY_INSTALLED))
+ {
+ g_propagate_error (error, g_steal_pointer (&local_error));
+ return FALSE;
+ }
- g_printerr (_("Skipping: %s\n"), (*error)->message);
- g_clear_error (error);
+ if (opt_or_update)
+ {
+ if (!flatpak_transaction_add_update (transaction, ref, (const char **) opt_subpaths, NULL, error))
+ return FALSE;
+ }
+ else
+ g_printerr (_("Skipping: %s\n"), local_error->message);
}
}
diff --git a/doc/flatpak-install.xml b/doc/flatpak-install.xml
index a6b8f96a..0b04b0fb 100644
--- a/doc/flatpak-install.xml
+++ b/doc/flatpak-install.xml
@@ -234,6 +234,14 @@
+
+
+
+ Normally install just ignores things that are already installed (printing a warning), but if
+ --or-update is specified it silently turns it into an update operation instead.
+
+
+
diff --git a/tests/test-run.sh b/tests/test-run.sh
index 233df9ad..18ee1d9f 100644
--- a/tests/test-run.sh
+++ b/tests/test-run.sh
@@ -24,7 +24,7 @@ set -euo pipefail
skip_without_bwrap
skip_revokefs_without_fuse
-echo "1..15"
+echo "1..16"
# Use stable rather than master as the branch so we can test that the run
# command automatically finds the branch correctly
@@ -244,6 +244,27 @@ assert_streq "$NEW_COMMIT" "$NEW_NEW_COMMIT"
echo "ok backwards update"
+make_updated_app "" "" stable UPDATED2
+
+OLD_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`
+
+# We should ignore the update (and warn) by default
+${FLATPAK} ${U} install -y test-repo org.test.Hello >& install_stderr
+
+NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`
+
+assert_streq "$OLD_COMMIT" "$NEW_COMMIT"
+assert_file_has_content install_stderr 'org.test.Hello/.* is already installed'
+
+# But --or-update should do the update
+${FLATPAK} ${U} install -y --or-update test-repo org.test.Hello
+
+NEW_COMMIT=`${FLATPAK} ${U} info --show-commit org.test.Hello`
+
+assert_not_streq "$OLD_COMMIT" "$NEW_COMMIT"
+
+echo "ok install --or-update"
+
DIR=`mktemp -d`
${FLATPAK} build-init ${DIR} org.test.Split org.test.Platform org.test.Platform stable