diff options
Diffstat (limited to 'paludis/repositories')
-rw-r--r-- | paludis/repositories/e/exndbam_repository.cc | 39 | ||||
-rw-r--r-- | paludis/repositories/e/exndbam_repository_TEST.cc | 127 | ||||
-rwxr-xr-x | paludis/repositories/e/exndbam_repository_TEST_setup.sh | 19 | ||||
-rw-r--r-- | paludis/repositories/e/vdb_merger.cc | 3 | ||||
-rw-r--r-- | paludis/repositories/unpackaged/installed_repository.cc | 3 |
5 files changed, 187 insertions, 4 deletions
diff --git a/paludis/repositories/e/exndbam_repository.cc b/paludis/repositories/e/exndbam_repository.cc index ca14dae10..81116a4de 100644 --- a/paludis/repositories/e/exndbam_repository.cc +++ b/paludis/repositories/e/exndbam_repository.cc @@ -49,7 +49,9 @@ #include <paludis/metadata_key.hh> #include <paludis/package_id.hh> #include <paludis/action.hh> +#include <paludis/choice.hh> #include <paludis/literal_metadata_key.hh> +#include <paludis/partitioning.hh> #include <paludis/slot.hh> #include <functional> @@ -330,6 +332,27 @@ namespace { return s->end() != s->find(f); } + + bool + should_merge(const std::shared_ptr<Partitioning> & partitioning, + const std::shared_ptr<const Choice> & parts, + const FSPath & path) + { + if (! partitioning) + return true; + + const auto classification(partitioning->classify(path).value()); + + // NOTE(compnerd) the empty name signifies the core partition + if (classification.empty()) + return true; + + for (const auto & part : *parts) + if (part->unprefixed_name().value() == classification) + return part->enabled(); + + throw InternalError(PALUDIS_HERE, classification + " choice not found"); + } } void @@ -429,9 +452,20 @@ ExndbamRepository::merge(const MergeParams & m) } } - auto eapi(std::static_pointer_cast<const ERepositoryID>(m.package_id())->eapi()->supported()); + auto package(std::static_pointer_cast<const ERepositoryID>(m.package_id())); + auto eapi(package->eapi()->supported()); auto fix_mtimes(eapi->ebuild_options()->fix_mtimes()); + std::function<bool(const FSPath &)> should_merge_callback; + if (auto prefix = eapi->parts_prefix()) + { + const auto choices(package->choices_key()->parse_value()); + const auto parts(choices->find(ChoicePrefixName(prefix->value()))); + + should_merge_callback = + std::bind(should_merge, m.parts(), *parts, std::placeholders::_1); + } + NDBAMMerger merger( make_named_values<NDBAMMergerParams>( n::config_protect() = config_protect, @@ -449,7 +483,8 @@ ExndbamRepository::merge(const MergeParams & m) n::package_id() = m.package_id(), n::parts() = m.parts(), n::permit_destination() = m.permit_destination(), - n::root() = installed_root_key()->parse_value() + n::root() = installed_root_key()->parse_value(), + n::should_merge() = should_merge_callback )); (m.used_this_for_config_protect())(config_protect); diff --git a/paludis/repositories/e/exndbam_repository_TEST.cc b/paludis/repositories/e/exndbam_repository_TEST.cc index 518978734..025dd31df 100644 --- a/paludis/repositories/e/exndbam_repository_TEST.cc +++ b/paludis/repositories/e/exndbam_repository_TEST.cc @@ -27,10 +27,13 @@ #include <paludis/util/join.hh> #include <paludis/util/make_named_values.hh> #include <paludis/util/sequence.hh> +#include <paludis/util/fs_iterator.hh> #include <paludis/util/fs_path.hh> +#include <paludis/util/fs_stat.hh> #include <paludis/standard_output_manager.hh> #include <paludis/action.hh> +#include <paludis/choice.hh> #include <paludis/filtered_generator.hh> #include <paludis/generator.hh> #include <paludis/selection.hh> @@ -38,6 +41,8 @@ #include <gtest/gtest.h> +#include <algorithm> + using namespace paludis; namespace @@ -95,6 +100,26 @@ namespace &env, { })), nullptr, { }))]->begin())->perform_action(install_action); } + void + uninstall(const Environment & env, const std::string & package) + { + UninstallAction action(make_named_values<UninstallActionOptions>( + n::config_protect() = "", + n::if_for_install_id() = nullptr, + n::ignore_for_unmerge() = [](const FSPath &) { return false; }, + n::is_overwrite() = false, + n::make_output_manager() = &make_standard_output_manager, + n::override_contents() = nullptr, + n::want_phase() = &want_all_phases + )); + + auto spec(parse_user_package_dep_spec(package, &env, { })); + auto matches(generator::Matches(spec, nullptr, { })); + auto id(*env[selection::RequireExactlyOne(matches)]->begin()); + + id->perform_action(action); + } + std::shared_ptr<Repository> make_exndbam_repository(Environment & env, const FSPath & root, const std::string & name) @@ -138,6 +163,39 @@ namespace return ERepository::repository_factory_create(&env, std::bind(from_keys, keys, _1)); } + + bool + recursive_image_matches(const FSPath & root, const FSPath & directory, + std::vector<FSPath> & contents) + { + for (FSIterator dentry(directory, { fsio_include_dotfiles }), invalid; + dentry != invalid; ++dentry) + { + const FSStat fstat(*dentry); + const auto entry(dentry->strip_leading(root)); + + auto expected = std::find(std::begin(contents), std::end(contents), + entry); + + if (expected == std::end(contents)) + return false; + + contents.erase(expected); + + if (fstat.is_directory()) + if (! recursive_image_matches(root, *dentry, contents)) + return false; + } + + return true; + } + + bool + image_matches(const FSPath & root, const std::vector<FSPath> & contents) + { + std::vector<FSPath> unseen(contents); + return recursive_image_matches(root, root, unseen) && !unseen.size(); + } } TEST(ExndbamRepository, RepoName) @@ -262,3 +320,72 @@ TEST(ExndbamRepository, UnlistedPartsFails) EXPECT_TRUE(installed->package_ids(partitioned, { })->empty()); } +TEST(ExndbamRepository, SelectivePartsCoreOnly) +{ + const auto partitioned(QualifiedPackageName("category/partitioned")); + + TestEnvironment env(exndbam_repository_TEST_root); + + auto parts(make_exheres_0_repository(env, exndbam_repository_TEST_dir, + "parts")); + auto installed(make_exndbam_repository(env, exndbam_repository_TEST_dir, + "installed")); + env.add_repository(0, installed); + env.add_repository(1, parts); + + EXPECT_TRUE(installed->package_ids(partitioned, { })->empty()); + EXPECT_TRUE(!parts->package_ids(partitioned, { })->empty()); + + install(env, installed, "=category/partitioned-1::parts", ""); + installed->invalidate(); + + EXPECT_TRUE(!installed->package_ids(partitioned, { })->empty()); + EXPECT_TRUE(image_matches(exndbam_repository_TEST_root, { + FSPath("/etc"), + FSPath("/usr"), + FSPath("/usr/share"), + FSPath("/usr/share/man"), + FSPath("/usr/share/man/man1"), + FSPath("/usr/share/man/man1/expart.1") + })); + + uninstall(env, "=category/partitioned-1::installed"); +} + +TEST(ExndbamRepository, SelectivePartsCoreAndSelectedParts) +{ + const auto partitioned(QualifiedPackageName("category/partitioned")); + + TestEnvironment env(exndbam_repository_TEST_root); + env.set_want_choice_enabled(ChoicePrefixName("parts"), + UnprefixedChoiceName("binaries"), + Tribool("true")); + + auto parts(make_exheres_0_repository(env, exndbam_repository_TEST_dir, + "parts")); + auto installed(make_exndbam_repository(env, exndbam_repository_TEST_dir, + "installed")); + env.add_repository(0, installed); + env.add_repository(1, parts); + + EXPECT_TRUE(installed->package_ids(partitioned, { })->empty()); + EXPECT_TRUE(!parts->package_ids(partitioned, { })->empty()); + + install(env, installed, "=category/partitioned-1::parts", ""); + installed->invalidate(); + + EXPECT_TRUE(!installed->package_ids(partitioned, { })->empty()); + EXPECT_TRUE(image_matches(exndbam_repository_TEST_root, { + FSPath("/etc"), + FSPath("/usr"), + FSPath("/usr/bin"), + FSPath("/usr/bin/binary"), + FSPath("/usr/share"), + FSPath("/usr/share/man"), + FSPath("/usr/share/man/man1"), + FSPath("/usr/share/man/man1/expart.1") + })); + + uninstall(env, "=category/partitioned-1::installed"); +} + diff --git a/paludis/repositories/e/exndbam_repository_TEST_setup.sh b/paludis/repositories/e/exndbam_repository_TEST_setup.sh index 4d2311f62..1636f26db 100755 --- a/paludis/repositories/e/exndbam_repository_TEST_setup.sh +++ b/paludis/repositories/e/exndbam_repository_TEST_setup.sh @@ -86,3 +86,22 @@ src_install() { } EOF +cat <<- EOF > parts/packages/category/partitioned/partitioned-1.exheres-0 +PLATFORMS="test" +MYOPTIONS="parts: binaries libraries" + +SLOT="0" + +src_unpack() { + edo mkdir -p "\${WORK}" +} + +src_install() { + edo mkdir -p "\${IMAGE}"/usr/{bin,lib,share/man/man1} + edo touch "\${IMAGE}"/usr/{bin/binary,lib/library.{so,a},share/man/man1/expart.1} + + expart binaries /usr/bin + expart libraries /usr/lib +} +EOF + diff --git a/paludis/repositories/e/vdb_merger.cc b/paludis/repositories/e/vdb_merger.cc index 9312f22bd..395a119d9 100644 --- a/paludis/repositories/e/vdb_merger.cc +++ b/paludis/repositories/e/vdb_merger.cc @@ -100,7 +100,8 @@ VDBMerger::VDBMerger(const VDBMergerParams & p) : n::options() = p.options(), n::parts() = nullptr, n::permit_destination() = p.permit_destination(), - n::root() = p.root() + n::root() = p.root(), + n::should_merge() = nullptr )), _imp(p) { diff --git a/paludis/repositories/unpackaged/installed_repository.cc b/paludis/repositories/unpackaged/installed_repository.cc index 2159e93fb..80bc4492d 100644 --- a/paludis/repositories/unpackaged/installed_repository.cc +++ b/paludis/repositories/unpackaged/installed_repository.cc @@ -347,7 +347,8 @@ InstalledUnpackagedRepository::merge(const MergeParams & m) n::package_id() = m.package_id(), n::parts() = m.parts(), n::permit_destination() = m.permit_destination(), - n::root() = installed_root_key()->parse_value().realpath() + n::root() = installed_root_key()->parse_value().realpath(), + n::should_merge() = nullptr )); if (m.check()) |