builder: Add --install-deps-from=REMOTE

This allows you to automatically install/update dependencies required
by the manifest. The dependencies include:
 Runtime, Sdk, Base, Sdk Extensions and Platform Extensions

There is also a --install-deps-only switch to make the build
stop after the dependencies are installed.

Fixes https://github.com/flatpak/flatpak/issues/955
tingping/wmclass
Alexander Larsson 2017-08-18 11:04:13 +02:00
parent 4e15d9a5f8
commit f9a06a0fcd
4 changed files with 266 additions and 0 deletions

View File

@ -68,6 +68,10 @@ static char **opt_sources_dirs;
static char **opt_sources_urls;
static int opt_jobs;
static char *opt_mirror_screenshots_url;
static char *opt_install_deps_from;
static gboolean opt_install_deps_only;
static gboolean opt_user;
static char *opt_installation;
static GOptionEntry entries[] = {
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &opt_verbose, "Print debug information during command processing", NULL },
@ -106,6 +110,11 @@ static GOptionEntry entries[] = {
{ "from-git", 0, 0, G_OPTION_ARG_STRING, &opt_from_git, "Get input files from git repo", "URL"},
{ "from-git-branch", 0, 0, G_OPTION_ARG_STRING, &opt_from_git_branch, "Branch to use in --from-git", "BRANCH"},
{ "mirror-screenshots-url", 0, 0, G_OPTION_ARG_STRING, &opt_mirror_screenshots_url, "Download and rewrite screenshots to match this url", "URL"},
{ "install-deps-from", 0, 0, G_OPTION_ARG_STRING, &opt_install_deps_from, "Install build dependencies from this remote", "REMOTE"},
{ "install-deps-only", 0, 0, G_OPTION_ARG_NONE, &opt_install_deps_only, "Stop after installing dependencies"},
{ "user", 0, 0, G_OPTION_ARG_NONE, &opt_user, "Install dependencies in user installations", NULL },
{ "system", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_user, "Install dependencies in system-wide installations (default)", NULL },
{ "installation", 0, 0, G_OPTION_ARG_STRING, &opt_installation, "Install dependencies in a specific system-wide installation", "NAME" },
{ NULL }
};
@ -489,6 +498,17 @@ main (int argc,
return 0;
}
if (opt_install_deps_from != NULL)
{
if (!builder_manifest_install_deps (manifest, build_context, opt_install_deps_from, opt_user, opt_installation, &error))
{
g_printerr ("Error running %s: %s\n", argv[3], error->message);
return 1;
}
if (opt_install_deps_only)
return 0;
}
app_dir_is_empty = !g_file_query_exists (app_dir, NULL) ||
directory_is_empty (app_dir_path);

View File

