aboutsummaryrefslogtreecommitdiff
path: root/paludis/repositories/e
diff options
context:
space:
mode:
Diffstat (limited to 'paludis/repositories/e')
-rw-r--r--paludis/repositories/e/exndbam_repository.cc39
-rw-r--r--paludis/repositories/e/exndbam_repository_TEST.cc127
-rwxr-xr-xpaludis/repositories/e/exndbam_repository_TEST_setup.sh19
-rw-r--r--paludis/repositories/e/vdb_merger.cc3
4 files changed, 185 insertions, 3 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)
{