diff options
author | 2011-02-27 16:11:53 +0000 | |
---|---|---|
committer | 2011-02-27 16:11:53 +0000 | |
commit | 7224ee80cc55396c267b2517c01ffd9527e16700 (patch) | |
tree | 85085d72bfa42878c40291e388c6a8c8fed173c9 | |
parent | 2c4c9b36faef13dd4ba408c80ca16461daee14bd (diff) | |
download | paludis-7224ee80cc55396c267b2517c01ffd9527e16700.tar.gz paludis-7224ee80cc55396c267b2517c01ffd9527e16700.tar.xz |
Make merge checks its own phase
Fixes: ticket:1085
23 files changed, 262 insertions, 145 deletions
diff --git a/paludis/repositories/accounts/accounts_id.cc b/paludis/repositories/accounts/accounts_id.cc index 1b196e42a..6755da625 100644 --- a/paludis/repositories/accounts/accounts_id.cc +++ b/paludis/repositories/accounts/accounts_id.cc @@ -504,24 +504,46 @@ AccountsID::perform_action(Action & action) const std::string used_config_protect; + MergeParams merge_params(make_named_values<MergeParams>( + n::build_start_time() = build_start_time, + n::check() = true, + n::environment_file() = FSPath("/dev/null"), + n::image_dir() = fs_location_key()->value(), + n::merged_entries() = std::make_shared<FSPathSet>(), + n::options() = MergerOptions() + mo_rewrite_symlinks + mo_allow_empty_dirs, + n::output_manager() = output_manager, + n::package_id() = shared_from_this(), + n::perform_uninstall() = install_action->options.perform_uninstall(), + n::replacing() = install_action->options.replacing(), + n::used_this_for_config_protect() = std::bind( + &used_this_for_config_protect, std::ref(used_config_protect), std::placeholders::_1) + )); + + switch (install_action->options.want_phase()("check_merge")) + { + case wp_yes: + { + merge_params.check() = true; + (*install_action->options.destination()).destination_interface()->merge(merge_params); + } + break; + + case wp_skip: + break; + + case wp_abort: + throw ActionAbortedError("Told to abort install"); + + case last_wp: + throw InternalError(PALUDIS_HERE, "bad WantPhase"); + } + switch (install_action->options.want_phase()("merge")) { case wp_yes: { - (*install_action->options.destination()).destination_interface()->merge( - make_named_values<MergeParams>( - n::build_start_time() = build_start_time, - n::environment_file() = FSPath("/dev/null"), - n::image_dir() = fs_location_key()->value(), - n::merged_entries() = std::make_shared<FSPathSet>(), - n::options() = MergerOptions() + mo_rewrite_symlinks + mo_allow_empty_dirs, - n::output_manager() = output_manager, - n::package_id() = shared_from_this(), - n::perform_uninstall() = install_action->options.perform_uninstall(), - n::replacing() = install_action->options.replacing(), - n::used_this_for_config_protect() = std::bind( - &used_this_for_config_protect, std::ref(used_config_protect), std::placeholders::_1) - )); + merge_params.check() = false; + (*install_action->options.destination()).destination_interface()->merge(merge_params); } break; diff --git a/paludis/repositories/accounts/accounts_repository.cc b/paludis/repositories/accounts/accounts_repository.cc index 1ca62acb4..a84d72a46 100644 --- a/paludis/repositories/accounts/accounts_repository.cc +++ b/paludis/repositories/accounts/accounts_repository.cc @@ -426,6 +426,9 @@ AccountsRepository::merge(const MergeParams & m) if (! _imp->handler_if_installed) throw ActionFailedError("Can't merge to here"); + if (m.check()) + return; + _imp->handler_if_installed->merge(m); } diff --git a/paludis/repositories/e/do_install_action.cc b/paludis/repositories/e/do_install_action.cc index f804ac0d0..d12349040 100644 --- a/paludis/repositories/e/do_install_action.cc +++ b/paludis/repositories/e/do_install_action.cc @@ -275,7 +275,7 @@ paludis::erepository::do_install_action( continue; } - if (phase->option("merge")) + if (phase->option("merge") || phase->option("check_merge")) { if (! (*install_action.options.destination()).destination_interface()) throw ActionFailedError("Can't install '" + stringify(*id) @@ -290,6 +290,7 @@ paludis::erepository::do_install_action( (*install_action.options.destination()).destination_interface()->merge( make_named_values<MergeParams>( n::build_start_time() = build_start_time, + n::check() = phase->option("check_merge"), n::environment_file() = package_builddir / "temp" / "loadsaveenv", n::image_dir() = package_builddir / "image", n::merged_entries() = merged_entries, diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc index acd9524ad..eda10b252 100644 --- a/paludis/repositories/e/e_repository.cc +++ b/paludis/repositories/e/e_repository.cc @@ -1889,8 +1889,12 @@ ERepository::merge(const MergeParams & m) n::tar_file() = _imp->params.binary_distdir() / (bin_dist_base + pbin_tar_extension) )); - if (! merger.check()) - throw ActionFailedError("Not proceeding with install due to merge sanity check failing"); + if (m.check()) + { + if (! merger.check()) + throw ActionFailedError("Not proceeding with install due to merge sanity check failing"); + return; + } merger.merge(); diff --git a/paludis/repositories/e/eapis/0.conf b/paludis/repositories/e/eapis/0.conf index 55848ea47..bd9f700cc 100644 --- a/paludis/repositories/e/eapis/0.conf +++ b/paludis/repositories/e/eapis/0.conf @@ -117,6 +117,7 @@ ebuild_install = \ skipname=install skipifno=install sandbox clearenv : loadenv install saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/2.conf b/paludis/repositories/e/eapis/2.conf index c841935ef..37a7385ad 100644 --- a/paludis/repositories/e/eapis/2.conf +++ b/paludis/repositories/e/eapis/2.conf @@ -24,6 +24,7 @@ ebuild_install = \ skipname=install skipifno=install sandbox clearenv : loadenv install saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/4.conf b/paludis/repositories/e/eapis/4.conf index a346fc24f..006a2d9bb 100644 --- a/paludis/repositories/e/eapis/4.conf +++ b/paludis/repositories/e/eapis/4.conf @@ -20,6 +20,7 @@ ebuild_install = \ skipname=install skipifno=*sources,unpack,prepare,configure,compile,test,install sandbox clearenv : loadenv install saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/exheres-0.conf b/paludis/repositories/e/eapis/exheres-0.conf index 34f523379..318d731d8 100644 --- a/paludis/repositories/e/eapis/exheres-0.conf +++ b/paludis/repositories/e/eapis/exheres-0.conf @@ -149,6 +149,7 @@ ebuild_install = \ skipname=install skipifno=*sources,unpack,prepare,configure,compile,test,install sydbox clearenv : loadenv install saveenv ; \ skipname=strip strip : ; \ skipname=preinst skipifno=preinst sydbox clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst skipifno=postinst sydbox clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/paludis-1.conf b/paludis/repositories/e/eapis/paludis-1.conf index fef8b795b..7416c6181 100644 --- a/paludis/repositories/e/eapis/paludis-1.conf +++ b/paludis/repositories/e/eapis/paludis-1.conf @@ -119,6 +119,7 @@ ebuild_install = \ skipname=install skipifno=install sandbox clearenv : loadenv install saveenv ; \ skipname=strip strip : ; \ skipname=preinst skipifno=preinst sandbox clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst skipifno=postinst sandbox clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/pbin-1+0.conf b/paludis/repositories/e/eapis/pbin-1+0.conf index dcfac15a6..ff471d56c 100644 --- a/paludis/repositories/e/eapis/pbin-1+0.conf +++ b/paludis/repositories/e/eapis/pbin-1+0.conf @@ -33,6 +33,7 @@ ebuild_install = \ skipname=installbin sandbox clearenv : loadenv installbin saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/pbin-1+1.conf b/paludis/repositories/e/eapis/pbin-1+1.conf index da518a473..bfebb9032 100644 --- a/paludis/repositories/e/eapis/pbin-1+1.conf +++ b/paludis/repositories/e/eapis/pbin-1+1.conf @@ -33,6 +33,7 @@ ebuild_install = \ skipname=installbin sandbox clearenv : loadenv installbin saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/pbin-1+2.conf b/paludis/repositories/e/eapis/pbin-1+2.conf index bd8f979ea..0c57a1457 100644 --- a/paludis/repositories/e/eapis/pbin-1+2.conf +++ b/paludis/repositories/e/eapis/pbin-1+2.conf @@ -33,6 +33,7 @@ ebuild_install = \ skipname=installbin sandbox clearenv : loadenv installbin saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/pbin-1+3.conf b/paludis/repositories/e/eapis/pbin-1+3.conf index 9fed0bf60..60bcb9815 100644 --- a/paludis/repositories/e/eapis/pbin-1+3.conf +++ b/paludis/repositories/e/eapis/pbin-1+3.conf @@ -34,6 +34,7 @@ ebuild_install = \ skipname=installbin sandbox clearenv : loadenv installbin saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/pbin-1+4.conf b/paludis/repositories/e/eapis/pbin-1+4.conf index 396544345..210964c97 100644 --- a/paludis/repositories/e/eapis/pbin-1+4.conf +++ b/paludis/repositories/e/eapis/pbin-1+4.conf @@ -35,6 +35,7 @@ ebuild_install = \ skipname=installbin sandbox clearenv : loadenv installbin saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/pbin-1+exheres-0.conf b/paludis/repositories/e/eapis/pbin-1+exheres-0.conf index 36500e49f..3ccfb5b4a 100644 --- a/paludis/repositories/e/eapis/pbin-1+exheres-0.conf +++ b/paludis/repositories/e/eapis/pbin-1+exheres-0.conf @@ -32,6 +32,7 @@ ebuild_install = \ skipname=installbin sydbox clearenv : loadenv installbin saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/eapis/pbin-1+paludis-1.conf b/paludis/repositories/e/eapis/pbin-1+paludis-1.conf index fc315acf1..2a00c62fd 100644 --- a/paludis/repositories/e/eapis/pbin-1+paludis-1.conf +++ b/paludis/repositories/e/eapis/pbin-1+paludis-1.conf @@ -31,6 +31,7 @@ ebuild_install = \ skipname=installbin sandbox clearenv : loadenv installbin saveenv ; \ skipname=strip strip : ; \ skipname=preinst clearenv prepost : loadenv preinst saveenv ; \ + skipname=check_merge check_merge : ; \ skipname=merge merge : ; \ skipname=postinst clearenv prepost : loadenv postinst saveenv ; \ skipname=tidyup tidyup clearenv : loadenv tidyup diff --git a/paludis/repositories/e/exndbam_repository.cc b/paludis/repositories/e/exndbam_repository.cc index 7b496226a..152e754c0 100644 --- a/paludis/repositories/e/exndbam_repository.cc +++ b/paludis/repositories/e/exndbam_repository.cc @@ -359,9 +359,11 @@ ExndbamRepository::merge(const MergeParams & m) { std::string uid(stringify(m.package_id()->name().category()) + "---" + stringify(m.package_id()->name().package())); uid_dir /= "data"; - uid_dir.mkdir(0755, { fspmkdo_ok_if_exists }); + if (! m.check()) + uid_dir.mkdir(0755, { fspmkdo_ok_if_exists }); uid_dir /= uid; - uid_dir.mkdir(0755, { fspmkdo_ok_if_exists }); + if (! m.check()) + uid_dir.mkdir(0755, { fspmkdo_ok_if_exists }); } FSPath target_ver_dir(uid_dir); @@ -370,39 +372,43 @@ ExndbamRepository::merge(const MergeParams & m) if (target_ver_dir.stat().exists()) throw ActionFailedError("Temporary merge directory '" + stringify(target_ver_dir) + "' already exists, probably " "due to a previous failed install. If it is safe to do so, please remove this directory and try again."); - target_ver_dir.mkdir(0755, { }); + if (! m.check()) + target_ver_dir.mkdir(0755, { }); - WriteVDBEntryCommand write_vdb_entry_command( - make_named_values<WriteVDBEntryParams>( - n::environment() = _imp->params.environment(), - n::environment_file() = m.environment_file(), - n::maybe_output_manager() = m.output_manager(), - n::output_directory() = target_ver_dir, - n::package_id() = std::static_pointer_cast<const ERepositoryID>(m.package_id()) - )); + std::string config_protect, config_protect_mask; + if (! m.check()) + { + WriteVDBEntryCommand write_vdb_entry_command( + make_named_values<WriteVDBEntryParams>( + n::environment() = _imp->params.environment(), + n::environment_file() = m.environment_file(), + n::maybe_output_manager() = m.output_manager(), + n::output_directory() = target_ver_dir, + n::package_id() = std::static_pointer_cast<const ERepositoryID>(m.package_id()) + )); - write_vdb_entry_command(); + write_vdb_entry_command(); - _imp->ndbam.add_entry(m.package_id()->name(), target_ver_dir); + _imp->ndbam.add_entry(m.package_id()->name(), target_ver_dir); - /* load CONFIG_PROTECT, CONFIG_PROTECT_MASK back */ - std::string config_protect, config_protect_mask; - try - { - SafeIFStream c(target_ver_dir / "CONFIG_PROTECT"); - config_protect = std::string((std::istreambuf_iterator<char>(c)), std::istreambuf_iterator<char>()); - } - catch (const SafeIFStreamError &) - { - } + /* load CONFIG_PROTECT, CONFIG_PROTECT_MASK back */ + try + { + SafeIFStream c(target_ver_dir / "CONFIG_PROTECT"); + config_protect = std::string((std::istreambuf_iterator<char>(c)), std::istreambuf_iterator<char>()); + } + catch (const SafeIFStreamError &) + { + } - try - { - SafeIFStream c_m(target_ver_dir / "CONFIG_PROTECT_MASK"); - config_protect_mask = std::string((std::istreambuf_iterator<char>(c_m)), std::istreambuf_iterator<char>()); - } - catch (const SafeIFStreamError &) - { + try + { + SafeIFStream c_m(target_ver_dir / "CONFIG_PROTECT_MASK"); + config_protect_mask = std::string((std::istreambuf_iterator<char>(c_m)), std::istreambuf_iterator<char>()); + } + catch (const SafeIFStreamError &) + { + } } bool fix_mtimes(std::static_pointer_cast<const ERepositoryID>( @@ -427,12 +433,11 @@ ExndbamRepository::merge(const MergeParams & m) (m.used_this_for_config_protect())(config_protect); - if (! merger.check()) + if (m.check()) { - for (FSIterator d(target_ver_dir, { fsio_inode_sort, fsio_include_dotfiles }), d_end ; d != d_end ; ++d) - d->unlink(); - target_ver_dir.rmdir(); - throw ActionFailedError("Not proceeding with install due to merge sanity check failing"); + if (! merger.check()) + throw ActionFailedError("Not proceeding with install due to merge sanity check failing"); + return; } merger.merge(); diff --git a/paludis/repositories/e/vdb_repository.cc b/paludis/repositories/e/vdb_repository.cc index 904246844..c8e19541e 100644 --- a/paludis/repositories/e/vdb_repository.cc +++ b/paludis/repositories/e/vdb_repository.cc @@ -893,44 +893,49 @@ VDBRepository::merge(const MergeParams & m) std::shared_ptr<const ERepositoryID> is_replace(package_id_if_exists(m.package_id()->name(), m.package_id()->version())); + std::string config_protect, config_protect_mask; + FSPath tmp_vdb_dir(_imp->params.location()); - if (! tmp_vdb_dir.stat().exists()) - tmp_vdb_dir.mkdir(0755, { }); tmp_vdb_dir /= stringify(m.package_id()->name().category()); - if (! tmp_vdb_dir.stat().exists()) - tmp_vdb_dir.mkdir(0755, { }); tmp_vdb_dir /= ("-checking-" + stringify(m.package_id()->name().package()) + "-" + stringify(m.package_id()->version())); - tmp_vdb_dir.mkdir(0755, { }); - WriteVDBEntryCommand write_vdb_entry_command( - make_named_values<WriteVDBEntryParams>( - n::environment() = _imp->params.environment(), - n::environment_file() = m.environment_file(), - n::maybe_output_manager() = m.output_manager(), - n::output_directory() = tmp_vdb_dir, - n::package_id() = std::static_pointer_cast<const ERepositoryID>(m.package_id()) - )); + if (! m.check()) + { + if (! tmp_vdb_dir.dirname().dirname().stat().exists()) + tmp_vdb_dir.dirname().dirname().mkdir(0755, { }); + if (! tmp_vdb_dir.dirname().stat().exists()) + tmp_vdb_dir.dirname().mkdir(0755, { }); + tmp_vdb_dir.mkdir(0755, { }); - write_vdb_entry_command(); + WriteVDBEntryCommand write_vdb_entry_command( + make_named_values<WriteVDBEntryParams>( + n::environment() = _imp->params.environment(), + n::environment_file() = m.environment_file(), + n::maybe_output_manager() = m.output_manager(), + n::output_directory() = tmp_vdb_dir, + n::package_id() = std::static_pointer_cast<const ERepositoryID>(m.package_id()) + )); - /* load CONFIG_PROTECT, CONFIG_PROTECT_MASK from vdb */ - std::string config_protect, config_protect_mask; - try - { - SafeIFStream c(tmp_vdb_dir / "CONFIG_PROTECT"); - config_protect = std::string((std::istreambuf_iterator<char>(c)), std::istreambuf_iterator<char>()); - } - catch (const SafeIFStreamError &) - { - } + write_vdb_entry_command(); - try - { - SafeIFStream c_m(tmp_vdb_dir / "CONFIG_PROTECT_MASK"); - config_protect_mask = std::string((std::istreambuf_iterator<char>(c_m)), std::istreambuf_iterator<char>()); - } - catch (const SafeIFStreamError &) - { + /* load CONFIG_PROTECT, CONFIG_PROTECT_MASK from vdb */ + try + { + SafeIFStream c(tmp_vdb_dir / "CONFIG_PROTECT"); + config_protect = std::string((std::istreambuf_iterator<char>(c)), std::istreambuf_iterator<char>()); + } + catch (const SafeIFStreamError &) + { + } + + try + { + SafeIFStream c_m(tmp_vdb_dir / "CONFIG_PROTECT_MASK"); + config_protect_mask = std::string((std::istreambuf_iterator<char>(c_m)), std::istreambuf_iterator<char>()); + } + catch (const SafeIFStreamError &) + { + } } FSPath vdb_dir(_imp->params.location()); @@ -957,12 +962,11 @@ VDBRepository::merge(const MergeParams & m) (m.used_this_for_config_protect())(config_protect); - if (! merger.check()) + if (m.check()) { - for (FSIterator d(tmp_vdb_dir, { fsio_include_dotfiles, fsio_inode_sort }), d_end ; d != d_end ; ++d) - d->unlink(); - tmp_vdb_dir.rmdir(); - throw ActionFailedError("Not proceeding with install due to merge sanity check failing"); + if (! merger.check()) + throw ActionFailedError("Not proceeding with install due to merge sanity check failing"); + return; } if (is_replace) diff --git a/paludis/repositories/repository/repository_repository.cc b/paludis/repositories/repository/repository_repository.cc index 3a5988729..bd30f8a08 100644 --- a/paludis/repositories/repository/repository_repository.cc +++ b/paludis/repositories/repository/repository_repository.cc @@ -442,6 +442,9 @@ RepositoryRepository::merge(const MergeParams & m) if (! is_suitable_destination_for(m.package_id())) throw ActionFailedError("Not a suitable destination for '" + stringify(*m.package_id()) + "'"); + if (m.check()) + return; + std::string repo_sync(get_string_key(m.package_id(), "REPOSITORY_SYNC")); std::string repo_format(get_string_key(m.package_id(), "REPOSITORY_FORMAT")); std::string repo_name(stringify(m.package_id()->name().package())); diff --git a/paludis/repositories/unavailable/unavailable_repository_id.cc b/paludis/repositories/unavailable/unavailable_repository_id.cc index 7a1fc26be..6875c5fb4 100644 --- a/paludis/repositories/unavailable/unavailable_repository_id.cc +++ b/paludis/repositories/unavailable/unavailable_repository_id.cc @@ -219,24 +219,46 @@ UnavailableRepositoryID::perform_action(Action & action) const std::shared_ptr<OutputManager> output_manager(install_action->options.make_output_manager()(*install_action)); std::string used_config_protect; + MergeParams merge_params(make_named_values<MergeParams>( + n::build_start_time() = build_start_time, + n::check() = true, + n::environment_file() = FSPath("/dev/null"), + n::image_dir() = FSPath("/dev/null"), + n::merged_entries() = std::make_shared<FSPathSet>(), + n::options() = MergerOptions(), + n::output_manager() = output_manager, + n::package_id() = shared_from_this(), + n::perform_uninstall() = install_action->options.perform_uninstall(), + n::replacing() = install_action->options.replacing(), + n::used_this_for_config_protect() = std::bind( + &used_this_for_config_protect, std::ref(used_config_protect), std::placeholders::_1) + )); + + switch (install_action->options.want_phase()("check_merge")) + { + case wp_yes: + { + merge_params.check() = true; + (*install_action->options.destination()).destination_interface()->merge(merge_params); + } + break; + + case wp_skip: + break; + + case wp_abort: + throw ActionAbortedError("Told to abort install"); + + case last_wp: + throw InternalError(PALUDIS_HERE, "bad WantPhase"); + } + switch (install_action->options.want_phase()("merge")) { case wp_yes: { - (*install_action->options.destination()).destination_interface()->merge( - make_named_values<MergeParams>( - n::build_start_time() = build_start_time, - n::environment_file() = FSPath("/dev/null"), - n::image_dir() = FSPath("/dev/null"), - n::merged_entries() = std::make_shared<FSPathSet>(), - n::options() = MergerOptions(), - n::output_manager() = output_manager, - n::package_id() = shared_from_this(), - n::perform_uninstall() = install_action->options.perform_uninstall(), - n::replacing() = install_action->options.replacing(), - n::used_this_for_config_protect() = std::bind( - &used_this_for_config_protect, std::ref(used_config_protect), std::placeholders::_1) - )); + merge_params.check() = false; + (*install_action->options.destination()).destination_interface()->merge(merge_params); } break; diff --git a/paludis/repositories/unpackaged/installed_repository.cc b/paludis/repositories/unpackaged/installed_repository.cc index dd7632443..66a8bd125 100644 --- a/paludis/repositories/unpackaged/installed_repository.cc +++ b/paludis/repositories/unpackaged/installed_repository.cc @@ -317,10 +317,14 @@ InstalledUnpackagedRepository::merge(const MergeParams & m) else { std::string uid(stringify(m.package_id()->name().category()) + "---" + stringify(m.package_id()->name().package())); + uid_dir /= "data"; - uid_dir.mkdir(0755, { fspmkdo_ok_if_exists }); + if (! m.check()) + uid_dir.mkdir(0755, { fspmkdo_ok_if_exists }); + uid_dir /= uid; - uid_dir.mkdir(0755, { fspmkdo_ok_if_exists }); + if (! m.check()) + uid_dir.mkdir(0755, { fspmkdo_ok_if_exists }); } FSPath target_ver_dir(uid_dir); @@ -329,29 +333,34 @@ InstalledUnpackagedRepository::merge(const MergeParams & m) if (target_ver_dir.stat().exists()) throw ActionFailedError("Temporary merge directory '" + stringify(target_ver_dir) + "' already exists, probably " "due to a previous failed install. If it is safe to do so, please remove this directory and try again."); - target_ver_dir.mkdir(0755, { }); - { - SafeOFStream source_repository_file(target_ver_dir / "source_repository", -1, true); - source_repository_file << m.package_id()->repository_name() << std::endl; - } + if (! m.check()) + target_ver_dir.mkdir(0755, { }); - if (m.package_id()->short_description_key()) + if (! m.check()) { - SafeOFStream description_file(target_ver_dir / "description", -1, true); - description_file << m.package_id()->short_description_key()->value() << std::endl; - } + { + SafeOFStream source_repository_file(target_ver_dir / "source_repository", -1, true); + source_repository_file << m.package_id()->repository_name() << std::endl; + } - if (m.package_id()->build_dependencies_key()) - { - SafeOFStream build_dependencies_file(target_ver_dir / "build_dependencies", -1, true); - build_dependencies_file << m.package_id()->build_dependencies_key()->pretty_print_value(UnformattedPrettyPrinter(), { }) << std::endl; - } + if (m.package_id()->short_description_key()) + { + SafeOFStream description_file(target_ver_dir / "description", -1, true); + description_file << m.package_id()->short_description_key()->value() << std::endl; + } - if (m.package_id()->run_dependencies_key()) - { - SafeOFStream run_dependencies_file(target_ver_dir / "run_dependencies", -1, true); - run_dependencies_file << m.package_id()->run_dependencies_key()->pretty_print_value(UnformattedPrettyPrinter(), { }) << std::endl; + if (m.package_id()->build_dependencies_key()) + { + SafeOFStream build_dependencies_file(target_ver_dir / "build_dependencies", -1, true); + build_dependencies_file << m.package_id()->build_dependencies_key()->pretty_print_value(UnformattedPrettyPrinter(), { }) << std::endl; + } + + if (m.package_id()->run_dependencies_key()) + { + SafeOFStream run_dependencies_file(target_ver_dir / "run_dependencies", -1, true); + run_dependencies_file << m.package_id()->run_dependencies_key()->pretty_print_value(UnformattedPrettyPrinter(), { }) << std::endl; + } } NDBAMMerger merger( @@ -372,12 +381,11 @@ InstalledUnpackagedRepository::merge(const MergeParams & m) n::root() = installed_root_key()->value() )); - if (! merger.check()) + if (m.check()) { - for (FSIterator d(target_ver_dir, { fsio_include_dotfiles, fsio_inode_sort }), d_end ; d != d_end ; ++d) - d->unlink(); - target_ver_dir.rmdir(); - throw ActionFailedError("Not proceeding with install due to merge sanity check failing"); + if (! merger.check()) + throw ActionFailedError("Not proceeding with install due to merge sanity check failing"); + return; } merger.merge(); diff --git a/paludis/repositories/unpackaged/unpackaged_id.cc b/paludis/repositories/unpackaged/unpackaged_id.cc index 0379f8952..12db7bc83 100644 --- a/paludis/repositories/unpackaged/unpackaged_id.cc +++ b/paludis/repositories/unpackaged/unpackaged_id.cc @@ -433,28 +433,51 @@ UnpackagedID::perform_action(Action & action) const throw InternalError(PALUDIS_HERE, "bad WantPhase"); } + MergerOptions extra_merger_options; + if (preserve_work_choice && preserve_work_choice->enabled()) + extra_merger_options += mo_nondestructive; + + MergeParams merge_params(make_named_values<MergeParams>( + n::build_start_time() = build_start_time, + n::check() = true, + n::environment_file() = FSPath("/dev/null"), + n::image_dir() = fs_location_key()->value(), + n::merged_entries() = std::make_shared<FSPathSet>(), + n::options() = (MergerOptions() + mo_rewrite_symlinks + mo_allow_empty_dirs) + | extra_merger_options, + n::output_manager() = output_manager, + n::package_id() = shared_from_this(), + n::perform_uninstall() = install_action->options.perform_uninstall(), + n::replacing() = install_action->options.replacing(), + n::used_this_for_config_protect() = std::bind( + &used_this_for_config_protect, std::ref(used_config_protect), std::placeholders::_1) + )); + + switch (install_action->options.want_phase()("check_merge")) + { + case wp_yes: + { + merge_params.check() = true; + (*install_action->options.destination()).destination_interface()->merge(merge_params); + } + break; + + case wp_skip: + break; + + case wp_abort: + throw ActionAbortedError("Told to abort install"); + + case last_wp: + throw InternalError(PALUDIS_HERE, "bad WantPhase"); + } + switch (install_action->options.want_phase()("merge")) { case wp_yes: { - MergerOptions extra_merger_options; - if (preserve_work_choice && preserve_work_choice->enabled()) - extra_merger_options += mo_nondestructive; - (*install_action->options.destination()).destination_interface()->merge( - make_named_values<MergeParams>( - n::build_start_time() = build_start_time, - n::environment_file() = FSPath("/dev/null"), - n::image_dir() = fs_location_key()->value(), - n::merged_entries() = std::make_shared<FSPathSet>(), - n::options() = (MergerOptions() + mo_rewrite_symlinks + mo_allow_empty_dirs) - | extra_merger_options, - n::output_manager() = output_manager, - n::package_id() = shared_from_this(), - n::perform_uninstall() = install_action->options.perform_uninstall(), - n::replacing() = install_action->options.replacing(), - n::used_this_for_config_protect() = std::bind( - &used_this_for_config_protect, std::ref(used_config_protect), std::placeholders::_1) - )); + merge_params.check() = false; + (*install_action->options.destination()).destination_interface()->merge(merge_params); } break; diff --git a/paludis/repository.hh b/paludis/repository.hh index d667bbe25..f99e1cafd 100644 --- a/paludis/repository.hh +++ b/paludis/repository.hh @@ -60,6 +60,7 @@ namespace paludis { typedef Name<struct name_arch> arch; typedef Name<struct name_build_start_time> build_start_time; + typedef Name<struct name_check> check; typedef Name<struct name_destination_interface> destination_interface; typedef Name<struct name_environment_file> environment_file; typedef Name<struct name_environment_variable_interface> environment_variable_interface; @@ -145,6 +146,15 @@ namespace paludis */ NamedValue<n::build_start_time, Timestamp> build_start_time; + /** + * Whether to check or perform the merge. + * + * A check must be performed before a merge. + * + * \since 0.59 + */ + NamedValue<n::check, bool> check; + NamedValue<n::environment_file, FSPath> environment_file; NamedValue<n::image_dir, FSPath> image_dir; |