2015-11-16 15:23:23 +00:00
/*
* Copyright © 2015 Red Hat , Inc
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
2016-07-29 18:27:49 +00:00
* version 2.1 of the License , or ( at your option ) any later version .
2015-11-16 15:23:23 +00:00
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library . If not , see < http : //www.gnu.org/licenses/>.
*
* Authors :
* Alexander Larsson < alexl @ redhat . com >
*/
# include "config.h"
# include <locale.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
2017-09-06 15:01:13 +00:00
# include <glib/gi18n.h>
2015-11-16 15:23:23 +00:00
# include <gio/gio.h>
# include "libglnx/libglnx.h"
2017-08-25 07:35:34 +00:00
# include "builder-flatpak-utils.h"
2015-11-16 15:23:23 +00:00
# include "builder-manifest.h"
2016-01-17 18:09:49 +00:00
# include "builder-utils.h"
2017-02-21 10:49:03 +00:00
# include "builder-git.h"
2015-11-16 15:23:23 +00:00
static gboolean opt_verbose ;
static gboolean opt_version ;
2016-02-17 08:45:12 +00:00
static gboolean opt_run ;
2015-11-16 15:23:23 +00:00
static gboolean opt_disable_cache ;
2017-11-15 13:41:08 +00:00
static gboolean opt_disable_tests ;
2017-02-07 15:37:42 +00:00
static gboolean opt_disable_rofiles ;
2015-11-16 15:23:23 +00:00
static gboolean opt_download_only ;
2018-03-27 13:15:36 +00:00
static gboolean opt_no_shallow_clone ;
2017-04-05 04:54:39 +00:00
static gboolean opt_bundle_sources ;
2015-11-26 13:38:13 +00:00
static gboolean opt_build_only ;
2016-10-07 22:41:46 +00:00
static gboolean opt_finish_only ;
2017-05-31 12:07:38 +00:00
static gboolean opt_export_only ;
2016-09-20 13:56:06 +00:00
static gboolean opt_show_deps ;
2015-11-16 15:23:23 +00:00
static gboolean opt_disable_download ;
2015-12-21 09:39:23 +00:00
static gboolean opt_disable_updates ;
2016-01-12 11:09:09 +00:00
static gboolean opt_ccache ;
2015-11-16 15:23:23 +00:00
static gboolean opt_require_changes ;
2015-12-09 20:10:22 +00:00
static gboolean opt_keep_build_dirs ;
2017-08-18 14:27:59 +00:00
static gboolean opt_delete_build_dirs ;
2016-04-14 03:06:59 +00:00
static gboolean opt_force_clean ;
2016-10-07 22:42:25 +00:00
static gboolean opt_allow_missing_runtimes ;
2016-08-22 15:23:32 +00:00
static gboolean opt_sandboxed ;
2017-02-10 15:37:33 +00:00
static gboolean opt_rebuild_on_sdk_change ;
2017-02-22 14:11:24 +00:00
static gboolean opt_skip_if_unchanged ;
2017-12-12 11:37:56 +00:00
static gboolean opt_install ;
2017-11-15 20:36:21 +00:00
static char * opt_state_dir ;
2017-02-21 10:49:03 +00:00
static char * opt_from_git ;
static char * opt_from_git_branch ;
2016-08-19 09:25:23 +00:00
static char * opt_stop_at ;
2017-02-20 14:02:09 +00:00
static char * opt_build_shell ;
2016-04-30 21:43:39 +00:00
static char * opt_arch ;
2017-03-21 12:16:29 +00:00
static char * opt_default_branch ;
2016-01-11 14:35:17 +00:00
static char * opt_repo ;
2016-01-12 11:18:11 +00:00
static char * opt_subject ;
static char * opt_body ;
2017-06-27 12:09:57 +00:00
static char * opt_collection_id = NULL ;
2016-01-12 11:18:11 +00:00
static char * opt_gpg_homedir ;
static char * * opt_key_ids ;
2017-03-31 05:56:10 +00:00
static char * * opt_sources_dirs ;
2017-07-29 15:43:10 +00:00
static char * * opt_sources_urls ;
2016-11-30 08:57:55 +00:00
static int opt_jobs ;
2017-05-22 14:18:45 +00:00
static char * opt_mirror_screenshots_url ;
2017-08-18 09:04:13 +00:00
static char * opt_install_deps_from ;
static gboolean opt_install_deps_only ;
static gboolean opt_user ;
static char * opt_installation ;
2017-11-09 13:12:14 +00:00
static gboolean opt_log_session_bus ;
static gboolean opt_log_system_bus ;
2018-02-16 07:22:49 +00:00
static gboolean opt_yes ;
2015-11-16 15:23:23 +00:00
static GOptionEntry entries [ ] = {
{ " verbose " , ' v ' , 0 , G_OPTION_ARG_NONE , & opt_verbose , " Print debug information during command processing " , NULL } ,
{ " version " , 0 , 0 , G_OPTION_ARG_NONE , & opt_version , " Print version information and exit " , NULL } ,
2016-04-30 21:43:39 +00:00
{ " arch " , 0 , 0 , G_OPTION_ARG_STRING , & opt_arch , " Architecture to build for (must be host compatible) " , " ARCH " } ,
2017-03-21 12:16:29 +00:00
{ " default-branch " , 0 , 0 , G_OPTION_ARG_STRING , & opt_default_branch , " Change the default branch " , " BRANCH " } ,
2016-05-26 09:13:37 +00:00
{ " run " , 0 , 0 , G_OPTION_ARG_NONE , & opt_run , " Run a command in the build directory (see --run --help) " , NULL } ,
2016-01-12 11:09:09 +00:00
{ " ccache " , 0 , 0 , G_OPTION_ARG_NONE , & opt_ccache , " Use ccache " , NULL } ,
2016-05-26 10:23:48 +00:00
{ " disable-cache " , 0 , 0 , G_OPTION_ARG_NONE , & opt_disable_cache , " Disable cache lookups " , NULL } ,
2017-11-15 13:41:08 +00:00
{ " disable-tests " , 0 , 0 , G_OPTION_ARG_NONE , & opt_disable_tests , " Don't run tests " , NULL } ,
2017-02-07 15:37:42 +00:00
{ " disable-rofiles-fuse " , 0 , 0 , G_OPTION_ARG_NONE , & opt_disable_rofiles , " Disable rofiles-fuse use " , NULL } ,
2015-11-16 15:23:23 +00:00
{ " disable-download " , 0 , 0 , G_OPTION_ARG_NONE , & opt_disable_download , " Don't download any new sources " , NULL } ,
2015-12-21 09:39:23 +00:00
{ " disable-updates " , 0 , 0 , G_OPTION_ARG_NONE , & opt_disable_updates , " Only download missing sources, never update to latest vcs version " , NULL } ,
2015-11-16 15:23:23 +00:00
{ " download-only " , 0 , 0 , G_OPTION_ARG_NONE , & opt_download_only , " Only download sources, don't build " , NULL } ,
2017-04-05 04:54:39 +00:00
{ " bundle-sources " , 0 , 0 , G_OPTION_ARG_NONE , & opt_bundle_sources , " Bundle module sources as runtime " , NULL } ,
2017-04-05 15:46:34 +00:00
{ " extra-sources " , 0 , 0 , G_OPTION_ARG_STRING_ARRAY , & opt_sources_dirs , " Add a directory of sources specified by SOURCE-DIR, multiple uses of this option possible " , " SOURCE-DIR " } ,
2017-07-29 15:43:10 +00:00
{ " extra-sources-url " , 0 , 0 , G_OPTION_ARG_STRING_ARRAY , & opt_sources_urls , " Add a url of sources specified by SOURCE-URL multiple uses of this option possible " , " SOURCE-URL " } ,
2015-11-26 13:38:13 +00:00
{ " build-only " , 0 , 0 , G_OPTION_ARG_NONE , & opt_build_only , " Stop after build, don't run clean and finish phases " , NULL } ,
2016-10-07 22:41:46 +00:00
{ " finish-only " , 0 , 0 , G_OPTION_ARG_NONE , & opt_finish_only , " Only run clean and finish and export phases " , NULL } ,
2017-05-31 12:07:38 +00:00
{ " export-only " , 0 , 0 , G_OPTION_ARG_NONE , & opt_export_only , " Only run export phase " , NULL } ,
2016-10-07 22:42:25 +00:00
{ " allow-missing-runtimes " , 0 , 0 , G_OPTION_ARG_NONE , & opt_allow_missing_runtimes , " Don't fail if runtime and sdk missing " , NULL } ,
2016-09-20 13:56:06 +00:00
{ " show-deps " , 0 , 0 , G_OPTION_ARG_NONE , & opt_show_deps , " List the dependencies of the json file (see --show-deps --help) " , NULL } ,
2016-01-11 14:35:17 +00:00
{ " require-changes " , 0 , 0 , G_OPTION_ARG_NONE , & opt_require_changes , " Don't create app dir or export if no changes " , NULL } ,
2015-12-09 20:10:22 +00:00
{ " keep-build-dirs " , 0 , 0 , G_OPTION_ARG_NONE , & opt_keep_build_dirs , " Don't remove build directories after install " , NULL } ,
2017-08-18 14:27:59 +00:00
{ " delete-build-dirs " , 0 , 0 , G_OPTION_ARG_NONE , & opt_delete_build_dirs , " Always remove build directories, even after build failure " , NULL } ,
2016-01-11 14:35:17 +00:00
{ " repo " , 0 , 0 , G_OPTION_ARG_STRING , & opt_repo , " Repo to export into " , " DIR " } ,
2016-01-12 11:18:11 +00:00
{ " subject " , ' s ' , 0 , G_OPTION_ARG_STRING , & opt_subject , " One line subject (passed to build-export) " , " SUBJECT " } ,
{ " body " , ' b ' , 0 , G_OPTION_ARG_STRING , & opt_body , " Full description (passed to build-export) " , " BODY " } ,
2017-06-27 12:09:57 +00:00
# ifdef FLATPAK_ENABLE_P2P
{ " collection-id " , 0 , 0 , G_OPTION_ARG_STRING , & opt_collection_id , " Collection ID (passed to build-export) " , " COLLECTION-ID " } ,
# endif /* FLATPAK_ENABLE_P2P */
2016-01-12 11:18:11 +00:00
{ " gpg-sign " , 0 , 0 , G_OPTION_ARG_STRING_ARRAY , & opt_key_ids , " GPG Key ID to sign the commit with " , " KEY-ID " } ,
{ " gpg-homedir " , 0 , 0 , G_OPTION_ARG_STRING , & opt_gpg_homedir , " GPG Homedir to use when looking for keyrings " , " HOMEDIR " } ,
2016-05-06 14:03:27 +00:00
{ " force-clean " , 0 , 0 , G_OPTION_ARG_NONE , & opt_force_clean , " Erase previous contents of DIRECTORY " , NULL } ,
2016-08-22 15:23:32 +00:00
{ " sandbox " , 0 , 0 , G_OPTION_ARG_NONE , & opt_sandboxed , " Enforce sandboxing, disabling build-args " , NULL } ,
2016-08-19 09:25:23 +00:00
{ " stop-at " , 0 , 0 , G_OPTION_ARG_STRING , & opt_stop_at , " Stop building at this module (implies --build-only) " , " MODULENAME " } ,
2016-11-30 08:57:55 +00:00
{ " jobs " , 0 , 0 , G_OPTION_ARG_INT , & opt_jobs , " Number of parallel jobs to build (default=NCPU) " , " JOBS " } ,
2017-02-10 15:37:33 +00:00
{ " rebuild-on-sdk-change " , 0 , 0 , G_OPTION_ARG_NONE , & opt_rebuild_on_sdk_change , " Rebuild if sdk changes " , NULL } ,
2017-02-22 14:11:24 +00:00
{ " skip-if-unchanged " , 0 , 0 , G_OPTION_ARG_NONE , & opt_skip_if_unchanged , " Don't do anything if the json didn't change " , NULL } ,
2017-02-20 14:02:09 +00:00
{ " build-shell " , 0 , 0 , G_OPTION_ARG_STRING , & opt_build_shell , " Extract and prepare sources for module, then start build shell " , " MODULENAME " } ,
2017-02-21 10:49:03 +00:00
{ " 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 " } ,
2017-05-22 14:18:45 +00:00
{ " mirror-screenshots-url " , 0 , 0 , G_OPTION_ARG_STRING , & opt_mirror_screenshots_url , " Download and rewrite screenshots to match this url " , " URL " } ,
2017-12-12 11:37:56 +00:00
{ " install " , 0 , 0 , G_OPTION_ARG_NONE , & opt_install , " Install if build succeeds " , NULL } ,
2017-08-18 09:04:13 +00:00
{ " 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 " } ,
2017-11-15 20:36:21 +00:00
{ " state-dir " , 0 , 0 , G_OPTION_ARG_FILENAME , & opt_state_dir , " Use this directory for state instead of .flatpak-builder " , " PATH " } ,
2018-02-16 07:22:49 +00:00
{ " assumeyes " , ' y ' , 0 , G_OPTION_ARG_NONE , & opt_yes , N_ ( " Automatically answer yes for all questions " ) , NULL } ,
2018-03-27 13:15:36 +00:00
{ " no-shallow-clone " , 0 , 0 , G_OPTION_ARG_NONE , & opt_no_shallow_clone , " Don't use shallow clones when mirroring git repos " , NULL } ,
2015-11-16 15:23:23 +00:00
{ NULL }
} ;
2016-05-26 09:13:37 +00:00
static GOptionEntry run_entries [ ] = {
{ " verbose " , ' v ' , 0 , G_OPTION_ARG_NONE , & opt_verbose , " Print debug information during command processing " , NULL } ,
{ " arch " , 0 , 0 , G_OPTION_ARG_STRING , & opt_arch , " Architecture to build for (must be host compatible) " , " ARCH " } ,
{ " run " , 0 , 0 , G_OPTION_ARG_NONE , & opt_run , " Run a command in the build directory " , NULL } ,
2017-11-09 13:12:14 +00:00
{ " log-session-bus " , 0 , 0 , G_OPTION_ARG_NONE , & opt_log_session_bus , N_ ( " Log session bus calls " ) , NULL } ,
{ " log-system-bus " , 0 , 0 , G_OPTION_ARG_NONE , & opt_log_system_bus , N_ ( " Log system bus calls " ) , NULL } ,
2016-05-26 09:13:37 +00:00
{ " ccache " , 0 , 0 , G_OPTION_ARG_NONE , & opt_ccache , " Use ccache " , NULL } ,
{ NULL }
} ;
2016-09-20 13:56:06 +00:00
static GOptionEntry show_deps_entries [ ] = {
{ " verbose " , ' v ' , 0 , G_OPTION_ARG_NONE , & opt_verbose , " Print debug information during command processing " , NULL } ,
{ " show-deps " , 0 , 0 , G_OPTION_ARG_NONE , & opt_show_deps , " List the dependencies of the json file (see --show-deps --help) " , NULL } ,
{ NULL }
} ;
2016-05-26 09:13:37 +00:00
2015-11-16 15:23:23 +00:00
static void
2016-05-06 14:03:27 +00:00
message_handler ( const gchar * log_domain ,
2015-11-16 15:23:23 +00:00
GLogLevelFlags log_level ,
2016-05-06 14:03:27 +00:00
const gchar * message ,
gpointer user_data )
2015-11-16 15:23:23 +00:00
{
/* Make this look like normal console output */
if ( log_level & G_LOG_LEVEL_DEBUG )
2017-11-15 14:28:06 +00:00
g_printerr ( " FB: %s \n " , message ) ;
2015-11-16 15:23:23 +00:00
else
g_printerr ( " %s: %s \n " , g_get_prgname ( ) , message ) ;
}
2017-07-06 13:38:10 +00:00
static int
2015-11-16 15:23:23 +00:00
usage ( GOptionContext * context , const char * message )
{
g_autofree gchar * help = g_option_context_get_help ( context , TRUE , NULL ) ;
2016-05-06 14:03:27 +00:00
2015-11-16 15:23:23 +00:00
g_printerr ( " %s \n " , message ) ;
g_printerr ( " %s " , help ) ;
return 1 ;
}
2016-02-18 18:22:34 +00:00
static const char skip_arg [ ] = " skip " ;
2016-01-11 14:35:17 +00:00
static gboolean
2016-04-30 21:43:39 +00:00
do_export ( BuilderContext * build_context ,
2016-05-06 14:03:27 +00:00
GError * * error ,
2016-04-30 21:43:39 +00:00
gboolean runtime ,
2017-06-27 12:07:03 +00:00
const gchar * location ,
const gchar * directory ,
2017-08-21 13:40:21 +00:00
char * * exclude_dirs ,
2017-06-27 12:07:03 +00:00
const gchar * branch ,
2017-06-27 12:09:57 +00:00
const gchar * collection_id ,
2016-01-11 14:35:17 +00:00
. . . )
{
va_list ap ;
const char * arg ;
2016-01-12 11:18:11 +00:00
int i ;
2016-01-11 14:35:17 +00:00
g_autoptr ( GPtrArray ) args = NULL ;
g_autoptr ( GSubprocess ) subp = NULL ;
args = g_ptr_array_new_with_free_func ( g_free ) ;
2016-05-09 09:07:53 +00:00
g_ptr_array_add ( args , g_strdup ( " flatpak " ) ) ;
2016-01-11 14:35:17 +00:00
g_ptr_array_add ( args , g_strdup ( " build-export " ) ) ;
2016-04-30 21:43:39 +00:00
g_ptr_array_add ( args , g_strdup_printf ( " --arch=%s " , builder_context_get_arch ( build_context ) ) ) ;
2016-01-18 10:43:02 +00:00
if ( runtime )
g_ptr_array_add ( args , g_strdup ( " --runtime " ) ) ;
2016-01-12 11:18:11 +00:00
if ( opt_subject )
g_ptr_array_add ( args , g_strdup_printf ( " --subject=%s " , opt_subject ) ) ;
if ( opt_body )
g_ptr_array_add ( args , g_strdup_printf ( " --body=%s " , opt_body ) ) ;
if ( opt_gpg_homedir )
g_ptr_array_add ( args , g_strdup_printf ( " --gpg-homedir=%s " , opt_gpg_homedir ) ) ;
for ( i = 0 ; opt_key_ids ! = NULL & & opt_key_ids [ i ] ! = NULL ; i + + )
g_ptr_array_add ( args , g_strdup_printf ( " --gpg-sign=%s " , opt_key_ids [ i ] ) ) ;
2017-06-27 12:09:57 +00:00
if ( collection_id )
g_ptr_array_add ( args , g_strdup_printf ( " --collection-id=%s " , collection_id ) ) ;
2017-06-27 12:07:03 +00:00
/* Additional flags. */
2017-06-27 12:09:57 +00:00
va_start ( ap , collection_id ) ;
2016-01-11 14:35:17 +00:00
while ( ( arg = va_arg ( ap , const gchar * ) ) )
2016-02-18 18:22:34 +00:00
if ( arg ! = skip_arg )
g_ptr_array_add ( args , g_strdup ( ( gchar * ) arg ) ) ;
2016-01-11 14:35:17 +00:00
va_end ( ap ) ;
2017-08-21 13:40:21 +00:00
if ( exclude_dirs )
{
for ( i = 0 ; exclude_dirs [ i ] ! = NULL ; i + + )
g_ptr_array_add ( args , g_strdup_printf ( " --exclude=/%s/* " , exclude_dirs [ i ] ) ) ;
}
2017-06-27 12:07:03 +00:00
/* Mandatory positional arguments. */
g_ptr_array_add ( args , g_strdup ( location ) ) ;
g_ptr_array_add ( args , g_strdup ( directory ) ) ;
g_ptr_array_add ( args , g_strdup ( branch ) ) ;
2016-01-11 14:35:17 +00:00
g_ptr_array_add ( args , NULL ) ;
subp =
g_subprocess_newv ( ( const gchar * const * ) args - > pdata ,
G_SUBPROCESS_FLAGS_NONE ,
error ) ;
if ( subp = = NULL | |
! g_subprocess_wait_check ( subp , NULL , error ) )
return FALSE ;
return TRUE ;
}
2017-12-12 11:37:56 +00:00
static gboolean
do_install ( BuilderContext * build_context ,
const gchar * repodir ,
const gchar * id ,
const gchar * branch ,
GError * * error )
{
g_autofree char * ref = NULL ;
g_autoptr ( GPtrArray ) args = NULL ;
g_autoptr ( GSubprocess ) subp = NULL ;
args = g_ptr_array_new_with_free_func ( g_free ) ;
g_ptr_array_add ( args , g_strdup ( " flatpak " ) ) ;
g_ptr_array_add ( args , g_strdup ( " install " ) ) ;
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 " ) ) ;
2018-02-16 07:22:49 +00:00
if ( opt_user )
g_ptr_array_add ( args , g_strdup ( " -y " ) ) ;
2017-12-15 11:20:21 +00:00
g_ptr_array_add ( args , g_strdup ( " --reinstall " ) ) ;
2017-12-12 11:37:56 +00:00
ref = flatpak_build_untyped_ref ( id , branch ,
builder_context_get_arch ( build_context ) ) ;
g_ptr_array_add ( args , g_strdup ( repodir ) ) ;
g_ptr_array_add ( args , g_strdup ( ref ) ) ;
g_ptr_array_add ( args , NULL ) ;
subp =
g_subprocess_newv ( ( const gchar * const * ) args - > pdata ,
G_SUBPROCESS_FLAGS_NONE ,
error ) ;
if ( subp = = NULL | |
! g_subprocess_wait_check ( subp , NULL , error ) )
return FALSE ;
return TRUE ;
}
2016-01-11 14:35:17 +00:00
2015-11-16 15:23:23 +00:00
int
main ( int argc ,
char * * argv )
{
g_autofree const char * old_env = NULL ;
2016-05-06 14:03:27 +00:00
2015-11-16 15:23:23 +00:00
g_autoptr ( GError ) error = NULL ;
g_autoptr ( BuilderManifest ) manifest = NULL ;
2016-07-28 19:51:02 +00:00
g_autoptr ( GOptionContext ) context = NULL ;
2017-02-21 10:49:03 +00:00
const char * app_dir_path = NULL , * manifest_rel_path ;
2018-04-14 17:17:59 +00:00
g_autofree gchar * manifest_contents = NULL ;
g_autofree gchar * manifest_sha256 = NULL ;
g_autofree gchar * old_manifest_sha256 = NULL ;
2015-11-16 15:23:23 +00:00
g_autoptr ( BuilderContext ) build_context = NULL ;
g_autoptr ( GFile ) base_dir = NULL ;
2016-05-04 06:47:38 +00:00
g_autoptr ( GFile ) manifest_file = NULL ;
2015-11-16 15:23:23 +00:00
g_autoptr ( GFile ) app_dir = NULL ;
g_autoptr ( BuilderCache ) cache = NULL ;
g_autofree char * cache_branch = NULL ;
2017-11-15 20:36:21 +00:00
g_autofree char * escaped_cache_branch = NULL ;
2016-02-18 18:22:34 +00:00
g_autoptr ( GFileEnumerator ) dir_enum = NULL ;
2016-02-18 20:49:13 +00:00
g_autoptr ( GFileEnumerator ) dir_enum2 = NULL ;
2017-02-21 09:25:36 +00:00
g_autofree char * cwd = NULL ;
g_autoptr ( GFile ) cwd_dir = NULL ;
2016-02-18 18:22:34 +00:00
GFileInfo * next = NULL ;
2016-01-18 14:22:56 +00:00
const char * platform_id = NULL ;
2017-01-18 22:46:55 +00:00
g_autofree char * * orig_argv = NULL ;
2016-05-26 09:13:37 +00:00
gboolean is_run = FALSE ;
2016-09-20 13:56:06 +00:00
gboolean is_show_deps = FALSE ;
2016-10-07 22:41:46 +00:00
gboolean app_dir_is_empty = FALSE ;
2018-06-10 18:47:09 +00:00
gboolean prune_unused_stages = FALSE ;
2016-05-26 10:23:48 +00:00
g_autoptr ( FlatpakContext ) arg_context = NULL ;
2017-02-21 10:49:03 +00:00
g_autoptr ( FlatpakTempDir ) cleanup_manifest_dir = NULL ;
2017-02-22 14:11:24 +00:00
g_autofree char * manifest_basename = NULL ;
2017-12-15 11:18:38 +00:00
g_autoptr ( GFile ) export_repo = NULL ;
2016-05-26 10:44:51 +00:00
int i , first_non_arg , orig_argc ;
2016-09-20 13:56:06 +00:00
int argnr ;
2017-11-15 20:36:21 +00:00
char * p ;
2015-11-16 15:23:23 +00:00
setlocale ( LC_ALL , " " ) ;
g_log_set_handler ( NULL , G_LOG_LEVEL_MESSAGE , message_handler , NULL ) ;
g_set_prgname ( argv [ 0 ] ) ;
/* avoid gvfs (http://bugzilla.gnome.org/show_bug.cgi?id=526454) */
old_env = g_strdup ( g_getenv ( " GIO_USE_VFS " ) ) ;
g_setenv ( " GIO_USE_VFS " , " local " , TRUE ) ;
g_vfs_get_default ( ) ;
if ( old_env )
g_setenv ( " GIO_USE_VFS " , old_env , TRUE ) ;
else
g_unsetenv ( " GIO_USE_VFS " ) ;
2018-05-18 06:02:51 +00:00
/* Work around libsoup/glib race condition, as per:
https : //bugzilla.gnome.org/show_bug.cgi?id=796031 and
https : //bugzilla.gnome.org/show_bug.cgi?id=674885#c87 */
g_type_ensure ( G_TYPE_SOCKET_FAMILY ) ;
g_type_ensure ( G_TYPE_SOCKET_TYPE ) ;
g_type_ensure ( G_TYPE_SOCKET_PROTOCOL ) ;
g_type_ensure ( G_TYPE_SOCKET_ADDRESS ) ;
2016-05-26 10:44:51 +00:00
orig_argv = g_memdup ( argv , sizeof ( char * ) * argc ) ;
orig_argc = argc ;
first_non_arg = 1 ;
2016-05-26 09:13:37 +00:00
for ( i = 1 ; i < argc ; i + + )
{
if ( argv [ i ] [ 0 ] ! = ' - ' )
break ;
2016-05-26 10:44:51 +00:00
first_non_arg = i + 1 ;
2016-05-26 09:13:37 +00:00
if ( strcmp ( argv [ i ] , " --run " ) = = 0 )
2016-05-26 10:44:51 +00:00
is_run = TRUE ;
2016-09-20 13:56:06 +00:00
if ( strcmp ( argv [ i ] , " --show-deps " ) = = 0 )
is_show_deps = TRUE ;
2016-05-26 09:13:37 +00:00
}
if ( is_run )
{
context = g_option_context_new ( " DIRECTORY MANIFEST COMMAND [args] - Run command in build sandbox " ) ;
g_option_context_add_main_entries ( context , run_entries , NULL ) ;
2016-05-26 10:23:48 +00:00
arg_context = flatpak_context_new ( ) ;
g_option_context_add_group ( context , flatpak_context_get_options ( arg_context ) ) ;
2016-05-26 10:44:51 +00:00
/* We drop the post-command part from the args, these go with the command in the sandbox */
argc = MIN ( first_non_arg + 3 , argc ) ;
2016-05-26 09:13:37 +00:00
}
2016-09-20 13:56:06 +00:00
else if ( is_show_deps )
{
context = g_option_context_new ( " MANIFEST - Show manifest dependencies " ) ;
g_option_context_add_main_entries ( context , show_deps_entries , NULL ) ;
}
2016-05-26 09:13:37 +00:00
else
{
context = g_option_context_new ( " DIRECTORY MANIFEST - Build manifest " ) ;
g_option_context_add_main_entries ( context , entries , NULL ) ;
}
2015-11-16 15:23:23 +00:00
if ( ! g_option_context_parse ( context , & argc , & argv , & error ) )
{
2016-06-02 06:50:58 +00:00
g_printerr ( " Option parsing failed: %s \n " , error - > message ) ;
2015-11-16 15:23:23 +00:00
return 1 ;
}
if ( opt_version )
{
g_print ( " %s \n " , PACKAGE_STRING ) ;
exit ( EXIT_SUCCESS ) ;
}
if ( opt_verbose )
2016-12-19 13:55:22 +00:00
g_log_set_handler ( G_LOG_DOMAIN , G_LOG_LEVEL_DEBUG , message_handler , NULL ) ;
2015-11-16 15:23:23 +00:00
2016-09-20 13:56:06 +00:00
argnr = 1 ;
2015-11-16 15:23:23 +00:00
2016-09-20 13:56:06 +00:00
if ( ! is_show_deps )
{
if ( argc = = argnr )
return usage ( context , " DIRECTORY must be specified " ) ;
app_dir_path = argv [ argnr + + ] ;
}
2015-11-16 15:23:23 +00:00
2016-09-20 13:56:06 +00:00
if ( argc = = argnr )
2015-11-16 15:23:23 +00:00
return usage ( context , " MANIFEST must be specified " ) ;
2017-02-21 10:49:03 +00:00
manifest_rel_path = argv [ argnr + + ] ;
2017-02-22 14:11:24 +00:00
manifest_basename = g_path_get_basename ( manifest_rel_path ) ;
2015-11-16 15:23:23 +00:00
2017-06-27 12:09:57 +00:00
# ifdef FLATPAK_ENABLE_P2P
if ( opt_collection_id ! = NULL & &
! ostree_validate_collection_id ( opt_collection_id , & error ) )
{
g_printerr ( " ‘ %s’ is not a valid collection ID: %s" , opt_collection_id , error - > message ) ;
return 1 ;
}
# endif /* FLATPAK_ENABLE_P2P */
2017-02-21 09:25:36 +00:00
if ( app_dir_path )
app_dir = g_file_new_for_path ( app_dir_path ) ;
cwd = g_get_current_dir ( ) ;
cwd_dir = g_file_new_for_path ( cwd ) ;
2017-11-15 20:36:21 +00:00
build_context = builder_context_new ( cwd_dir , app_dir , opt_state_dir ) ;
2017-02-21 09:25:36 +00:00
builder_context_set_use_rofiles ( build_context , ! opt_disable_rofiles ) ;
2017-11-15 13:41:08 +00:00
builder_context_set_run_tests ( build_context , ! opt_disable_tests ) ;
2018-03-27 13:15:36 +00:00
builder_context_set_no_shallow_clone ( build_context , opt_no_shallow_clone ) ;
2017-02-21 09:25:36 +00:00
builder_context_set_keep_build_dirs ( build_context , opt_keep_build_dirs ) ;
2017-08-18 14:27:59 +00:00
builder_context_set_delete_build_dirs ( build_context , opt_delete_build_dirs ) ;
2017-02-21 09:25:36 +00:00
builder_context_set_sandboxed ( build_context , opt_sandboxed ) ;
builder_context_set_jobs ( build_context , opt_jobs ) ;
builder_context_set_rebuild_on_sdk_change ( build_context , opt_rebuild_on_sdk_change ) ;
2017-04-05 04:54:39 +00:00
builder_context_set_bundle_sources ( build_context , opt_bundle_sources ) ;
2017-02-21 09:25:36 +00:00
2017-03-31 05:56:10 +00:00
if ( opt_sources_dirs )
{
g_autoptr ( GPtrArray ) sources_dirs = NULL ;
sources_dirs = g_ptr_array_new_with_free_func ( g_object_unref ) ;
for ( i = 0 ; opt_sources_dirs ! = NULL & & opt_sources_dirs [ i ] ! = NULL ; i + + )
{
GFile * file = g_file_new_for_commandline_arg ( opt_sources_dirs [ i ] ) ;
g_ptr_array_add ( sources_dirs , file ) ;
}
builder_context_set_sources_dirs ( build_context , sources_dirs ) ;
}
2017-07-29 15:43:10 +00:00
if ( opt_sources_urls )
{
g_autoptr ( GPtrArray ) sources_urls = NULL ;
sources_urls = g_ptr_array_new_with_free_func ( ( GDestroyNotify ) soup_uri_free ) ;
for ( i = 0 ; opt_sources_urls [ i ] ! = NULL ; i + + )
{
SoupURI * uri = soup_uri_new ( opt_sources_urls [ i ] ) ;
if ( uri = = NULL )
{
g_printerr ( " Invalid URL '%s' " , opt_sources_urls [ i ] ) ;
return 1 ;
}
g_ptr_array_add ( sources_urls , uri ) ;
}
builder_context_set_sources_urls ( build_context , sources_urls ) ;
}
2017-02-21 09:25:36 +00:00
if ( opt_arch )
builder_context_set_arch ( build_context , opt_arch ) ;
if ( opt_stop_at )
{
opt_build_only = TRUE ;
builder_context_set_stop_at ( build_context , opt_stop_at ) ;
}
2018-03-27 12:39:09 +00:00
if ( ! builder_context_set_enable_ccache ( build_context , opt_ccache , & error ) )
2017-02-21 09:25:36 +00:00
{
g_printerr ( " Can't initialize ccache use: %s \n " , error - > message ) ;
return 1 ;
}
2017-02-21 10:49:03 +00:00
if ( opt_from_git )
{
g_autofree char * manifest_dirname = g_path_get_dirname ( manifest_rel_path ) ;
2017-03-07 13:20:44 +00:00
const char * git_branch = opt_from_git_branch ? opt_from_git_branch : " master " ;
2017-03-06 08:18:17 +00:00
g_autoptr ( GFile ) build_subdir = NULL ;
2017-02-21 10:49:03 +00:00
2017-03-06 08:18:17 +00:00
build_subdir = builder_context_allocate_build_subdir ( build_context , manifest_basename , & error ) ;
if ( build_subdir = = NULL )
2017-02-21 10:49:03 +00:00
{
g_printerr ( " Can't check out manifest repo: %s \n " , error - > message ) ;
return 1 ;
}
2017-03-06 08:18:17 +00:00
cleanup_manifest_dir = g_object_ref ( build_subdir ) ;
2017-02-21 10:49:03 +00:00
2017-10-31 11:50:51 +00:00
if ( ! builder_git_mirror_repo ( opt_from_git ,
NULL ,
2017-11-06 11:46:50 +00:00
opt_disable_updates ? 0 : FLATPAK_GIT_MIRROR_FLAGS_UPDATE ,
2017-10-31 11:50:51 +00:00
git_branch , build_context , & error ) )
{
g_printerr ( " Can't clone manifest repo: %s \n " , error - > message ) ;
return 1 ;
}
2017-02-21 10:49:03 +00:00
if ( ! builder_git_checkout_dir ( opt_from_git ,
2017-10-31 10:24:20 +00:00
git_branch ,
2017-02-21 10:49:03 +00:00
manifest_dirname ,
2017-03-06 08:18:17 +00:00
build_subdir ,
2017-02-21 10:49:03 +00:00
build_context ,
& error ) )
{
g_printerr ( " Can't check out manifest repo: %s \n " , error - > message ) ;
return 1 ;
}
2017-03-06 08:18:17 +00:00
manifest_file = g_file_get_child ( build_subdir , manifest_rel_path ) ;
base_dir = g_file_resolve_relative_path ( build_subdir , manifest_dirname ) ;
2017-02-21 10:49:03 +00:00
}
else
{
manifest_file = g_file_new_for_path ( manifest_rel_path ) ;
base_dir = g_file_get_parent ( manifest_file ) ;
}
2017-02-21 09:25:36 +00:00
builder_context_set_base_dir ( build_context , base_dir ) ;
2018-04-14 17:17:59 +00:00
if ( ! g_file_get_contents ( flatpak_file_get_path_cached ( manifest_file ) , & manifest_contents , NULL , & error ) )
2015-11-16 15:23:23 +00:00
{
2017-02-21 10:49:03 +00:00
g_printerr ( " Can't load '%s': %s \n " , manifest_rel_path , error - > message ) ;
2015-11-16 15:23:23 +00:00
return 1 ;
}
2018-04-14 17:17:59 +00:00
manifest_sha256 = g_compute_checksum_for_string ( G_CHECKSUM_SHA256 , manifest_contents , - 1 ) ;
2017-02-22 14:11:24 +00:00
if ( opt_skip_if_unchanged )
{
2018-04-14 17:17:59 +00:00
old_manifest_sha256 = builder_context_get_checksum_for ( build_context , manifest_basename ) ;
if ( old_manifest_sha256 ! = NULL & & strcmp ( manifest_sha256 , old_manifest_sha256 ) = = 0 )
2017-02-22 14:11:24 +00:00
{
g_print ( " No changes to manifest, skipping \n " ) ;
return 42 ;
}
}
2017-03-06 08:18:17 +00:00
/* Can't push this as user data to the demarshalling :/ */
2017-04-19 15:46:28 +00:00
builder_manifest_set_demarshal_base_dir ( builder_context_get_base_dir ( build_context ) ) ;
2017-03-06 08:18:17 +00:00
2018-04-14 17:17:59 +00:00
manifest = ( BuilderManifest * ) builder_gobject_from_data ( BUILDER_TYPE_MANIFEST , manifest_rel_path ,
manifest_contents , & error ) ;
2017-03-06 08:18:17 +00:00
2017-04-19 15:46:28 +00:00
builder_manifest_set_demarshal_base_dir ( NULL ) ;
2017-03-06 08:18:17 +00:00
2015-11-16 15:23:23 +00:00
if ( manifest = = NULL )
{
2017-02-21 10:49:03 +00:00
g_printerr ( " Can't parse '%s': %s \n " , manifest_rel_path , error - > message ) ;
2015-11-16 15:23:23 +00:00
return 1 ;
}
2017-06-19 19:16:46 +00:00
if ( opt_default_branch )
builder_manifest_set_default_branch ( manifest , opt_default_branch ) ;
2017-06-27 12:09:57 +00:00
if ( opt_collection_id )
builder_manifest_set_default_collection_id ( manifest , opt_collection_id ) ;
2016-05-26 09:13:37 +00:00
if ( is_run & & argc = = 3 )
return usage ( context , " Program to run must be specified " ) ;
2017-07-10 03:06:00 +00:00
if ( opt_show_deps & & ! is_show_deps )
return usage ( context , " Can't use --show-deps after a non-option " ) ;
if ( opt_run & & ! is_run )
return usage ( context , " Can't use --run after a non-option " ) ;
2016-09-20 13:56:06 +00:00
if ( is_show_deps )
{
2017-02-28 11:07:53 +00:00
if ( ! builder_manifest_show_deps ( manifest , build_context , & error ) )
2016-09-20 13:56:06 +00:00
{
g_printerr ( " Error running %s: %s \n " , argv [ 3 ] , error - > message ) ;
return 1 ;
}
return 0 ;
}
2017-08-18 09:04:13 +00:00
if ( opt_install_deps_from ! = NULL )
{
2018-02-16 07:22:49 +00:00
if ( ! builder_manifest_install_deps ( manifest , build_context , opt_install_deps_from , opt_user , opt_installation ,
opt_yes , & error ) )
2017-08-18 09:04:13 +00:00
{
g_printerr ( " Error running %s: %s \n " , argv [ 3 ] , error - > message ) ;
return 1 ;
}
if ( opt_install_deps_only )
return 0 ;
}
2016-10-07 22:41:46 +00:00
app_dir_is_empty = ! g_file_query_exists ( app_dir , NULL ) | |
directory_is_empty ( app_dir_path ) ;
2016-05-26 09:13:37 +00:00
if ( is_run )
2016-02-17 08:45:12 +00:00
{
2016-05-26 09:13:37 +00:00
g_assert ( opt_run ) ;
2016-02-17 08:45:12 +00:00
2016-10-07 22:41:46 +00:00
if ( app_dir_is_empty )
2016-02-17 08:45:12 +00:00
{
g_printerr ( " App dir '%s' is empty or doesn't exist. \n " , app_dir_path ) ;
return 1 ;
}
2016-05-26 10:44:51 +00:00
if ( ! builder_manifest_run ( manifest , build_context , arg_context ,
orig_argv + first_non_arg + 2 ,
2017-11-09 13:12:14 +00:00
orig_argc - first_non_arg - 2 ,
opt_log_session_bus , opt_log_system_bus ,
& error ) )
2016-02-17 08:45:12 +00:00
{
g_printerr ( " Error running %s: %s \n " , argv [ 3 ] , error - > message ) ;
return 1 ;
}
return 0 ;
}
2016-05-26 09:13:37 +00:00
g_assert ( ! opt_run ) ;
2016-09-20 13:56:06 +00:00
g_assert ( ! opt_show_deps ) ;
2016-05-26 09:13:37 +00:00
2017-05-31 12:07:38 +00:00
if ( opt_export_only | | opt_finish_only | | opt_build_shell )
2016-02-17 08:45:12 +00:00
{
2017-02-20 14:02:09 +00:00
if ( app_dir_is_empty )
2016-04-14 03:06:59 +00:00
{
2017-02-20 14:02:09 +00:00
g_printerr ( " App dir '%s' is empty or doesn't exist. \n " , app_dir_path ) ;
2016-04-14 03:06:59 +00:00
return 1 ;
}
2016-02-17 08:45:12 +00:00
}
2017-02-20 14:02:09 +00:00
else
2016-10-07 22:41:46 +00:00
{
2017-02-20 14:02:09 +00:00
if ( ! app_dir_is_empty )
{
if ( opt_force_clean )
{
g_print ( " Emptying app dir '%s' \n " , app_dir_path ) ;
if ( ! flatpak_rm_rf ( app_dir , NULL , & error ) )
{
g_printerr ( " Couldn't empty app dir '%s': %s " ,
app_dir_path , error - > message ) ;
return 1 ;
}
}
else
{
g_printerr ( " App dir '%s' is not empty. Please delete "
2017-03-15 23:14:25 +00:00
" the existing contents or use --force-clean. \n " , app_dir_path ) ;
2017-02-20 14:02:09 +00:00
return 1 ;
}
}
2016-10-07 22:41:46 +00:00
}
2016-02-17 08:45:12 +00:00
2017-11-15 20:36:21 +00:00
/* Verify that cache and build dir is on same filesystem */
2018-05-03 15:34:18 +00:00
if ( ! opt_download_only )
{
g_autofree char * state_path = g_file_get_path ( builder_context_get_state_dir ( build_context ) ) ;
g_autoptr ( GFile ) app_parent = g_file_get_parent ( builder_context_get_app_dir ( build_context ) ) ;
g_autofree char * app_parent_path = g_file_get_path ( app_parent ) ;
struct stat buf1 , buf2 ;
if ( stat ( app_parent_path , & buf1 ) = = 0 & & stat ( state_path , & buf2 ) = = 0 & &
buf1 . st_dev ! = buf2 . st_dev )
{
g_printerr ( " The state dir (%s) is not on the same filesystem as the target dir (%s) \n " ,
state_path , app_parent_path ) ;
return 1 ;
}
}
2017-11-15 20:36:21 +00:00
2018-04-14 17:17:59 +00:00
if ( ! builder_context_set_checksum_for ( build_context , manifest_basename , manifest_sha256 , & error ) )
2017-12-05 12:16:37 +00:00
{
g_printerr ( " Failed to set checksum for ‘ %s’ : %s \n " , manifest_basename , error - > message ) ;
return 1 ;
}
2017-02-22 14:11:24 +00:00
2018-05-03 15:34:18 +00:00
if ( ! builder_manifest_start ( manifest , opt_download_only , opt_allow_missing_runtimes , build_context , & error ) )
2016-02-03 09:57:50 +00:00
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Failed to init: %s \n " , error - > message ) ;
2016-02-03 09:57:50 +00:00
return 1 ;
}
2016-10-07 22:41:46 +00:00
if ( ! opt_finish_only & &
2017-05-31 12:07:38 +00:00
! opt_export_only & &
2016-10-07 22:41:46 +00:00
! opt_disable_download & &
2017-02-20 14:02:09 +00:00
! builder_manifest_download ( manifest , ! opt_disable_updates , opt_build_shell , build_context , & error ) )
2016-01-12 11:09:09 +00:00
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Failed to download sources: %s \n " , error - > message ) ;
2016-01-12 11:09:09 +00:00
return 1 ;
2015-11-16 15:23:23 +00:00
}
if ( opt_download_only )
return 0 ;
2017-02-20 14:02:09 +00:00
if ( opt_build_shell )
{
if ( ! builder_manifest_build_shell ( manifest , build_context , opt_build_shell , & error ) )
{
g_printerr ( " Failed to setup module: %s \n " , error - > message ) ;
return 1 ;
}
return 0 ;
}
2017-11-15 20:36:21 +00:00
if ( opt_state_dir )
{
/* If the state dir can be shared we need to use a global identifier for the key */
g_autofree char * manifest_path = g_file_get_path ( manifest_file ) ;
cache_branch = g_strconcat ( builder_context_get_arch ( build_context ) , " - " , manifest_path + 1 , NULL ) ;
}
else
cache_branch = g_strconcat ( builder_context_get_arch ( build_context ) , " - " , manifest_basename , NULL ) ;
escaped_cache_branch = g_uri_escape_string ( cache_branch , " " , TRUE ) ;
for ( p = escaped_cache_branch ; * p ; p + + )
{
if ( * p = = ' % ' )
* p = ' _ ' ;
}
2015-11-16 15:23:23 +00:00
2017-11-15 20:36:21 +00:00
cache = builder_cache_new ( build_context , app_dir , escaped_cache_branch ) ;
2015-11-16 15:23:23 +00:00
if ( ! builder_cache_open ( cache , & error ) )
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Error opening cache: %s \n " , error - > message ) ;
2015-11-16 15:23:23 +00:00
return 1 ;
}
if ( opt_disable_cache ) /* This disables *lookups*, but we still build the cache */
builder_cache_disable_lookups ( cache ) ;
builder_manifest_checksum ( manifest , cache , build_context ) ;
2017-05-31 12:07:38 +00:00
if ( ! opt_finish_only & & ! opt_export_only )
2015-11-16 15:23:23 +00:00
{
2016-10-07 22:41:46 +00:00
if ( ! builder_cache_lookup ( cache , " init " ) )
2015-11-16 15:23:23 +00:00
{
2016-10-07 22:41:46 +00:00
g_autofree char * body =
g_strdup_printf ( " Initialized %s \n " ,
builder_manifest_get_id ( manifest ) ) ;
2017-02-16 09:51:00 +00:00
if ( ! builder_manifest_init_app_dir ( manifest , cache , build_context , & error ) )
2016-10-07 22:41:46 +00:00
{
g_printerr ( " Error: %s \n " , error - > message ) ;
return 1 ;
}
if ( ! builder_cache_commit ( cache , body , & error ) )
{
g_printerr ( " Error: %s \n " , error - > message ) ;
return 1 ;
}
2015-11-16 15:23:23 +00:00
}
2016-10-07 22:41:46 +00:00
if ( ! builder_manifest_build ( manifest , cache , build_context , & error ) )
2015-11-16 15:23:23 +00:00
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Error: %s \n " , error - > message ) ;
2015-11-16 15:23:23 +00:00
return 1 ;
}
}
2017-05-31 12:07:38 +00:00
if ( ! opt_build_only & & ! opt_export_only )
2015-11-16 15:23:23 +00:00
{
2015-11-26 13:38:13 +00:00
if ( ! builder_manifest_cleanup ( manifest , cache , build_context , & error ) )
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Error: %s \n " , error - > message ) ;
2015-11-26 13:38:13 +00:00
return 1 ;
}
2015-11-16 15:23:23 +00:00
2015-11-26 13:38:13 +00:00
if ( ! builder_manifest_finish ( manifest , cache , build_context , & error ) )
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Error: %s \n " , error - > message ) ;
2015-11-26 13:38:13 +00:00
return 1 ;
}
2016-01-18 14:22:56 +00:00
if ( ! builder_manifest_create_platform ( manifest , cache , build_context , & error ) )
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Error: %s \n " , error - > message ) ;
2016-01-18 14:22:56 +00:00
return 1 ;
}
2017-04-24 10:31:56 +00:00
if ( builder_context_get_bundle_sources ( build_context ) & &
2018-04-14 17:17:59 +00:00
! builder_manifest_bundle_sources ( manifest , manifest_contents , cache , build_context , & error ) )
2017-04-24 10:31:56 +00:00
{
g_printerr ( " Error: %s \n " , error - > message ) ;
return 1 ;
}
2015-11-16 15:23:23 +00:00
}
2017-05-31 12:07:38 +00:00
if ( ! opt_require_changes & & ! opt_export_only )
2016-05-06 14:03:27 +00:00
builder_cache_ensure_checkout ( cache ) ;
2016-01-11 14:35:17 +00:00
2017-05-31 12:07:38 +00:00
if ( opt_mirror_screenshots_url & & ! opt_export_only )
2017-05-22 14:18:45 +00:00
{
g_autofree char * screenshot_subdir = g_strdup_printf ( " %s-%s " , builder_manifest_get_id ( manifest ) ,
2017-06-19 19:16:46 +00:00
builder_manifest_get_branch ( manifest ) ) ;
2017-05-22 14:18:45 +00:00
g_autofree char * url = g_build_filename ( opt_mirror_screenshots_url , screenshot_subdir , NULL ) ;
g_autofree char * xml_relpath = g_strdup_printf ( " files/share/app-info/xmls/%s.xml.gz " , builder_manifest_get_id ( manifest ) ) ;
g_autoptr ( GFile ) xml = g_file_resolve_relative_path ( app_dir , xml_relpath ) ;
g_autoptr ( GFile ) cache = flatpak_build_file ( builder_context_get_state_dir ( build_context ) , " screenshots-cache " , NULL ) ;
g_autoptr ( GFile ) screenshots = flatpak_build_file ( app_dir , " screenshots " , NULL ) ;
g_autoptr ( GFile ) screenshots_sub = flatpak_build_file ( screenshots , screenshot_subdir , NULL ) ;
const char * argv [ ] = {
" appstream-util " ,
" mirror-screenshots " ,
flatpak_file_get_path_cached ( xml ) ,
url ,
flatpak_file_get_path_cached ( cache ) ,
flatpak_file_get_path_cached ( screenshots_sub ) ,
NULL
} ;
g_print ( " Mirroring screenshots from appdata \n " ) ;
2017-09-06 15:01:13 +00:00
builder_set_term_title ( _ ( " Mirroring screenshots " ) ) ;
2017-05-22 14:18:45 +00:00
if ( ! flatpak_mkdir_p ( screenshots , NULL , & error ) )
{
g_printerr ( " Error creating screenshot dir: %s \n " , error - > message ) ;
return 1 ;
}
if ( g_file_query_exists ( xml , NULL ) )
{
if ( ! builder_maybe_host_spawnv ( NULL ,
NULL ,
2018-01-11 10:41:17 +00:00
0 ,
2017-05-22 14:18:45 +00:00
& error ,
argv ) )
{
g_printerr ( " Error mirroring screenshots: %s \n " , error - > message ) ;
return 1 ;
}
}
g_print ( " Saved screenshots in %s \n " , flatpak_file_get_path_cached ( screenshots ) ) ;
}
2017-12-12 11:37:56 +00:00
if ( ! opt_build_only & &
( opt_repo | | opt_install ) & &
( opt_export_only | | builder_cache_has_checkout ( cache ) ) )
2016-01-11 14:35:17 +00:00
{
g_autoptr ( GFile ) debuginfo_metadata = NULL ;
2017-03-31 05:56:10 +00:00
g_autoptr ( GFile ) sourcesinfo_metadata = NULL ;
2017-08-21 13:40:21 +00:00
g_auto ( GStrv ) exclude_dirs = builder_manifest_get_exclude_dirs ( manifest ) ;
GList * l ;
2016-01-11 14:35:17 +00:00
2017-12-18 08:41:50 +00:00
if ( opt_repo )
export_repo = g_file_new_for_path ( opt_repo ) ;
else if ( opt_install )
2017-12-18 08:44:30 +00:00
export_repo = g_object_ref ( builder_context_get_cache_dir ( build_context ) ) ;
2017-12-12 11:37:56 +00:00
2016-06-02 06:50:58 +00:00
g_print ( " Exporting %s to repo \n " , builder_manifest_get_id ( manifest ) ) ;
2017-09-06 15:01:13 +00:00
builder_set_term_title ( _ ( " Exporting to repository " ) ) ;
2016-01-12 11:36:07 +00:00
2016-04-30 21:43:39 +00:00
if ( ! do_export ( build_context , & error ,
2017-01-27 14:27:55 +00:00
FALSE ,
2017-12-15 11:18:38 +00:00
flatpak_file_get_path_cached ( export_repo ) ,
app_dir_path , exclude_dirs , builder_manifest_get_branch ( manifest ) ,
2017-06-27 12:09:57 +00:00
builder_manifest_get_collection_id ( manifest ) ,
2016-01-18 10:43:02 +00:00
" --exclude=/lib/debug/* " ,
" --include=/lib/debug/app " ,
2016-02-18 18:22:34 +00:00
builder_context_get_separate_locales ( build_context ) ? " --exclude=/share/runtime/locale/*/* " : skip_arg ,
2017-06-27 12:07:03 +00:00
NULL ) )
2016-01-11 14:35:17 +00:00
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Export failed: %s \n " , error - > message ) ;
2016-01-11 14:35:17 +00:00
return 1 ;
}
2016-02-18 20:49:13 +00:00
/* Export regular locale extensions */
2016-02-18 18:22:34 +00:00
dir_enum = g_file_enumerate_children ( app_dir , " standard::name,standard::type " ,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS ,
NULL , NULL ) ;
while ( dir_enum ! = NULL & &
( next = g_file_enumerator_next_file ( dir_enum , NULL , NULL ) ) )
{
g_autoptr ( GFileInfo ) child_info = next ;
const char * name = g_file_info_get_name ( child_info ) ;
g_autofree char * metadata_arg = NULL ;
g_autofree char * files_arg = NULL ;
2016-10-26 18:57:57 +00:00
g_autofree char * locale_id = builder_manifest_get_locale_id ( manifest ) ;
2016-02-18 18:22:34 +00:00
2016-03-21 15:36:51 +00:00
if ( strcmp ( name , " metadata.locale " ) = = 0 )
2016-10-26 18:57:57 +00:00
g_print ( " Exporting %s to repo \n " , locale_id ) ;
2016-03-21 15:36:51 +00:00
else
continue ;
2016-02-18 18:22:34 +00:00
metadata_arg = g_strdup_printf ( " --metadata=%s " , name ) ;
files_arg = g_strconcat ( builder_context_get_build_runtime ( build_context ) ? " --files=usr " : " --files=files " ,
2016-04-07 11:00:01 +00:00
" /share/runtime/locale/ " , NULL ) ;
2016-04-30 21:43:39 +00:00
if ( ! do_export ( build_context , & error , TRUE ,
2017-12-15 11:18:38 +00:00
flatpak_file_get_path_cached ( export_repo ) ,
app_dir_path , NULL , builder_manifest_get_branch ( manifest ) ,
2017-06-27 12:09:57 +00:00
builder_manifest_get_collection_id ( manifest ) ,
2016-02-18 18:22:34 +00:00
metadata_arg ,
files_arg ,
2017-06-27 12:07:03 +00:00
NULL ) )
2016-02-18 18:22:34 +00:00
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Export failed: %s \n " , error - > message ) ;
2016-02-18 18:22:34 +00:00
return 1 ;
}
}
2016-02-18 20:49:13 +00:00
/* Export debug extensions */
2016-01-11 14:35:17 +00:00
debuginfo_metadata = g_file_get_child ( app_dir , " metadata.debuginfo " ) ;
if ( g_file_query_exists ( debuginfo_metadata , NULL ) )
{
2016-10-26 18:57:57 +00:00
g_autofree char * debug_id = builder_manifest_get_debug_id ( manifest ) ;
g_print ( " Exporting %s to repo \n " , debug_id ) ;
2016-01-12 11:36:07 +00:00
2016-04-30 21:43:39 +00:00
if ( ! do_export ( build_context , & error , TRUE ,
2017-12-15 11:18:38 +00:00
flatpak_file_get_path_cached ( export_repo ) ,
app_dir_path , NULL , builder_manifest_get_branch ( manifest ) ,
2017-06-27 12:09:57 +00:00
builder_manifest_get_collection_id ( manifest ) ,
2016-01-18 10:43:02 +00:00
" --metadata=metadata.debuginfo " ,
builder_context_get_build_runtime ( build_context ) ? " --files=usr/lib/debug " : " --files=files/lib/debug " ,
2017-06-27 12:07:03 +00:00
NULL ) )
2016-01-11 14:35:17 +00:00
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Export failed: %s \n " , error - > message ) ;
2016-01-11 14:35:17 +00:00
return 1 ;
}
}
2016-02-18 20:49:13 +00:00
2017-08-21 13:40:21 +00:00
for ( l = builder_manifest_get_add_extensions ( manifest ) ; l ! = NULL ; l = l - > next )
{
BuilderExtension * e = l - > data ;
const char * extension_id = NULL ;
g_autofree char * metadata_arg = NULL ;
g_autofree char * files_arg = NULL ;
if ( ! builder_extension_is_bundled ( e ) )
continue ;
extension_id = builder_extension_get_name ( e ) ;
g_print ( " Exporting %s to repo \n " , extension_id ) ;
metadata_arg = g_strdup_printf ( " --metadata=metadata.%s " , extension_id ) ;
files_arg = g_strdup_printf ( " --files=%s/%s " ,
builder_context_get_build_runtime ( build_context ) ? " usr " : " files " ,
builder_extension_get_directory ( e ) ) ;
if ( ! do_export ( build_context , & error , TRUE ,
2017-12-15 11:18:38 +00:00
flatpak_file_get_path_cached ( export_repo ) ,
app_dir_path , NULL , builder_manifest_get_branch ( manifest ) ,
2017-08-21 13:40:21 +00:00
builder_manifest_get_collection_id ( manifest ) ,
metadata_arg , files_arg ,
NULL ) )
{
g_printerr ( " Export failed: %s \n " , error - > message ) ;
return 1 ;
}
}
2017-03-31 05:56:10 +00:00
/* Export sources extensions */
2017-04-05 04:54:39 +00:00
sourcesinfo_metadata = g_file_get_child ( app_dir , " metadata.sources " ) ;
2017-04-24 10:31:56 +00:00
if ( g_file_query_exists ( sourcesinfo_metadata , NULL ) )
2017-03-31 05:56:10 +00:00
{
g_autofree char * sources_id = builder_manifest_get_sources_id ( manifest ) ;
g_print ( " Exporting %s to repo \n " , sources_id ) ;
if ( ! do_export ( build_context , & error , TRUE ,
2017-12-15 11:18:38 +00:00
flatpak_file_get_path_cached ( export_repo ) ,
app_dir_path , NULL , builder_manifest_get_branch ( manifest ) ,
2017-06-27 12:09:57 +00:00
builder_manifest_get_collection_id ( manifest ) ,
2017-04-05 04:54:39 +00:00
" --metadata=metadata.sources " ,
2017-04-05 05:04:10 +00:00
" --files=sources " ,
2017-06-27 12:07:03 +00:00
NULL ) )
2017-03-31 05:56:10 +00:00
{
g_printerr ( " Export failed: %s \n " , error - > message ) ;
return 1 ;
}
}
2016-02-18 20:49:13 +00:00
/* Export platform */
platform_id = builder_manifest_get_id_platform ( manifest ) ;
if ( builder_context_get_build_runtime ( build_context ) & &
platform_id ! = NULL )
{
2016-06-02 06:50:58 +00:00
g_print ( " Exporting %s to repo \n " , platform_id ) ;
2016-02-18 20:49:13 +00:00
2016-05-06 14:03:27 +00:00
if ( ! do_export ( build_context , & error , TRUE ,
2017-12-15 11:18:38 +00:00
flatpak_file_get_path_cached ( export_repo ) ,
app_dir_path , NULL , builder_manifest_get_branch ( manifest ) ,
2017-06-27 12:09:57 +00:00
builder_manifest_get_collection_id ( manifest ) ,
2016-05-06 14:03:27 +00:00
" --metadata=metadata.platform " ,
" --files=platform " ,
builder_context_get_separate_locales ( build_context ) ? " --exclude=/share/runtime/locale/*/* " : skip_arg ,
2017-06-27 12:07:03 +00:00
NULL ) )
2016-05-06 14:03:27 +00:00
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Export failed: %s \n " , error - > message ) ;
2016-05-06 14:03:27 +00:00
return 1 ;
}
2016-02-18 20:49:13 +00:00
}
/* Export platform locales */
dir_enum2 = g_file_enumerate_children ( app_dir , " standard::name,standard::type " ,
2016-05-06 14:03:27 +00:00
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS ,
NULL , NULL ) ;
2016-02-18 20:49:13 +00:00
while ( dir_enum2 ! = NULL & &
( next = g_file_enumerator_next_file ( dir_enum2 , NULL , NULL ) ) )
{
g_autoptr ( GFileInfo ) child_info = next ;
const char * name = g_file_info_get_name ( child_info ) ;
g_autofree char * metadata_arg = NULL ;
g_autofree char * files_arg = NULL ;
2016-10-26 18:57:57 +00:00
g_autofree char * locale_id = builder_manifest_get_locale_id_platform ( manifest ) ;
2016-02-18 20:49:13 +00:00
2016-03-21 15:36:51 +00:00
if ( strcmp ( name , " metadata.platform.locale " ) = = 0 )
2016-10-26 18:57:57 +00:00
g_print ( " Exporting %s to repo \n " , locale_id ) ;
2016-03-21 15:36:51 +00:00
else
2016-02-18 20:49:13 +00:00
continue ;
metadata_arg = g_strdup_printf ( " --metadata=%s " , name ) ;
2016-04-07 11:00:01 +00:00
files_arg = g_strconcat ( " --files=platform/share/runtime/locale/ " , NULL ) ;
2016-04-30 21:43:39 +00:00
if ( ! do_export ( build_context , & error , TRUE ,
2017-12-15 11:18:38 +00:00
flatpak_file_get_path_cached ( export_repo ) ,
app_dir_path , NULL , builder_manifest_get_branch ( manifest ) ,
2017-06-27 12:09:57 +00:00
builder_manifest_get_collection_id ( manifest ) ,
2016-02-18 20:49:13 +00:00
metadata_arg ,
files_arg ,
2017-06-27 12:07:03 +00:00
NULL ) )
2016-02-18 20:49:13 +00:00
{
2016-06-28 13:08:09 +00:00
g_printerr ( " Export failed: %s \n " , error - > message ) ;
2016-02-18 20:49:13 +00:00
return 1 ;
}
}
2016-01-11 14:35:17 +00:00
}
2015-11-16 15:23:23 +00:00
2017-12-12 11:37:56 +00:00
if ( opt_install )
{
2017-12-15 11:19:36 +00:00
/* We may end here with a NULL export repo if --require-changes was
passed and there were no changes , do nothing in that case */
if ( export_repo = = NULL )
g_printerr ( " NOTE: No export due to --require-changes, ignoring --install \n " ) ;
else if ( ! do_install ( build_context , flatpak_file_get_path_cached ( export_repo ) ,
builder_manifest_get_id ( manifest ) ,
builder_manifest_get_branch ( manifest ) ,
& error ) )
2017-12-12 11:37:56 +00:00
{
g_printerr ( " Install failed: %s \n " , error - > message ) ;
return 1 ;
}
}
2018-06-10 18:47:09 +00:00
if ( ! opt_finish_only & & ! opt_export_only )
prune_unused_stages = TRUE ;
if ( ! builder_gc ( cache , prune_unused_stages , & error ) )
2015-11-16 15:23:23 +00:00
{
2017-07-07 14:10:27 +00:00
g_warning ( " Failed to GC build cache: %s " , error - > message ) ;
2015-11-16 15:23:23 +00:00
g_clear_error ( & error ) ;
}
return 0 ;
}