diff options
author | 2013-02-22 19:58:18 -0800 | |
---|---|---|
committer | 2013-03-11 22:35:15 -0700 | |
commit | 0e6261448e1613a45e4a3e79f7d9cf158e71df2d (patch) | |
tree | 2fbdab0aa9e6cd46db7d75504c797bbd9eb6e94e | |
parent | b62787ab8a2f2c1f7dc8793c8451ee7f7e932ca3 (diff) | |
download | paludis-0e6261448e1613a45e4a3e79f7d9cf158e71df2d.tar.gz paludis-0e6261448e1613a45e4a3e79f7d9cf158e71df2d.tar.xz |
allow partitioning image
This adds a new function `expart' which allows partitioning the image into
separate parts. This information is then provided to the merge to record.
Signed-off-by: Saleem Abdulrasool <compnerd@compnerd.org>
38 files changed, 553 insertions, 25 deletions
diff --git a/paludis/contents.cc b/paludis/contents.cc index 7b2418289..0d2c154e8 100644 --- a/paludis/contents.cc +++ b/paludis/contents.cc @@ -18,6 +18,7 @@ */ #include <paludis/contents.hh> +#include <paludis/util/make_null_shared_ptr.hh> #include <paludis/util/pimp-impl.hh> #include <paludis/util/wrapped_forward_iterator-impl.hh> #include <paludis/literal_metadata_key.hh> @@ -62,9 +63,38 @@ ContentsEntry::location_key() const return _imp->location_key; } -ContentsFileEntry::ContentsFileEntry(const FSPath & our_name) : - ContentsEntry(our_name) +namespace paludis +{ + template <> + struct Imp<ContentsFileEntry> + { + const std::shared_ptr<const MetadataValueKey<std::string> > part_key; + + Imp(const std::string & part) : + part_key(part.empty() + ? make_null_shared_ptr() + : std::make_shared<LiteralMetadataValueKey<std::string>>("part", "part", mkt_normal, part)) + { + } + }; +} + +ContentsFileEntry::ContentsFileEntry(const FSPath & our_name, + const std::string & our_part) : + ContentsEntry(our_name), _imp(our_part) { + if (_imp->part_key) + add_metadata_key(_imp->part_key); +} + +ContentsFileEntry::~ContentsFileEntry() +{ +} + +const std::shared_ptr<const MetadataValueKey<std::string> > +ContentsFileEntry::part_key() const +{ + return _imp->part_key; } ContentsDirEntry::ContentsDirEntry(const FSPath & our_name) : @@ -83,19 +113,26 @@ namespace paludis struct Imp<ContentsSymEntry> { const std::shared_ptr<const MetadataValueKey<std::string> > target_key; + const std::shared_ptr<const MetadataValueKey<std::string> > part_key; - Imp(const std::string & t) : - target_key(std::make_shared<LiteralMetadataValueKey<std::string>>("target", "target", mkt_normal, t)) + Imp(const std::string & target, const std::string & part) : + target_key(std::make_shared<LiteralMetadataValueKey<std::string>>("target", "target", mkt_normal, target)), + part_key(part.empty() + ? make_null_shared_ptr() + : std::make_shared<LiteralMetadataValueKey<std::string>>("part", "part", mkt_normal, part)) { } }; } -ContentsSymEntry::ContentsSymEntry(const FSPath & our_name, const std::string & our_target) : - ContentsEntry(our_name), - _imp(our_target) +ContentsSymEntry::ContentsSymEntry(const FSPath & our_name, + const std::string & our_target, + const std::string & our_part) : + ContentsEntry(our_name), _imp(our_target, our_part) { add_metadata_key(_imp->target_key); + if (_imp->part_key) + add_metadata_key(_imp->part_key); } ContentsSymEntry::~ContentsSymEntry() @@ -108,6 +145,12 @@ ContentsSymEntry::target_key() const return _imp->target_key; } +const std::shared_ptr<const MetadataValueKey<std::string> > +ContentsSymEntry::part_key() const +{ + return _imp->part_key; +} + namespace paludis { template<> @@ -155,6 +198,7 @@ namespace paludis template class Pimp<Contents>; template class Pimp<ContentsEntry>; template class Pimp<ContentsSymEntry>; + template class Pimp<ContentsFileEntry>; template class WrappedForwardIterator<Contents::ConstIteratorTag, const std::shared_ptr<const ContentsEntry> >; } diff --git a/paludis/contents.hh b/paludis/contents.hh index f4358c2a2..77b9b9e8f 100644 --- a/paludis/contents.hh +++ b/paludis/contents.hh @@ -107,11 +107,23 @@ namespace paludis public ContentsEntry, public ImplementAcceptMethods<ContentsEntry, ContentsFileEntry> { + private: + Pimp<ContentsFileEntry> _imp; + public: ///\name Basic operations ///\{ - ContentsFileEntry(const FSPath &); + ContentsFileEntry(const FSPath &, const std::string &); + ~ContentsFileEntry(); + + ///\} + + ///\name Specific metadata keys + ///\{ + + const std::shared_ptr<const MetadataValueKey<std::string> > + part_key() const; ///\} }; @@ -172,7 +184,8 @@ namespace paludis ///\name Basic operations ///\{ - ContentsSymEntry(const FSPath &, const std::string & target); + ContentsSymEntry(const FSPath &, const std::string &, + const std::string &); ~ContentsSymEntry(); ///\} @@ -187,6 +200,9 @@ namespace paludis */ const std::shared_ptr<const MetadataValueKey<std::string> > target_key() const; + const std::shared_ptr<const MetadataValueKey<std::string> > + part_key() const; + ///\} }; @@ -234,6 +250,7 @@ namespace paludis extern template class Pimp<Contents>; extern template class Pimp<ContentsEntry>; extern template class Pimp<ContentsSymEntry>; + extern template class Pimp<ContentsFileEntry>; extern template class PALUDIS_VISIBLE WrappedForwardIterator<Contents::ConstIteratorTag, const std::shared_ptr<const ContentsEntry> >; } diff --git a/paludis/files.m4 b/paludis/files.m4 index 03e8b232a..3b6e83c6b 100644 --- a/paludis/files.m4 +++ b/paludis/files.m4 @@ -82,6 +82,7 @@ add(`package_id', `hh', `cc', `fwd', `se') add(`paludis', `hh') add(`paludislike_options_conf', `hh', `cc', `fwd') add(`partially_made_package_dep_spec', `hh', `cc', `fwd', `se') +add(`partitioning', `hh', `cc', `fwd', `gtest') add(`permitted_choice_value_parameter_values', `hh', `cc', `fwd') add(`pretty_print_options', `hh', `cc', `fwd', `se') add(`pretty_printer', `hh', `cc', `fwd') diff --git a/paludis/fs_merger.hh b/paludis/fs_merger.hh index 9843528c0..008417181 100644 --- a/paludis/fs_merger.hh +++ b/paludis/fs_merger.hh @@ -29,6 +29,7 @@ #include <paludis/merger.hh> #include <paludis/environment-fwd.hh> #include <paludis/hook-fwd.hh> +#include <paludis/partitioning-fwd.hh> #include <iosfwd> #include <sys/stat.h> #include <sys/types.h> @@ -58,6 +59,7 @@ namespace paludis typedef Name<struct name_merged_entries> merged_entries; typedef Name<struct name_no_chown> no_chown; typedef Name<struct name_options> options; + typedef Name<struct name_parts> parts; typedef Name<struct name_permit_destination> permit_destination; typedef Name<struct name_root> root; } @@ -106,6 +108,8 @@ namespace paludis NamedValue<n::no_chown, bool> no_chown; NamedValue<n::options, MergerOptions> options; + NamedValue<n::parts, std::shared_ptr<const Partitioning> > parts; + ///\since 0.66 NamedValue<n::permit_destination, PermitDestinationFn> permit_destination; diff --git a/paludis/fs_merger_TEST.cc b/paludis/fs_merger_TEST.cc index 156e1b35c..adc0c7b7e 100644 --- a/paludis/fs_merger_TEST.cc +++ b/paludis/fs_merger_TEST.cc @@ -175,6 +175,7 @@ namespace n::merged_entries() = std::make_shared<FSPathSet>(), n::no_chown() = true, n::options() = MergerOptions() + mo_rewrite_symlinks + mo_allow_empty_dirs, + n::parts() = make_null_shared_ptr(), n::permit_destination() = std::bind(return_literal_function(true)), n::root() = root_dir.realpath() )) @@ -198,6 +199,7 @@ namespace n::merged_entries() = std::make_shared<FSPathSet>(), n::no_chown() = true, n::options() = o, + n::parts() = make_null_shared_ptr(), n::permit_destination() = std::bind(return_literal_function(true)), n::root() = root_dir.realpath() )) diff --git a/paludis/name-fwd.hh b/paludis/name-fwd.hh index 6bf645fbe..8646f6c74 100644 --- a/paludis/name-fwd.hh +++ b/paludis/name-fwd.hh @@ -131,6 +131,17 @@ namespace paludis typedef WrappedValue<SetNameTag> SetName; typedef Set<SetName> SetNameSet; + + class PartNameTag; + class PartNameError; + template <> struct WrappedValueTraits<PartNameTag>; + + /** + * A PartName holds a std::string that is a valid name for a part. + * + * \ingroup g_names + */ + typedef WrappedValue<PartNameTag> PartName; } #endif diff --git a/paludis/name.cc b/paludis/name.cc index ff53411d8..79cd895fe 100644 --- a/paludis/name.cc +++ b/paludis/name.cc @@ -41,6 +41,7 @@ namespace paludis template class WrappedValue<SlotNameTag>; template class WrappedValue<KeywordNameTag>; template class WrappedValue<SetNameTag>; + template class WrappedValue<PartNameTag>; template class PALUDIS_VISIBLE Sequence<RepositoryName>; template class PALUDIS_VISIBLE WrappedForwardIterator<Sequence<RepositoryName>::ConstIteratorTag, const RepositoryName>; @@ -79,6 +80,7 @@ template PALUDIS_VISIBLE std::ostream & paludis::operator<< (std::ostream &, con template PALUDIS_VISIBLE std::ostream & paludis::operator<< (std::ostream &, const WrappedValue<SlotNameTag> &); template PALUDIS_VISIBLE std::ostream & paludis::operator<< (std::ostream &, const WrappedValue<KeywordNameTag> &); template PALUDIS_VISIBLE std::ostream & paludis::operator<< (std::ostream &, const WrappedValue<SetNameTag> &); +template PALUDIS_VISIBLE std::ostream & paludis::operator<< (std::ostream &, const WrappedValue<PartNameTag> &); std::ostream & paludis::operator<< (std::ostream & s, const QualifiedPackageName & q) @@ -337,6 +339,22 @@ SetNameError::SetNameError(const std::string & name) throw () : { } +PartNameError::PartNameError(const std::string & name) throw () : + NameError(name, "part") +{ +} + +bool +WrappedValueTraits<PartNameTag>::validate(const std::string & name) +{ + static const std::string allowed_chars( + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789-+_"); + + return name.find_first_not_of(allowed_chars) == std::string::npos; +} + std::size_t QualifiedPackageName::hash() const { diff --git a/paludis/name.hh b/paludis/name.hh index cf48255b3..855d83d6d 100644 --- a/paludis/name.hh +++ b/paludis/name.hh @@ -244,10 +244,37 @@ namespace paludis static bool validate(const std::string &) PALUDIS_ATTRIBUTE((warn_unused_result)); }; + /** + * A PartNameError is thrown if an invalid value is assigned to a PartName. + * + * \ingroup g_exceptions + * \ingroup g_names + */ + class PALUDIS_VISIBLE PartNameError : public NameError + { + public: + /** + * Constructor + */ + PartNameError(const std::string & name) throw (); + }; + + template <> + struct PALUDIS_VISIBLE WrappedValueTraits<PartNameTag> + { + typedef std::string UnderlyingType; + typedef void ValidationParamsType; + typedef PartNameError ExceptionType; + + static bool validate(const std::string &) + PALUDIS_ATTRIBUTE((warn_unused_result)); + }; + extern template class PALUDIS_VISIBLE WrappedValue<RepositoryNameTag>; extern template class PALUDIS_VISIBLE WrappedValue<SlotNameTag>; extern template class PALUDIS_VISIBLE WrappedValue<KeywordNameTag>; extern template class PALUDIS_VISIBLE WrappedValue<SetNameTag>; + extern template class PALUDIS_VISIBLE WrappedValue<PartNameTag>; extern template class PALUDIS_VISIBLE Set<QualifiedPackageName>; extern template class PALUDIS_VISIBLE WrappedForwardIterator<Set<QualifiedPackageName>::ConstIteratorTag, const QualifiedPackageName>; diff --git a/paludis/ndbam.cc b/paludis/ndbam.cc index 7003ce89c..6a6a9b734 100644 --- a/paludis/ndbam.cc +++ b/paludis/ndbam.cc @@ -544,6 +544,10 @@ NDBAM::parse_contents(const PackageID & id, } std::string md5(tokens.find("md5")->second); + std::string part; + if (tokens.count("part")) + part = tokens.find("part")->second; + if (! tokens.count("mtime")) { Log::get_instance()->message("ndbam.contents.no_key.mtime", ll_warning, lc_context) << @@ -552,7 +556,7 @@ NDBAM::parse_contents(const PackageID & id, } time_t mtime(destringify<time_t>(tokens.find("mtime")->second)); - std::shared_ptr<ContentsFileEntry> entry(std::make_shared<ContentsFileEntry>(FSPath(path))); + std::shared_ptr<ContentsFileEntry> entry(std::make_shared<ContentsFileEntry>(FSPath(path), part)); entry->add_metadata_key(std::make_shared<LiteralMetadataValueKey<std::string>>("md5", "md5", mkt_normal, md5)); entry->add_metadata_key(std::make_shared<LiteralMetadataTimeKey>("mtime", "mtime", mkt_normal, Timestamp(mtime, 0))); on_file(entry); @@ -580,7 +584,11 @@ NDBAM::parse_contents(const PackageID & id, } time_t mtime(destringify<time_t>(tokens.find("mtime")->second)); - std::shared_ptr<ContentsSymEntry> entry(std::make_shared<ContentsSymEntry>(FSPath(path), target)); + std::string part; + if (tokens.count("part")) + part = tokens.find("part")->second; + + std::shared_ptr<ContentsSymEntry> entry(std::make_shared<ContentsSymEntry>(FSPath(path), target, part)); entry->add_metadata_key(std::make_shared<LiteralMetadataTimeKey>("mtime", "mtime", mkt_normal, Timestamp(mtime, 0))); on_sym(entry); } diff --git a/paludis/ndbam_merger.cc b/paludis/ndbam_merger.cc index 7a0de31f0..fa7528785 100644 --- a/paludis/ndbam_merger.cc +++ b/paludis/ndbam_merger.cc @@ -43,6 +43,7 @@ #include <paludis/ndbam_merger.hh> #include <paludis/metadata_key.hh> #include <paludis/version_spec.hh> +#include <paludis/partitioning.hh> #include <paludis/slot.hh> #include <iomanip> @@ -84,6 +85,7 @@ NDBAMMerger::NDBAMMerger(const NDBAMMergerParams & p) : n::merged_entries() = p.merged_entries(), n::no_chown() = ! getenv_with_default(env_vars::no_chown, "").empty(), n::options() = p.options(), + n::parts() = p.parts(), n::permit_destination() = p.permit_destination(), n::root() = p.root() )), @@ -177,10 +179,16 @@ NDBAMMerger::record_install_file(const FSPath & src, const FSPath & dst_dir, con line.append(" (" + FSPath(tidy).basename() + ")"); display_override(line); + std::string part; + if (_imp->params.parts()) + part = _imp->params.parts()->classify(FSPath(tidy)).value(); + *_imp->contents_file << "type=file"; *_imp->contents_file << " path=" << escape(tidy_real); *_imp->contents_file << " md5=" << md5.hexsum(); *_imp->contents_file << " mtime=" << timestamp; + if (!part.empty()) + *_imp->contents_file << " part=" << part; *_imp->contents_file << std::endl; } diff --git a/paludis/ndbam_merger.hh b/paludis/ndbam_merger.hh index 0d885ddfb..7bfa7fdd2 100644 --- a/paludis/ndbam_merger.hh +++ b/paludis/ndbam_merger.hh @@ -24,6 +24,7 @@ #include <paludis/package_id-fwd.hh> #include <paludis/util/named_value.hh> #include <paludis/output_manager-fwd.hh> +#include <paludis/partitioning-fwd.hh> #include <functional> namespace paludis @@ -43,6 +44,7 @@ namespace paludis typedef Name<struct name_options> options; typedef Name<struct name_output_manager> output_manager; typedef Name<struct name_package_id> package_id; + typedef Name<struct name_parts> parts; typedef Name<struct name_permit_destination> permit_destination; typedef Name<struct name_root> root; } @@ -62,6 +64,7 @@ namespace paludis NamedValue<n::options, MergerOptions> options; NamedValue<n::output_manager, std::shared_ptr<OutputManager> > output_manager; NamedValue<n::package_id, std::shared_ptr<const PackageID> > package_id; + NamedValue<n::parts, std::shared_ptr<const Partitioning> > parts; NamedValue<n::permit_destination, PermitDestinationFn> permit_destination; NamedValue<n::root, FSPath> root; }; diff --git a/paludis/partitioning-fwd.hh b/paludis/partitioning-fwd.hh new file mode 100644 index 000000000..a26d2d75a --- /dev/null +++ b/paludis/partitioning-fwd.hh @@ -0,0 +1,28 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2013 Saleem Abdulrasool <compnerd@compnerd.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis 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 General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_PARTITIONING_FWD_HH +#define PALUDIS_GUARD_PALUDIS_PARTITIONING_FWD_HH 1 + +namespace paludis +{ + class Partitioning; +} + +#endif diff --git a/paludis/partitioning.cc b/paludis/partitioning.cc new file mode 100644 index 000000000..791c655d6 --- /dev/null +++ b/paludis/partitioning.cc @@ -0,0 +1,64 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2013 Saleem Abdulrasool <compnerd@compnerd.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis 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 General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/name.hh> +#include <paludis/partitioning.hh> +#include <paludis/util/pimp-impl.hh> + +#include <map> +#include <utility> +#include <algorithm> + +using namespace paludis; + +namespace paludis +{ + template <> + struct Imp<Partitioning> + { + std::vector<std::pair<FSPath, PartName>> parts; + }; +} + +Partitioning::Partitioning() : + _imp() +{ +} + +Partitioning::~Partitioning() = default; + +void +Partitioning::mark(const std::vector<FSPath> & paths, const PartName & name) +{ + for (auto path = paths.begin(), path_end = paths.end(); + path != path_end; ++path) + _imp->parts.push_back(std::make_pair(*path, name)); +} + +PartName +Partitioning::classify(const FSPath & path) const +{ + for (auto part = _imp->parts.rbegin(), end = _imp->parts.rend(); + part != end; ++part) + if (path.starts_with(part->first)) + return part->second; + + return PartName(""); +} + diff --git a/paludis/partitioning.hh b/paludis/partitioning.hh new file mode 100644 index 000000000..26bf8d060 --- /dev/null +++ b/paludis/partitioning.hh @@ -0,0 +1,83 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2013 Saleem Abdulrasool <compnerd@compnerd.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis 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 General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_PARTITIONING_HH +#define PALUDIS_GUARD_PALUDIS_PARTITIONING_HH 1 + +#include <paludis/name-fwd.hh> +#include <paludis/partitioning-fwd.hh> +#include <paludis/util/exception.hh> +#include <paludis/util/fs_path.hh> +#include <paludis/util/pimp.hh> + +#include <string> +#include <vector> + +/** \file + * Declarations for the Partitioning class. + * + * \ingroup g_contents + */ + +namespace paludis +{ + /** + * Package partitioning as defined by the package installation metadata. + * + * \ingroup g_contents + * \since 1.1.0 + */ + class PALUDIS_VISIBLE Partitioning + { + private: + Pimp<Partitioning> _imp; + + public: + ///\name Basic operations + ///\{ + + Partitioning(); + ~Partitioning(); + + ///\} + + /** + * Mark a set of paths as belonging to a partition. + * + * \arg [in] paths the paths to partition + * \arg [in] name the partition name (or empty to indicate core) + * + * \since 1.1.0 + */ + void mark(const std::vector<FSPath> &, const PartName &); + + /** + * Classify a path into a partition. + * + * \arg [in] path the path to classify + * + * \return the partition the path was classified into, empty if none + * + * \since 1.1.0 + */ + PartName classify(const FSPath &) const; + }; +} + +#endif diff --git a/paludis/partitioning_TEST.cc b/paludis/partitioning_TEST.cc new file mode 100644 index 000000000..667186c87 --- /dev/null +++ b/paludis/partitioning_TEST.cc @@ -0,0 +1,77 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2013 Saleem Abdulrasool <compnerd@compnerd.org> + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis 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 General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/name.hh> +#include <paludis/partitioning.hh> +#include <paludis/util/fs_path.hh> + +#include <gtest/gtest.h> + +#include <memory> + +using namespace paludis; + +namespace +{ + const FSPath kBin("/bin"); + const FSPath kLib("/lib"); + const FSPath kTest("test"); + + const PartName kBinaries("binaries"); + const PartName kCore(""); +} + +TEST(Partitioning, DefaultParts) +{ + auto parts(std::make_shared<Partitioning>()); + + parts->mark(std::vector<FSPath>{ kBin }, kBinaries); + + ASSERT_EQ(kBinaries, parts->classify(kBin)); + ASSERT_EQ(kCore, parts->classify(kLib)); +} + +TEST(Partitioning, PartsExludes) +{ + auto parts(std::make_shared<Partitioning>()); + + parts->mark(std::vector<FSPath>{ kBin }, kBinaries); + parts->mark(std::vector<FSPath>{ kBin / kTest }, kCore); + + ASSERT_EQ(kBinaries, parts->classify(kBin)); + ASSERT_EQ(kCore, parts->classify(kBin / kTest)); +} + +TEST(Partitioning, PartsOrder) +{ + auto parts(std::make_shared<Partitioning>()); + + parts->mark(std::vector<FSPath>{ kBin / kTest }, kCore); + parts->mark(std::vector<FSPath>{ kBin }, kBinaries); + + ASSERT_EQ(kBinaries, parts->classify(kBin)); + ASSERT_EQ(kBinaries, parts->classify(kBin / kTest)); +} + +TEST(Partitioning, NameValidation) +{ + ASSERT_THROW(PartName(" "), PartNameError); + ASSERT_THROW(PartName(","), PartNameError); +} + diff --git a/paludis/repositories/accounts/accounts_id.cc b/paludis/repositories/accounts/accounts_id.cc index 9f99aee08..4962665d2 100644 --- a/paludis/repositories/accounts/accounts_id.cc +++ b/paludis/repositories/accounts/accounts_id.cc @@ -480,6 +480,7 @@ AccountsID::perform_action(Action & action) const n::options() = MergerOptions() + mo_rewrite_symlinks + mo_allow_empty_dirs, n::output_manager() = output_manager, n::package_id() = shared_from_this(), + n::parts() = make_null_shared_ptr(), n::perform_uninstall() = install_action->options.perform_uninstall(), n::permit_destination() = std::bind(return_literal_function(true)), n::replacing() = install_action->options.replacing(), diff --git a/paludis/repositories/e/do_fetch_action.cc b/paludis/repositories/e/do_fetch_action.cc index a615d35e0..ae47d70f3 100644 --- a/paludis/repositories/e/do_fetch_action.cc +++ b/paludis/repositories/e/do_fetch_action.cc @@ -195,6 +195,7 @@ paludis::erepository::do_fetch_action( n::maybe_output_manager() = output_manager, n::package_builddir() = package_builddir, n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = (params.master_repositories() && ! params.master_repositories()->empty()) @@ -244,6 +245,7 @@ paludis::erepository::do_fetch_action( n::maybe_output_manager() = output_manager, n::package_builddir() = repo->params().builddir() / (stringify(id->name().category()) + "-" + stringify(id->name().package()) + "-" + stringify(id->version()) + "-nofetch"), n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = (repo->params().master_repositories() && ! repo->params().master_repositories()->empty()) ? (*repo->params().master_repositories()->begin())->params().location() : repo->params().location(), diff --git a/paludis/repositories/e/do_info_action.cc b/paludis/repositories/e/do_info_action.cc index 375599e9f..ed02f7aa8 100644 --- a/paludis/repositories/e/do_info_action.cc +++ b/paludis/repositories/e/do_info_action.cc @@ -104,6 +104,7 @@ paludis::erepository::do_info_action( n::maybe_output_manager() = output_manager, n::package_builddir() = params.builddir() / (stringify(id->name().category()) + "-" + stringify(id->name().package()) + "-" + stringify(id->version()) + "-info"), n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = (params.master_repositories() && ! params.master_repositories()->empty()) diff --git a/paludis/repositories/e/do_install_action.cc b/paludis/repositories/e/do_install_action.cc index a0ac4d264..f1a3afb0f 100644 --- a/paludis/repositories/e/do_install_action.cc +++ b/paludis/repositories/e/do_install_action.cc @@ -48,6 +48,7 @@ #include <paludis/choice.hh> #include <paludis/elike_choices.hh> #include <paludis/output_manager.hh> +#include <paludis/partitioning.hh> #include <paludis/slot.hh> #include <vector> @@ -216,6 +217,7 @@ paludis::erepository::do_install_action( } } + auto parts(std::make_shared<Partitioning>()); auto choices(id->choices_key()->parse_value()); auto work_choice(choices->find_by_name_with_prefix(ELikeWorkChoiceValue::canonical_name_with_prefix())); @@ -283,8 +285,12 @@ paludis::erepository::do_install_action( n::options() = id->eapi()->supported()->merger_options() | extra_merger_options, n::output_manager() = output_manager, n::package_id() = id, + n::parts() = parts, n::perform_uninstall() = install_action.options.perform_uninstall(), - n::permit_destination() = std::bind(&PermittedDirectories::permit, permitted_directories, std::placeholders::_1), + n::permit_destination() = + std::bind(&PermittedDirectories::permit, + permitted_directories, + std::placeholders::_1), 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), @@ -375,6 +381,7 @@ paludis::erepository::do_install_action( n::maybe_output_manager() = output_manager, n::package_builddir() = package_builddir, n::package_id() = id, + n::parts() = parts, n::permitted_directories() = permitted_directories, n::portdir() = (params.master_repositories() && ! params.master_repositories()->empty()) ? @@ -436,6 +443,7 @@ paludis::erepository::do_install_action( n::maybe_output_manager() = output_manager, n::package_builddir() = package_builddir, n::package_id() = id, + n::parts() = parts, n::permitted_directories() = permitted_directories, n::portdir() = (params.master_repositories() && ! params.master_repositories()->empty()) diff --git a/paludis/repositories/e/do_pretend_action.cc b/paludis/repositories/e/do_pretend_action.cc index eeb743621..6806e1f72 100644 --- a/paludis/repositories/e/do_pretend_action.cc +++ b/paludis/repositories/e/do_pretend_action.cc @@ -121,6 +121,7 @@ paludis::erepository::do_pretend_action( n::maybe_output_manager() = output_manager, n::package_builddir() = params.builddir() / (stringify(id->name().category()) + "-" + stringify(id->name().package()) + "-" + stringify(id->version()) + "-bad_options"), n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = (params.master_repositories() && ! params.master_repositories()->empty()) ? @@ -186,6 +187,7 @@ paludis::erepository::do_pretend_action( n::maybe_output_manager() = output_manager, n::package_builddir() = params.builddir() / (stringify(id->name().category()) + "-" + stringify(id->name().package()) + "-" + stringify(id->version()) + "-bad_options"), n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = (params.master_repositories() && ! params.master_repositories()->empty()) @@ -250,6 +252,7 @@ paludis::erepository::do_pretend_action( n::maybe_output_manager() = output_manager, n::package_builddir() = params.builddir() / (stringify(id->name().category()) + "-" + stringify(id->name().package()) + "-" + stringify(id->version()) + "-pretend"), n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = (params.master_repositories() && ! params.master_repositories()->empty()) diff --git a/paludis/repositories/e/e_installed_repository.cc b/paludis/repositories/e/e_installed_repository.cc index e021f777b..7092794b5 100644 --- a/paludis/repositories/e/e_installed_repository.cc +++ b/paludis/repositories/e/e_installed_repository.cc @@ -268,6 +268,7 @@ EInstalledRepository::perform_config( n::maybe_output_manager() = output_manager, n::package_builddir() = _imp->params.builddir() / (stringify(id->name().category()) + "-" + stringify(id->name().package()) + "-" + stringify(id->version()) + "-config"), n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = ver_dir, n::root() = stringify(_imp->params.root()), @@ -376,6 +377,7 @@ EInstalledRepository::perform_info( n::maybe_output_manager() = output_manager, n::package_builddir() = _imp->params.builddir() / (stringify(id->name().category()) + "-" + stringify(id->name().package()) + "-" + stringify(id->version()) + "-info"), n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = ver_dir, n::root() = stringify(_imp->params.root()), diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc index a430aa369..dc29c64ca 100644 --- a/paludis/repositories/e/e_repository.cc +++ b/paludis/repositories/e/e_repository.cc @@ -1749,6 +1749,7 @@ ERepository::get_environment_variable( n::maybe_output_manager() = make_null_shared_ptr(), n::package_builddir() = _imp->params.builddir() / (stringify(id->name().category()) + "-" + stringify(id->name().package()) + "-" + stringify(id->version()) + "-variable"), n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = (_imp->params.master_repositories() && ! _imp->params.master_repositories()->empty()) ? diff --git a/paludis/repositories/e/ebuild.cc b/paludis/repositories/e/ebuild.cc index 421621082..815263504 100644 --- a/paludis/repositories/e/ebuild.cc +++ b/paludis/repositories/e/ebuild.cc @@ -146,8 +146,14 @@ EbuildCommand::operator() () using namespace std::placeholders; - process.pipe_command_handler("PALUDIS_PIPE_COMMAND", std::bind(&pipe_command_handler, params.environment(), - params.package_id(), params.permitted_directories(), in_metadata_generation(), _1, params.maybe_output_manager())); + process.pipe_command_handler("PALUDIS_PIPE_COMMAND", + std::bind(&pipe_command_handler, + params.environment(), + params.package_id(), + params.permitted_directories(), + params.parts(), + in_metadata_generation(), _1, + params.maybe_output_manager())); std::shared_ptr<const FSPathSequence> syncers_dirs(params.environment()->syncers_dirs()); std::shared_ptr<const FSPathSequence> bashrc_files(params.environment()->bashrc_files()); @@ -1056,8 +1062,13 @@ WriteVDBEntryCommand::operator() () params.package_id()->eapi()->supported()->ebuild_environment_variables()->env_ebuild_phase_func()) .setenv("PALUDIS_PIPE_COMMANDS_SUPPORTED", "yes") .setenv("PALUDIS_PIPE_COMMANDS_STATUS_SUPPORTED", "yes") - .pipe_command_handler("PALUDIS_PIPE_COMMAND", std::bind(&pipe_command_handler, params.environment(), - params.package_id(), make_null_shared_ptr(), false, _1, params.maybe_output_manager())); + .pipe_command_handler("PALUDIS_PIPE_COMMAND", + std::bind(&pipe_command_handler, + params.environment(), + params.package_id(), + make_null_shared_ptr(), + make_null_shared_ptr(), false, _1, + params.maybe_output_manager())); if (! params.package_id()->eapi()->supported()->ebuild_metadata_variables()->iuse_effective()->name().empty()) if (params.package_id()->raw_iuse_effective_key()) @@ -1315,8 +1326,13 @@ WriteBinaryEbuildCommand::operator() () params.package_id()->eapi()->supported()->ebuild_environment_variables()->env_ebuild_phase_func()) .setenv("PALUDIS_PIPE_COMMANDS_SUPPORTED", "yes") .setenv("PALUDIS_PIPE_COMMANDS_STATUS_SUPPORTED", "yes") - .pipe_command_handler("PALUDIS_PIPE_COMMAND", std::bind(&pipe_command_handler, params.environment(), - params.package_id(), make_null_shared_ptr(), false, _1, params.maybe_output_manager())); + .pipe_command_handler("PALUDIS_PIPE_COMMAND", + std::bind(&pipe_command_handler, + params.environment(), + params.package_id(), + make_null_shared_ptr(), + make_null_shared_ptr(), false, _1, + params.maybe_output_manager())); if (! params.package_id()->eapi()->supported()->ebuild_metadata_variables()->scm_revision()->name().empty()) if (params.package_id()->scm_revision_key()) diff --git a/paludis/repositories/e/ebuild.hh b/paludis/repositories/e/ebuild.hh index c400a2180..42d1b298b 100644 --- a/paludis/repositories/e/ebuild.hh +++ b/paludis/repositories/e/ebuild.hh @@ -33,6 +33,7 @@ #include <paludis/output_manager-fwd.hh> #include <paludis/repository-fwd.hh> #include <paludis/package_id-fwd.hh> +#include <paludis/partitioning-fwd.hh> #include <paludis/merger.hh> #include <string> @@ -85,6 +86,7 @@ namespace paludis typedef Name<struct name_output_directory> output_directory; typedef Name<struct name_package_builddir> package_builddir; typedef Name<struct name_package_id> package_id; + typedef Name<struct name_parts> parts; typedef Name<struct name_permitted_directories> permitted_directories; typedef Name<struct name_portdir> portdir; typedef Name<struct name_profiles> profiles; @@ -131,6 +133,7 @@ namespace paludis NamedValue<n::maybe_output_manager, std::shared_ptr<OutputManager> > maybe_output_manager; NamedValue<n::package_builddir, FSPath> package_builddir; NamedValue<n::package_id, std::shared_ptr<const erepository::ERepositoryID> > package_id; + NamedValue<n::parts, std::shared_ptr<Partitioning> > parts; NamedValue<n::permitted_directories, std::shared_ptr<erepository::PermittedDirectories> > permitted_directories; NamedValue<n::portdir, FSPath> portdir; NamedValue<n::root, std::string> root; diff --git a/paludis/repositories/e/ebuild/exheres-0/output_functions.bash b/paludis/repositories/e/ebuild/exheres-0/output_functions.bash index e9dcc771f..a09127ac9 100644 --- a/paludis/repositories/e/ebuild/exheres-0/output_functions.bash +++ b/paludis/repositories/e/ebuild/exheres-0/output_functions.bash @@ -49,4 +49,8 @@ exdirectory() paludis_pipe_command PERMIT_DIRECTORY "$EAPI" "$@" >/dev/null } +expart() +{ + paludis_pipe_command PARTITION "$EAPI" "$@" >/dev/null +} diff --git a/paludis/repositories/e/ebuild_id.cc b/paludis/repositories/e/ebuild_id.cc index cc14446b5..5060654a3 100644 --- a/paludis/repositories/e/ebuild_id.cc +++ b/paludis/repositories/e/ebuild_id.cc @@ -317,6 +317,7 @@ EbuildID::need_non_xml_keys_added() const n::maybe_output_manager() = make_null_shared_ptr(), n::package_builddir() = e_repo->params().builddir() / (stringify(name().category()) + "-" + stringify(name().package()) + "-" + stringify(version()) + "-metadata"), n::package_id() = shared_from_this(), + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = (e_repo->params().master_repositories() && ! e_repo->params().master_repositories()->empty()) ? diff --git a/paludis/repositories/e/exndbam_repository.cc b/paludis/repositories/e/exndbam_repository.cc index 86e314af6..d3c76436e 100644 --- a/paludis/repositories/e/exndbam_repository.cc +++ b/paludis/repositories/e/exndbam_repository.cc @@ -447,6 +447,7 @@ ExndbamRepository::merge(const MergeParams & m) n::options() = m.options(), n::output_manager() = m.output_manager(), n::package_id() = m.package_id(), + n::parts() = m.parts(), n::permit_destination() = m.permit_destination(), n::root() = installed_root_key()->parse_value() )); @@ -636,6 +637,7 @@ ExndbamRepository::perform_uninstall( n::maybe_output_manager() = output_manager, n::package_builddir() = package_builddir, n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = _imp->params.location(), n::root() = stringify(_imp->params.root()), diff --git a/paludis/repositories/e/pipe_command_handler.cc b/paludis/repositories/e/pipe_command_handler.cc index 6899398f5..3fb6fff25 100644 --- a/paludis/repositories/e/pipe_command_handler.cc +++ b/paludis/repositories/e/pipe_command_handler.cc @@ -3,6 +3,7 @@ /* * Copyright (c) 2007, 2008, 2009, 2010, 2011 Ciaran McCreesh * Copyright (c) 2009 Ingmar Vanhassel + * Copyright (c) 2013 Saleem Abdulrasool <compnerd@compnerd.org> * * This file is part of the Paludis package manager. Paludis is free software; * you can redistribute it and/or modify it under the terms of the GNU General @@ -52,9 +53,11 @@ #include <paludis/dep_spec_annotations.hh> #include <paludis/unformatted_pretty_printer.hh> #include <paludis/version_spec.hh> +#include <paludis/partitioning.hh> #include <paludis/repository.hh> #include <paludis/elike_choices.hh> +#include <list> #include <vector> #include <limits> #include <sstream> @@ -180,6 +183,7 @@ std::string paludis::erepository::pipe_command_handler(const Environment * const environment, const std::shared_ptr<const ERepositoryID> & package_id, const std::shared_ptr<PermittedDirectories> & maybe_permitted_directories, + const std::shared_ptr<Partitioning> & maybe_partitioning, bool in_metadata_generation, const std::string & s, const std::shared_ptr<OutputManager> & maybe_output_manager) { @@ -564,6 +568,55 @@ paludis::erepository::pipe_command_handler(const Environment * const environment maybe_permitted_directories->add(FSPath(tokens[3]), permit); return "O0;"; } + else if (tokens[0] == "PARTITION") + { + bool exclude(false); + std::shared_ptr<const EAPI> eapi = + EAPIData::get_instance()->eapi_from_string(tokens[1]); + if (! eapi->supported()) + return "EPARTITION EAPI " + tokens[1] + " unsupported"; + + if (tokens.size() < 4 || + ((exclude = (tokens[2] == "--exclude")) && tokens.size() < 5)) + { + Log::get_instance()->message("e.pipe_commands.partition.bad", + ll_warning, lc_context) + << "Got bad PARTITION pipe command"; + return "Ebad PARTITION command"; + } + + const std::string partition_id(tokens[2]); + std::vector<FSPath> contents; + + for (auto token = tokens.begin() + (exclude ? 3 : 2), + last = tokens.end(); + token != last; ++token) + contents.push_back(FSPath(*token)); + + try + { + if (maybe_partitioning == NULL) + { + Log::get_instance()->message("e.pipe_commands.partitioning.unsupported", + ll_warning, lc_context) + << "parts not supported by destination repository"; + return "EPARTITION EXPART not supported by destination repository"; + } + else + { + maybe_partitioning->mark(contents, + exclude ? PartName("") + : PartName(partition_id)); + } + + return "O0;"; + } + catch (const Exception & e) + { + return "Egot error '" + e.message() + "' (" + e.what() + ") " + "when trying to create partition"; + } + } else if (tokens[0] == "REWRITE_VAR") { if (tokens.size() < 4) diff --git a/paludis/repositories/e/pipe_command_handler.hh b/paludis/repositories/e/pipe_command_handler.hh index d3d6a7f3d..56be424d5 100644 --- a/paludis/repositories/e/pipe_command_handler.hh +++ b/paludis/repositories/e/pipe_command_handler.hh @@ -24,6 +24,7 @@ #include <paludis/environment-fwd.hh> #include <paludis/package_id-fwd.hh> #include <paludis/output_manager-fwd.hh> +#include <paludis/partitioning-fwd.hh> #include <functional> #include <string> @@ -36,6 +37,7 @@ namespace paludis std::string pipe_command_handler(const Environment * const, const std::shared_ptr<const ERepositoryID> &, const std::shared_ptr<PermittedDirectories> &, + const std::shared_ptr<Partitioning> &, bool in_metadata_generation, const std::string & s, const std::shared_ptr<OutputManager> & maybe_output_manager); diff --git a/paludis/repositories/e/vdb_id.cc b/paludis/repositories/e/vdb_id.cc index 23efddb14..ff6bb38f6 100644 --- a/paludis/repositories/e/vdb_id.cc +++ b/paludis/repositories/e/vdb_id.cc @@ -64,6 +64,9 @@ VDBID::contents_filename() const const std::shared_ptr<const Contents> VDBID::contents() const { + // NOTE(compnerd) VDB does not support parts + static const std::string kNoPart = ""; + FSPath contents_location(fs_location_key()->parse_value() / "CONTENTS"); Context context("When creating contents from '" + stringify(contents_location) + "':"); @@ -94,7 +97,8 @@ VDBID::contents() const if ("obj" == tokens.at(0)) { - std::shared_ptr<ContentsEntry> e(std::make_shared<ContentsFileEntry>(FSPath(tokens.at(1)))); + auto e(std::make_shared<ContentsFileEntry>(FSPath(tokens.at(1)), + kNoPart)); e->add_metadata_key(std::make_shared<LiteralMetadataTimeKey>("mtime", "mtime", mkt_normal, Timestamp(destringify<time_t>(tokens.at(3)), 0))); e->add_metadata_key(std::make_shared<LiteralMetadataValueKey<std::string>>("md5", "md5", mkt_normal, tokens.at(2))); @@ -107,7 +111,8 @@ VDBID::contents() const } else if ("sym" == tokens.at(0)) { - std::shared_ptr<ContentsEntry> e(std::make_shared<ContentsSymEntry>(FSPath(tokens.at(1)), tokens.at(2))); + auto e(std::make_shared<ContentsSymEntry>(FSPath(tokens.at(1)), + tokens.at(2), kNoPart)); e->add_metadata_key(std::make_shared<LiteralMetadataTimeKey>("mtime", "mtime", mkt_normal, Timestamp(destringify<time_t>(tokens.at(3)), 0))); value->add(e); diff --git a/paludis/repositories/e/vdb_merger.cc b/paludis/repositories/e/vdb_merger.cc index 0036c6cf0..244c64691 100644 --- a/paludis/repositories/e/vdb_merger.cc +++ b/paludis/repositories/e/vdb_merger.cc @@ -30,6 +30,7 @@ #include <paludis/util/strip.hh> #include <paludis/util/options.hh> #include <paludis/util/make_named_values.hh> +#include <paludis/util/make_null_shared_ptr.hh> #include <paludis/util/enum_iterator.hh> #include <paludis/util/timestamp.hh> #include <paludis/util/env_var_names.hh> @@ -98,6 +99,7 @@ VDBMerger::VDBMerger(const VDBMergerParams & p) : n::merged_entries() = p.merged_entries(), n::no_chown() = ! getenv_with_default(env_vars::no_chown, "").empty(), n::options() = p.options(), + n::parts() = make_null_shared_ptr(), n::permit_destination() = p.permit_destination(), n::root() = p.root() )), diff --git a/paludis/repositories/e/vdb_repository.cc b/paludis/repositories/e/vdb_repository.cc index f7e210e4e..5c828dc31 100644 --- a/paludis/repositories/e/vdb_repository.cc +++ b/paludis/repositories/e/vdb_repository.cc @@ -508,6 +508,7 @@ VDBRepository::perform_uninstall( n::maybe_output_manager() = output_manager, n::package_builddir() = package_builddir, n::package_id() = id, + n::parts() = make_null_shared_ptr(), n::permitted_directories() = make_null_shared_ptr(), n::portdir() = _imp->params.location(), n::root() = stringify(_imp->params.root()), diff --git a/paludis/repositories/unavailable/unavailable_repository_id.cc b/paludis/repositories/unavailable/unavailable_repository_id.cc index 89922e85a..764cec4da 100644 --- a/paludis/repositories/unavailable/unavailable_repository_id.cc +++ b/paludis/repositories/unavailable/unavailable_repository_id.cc @@ -229,6 +229,7 @@ UnavailableRepositoryID::perform_action(Action & action) const n::options() = MergerOptions(), n::output_manager() = output_manager, n::package_id() = shared_from_this(), + n::parts() = make_null_shared_ptr(), n::perform_uninstall() = install_action->options.perform_uninstall(), n::permit_destination() = std::bind(return_literal_function(true)), n::replacing() = install_action->options.replacing(), diff --git a/paludis/repositories/unpackaged/installed_repository.cc b/paludis/repositories/unpackaged/installed_repository.cc index 46e68a1ae..3e572796a 100644 --- a/paludis/repositories/unpackaged/installed_repository.cc +++ b/paludis/repositories/unpackaged/installed_repository.cc @@ -380,6 +380,7 @@ InstalledUnpackagedRepository::merge(const MergeParams & m) n::options() = m.options(), n::output_manager() = m.output_manager(), n::package_id() = m.package_id(), + n::parts() = m.parts(), n::permit_destination() = m.permit_destination(), n::root() = installed_root_key()->parse_value().realpath() )); diff --git a/paludis/repositories/unpackaged/unpackaged_id.cc b/paludis/repositories/unpackaged/unpackaged_id.cc index 498d2220f..7d02ec851 100644 --- a/paludis/repositories/unpackaged/unpackaged_id.cc +++ b/paludis/repositories/unpackaged/unpackaged_id.cc @@ -415,6 +415,7 @@ UnpackagedID::perform_action(Action & action) const | extra_merger_options, n::output_manager() = output_manager, n::package_id() = shared_from_this(), + n::parts() = make_null_shared_ptr(), n::perform_uninstall() = install_action->options.perform_uninstall(), n::permit_destination() = std::bind(return_literal_function(true)), n::replacing() = install_action->options.replacing(), diff --git a/paludis/repository.hh b/paludis/repository.hh index 6da5caee4..638594385 100644 --- a/paludis/repository.hh +++ b/paludis/repository.hh @@ -26,6 +26,7 @@ #include <paludis/spec_tree-fwd.hh> #include <paludis/name.hh> #include <paludis/package_id-fwd.hh> +#include <paludis/partitioning-fwd.hh> #include <paludis/util/attributes.hh> #include <paludis/util/exception.hh> #include <paludis/util/fs_path.hh> @@ -70,6 +71,7 @@ namespace paludis typedef Name<struct name_options> options; typedef Name<struct name_output_manager> output_manager; typedef Name<struct name_package_id> package_id; + typedef Name<struct name_parts> parts; typedef Name<struct name_path> path; typedef Name<struct name_perform_uninstall> perform_uninstall; typedef Name<struct name_permit_destination> permit_destination; @@ -134,6 +136,12 @@ namespace paludis NamedValue<n::package_id, std::shared_ptr<const PackageID> > package_id; /** + * Package partioning. + * \since 1.1.0 + */ + NamedValue<n::parts, std::shared_ptr<Partitioning> > parts; + + /** * Some merges need to do an uninstall mid-way through the merge process. * * \see InstallActionOptions::perform_uninstall diff --git a/src/clients/cave/cmd_contents-fmt.hh b/src/clients/cave/cmd_contents-fmt.hh index ccae47be5..7d70fed83 100644 --- a/src/clients/cave/cmd_contents-fmt.hh +++ b/src/clients/cave/cmd_contents-fmt.hh @@ -1,13 +1,21 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ const auto fs_file = make_format_string_fetcher("contents/file", 1) - << c::bold_blue_or_pink() << param<'s'>() << c::normal(); + << c::bold_blue_or_pink() << param<'s'>() + << param_if<'p'>() + << c::yellow() << " [" << param<'p'>() << "]" + << param_endif<'p'>() + << c::normal(); const auto fs_dir = make_format_string_fetcher("contents/dir", 1) << c::blue_or_pink() << param<'s'>() << c::normal(); const auto fs_sym = make_format_string_fetcher("contents/sym", 1) - << c::bold_green_or_pink() << param<'s'>() << c::normal() << " -> " << param<'t'>(); + << c::bold_green_or_pink() << param<'s'>() + << c::normal() << " -> " << param<'t'>() + << param_if<'p'>() + << c::yellow() << " [" << param<'p'>() << "]" << c::normal() + << param_endif<'p'>(); const auto fs_other = make_format_string_fetcher("contents/other", 1) << c::bold_yellow() << param<'s'>() << c::normal(); diff --git a/src/clients/cave/cmd_contents.cc b/src/clients/cave/cmd_contents.cc index 23f00adc8..2122dd2dc 100644 --- a/src/clients/cave/cmd_contents.cc +++ b/src/clients/cave/cmd_contents.cc @@ -82,7 +82,11 @@ namespace { std::string visit(const ContentsFileEntry & e) const { - return fuc(fs_file(), fv<'s'>(stringify(e.location_key()->parse_value()))); + return fuc(fs_file(), + fv<'p'>(e.part_key() + ? stringify(e.part_key()->parse_value()) + : ""), + fv<'s'>(stringify(e.location_key()->parse_value()))); } std::string visit(const ContentsDirEntry & e) const @@ -93,8 +97,11 @@ namespace std::string visit(const ContentsSymEntry & e) const { return fuc(fs_sym(), - fv<'s'>(stringify(e.location_key()->parse_value())), - fv<'t'>(stringify(e.target_key()->parse_value()))); + fv<'p'>(e.part_key() + ? stringify(e.part_key()->parse_value()) + : ""), + fv<'s'>(stringify(e.location_key()->parse_value())), + fv<'t'>(stringify(e.target_key()->parse_value()))); } std::string visit(const ContentsOtherEntry & e) const |