@ -1152,6 +1152,49 @@ flatpak (GError **error,
return NULL;
}
static void
add_installation_args (GPtrArray *args,
gboolean opt_user,
const char *opt_installation)
{
if (opt_user)
g_ptr_array_add (args, g_strdup ("--user"));
else if (opt_installation)
g_ptr_array_add (args, g_strdup_printf ("--installation=%s", opt_installation));
else
g_ptr_array_add (args, g_strdup ("--system"));
}
static char *
flatpak_info (gboolean opt_user,
const char *opt_installation,
const char *ref,
const char *extra_arg,
GError **error)
{
gboolean res;
g_autofree char *output = NULL;
g_autoptr(GPtrArray) args = NULL;
args = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (args, g_strdup ("flatpak"));
add_installation_args (args, opt_user, opt_installation);
g_ptr_array_add (args, g_strdup ("info"));
if (extra_arg)
g_ptr_array_add (args, g_strdup (extra_arg));
g_ptr_array_add (args, g_strdup (ref));
g_ptr_array_add (args, NULL);
res = flatpak_spawnv (NULL, &output, G_SUBPROCESS_FLAGS_STDERR_SILENCE, error, (const char * const *)args->pdata);
if (res)
{
g_strchomp (output);
return g_steal_pointer (&output);
}
return NULL;
}
gboolean
builder_manifest_start (BuilderManifest *self,
gboolean allow_missing_runtimes,
@ -2850,6 +2893,158 @@ builder_manifest_show_deps (BuilderManifest *self,
return TRUE;
}
static gboolean
builder_manifest_install_dep (BuilderManifest *self,
BuilderContext *context,
const char *remote,
gboolean opt_user,
const char *opt_installation,
const char *runtime,
const char *version,
GError **error)
{
g_autofree char *ref = NULL;
g_autofree char *commit = NULL;
g_autoptr(GPtrArray) args = NULL;
gboolean installed;
if (version == NULL)
version = builder_manifest_get_runtime_version (self);
ref = flatpak_build_untyped_ref (runtime,
version,
builder_context_get_arch (context));
commit = flatpak_info (opt_user, opt_installation, "--show-commit", ref, NULL);
installed = (commit != NULL);
args = g_ptr_array_new_with_free_func (g_free);
g_ptr_array_add (args, g_strdup ("flatpak"));
add_installation_args (args, opt_user, opt_installation);
if (installed)
g_ptr_array_add (args, g_strdup ("update"));
else
{
g_ptr_array_add (args, g_strdup ("install"));
g_ptr_array_add (args, g_strdup (remote));
}
g_ptr_array_add (args, g_strdup (ref));
g_ptr_array_add (args, NULL);
if (!flatpak_spawnv (NULL, NULL, 0, error, (const char * const *)args->pdata))
return FALSE;
return TRUE;
}
static gboolean
builder_manifest_install_extension_deps (BuilderManifest *self,
BuilderContext *context,
const char *runtime,
char **runtime_extensions,
const char *remote,
gboolean opt_user,
const char *opt_installation,
GError **error)
{
g_autofree char *runtime_ref = flatpak_build_runtime_ref (runtime, builder_manifest_get_runtime_version (self),
builder_context_get_arch (context));
g_autofree char *metadata = NULL;
g_autoptr(GKeyFile) keyfile = g_key_file_new ();
int i;
if (runtime_extensions == NULL)
return TRUE;
metadata = flatpak_info (opt_user, opt_installation, "--show-metadata", runtime_ref, NULL);
if (metadata == NULL)
return FALSE;
if (!g_key_file_load_from_data (keyfile,
metadata, -1,
0,
error))
return FALSE;
for (i = 0; runtime_extensions != NULL && runtime_extensions[i] != NULL; i++)
{
g_autofree char *extension_group = g_strdup_printf ("Extension %s", runtime_extensions[i]);
g_autofree char *extension_version = NULL;
if (!g_key_file_has_group (keyfile, extension_group))
{
g_autofree char *base = g_strdup (runtime_extensions[i]);
char *dot = strrchr (base, '.');
if (dot != NULL)
*dot = 0;
g_free (extension_group);
extension_group = g_strdup_printf ("Extension %s", base);
if (!g_key_file_has_group (keyfile, extension_group))
return flatpak_fail (error, "Unknown extension '%s' in runtime\n", runtime_extensions[i]);
}
extension_version = g_key_file_get_string (keyfile, extension_group, "version", NULL);
if (extension_version == NULL)
extension_version = g_strdup (builder_manifest_get_runtime_version (self));
g_print ("Dependency Extension: %s %s\n", runtime_extensions[i], extension_version);
if (!builder_manifest_install_dep (self, context, remote, opt_user, opt_installation,
runtime_extensions[i], extension_version,
error))
return FALSE;
}
return TRUE;
}
gboolean
builder_manifest_install_deps (BuilderManifest *self,
BuilderContext *context,
const char *remote,
gboolean opt_user,
const char *opt_installation,
GError **error)
{
/* Sdk */
g_print ("Dependency Sdk: %s %s\n", self->sdk, builder_manifest_get_runtime_version (self));
if (!builder_manifest_install_dep (self, context, remote, opt_user, opt_installation,
self->sdk, builder_manifest_get_runtime_version (self),
error))
return FALSE;
/* Runtime */
g_print ("Dependency Runtime: %s %s\n", self->runtime, builder_manifest_get_runtime_version (self));
if (!builder_manifest_install_dep (self, context, remote, opt_user, opt_installation,
self->runtime, builder_manifest_get_runtime_version (self),
error))
return FALSE;
if (self->base)
{
g_print ("Dependency Base: %s %s\n", self->base, builder_manifest_get_base_version (self));
if (!builder_manifest_install_dep (self, context, remote, opt_user, opt_installation,
self->base, builder_manifest_get_base_version (self),
error))
return FALSE;
}
if (!builder_manifest_install_extension_deps (self, context,
self->sdk, self->sdk_extensions,
remote,opt_user, opt_installation,
error))
return FALSE;
if (!builder_manifest_install_extension_deps (self, context,
self->runtime, self->platform_extensions,
remote, opt_user, opt_installation,
error))
return FALSE;
return TRUE;
}
gboolean
builder_manifest_run (BuilderManifest *self,
BuilderContext *context,

View File

@ -81,6 +81,12 @@ gboolean builder_manifest_build (BuilderManifest *self,
BuilderCache *cache,
BuilderContext *context,
GError **error);
gboolean builder_manifest_install_deps (BuilderManifest *self,
BuilderContext *context,
const char *remote,
gboolean opt_user,
const char *opt_installation,
GError **error);
gboolean builder_manifest_run (BuilderManifest *self,
BuilderContext *context,
FlatpakContext *arg_context,

View File

@ -438,6 +438,51 @@
The branch to use with --from-git.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--install-deps-from=REMOTE</option></term>
<listitem><para>
Install/update build required dependencies from the specified remote.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--install-deps-only</option></term>
<listitem><para>
Stop after downloading dependencies.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--user</option></term>
<listitem><para>
Install the dependencies in a per-user installation.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--system</option></term>
<listitem><para>
Install the dependenceis in the default system-wide installation.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--installation=NAME</option></term>
<listitem><para>
Install the dependencies in a system-wide installation
specified by <arg choice="plain">NAME</arg> among those defined in
<filename>/etc/flatpak/installations.d/</filename>. Using
<arg choice="plain">--installation=default</arg> is equivalent to using
<arg choice="plain">--system</arg>.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>