aboutsummaryrefslogtreecommitdiff
path: root/paludis/repositories
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-07-16 19:19:52 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-07-16 19:19:52 +0000
commitae97e3f4b15b180fe0d1bcc4257103c3ad116f83 (patch)
tree6150b02237e5b668b36743d296df0cf799347b55 /paludis/repositories
parent4efa00282a8282be189bcda866a8fad9c448a407 (diff)
downloadpaludis-ae97e3f4b15b180fe0d1bcc4257103c3ad116f83.tar.gz
paludis-ae97e3f4b15b180fe0d1bcc4257103c3ad116f83.tar.xz
Smarter mask reasons code. Fixes: ticket:317
Diffstat (limited to 'paludis/repositories')
-rw-r--r--paludis/repositories/e/Makefile.am84
-rw-r--r--paludis/repositories/e/e_mask.cc154
-rw-r--r--paludis/repositories/e/e_mask.hh70
-rw-r--r--paludis/repositories/e/e_repository.cc11
-rw-r--r--paludis/repositories/e/e_repository.hh11
-rw-r--r--paludis/repositories/e/e_repository_TEST.cc12
-rw-r--r--paludis/repositories/e/e_repository_news.cc1
-rw-r--r--paludis/repositories/e/e_repository_profile.cc1
-rw-r--r--paludis/repositories/e/ebuild.cc1
-rw-r--r--paludis/repositories/e/ebuild_id.cc117
-rw-r--r--paludis/repositories/e/ebuild_id.hh1
-rw-r--r--paludis/repositories/e/vdb_id.cc5
-rw-r--r--paludis/repositories/e/vdb_id.hh1
-rw-r--r--paludis/repositories/e/vdb_repository.cc1
-rw-r--r--paludis/repositories/fake/fake_installed_repository.cc1
-rw-r--r--paludis/repositories/fake/fake_package_id.cc208
-rw-r--r--paludis/repositories/fake/fake_package_id.hh31
-rw-r--r--paludis/repositories/fake/fake_repository.cc1
-rw-r--r--paludis/repositories/fake/fake_repository_base.cc15
-rw-r--r--paludis/repositories/fake/fake_repository_base.hh9
-rw-r--r--paludis/repositories/gems/gem_specification.cc43
-rw-r--r--paludis/repositories/gems/gem_specification.hh5
-rw-r--r--paludis/repositories/gems/gem_specification_TEST.cc4
-rw-r--r--paludis/repositories/gems/gem_specifications.cc19
-rw-r--r--paludis/repositories/gems/gem_specifications.hh2
-rw-r--r--paludis/repositories/gems/gems_repository.cc3
-rw-r--r--paludis/repositories/gems/installed_gems_repository.cc4
-rw-r--r--paludis/repositories/virtuals/installed_virtuals_repository.cc1
-rw-r--r--paludis/repositories/virtuals/package_id.cc48
-rw-r--r--paludis/repositories/virtuals/package_id.hh1
-rw-r--r--paludis/repositories/virtuals/virtuals_repository.cc1
31 files changed, 746 insertions, 120 deletions
diff --git a/paludis/repositories/e/Makefile.am b/paludis/repositories/e/Makefile.am
index fb4313a29..3063367f3 100644
--- a/paludis/repositories/e/Makefile.am
+++ b/paludis/repositories/e/Makefile.am
@@ -31,73 +31,75 @@ paludis_repositories_e_includedir = $(includedir)/paludis-$(PALUDIS_PC_SLOT)/pal
libpaludiserepository_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
paludis_repositories_e_include_HEADERS = \
- ebuild.hh \
- ebuild-sr.hh \
- ebin.hh \
- ebin-se.hh \
- ebin-sr.hh \
- glsa.hh \
- glsa-sr.hh \
+ e_key.hh \
+ e_mask.hh \
e_repository.hh \
- e_repository_profile_file.hh \
- e_repository_profile.hh \
+ e_repository_entries.hh \
e_repository_exceptions.hh \
e_repository_news.hh \
- e_repository_params.hh \
e_repository_params-sr.hh \
+ e_repository_params.hh \
+ e_repository_profile.hh \
+ e_repository_profile_file.hh \
e_repository_sets.hh \
- e_repository_entries.hh \
- ebuild_entries.hh \
+ eapi_phase.hh \
+ ebin-se.hh \
+ ebin-sr.hh \
+ ebin.hh \
ebin_entries.hh \
+ ebuild-sr.hh \
+ ebuild.hh \
+ ebuild_entries.hh \
ebuild_flat_metadata_cache.hh \
+ ebuild_id.hh \
eclass_mtimes.hh \
- make_ebuild_repository.hh \
+ exheres_layout.hh \
+ glsa-sr.hh \
+ glsa.hh \
+ layout.hh \
make_ebin_repository.hh \
+ make_ebuild_repository.hh \
+ traditional_layout.hh \
use_desc.hh \
- vdb_repository.hh \
- vdb_repository-sr.hh \
+ vdb_id.hh \
vdb_merger-sr.hh \
vdb_merger.hh \
+ vdb_repository-sr.hh \
+ vdb_repository.hh \
vdb_unmerger-sr.hh \
- vdb_unmerger.hh \
- layout.hh \
- traditional_layout.hh \
- exheres_layout.hh \
- eapi_phase.hh \
- ebuild_id.hh \
- vdb_id.hh \
- e_key.hh
+ vdb_unmerger.hh
libpaludiserepository_la_SOURCES = \
- ebuild.cc \
- ebin.cc \
- glsa.cc \
+ e_key.cc \
+ e_mask.cc \
e_repository.cc \
- e_repository_profile_file.cc \
- e_repository_profile.cc \
+ e_repository_entries.cc \
e_repository_exceptions.cc \
e_repository_news.cc \
+ e_repository_params.cc \
+ e_repository_profile.cc \
+ e_repository_profile_file.cc \
e_repository_sets.cc \
- e_repository_entries.cc \
- ebuild_entries.cc \
+ eapi_phase.cc \
+ ebin.cc \
ebin_entries.cc \
+ ebuild.cc \
+ ebuild_entries.cc \
ebuild_flat_metadata_cache.cc \
+ ebuild_id.cc \
eclass_mtimes.cc \
- e_repository_params.cc \
- make_ebuild_repository.cc \
+ exheres_layout.cc \
+ glsa.cc \
+ layout.cc \
make_ebin_repository.cc \
- use_desc.cc \
+ make_ebuild_repository.cc \
registration.cc \
- vdb_repository.cc \
- vdb_merger.cc \
- vdb_unmerger.cc \
- layout.cc \
traditional_layout.cc \
- exheres_layout.cc \
- eapi_phase.cc \
- ebuild_id.cc \
+ use_desc.cc \
vdb_id.cc \
- e_key.cc \
+ vdb_merger.cc \
+ vdb_repository.cc \
+ vdb_unmerger.cc \
$(paludis_repositories_e_include_HEADERS)
if ENABLE_QA
diff --git a/paludis/repositories/e/e_mask.cc b/paludis/repositories/e/e_mask.cc
new file mode 100644
index 000000000..16fcd148a
--- /dev/null
+++ b/paludis/repositories/e/e_mask.cc
@@ -0,0 +1,154 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.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/repositories/e/e_mask.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+
+using namespace paludis;
+using namespace paludis::erepository;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<EUnacceptedMask>
+ {
+ const char key;
+ const std::string description;
+ const tr1::shared_ptr<const MetadataKey> unaccepted_key;
+
+ Implementation(const char k, const std::string & d, const tr1::shared_ptr<const MetadataKey> & u) :
+ key(k),
+ description(d),
+ unaccepted_key(u)
+ {
+ }
+ };
+}
+
+EUnacceptedMask::EUnacceptedMask(const char k, const std::string & d, const tr1::shared_ptr<const MetadataKey> & u) :
+ PrivateImplementationPattern<EUnacceptedMask>(new Implementation<EUnacceptedMask>(k, d, u))
+{
+}
+
+EUnacceptedMask::~EUnacceptedMask()
+{
+}
+
+const char
+EUnacceptedMask::key() const
+{
+ return _imp->key;
+}
+
+const std::string
+EUnacceptedMask::description() const
+{
+ return _imp->description;
+}
+
+const tr1::shared_ptr<const MetadataKey>
+EUnacceptedMask::unaccepted_key() const
+{
+ return _imp->unaccepted_key;
+}
+
+namespace paludis
+{
+ template <>
+ struct Implementation<EUnsupportedMask>
+ {
+ const char key;
+ const std::string description;
+ const std::string eapi_name;
+
+ Implementation(const char k, const std::string & d, const std::string & n) :
+ key(k),
+ description(d),
+ eapi_name(n)
+ {
+ }
+ };
+}
+
+EUnsupportedMask::EUnsupportedMask(const char k, const std::string & d, const std::string & n) :
+ PrivateImplementationPattern<EUnsupportedMask>(new Implementation<EUnsupportedMask>(k, d, n))
+{
+}
+
+EUnsupportedMask::~EUnsupportedMask()
+{
+}
+
+const char
+EUnsupportedMask::key() const
+{
+ return _imp->key;
+}
+
+const std::string
+EUnsupportedMask::description() const
+{
+ return _imp->description;
+}
+
+const std::string
+EUnsupportedMask::explanation() const
+{
+ if (_imp->eapi_name == "UNKNOWN")
+ return "Unsupported EAPI 'UNKNOWN' (likely a broken package or configuration error)";
+ return "Unsupported EAPI '" + _imp->eapi_name + "'";
+}
+
+namespace paludis
+{
+ template <>
+ struct Implementation<ERepositoryMask>
+ {
+ const char key;
+ const std::string description;
+
+ Implementation(const char k, const std::string & d) :
+ key(k),
+ description(d)
+ {
+ }
+ };
+}
+
+ERepositoryMask::ERepositoryMask(const char k, const std::string & d) :
+ PrivateImplementationPattern<ERepositoryMask>(new Implementation<ERepositoryMask>(k, d))
+{
+}
+
+ERepositoryMask::~ERepositoryMask()
+{
+}
+
+const char
+ERepositoryMask::key() const
+{
+ return _imp->key;
+}
+
+const std::string
+ERepositoryMask::description() const
+{
+ return _imp->description;
+}
+
diff --git a/paludis/repositories/e/e_mask.hh b/paludis/repositories/e/e_mask.hh
new file mode 100644
index 000000000..23bad5eaa
--- /dev/null
+++ b/paludis/repositories/e/e_mask.hh
@@ -0,0 +1,70 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.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_REPOSITORIES_E_E_MASK_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_E_E_MASK_HH 1
+
+#include <paludis/mask.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+
+namespace paludis
+{
+ namespace erepository
+ {
+ class EUnacceptedMask :
+ public UnacceptedMask,
+ private PrivateImplementationPattern<EUnacceptedMask>
+ {
+ public:
+ EUnacceptedMask(const char, const std::string &, const tr1::shared_ptr<const MetadataKey> &);
+ ~EUnacceptedMask();
+
+ const char key() const;
+ const std::string description() const;
+ const tr1::shared_ptr<const MetadataKey> unaccepted_key() const;
+ };
+
+ class EUnsupportedMask :
+ public UnsupportedMask,
+ private PrivateImplementationPattern<EUnsupportedMask>
+ {
+ public:
+ EUnsupportedMask(const char, const std::string &, const std::string &);
+ ~EUnsupportedMask();
+
+ virtual const char key() const;
+ virtual const std::string description() const;
+ virtual const std::string explanation() const;
+ };
+
+ class ERepositoryMask :
+ public RepositoryMask,
+ private PrivateImplementationPattern<ERepositoryMask>
+ {
+ public:
+ ERepositoryMask(const char, const std::string &);
+ ~ERepositoryMask();
+
+ const char key() const;
+ const std::string description() const;
+ };
+ }
+}
+
+#endif
diff --git a/paludis/repositories/e/e_repository.cc b/paludis/repositories/e/e_repository.cc
index 0b5dc7f77..9aa3eb074 100644
--- a/paludis/repositories/e/e_repository.cc
+++ b/paludis/repositories/e/e_repository.cc
@@ -51,6 +51,7 @@
#include <paludis/util/iterator.hh>
#include <paludis/util/log.hh>
#include <paludis/util/random.hh>
+#include <paludis/util/options.hh>
#include <paludis/util/make_shared_ptr.hh>
#include <paludis/util/stringify.hh>
#include <paludis/util/tokeniser.hh>
@@ -250,7 +251,6 @@ namespace
ERepository::ERepository(const ERepositoryParams & p) :
Repository(fetch_repo_name(p.location),
RepositoryCapabilities::create()
- .mask_interface(this)
.installed_interface(0)
.sets_interface(this)
.syncable_interface(this)
@@ -341,7 +341,7 @@ ERepository::do_package_ids(const QualifiedPackageName & n) const
}
bool
-ERepository::do_query_repository_masks(const PackageID & id) const
+ERepository::repository_masked(const PackageID & id) const
{
if (! _imp->has_repo_mask)
{
@@ -394,13 +394,6 @@ ERepository::do_query_repository_masks(const PackageID & id) const
return false;
}
-bool
-ERepository::do_query_profile_masks(const PackageID & id) const
-{
- _imp->need_profiles();
- return _imp->profile_ptr->profile_masked(id);
-}
-
UseFlagState
ERepository::do_query_use(const UseFlagName & f, const PackageID & e) const
{
diff --git a/paludis/repositories/e/e_repository.hh b/paludis/repositories/e/e_repository.hh
index ed8b9aba1..393ad7893 100644
--- a/paludis/repositories/e/e_repository.hh
+++ b/paludis/repositories/e/e_repository.hh
@@ -50,7 +50,6 @@ namespace paludis
*/
class PALUDIS_VISIBLE ERepository :
public Repository,
- public RepositoryMaskInterface,
public RepositoryUseInterface,
public RepositorySyncableInterface,
public RepositorySetsInterface,
@@ -84,14 +83,6 @@ namespace paludis
virtual bool do_sync() const;
- /* RepositoryMaskInterface */
-
- virtual bool do_query_repository_masks(const PackageID &) const
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual bool do_query_profile_masks(const PackageID &) const
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
/* RepositoryUseInterface */
virtual UseFlagState do_query_use(const UseFlagName &, const PackageID &) const
@@ -232,6 +223,8 @@ namespace paludis
const tr1::shared_ptr<const ERepositoryEntries> entries() const;
const tr1::shared_ptr<const ERepositoryProfile> profile() const;
+ bool repository_masked(const PackageID &) const;
+
void regenerate_cache() const;
};
}
diff --git a/paludis/repositories/e/e_repository_TEST.cc b/paludis/repositories/e/e_repository_TEST.cc
index 62bf3ae59..42f3e29e5 100644
--- a/paludis/repositories/e/e_repository_TEST.cc
+++ b/paludis/repositories/e/e_repository_TEST.cc
@@ -652,12 +652,12 @@ namespace test_cases
{
TestMessageSuffix pass_suffix(stringify(pass), true);
- TEST_CHECK(repo->query_profile_masks(**env.package_database()->query(query::Matches(PackageDepSpec(
- "=cat/masked-0", pds_pm_unspecific)), qo_require_exactly_one)->begin()));
- TEST_CHECK(! repo->query_profile_masks(**env.package_database()->query(query::Matches(PackageDepSpec(
- "=cat/not_masked-0", pds_pm_unspecific)), qo_require_exactly_one)->begin()));
- TEST_CHECK(! repo->query_profile_masks(**env.package_database()->query(query::Matches(PackageDepSpec(
- "=cat/was_masked-0", pds_pm_unspecific)), qo_require_exactly_one)->begin()));
+ TEST_CHECK((*env.package_database()->query(query::Matches(PackageDepSpec("=cat/masked-0", pds_pm_unspecific)),
+ qo_require_exactly_one)->begin())->masked());
+ TEST_CHECK((*env.package_database()->query(query::Matches(PackageDepSpec("=cat/was_masked-0", pds_pm_unspecific)),
+ qo_require_exactly_one)->begin())->masked());
+ TEST_CHECK((*env.package_database()->query(query::Matches(PackageDepSpec("=cat/not_masked-0", pds_pm_unspecific)),
+ qo_require_exactly_one)->begin())->masked());
}
}
} test_e_repository_query_profile_masks;
diff --git a/paludis/repositories/e/e_repository_news.cc b/paludis/repositories/e/e_repository_news.cc
index 5009d3e00..ab09ecb94 100644
--- a/paludis/repositories/e/e_repository_news.cc
+++ b/paludis/repositories/e/e_repository_news.cc
@@ -28,6 +28,7 @@
#include <paludis/util/strip.hh>
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/sequence.hh>
+#include <paludis/util/options.hh>
#include <paludis/query.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
diff --git a/paludis/repositories/e/e_repository_profile.cc b/paludis/repositories/e/e_repository_profile.cc
index 17ed4b097..c9718096a 100644
--- a/paludis/repositories/e/e_repository_profile.cc
+++ b/paludis/repositories/e/e_repository_profile.cc
@@ -30,6 +30,7 @@
#include <paludis/util/join.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/set.hh>
+#include <paludis/util/options.hh>
#include <paludis/config_file.hh>
#include <paludis/dep_tag.hh>
#include <paludis/eapi.hh>
diff --git a/paludis/repositories/e/ebuild.cc b/paludis/repositories/e/ebuild.cc
index 2dbb6bc94..bc72d57e2 100644
--- a/paludis/repositories/e/ebuild.cc
+++ b/paludis/repositories/e/ebuild.cc
@@ -26,6 +26,7 @@
#include <paludis/util/pstream.hh>
#include <paludis/util/log.hh>
#include <paludis/util/sequence.hh>
+#include <paludis/util/options.hh>
#include <paludis/util/map.hh>
#include <paludis/about.hh>
diff --git a/paludis/repositories/e/ebuild_id.cc b/paludis/repositories/e/ebuild_id.cc
index 74ee63222..be089f8f2 100644
--- a/paludis/repositories/e/ebuild_id.cc
+++ b/paludis/repositories/e/ebuild_id.cc
@@ -24,6 +24,7 @@
#include <paludis/repositories/e/e_repository_entries.hh>
#include <paludis/repositories/e/eapi_phase.hh>
#include <paludis/repositories/e/e_key.hh>
+#include <paludis/repositories/e/e_mask.hh>
#include <paludis/name.hh>
#include <paludis/version_spec.hh>
@@ -39,6 +40,8 @@
#include <paludis/util/private_implementation_pattern-impl.hh>
#include <paludis/util/idle_action_pool.hh>
#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/save.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
@@ -77,6 +80,7 @@ namespace paludis
const time_t master_mtime;
const tr1::shared_ptr<const EclassMtimes> eclass_mtimes;
mutable bool has_keys;
+ mutable bool has_masks;
mutable tr1::shared_ptr<const EStringKey> short_description;
mutable tr1::shared_ptr<const EDependenciesKey> build_dependencies;
@@ -103,7 +107,8 @@ namespace paludis
guessed_eapi(g),
master_mtime(t),
eclass_mtimes(m),
- has_keys(false)
+ has_keys(false),
+ has_masks(false)
{
}
};
@@ -249,6 +254,116 @@ EbuildID::need_keys_added() const
}
}
+namespace
+{
+ struct LicenceChecker :
+ ConstVisitor<LicenseSpecTree>,
+ ConstVisitor<LicenseSpecTree>::VisitConstSequence<LicenceChecker, AllDepSpec>
+ {
+ using ConstVisitor<LicenseSpecTree>::VisitConstSequence<LicenceChecker, AllDepSpec>::visit_sequence;
+
+ bool ok;
+ const Environment * const env;
+ bool (Environment::* const func) (const std::string &, const PackageID &) const;
+ const PackageID * const id;
+
+ LicenceChecker(const Environment * const e,
+ bool (Environment::* const f) (const std::string &, const PackageID &) const,
+ const PackageID * const d) :
+ ok(true),
+ env(e),
+ func(f),
+ id(d)
+ {
+ }
+
+ void visit_sequence(const AnyDepSpec &,
+ LicenseSpecTree::ConstSequenceIterator begin,
+ LicenseSpecTree::ConstSequenceIterator end)
+ {
+ bool local_ok(false);
+
+ if (begin == end)
+ local_ok = true;
+ else
+ {
+ for ( ; begin != end ; ++begin)
+ {
+ Save<bool> save_ok(&ok, true);
+ begin->accept(*this);
+ local_ok |= ok;
+ }
+ }
+
+ ok &= local_ok;
+ }
+
+ void visit_sequence(const UseDepSpec & spec,
+ LicenseSpecTree::ConstSequenceIterator begin,
+ LicenseSpecTree::ConstSequenceIterator end)
+ {
+ if (env->query_use(spec.flag(), *id))
+ std::for_each(begin, end, accept_visitor(*this));
+ }
+
+ void visit_leaf(const PlainTextDepSpec & spec)
+ {
+ if (! (env->*func)(spec.text(), *id))
+ ok = false;
+ }
+ };
+}
+
+void
+EbuildID::need_masks_added() const
+{
+ if (_imp->has_masks)
+ return;
+
+ _imp->has_masks = true;
+
+ Context context("When generating masks for ID '" + canonical_form(idcf_full) + "':");
+
+ if (! eapi()->supported)
+ {
+ add_mask(make_shared_ptr(new EUnsupportedMask('E', "eapi", eapi()->name)));
+ return;
+ }
+
+ if (keywords_key())
+ if (! _imp->environment->accept_keywords(keywords_key()->value(), *this))
+ add_mask(make_shared_ptr(new EUnacceptedMask('K', "keywords", keywords_key())));
+
+ if (license_key())
+ {
+ LicenceChecker c(_imp->environment, &Environment::accept_license, this);
+ license_key()->value()->accept(c);
+ if (! c.ok)
+ add_mask(make_shared_ptr(new EUnacceptedMask('L', "license", license_key())));
+ }
+
+ if (! _imp->environment->unmasked_by_user(*this))
+ {
+ /* repo unless user */
+ if (tr1::static_pointer_cast<const ERepository>(repository())->repository_masked(*this))
+ add_mask(make_shared_ptr(new ERepositoryMask('R', "repository")));
+
+ /* profile unless user */
+ if (tr1::static_pointer_cast<const ERepository>(repository())->profile()->profile_masked(*this))
+ add_mask(make_shared_ptr(new ERepositoryMask('P', "profile")));
+
+ /* user */
+ tr1::shared_ptr<const Mask> user_mask(_imp->environment->mask_for_user(*this));
+ if (user_mask)
+ add_mask(user_mask);
+ }
+
+ /* break portage */
+ tr1::shared_ptr<const Mask> breaks_mask(_imp->environment->mask_for_breakage(*this));
+ if (breaks_mask)
+ add_mask(breaks_mask);
+}
+
const std::string
EbuildID::canonical_form(const PackageIDCanonicalForm f) const
{
diff --git a/paludis/repositories/e/ebuild_id.hh b/paludis/repositories/e/ebuild_id.hh
index cafe338e2..f54a8f2ab 100644
--- a/paludis/repositories/e/ebuild_id.hh
+++ b/paludis/repositories/e/ebuild_id.hh
@@ -42,6 +42,7 @@ namespace paludis
protected:
virtual void need_keys_added() const;
+ virtual void need_masks_added() const;
public:
EbuildID(const QualifiedPackageName &, const VersionSpec &,
diff --git a/paludis/repositories/e/vdb_id.cc b/paludis/repositories/e/vdb_id.cc
index e199d857d..097b4975a 100644
--- a/paludis/repositories/e/vdb_id.cc
+++ b/paludis/repositories/e/vdb_id.cc
@@ -321,6 +321,11 @@ VDBID::need_keys_added() const
}
}
+void
+VDBID::need_masks_added() const
+{
+}
+
const std::string
VDBID::canonical_form(const PackageIDCanonicalForm f) const
{
diff --git a/paludis/repositories/e/vdb_id.hh b/paludis/repositories/e/vdb_id.hh
index a0c46b6bf..52a6a639a 100644
--- a/paludis/repositories/e/vdb_id.hh
+++ b/paludis/repositories/e/vdb_id.hh
@@ -39,6 +39,7 @@ namespace paludis
protected:
virtual void need_keys_added() const;
+ virtual void need_masks_added() const;
public:
VDBID(const QualifiedPackageName &, const VersionSpec &,
diff --git a/paludis/repositories/e/vdb_repository.cc b/paludis/repositories/e/vdb_repository.cc
index b7837da09..3fdc07fc6 100644
--- a/paludis/repositories/e/vdb_repository.cc
+++ b/paludis/repositories/e/vdb_repository.cc
@@ -127,7 +127,6 @@ VDBRepository::VDBRepository(const VDBRepositoryParams & p) :
Repository(RepositoryName("installed"),
RepositoryCapabilities::create()
.installed_interface(this)
- .mask_interface(0)
.sets_interface(this)
.syncable_interface(0)
.use_interface(this)
diff --git a/paludis/repositories/fake/fake_installed_repository.cc b/paludis/repositories/fake/fake_installed_repository.cc
index 6b8ec694f..52df82e18 100644
--- a/paludis/repositories/fake/fake_installed_repository.cc
+++ b/paludis/repositories/fake/fake_installed_repository.cc
@@ -38,7 +38,6 @@ using namespace paludis;
FakeInstalledRepository::FakeInstalledRepository(const Environment * const e, const RepositoryName & our_name) :
FakeRepositoryBase(e, our_name, RepositoryCapabilities::create()
.installed_interface(this)
- .mask_interface(this)
.sets_interface(this)
.syncable_interface(0)
.use_interface(this)
diff --git a/paludis/repositories/fake/fake_package_id.cc b/paludis/repositories/fake/fake_package_id.cc
index 3547e7e90..303fd2bca 100644
--- a/paludis/repositories/fake/fake_package_id.cc
+++ b/paludis/repositories/fake/fake_package_id.cc
@@ -22,6 +22,7 @@
#include <paludis/eapi.hh>
#include <paludis/name.hh>
#include <paludis/action.hh>
+#include <paludis/environment.hh>
#include <paludis/version_spec.hh>
#include <paludis/portage_dep_parser.hh>
#include <paludis/hashed_containers.hh>
@@ -30,7 +31,9 @@
#include <paludis/util/tokeniser.hh>
#include <paludis/util/iterator.hh>
#include <paludis/util/set.hh>
+#include <paludis/util/save.hh>
#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/make_shared_ptr.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
@@ -177,11 +180,104 @@ FakeMetadataPackageIDKey::value() const
namespace paludis
{
+ template <>
+ struct Implementation<FakeUnacceptedMask>
+ {
+ const char key;
+ const std::string description;
+ const tr1::shared_ptr<const MetadataKey> unaccepted_key;
+
+ Implementation(const char k, const std::string & d, const tr1::shared_ptr<const MetadataKey> & u) :
+ key(k),
+ description(d),
+ unaccepted_key(u)
+ {
+ }
+ };
+}
+
+FakeUnacceptedMask::FakeUnacceptedMask(const char c, const std::string & s, const tr1::shared_ptr<const MetadataKey> & k) :
+ PrivateImplementationPattern<FakeUnacceptedMask>(new Implementation<FakeUnacceptedMask>(c, s, k))
+{
+}
+
+FakeUnacceptedMask::~FakeUnacceptedMask()
+{
+}
+
+const char
+FakeUnacceptedMask::key() const
+{
+ return _imp->key;
+}
+
+const std::string
+FakeUnacceptedMask::description() const
+{
+ return _imp->description;
+}
+
+const tr1::shared_ptr<const MetadataKey>
+FakeUnacceptedMask::unaccepted_key() const
+{
+ return _imp->unaccepted_key;
+}
+
+namespace paludis
+{
+ template <>
+ struct Implementation<FakeUnsupportedMask>
+ {
+ const char key;
+ const std::string description;
+ const std::string eapi_name;
+
+ Implementation(const char k, const std::string & d, const std::string & n) :
+ key(k),
+ description(d),
+ eapi_name(n)
+ {
+ }
+ };
+}
+
+FakeUnsupportedMask::FakeUnsupportedMask(const char c, const std::string & s, const std::string & n) :
+ PrivateImplementationPattern<FakeUnsupportedMask>(new Implementation<FakeUnsupportedMask>(c, s, n))
+{
+}
+
+FakeUnsupportedMask::~FakeUnsupportedMask()
+{
+}
+
+const char
+FakeUnsupportedMask::key() const
+{
+ return _imp->key;
+}
+
+const std::string
+FakeUnsupportedMask::description() const
+{
+ return _imp->description;
+}
+
+const std::string
+FakeUnsupportedMask::explanation() const
+{
+ if (_imp->eapi_name == "UNKNOWN")
+ return "Unsupported EAPI 'UNKNOWN' (likely a broken package or configuration error)";
+ return "Unsupported EAPI '" + _imp->eapi_name + "'";
+}
+
+namespace paludis
+{
using namespace tr1::placeholders;
template <>
struct Implementation<FakePackageID>
{
+ const Environment * const env;
const tr1::shared_ptr<const FakeRepositoryBase> repository;
const QualifiedPackageName name;
const VersionSpec version;
@@ -203,8 +299,11 @@ namespace paludis
tr1::shared_ptr<FakeMetadataSpecTreeKey<URISpecTree> > bin_uri;
tr1::shared_ptr<FakeMetadataSpecTreeKey<URISpecTree> > homepage;
- Implementation(const tr1::shared_ptr<const FakeRepositoryBase> & r,
+ mutable bool has_masks;
+
+ Implementation(const Environment * const e, const tr1::shared_ptr<const FakeRepositoryBase> & r,
const QualifiedPackageName & q, const VersionSpec & v) :
+ env(e),
repository(r),
name(q),
version(v),
@@ -223,15 +322,16 @@ namespace paludis
post_dependencies(new FakeMetadataSpecTreeKey<DependencySpecTree>("PDEPEND", "Post dependencies",
"", tr1::bind(&PortageDepParser::parse_depend, _1, tr1::cref(*eapi)), mkt_dependencies)),
suggested_dependencies(new FakeMetadataSpecTreeKey<DependencySpecTree>("SDEPEND", "Suggested dependencies",
- "", tr1::bind(&PortageDepParser::parse_depend, _1, tr1::cref(*eapi)), mkt_dependencies))
+ "", tr1::bind(&PortageDepParser::parse_depend, _1, tr1::cref(*eapi)), mkt_dependencies)),
+ has_masks(false)
{
}
};
}
-FakePackageID::FakePackageID(const tr1::shared_ptr<const FakeRepositoryBase> & r,
+FakePackageID::FakePackageID(const Environment * const e, const tr1::shared_ptr<const FakeRepositoryBase> & r,
const QualifiedPackageName & q, const VersionSpec & v) :
- PrivateImplementationPattern<FakePackageID>(new Implementation<FakePackageID>(r, q, v)),
+ PrivateImplementationPattern<FakePackageID>(new Implementation<FakePackageID>(e, r, q, v)),
_imp(PrivateImplementationPattern<FakePackageID>::_imp.get())
{
add_metadata_key(_imp->keywords);
@@ -498,6 +598,106 @@ FakePackageID::supports_action(const SupportsActionTestBase & b) const
namespace
{
+ struct LicenceChecker :
+ ConstVisitor<LicenseSpecTree>,
+ ConstVisitor<LicenseSpecTree>::VisitConstSequence<LicenceChecker, AllDepSpec>
+ {
+ using ConstVisitor<LicenseSpecTree>::VisitConstSequence<LicenceChecker, AllDepSpec>::visit_sequence;
+
+ bool ok;
+ const Environment * const env;
+ bool (Environment::* const func) (const std::string &, const PackageID &) const;
+ const PackageID * const id;
+
+ LicenceChecker(const Environment * const e,
+ bool (Environment::* const f) (const std::string &, const PackageID &) const,
+ const PackageID * const d) :
+ ok(true),
+ env(e),
+ func(f),
+ id(d)
+ {
+ }
+
+ void visit_sequence(const AnyDepSpec &,
+ LicenseSpecTree::ConstSequenceIterator begin,
+ LicenseSpecTree::ConstSequenceIterator end)
+ {
+ bool local_ok(false);
+
+ if (begin == end)
+ local_ok = true;
+ else
+ {
+ for ( ; begin != end ; ++begin)
+ {
+ Save<bool> save_ok(&ok, true);
+ begin->accept(*this);
+ local_ok |= ok;
+ }
+ }
+
+ ok &= local_ok;
+ }
+
+ void visit_sequence(const UseDepSpec & spec,
+ LicenseSpecTree::ConstSequenceIterator begin,
+ LicenseSpecTree::ConstSequenceIterator end)
+ {
+ if (env->query_use(spec.flag(), *id))
+ std::for_each(begin, end, accept_visitor(*this));
+ }
+
+ void visit_leaf(const PlainTextDepSpec & spec)
+ {
+ if (! (env->*func)(spec.text(), *id))
+ ok = false;
+ }
+ };
+}
+
+void
+FakePackageID::need_masks_added() const
+{
+ if (_imp->has_masks)
+ return;
+
+ _imp->has_masks = true;
+
+ Context context("When generating masks for ID '" + canonical_form(idcf_full) + "':");
+
+ if (! eapi()->supported)
+ {
+ add_mask(make_shared_ptr(new FakeUnsupportedMask('E', "eapi", eapi()->name)));
+ return;
+ }
+
+ if (keywords_key())
+ if (! _imp->env->accept_keywords(keywords_key()->value(), *this))
+ add_mask(make_shared_ptr(new FakeUnacceptedMask('K', "keywords", keywords_key())));
+
+ if (license_key())
+ {
+ LicenceChecker c(_imp->env, &Environment::accept_license, this);
+ license_key()->value()->accept(c);
+ if (! c.ok)
+ add_mask(make_shared_ptr(new FakeUnacceptedMask('L', "license", license_key())));
+ }
+
+ if (! _imp->env->unmasked_by_user(*this))
+ {
+ tr1::shared_ptr<const Mask> user_mask(_imp->env->mask_for_user(*this));
+ if (user_mask)
+ add_mask(user_mask);
+ }
+
+ tr1::shared_ptr<const Mask> breaks_mask(_imp->env->mask_for_breakage(*this));
+ if (breaks_mask)
+ add_mask(breaks_mask);
+}
+
+namespace
+{
struct PerformAction :
ConstVisitor<ActionVisitorTypes>
{
diff --git a/paludis/repositories/fake/fake_package_id.hh b/paludis/repositories/fake/fake_package_id.hh
index 8c9f54e8b..60ae6e47f 100644
--- a/paludis/repositories/fake/fake_package_id.hh
+++ b/paludis/repositories/fake/fake_package_id.hh
@@ -22,6 +22,7 @@
#include <paludis/package_id.hh>
#include <paludis/metadata_key.hh>
+#include <paludis/mask.hh>
#include <paludis/util/tr1_functional.hh>
namespace paludis
@@ -98,6 +99,32 @@ namespace paludis
PALUDIS_ATTRIBUTE((warn_unused_result));
};
+ class PALUDIS_VISIBLE FakeUnacceptedMask :
+ public UnacceptedMask,
+ private PrivateImplementationPattern<FakeUnacceptedMask>
+ {
+ public:
+ FakeUnacceptedMask(const char, const std::string &, const tr1::shared_ptr<const MetadataKey> &);
+ ~FakeUnacceptedMask();
+
+ const char key() const;
+ const std::string description() const;
+ const tr1::shared_ptr<const MetadataKey> unaccepted_key() const;
+ };
+
+ class PALUDIS_VISIBLE FakeUnsupportedMask :
+ public UnsupportedMask,
+ private PrivateImplementationPattern<FakeUnsupportedMask>
+ {
+ public:
+ FakeUnsupportedMask(const char, const std::string &, const std::string &);
+ ~FakeUnsupportedMask();
+
+ const char key() const;
+ const std::string description() const;
+ const std::string explanation() const;
+ };
+
class PALUDIS_VISIBLE FakePackageID :
public PackageID,
private PrivateImplementationPattern<FakePackageID>
@@ -107,9 +134,11 @@ namespace paludis
protected:
virtual void need_keys_added() const;
+ virtual void need_masks_added() const;
public:
- FakePackageID(const tr1::shared_ptr<const FakeRepositoryBase> &,
+ FakePackageID(const Environment * const e,
+ const tr1::shared_ptr<const FakeRepositoryBase> &,
const QualifiedPackageName &, const VersionSpec &);
~FakePackageID();
diff --git a/paludis/repositories/fake/fake_repository.cc b/paludis/repositories/fake/fake_repository.cc
index d6658dcc6..89f60ebc2 100644
--- a/paludis/repositories/fake/fake_repository.cc
+++ b/paludis/repositories/fake/fake_repository.cc
@@ -53,7 +53,6 @@ FakeRepository::FakeRepository(const Environment * const e, const RepositoryName
PrivateImplementationPattern<FakeRepository>(new Implementation<FakeRepository>),
FakeRepositoryBase(e, our_name, RepositoryCapabilities::create()
.installed_interface(0)
- .mask_interface(this)
.sets_interface(this)
.syncable_interface(0)
.use_interface(this)
diff --git a/paludis/repositories/fake/fake_repository_base.cc b/paludis/repositories/fake/fake_repository_base.cc
index 71168c03d..a611b84d3 100644
--- a/paludis/repositories/fake/fake_repository_base.cc
+++ b/paludis/repositories/fake/fake_repository_base.cc
@@ -81,7 +81,6 @@ FakeRepositoryBase::FakeRepositoryBase(const Environment * const e,
const RepositoryName & our_name, const RepositoryCapabilities & caps,
const std::string & f) :
Repository(our_name, caps, f),
- RepositoryMaskInterface(),
RepositoryUseInterface(),
PrivateImplementationPattern<FakeRepositoryBase>(new Implementation<FakeRepositoryBase>(e))
{
@@ -158,23 +157,11 @@ tr1::shared_ptr<FakePackageID>
FakeRepositoryBase::add_version(const QualifiedPackageName & q, const VersionSpec & v)
{
add_package(q);
- tr1::shared_ptr<FakePackageID> id(new FakePackageID(shared_from_this(), q, v));
+ tr1::shared_ptr<FakePackageID> id(new FakePackageID(_imp->env, shared_from_this(), q, v));
_imp->ids.find(q)->second->push_back(id);
return id;
}
-bool
-FakeRepositoryBase::do_query_repository_masks(const PackageID &) const
-{
- return false;
-}
-
-bool
-FakeRepositoryBase::do_query_profile_masks(const PackageID &) const
-{
- return false;
-}
-
UseFlagState
FakeRepositoryBase::do_query_use(const UseFlagName &, const PackageID &) const
{
diff --git a/paludis/repositories/fake/fake_repository_base.hh b/paludis/repositories/fake/fake_repository_base.hh
index 4011dec7a..c07c9a69b 100644
--- a/paludis/repositories/fake/fake_repository_base.hh
+++ b/paludis/repositories/fake/fake_repository_base.hh
@@ -44,7 +44,6 @@ namespace paludis
*/
class PALUDIS_VISIBLE FakeRepositoryBase :
public Repository,
- public RepositoryMaskInterface,
public RepositoryUseInterface,
public RepositorySetsInterface,
private PrivateImplementationPattern<FakeRepositoryBase>,
@@ -57,14 +56,6 @@ namespace paludis
FakeRepositoryBase(const Environment * const env, const RepositoryName & name,
const RepositoryCapabilities & caps, const std::string &);
- /* RepositoryMaskInterface */
-
- virtual bool do_query_repository_masks(const PackageID &) const
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
- virtual bool do_query_profile_masks(const PackageID &) const
- PALUDIS_ATTRIBUTE((warn_unused_result));
-
/* RepositoryUseInterface */
virtual UseFlagState do_query_use(const UseFlagName &, const PackageID &) const
diff --git a/paludis/repositories/gems/gem_specification.cc b/paludis/repositories/gems/gem_specification.cc
index 4a54e554e..bd9c74e81 100644
--- a/paludis/repositories/gems/gem_specification.cc
+++ b/paludis/repositories/gems/gem_specification.cc
@@ -29,6 +29,7 @@
#include <paludis/repository.hh>
#include <paludis/metadata_key.hh>
#include <paludis/action.hh>
+#include <paludis/environment.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
@@ -85,12 +86,17 @@ namespace paludis
tr1::shared_ptr<const FSEntry> load_from_file;
+ const Environment * const environment;
const tr1::shared_ptr<const Repository> repository;
const tr1::shared_ptr<const EAPI> eapi;
- Implementation(const tr1::shared_ptr<const Repository> & r) :
+ mutable bool has_masks;
+
+ Implementation(const Environment * const e, const tr1::shared_ptr<const Repository> & r) :
+ environment(e),
repository(r),
- eapi(EAPIData::get_instance()->eapi_from_string("gems-1"))
+ eapi(EAPIData::get_instance()->eapi_from_string("gems-1")),
+ has_masks(false)
{
}
};
@@ -268,8 +274,9 @@ namespace
}
}
-GemSpecification::GemSpecification(const tr1::shared_ptr<const Repository> & r, const yaml::Node & node) :
- PrivateImplementationPattern<GemSpecification>(new Implementation<GemSpecification>(r)),
+GemSpecification::GemSpecification(const Environment * const e,
+ const tr1::shared_ptr<const Repository> & r, const yaml::Node & node) :
+ PrivateImplementationPattern<GemSpecification>(new Implementation<GemSpecification>(e, r)),
_imp(PrivateImplementationPattern<GemSpecification>::_imp.get())
{
TopVisitor v(_imp);
@@ -289,9 +296,9 @@ GemSpecification::GemSpecification(const tr1::shared_ptr<const Repository> & r,
}
-GemSpecification::GemSpecification(const tr1::shared_ptr<const Repository> & r,
+GemSpecification::GemSpecification(const Environment * const e, const tr1::shared_ptr<const Repository> & r,
const PackageNamePart & q, const VersionSpec & v, const FSEntry & f) :
- PrivateImplementationPattern<GemSpecification>(new Implementation<GemSpecification>(r)),
+ PrivateImplementationPattern<GemSpecification>(new Implementation<GemSpecification>(e, r)),
_imp(PrivateImplementationPattern<GemSpecification>::_imp.get())
{
_imp->name_part = stringify(q);
@@ -600,3 +607,27 @@ GemSpecification::perform_action(Action & a) const
a.accept(b);
}
+void
+GemSpecification::need_masks_added() const
+{
+ if (_imp->has_masks)
+ return;
+
+ _imp->has_masks = true;
+
+ Context context("When generating masks for ID '" + canonical_form(idcf_full) + "':");
+
+ if (! _imp->environment->unmasked_by_user(*this))
+ {
+ /* user */
+ tr1::shared_ptr<const Mask> user_mask(_imp->environment->mask_for_user(*this));
+ if (user_mask)
+ add_mask(user_mask);
+ }
+
+ /* break portage */
+ tr1::shared_ptr<const Mask> breaks_mask(_imp->environment->mask_for_breakage(*this));
+ if (breaks_mask)
+ add_mask(breaks_mask);
+}
+
diff --git a/paludis/repositories/gems/gem_specification.hh b/paludis/repositories/gems/gem_specification.hh
index e9ae86f7f..1983e8a46 100644
--- a/paludis/repositories/gems/gem_specification.hh
+++ b/paludis/repositories/gems/gem_specification.hh
@@ -68,13 +68,14 @@ namespace paludis
protected:
void need_keys_added() const;
+ virtual void need_masks_added() const;
public:
///\name Basic operations
///\{
- GemSpecification(const tr1::shared_ptr<const Repository> &, const yaml::Node &);
- GemSpecification(const tr1::shared_ptr<const Repository> &, const PackageNamePart &,
+ GemSpecification(const Environment * const e, const tr1::shared_ptr<const Repository> &, const yaml::Node &);
+ GemSpecification(const Environment * const e, const tr1::shared_ptr<const Repository> &, const PackageNamePart &,
const VersionSpec &, const FSEntry &);
~GemSpecification();
diff --git a/paludis/repositories/gems/gem_specification_TEST.cc b/paludis/repositories/gems/gem_specification_TEST.cc
index 06bc8123e..2752e6e59 100644
--- a/paludis/repositories/gems/gem_specification_TEST.cc
+++ b/paludis/repositories/gems/gem_specification_TEST.cc
@@ -21,6 +21,7 @@
#include <test/test_framework.hh>
#include <paludis/repositories/gems/gem_specification.hh>
#include <paludis/repositories/gems/yaml.hh>
+#include <paludis/environments/test/test_environment.hh>
#include <paludis/util/visitor-impl.hh>
#include <paludis/name.hh>
#include <paludis/metadata_key.hh>
@@ -118,7 +119,8 @@ namespace test_cases
yaml::Document spec_doc(spec_text);
TEST_CHECK(spec_doc.top());
- GemSpecification spec(tr1::shared_ptr<Repository>(), *spec_doc.top());
+ TestEnvironment env;
+ GemSpecification spec(&env, tr1::shared_ptr<Repository>(), *spec_doc.top());
TEST_CHECK(spec.short_description_key());
TEST_CHECK_EQUAL(spec.short_description_key()->value(), "This is the summary");
diff --git a/paludis/repositories/gems/gem_specifications.cc b/paludis/repositories/gems/gem_specifications.cc
index de5291f86..26cf24f1e 100644
--- a/paludis/repositories/gems/gem_specifications.cc
+++ b/paludis/repositories/gems/gem_specifications.cc
@@ -101,10 +101,13 @@ namespace
ConstVisitor<yaml::NodeVisitorTypes>
{
Implementation<GemSpecifications> * const _imp;
+ const Environment * const environment;
const tr1::shared_ptr<const Repository> repository;
- GemsVisitor(const tr1::shared_ptr<const Repository> & r, Implementation<GemSpecifications> * const i) :
+ GemsVisitor(const Environment * const e,
+ const tr1::shared_ptr<const Repository> & r, Implementation<GemSpecifications> * const i) :
_imp(i),
+ environment(e),
repository(r)
{
}
@@ -118,7 +121,7 @@ namespace
try
{
- tr1::shared_ptr<GemSpecification> spec(new GemSpecification(repository, *i->second));
+ tr1::shared_ptr<GemSpecification> spec(new GemSpecification(environment, repository, *i->second));
_imp->specs.insert(std::make_pair(std::make_pair(spec->name(), spec->version()), spec));
}
catch (const Exception & e)
@@ -148,10 +151,13 @@ namespace
ConstVisitor<yaml::NodeVisitorTypes>
{
Implementation<GemSpecifications> * const _imp;
+ const Environment * const environment;
const tr1::shared_ptr<const Repository> repository;
- TopVisitor(const tr1::shared_ptr<const Repository> & r, Implementation<GemSpecifications> * const i) :
+ TopVisitor(const Environment * const e,
+ const tr1::shared_ptr<const Repository> & r, Implementation<GemSpecifications> * const i) :
_imp(i),
+ environment(e),
repository(r)
{
}
@@ -162,7 +168,7 @@ namespace
if (n.end() == i)
throw BadSpecificationError("Top level map does not contain 'gems' node");
- GemsVisitor g(repository, _imp);
+ GemsVisitor g(environment, repository, _imp);
i->second->accept(g);
}
@@ -182,10 +188,11 @@ namespace
}
}
-GemSpecifications::GemSpecifications(const tr1::shared_ptr<const Repository> & r, const yaml::Node & n) :
+GemSpecifications::GemSpecifications(const Environment * const e,
+ const tr1::shared_ptr<const Repository> & r, const yaml::Node & n) :
PrivateImplementationPattern<GemSpecifications>(new Implementation<GemSpecifications>)
{
- TopVisitor v(r, _imp.get());
+ TopVisitor v(e, r, _imp.get());
n.accept(v);
}
diff --git a/paludis/repositories/gems/gem_specifications.hh b/paludis/repositories/gems/gem_specifications.hh
index 629abe766..42a08a36b 100644
--- a/paludis/repositories/gems/gem_specifications.hh
+++ b/paludis/repositories/gems/gem_specifications.hh
@@ -50,7 +50,7 @@ namespace paludis
///\name Basic operations
///\{
- GemSpecifications(const tr1::shared_ptr<const Repository> &, const yaml::Node &);
+ GemSpecifications(const Environment * const, const tr1::shared_ptr<const Repository> &, const yaml::Node &);
~GemSpecifications();
///\}
diff --git a/paludis/repositories/gems/gems_repository.cc b/paludis/repositories/gems/gems_repository.cc
index 94dab62f3..20abc7177 100644
--- a/paludis/repositories/gems/gems_repository.cc
+++ b/paludis/repositories/gems/gems_repository.cc
@@ -65,7 +65,6 @@ namespace paludis
GemsRepository::GemsRepository(const gems::RepositoryParams & params) :
Repository(RepositoryName("gems"),
RepositoryCapabilities::create()
- .mask_interface(0)
.installed_interface(0)
.sets_interface(0)
.syncable_interface(0)
@@ -192,7 +191,7 @@ GemsRepository::need_ids() const
std::string output((std::istreambuf_iterator<char>(yaml_file)), std::istreambuf_iterator<char>());
yaml::Document master_doc(output);
- gems::GemSpecifications specs(shared_from_this(), *master_doc.top());
+ gems::GemSpecifications specs(_imp->params.environment, shared_from_this(), *master_doc.top());
for (gems::GemSpecifications::Iterator i(specs.begin()), i_end(specs.end()) ;
i != i_end ; ++i)
diff --git a/paludis/repositories/gems/installed_gems_repository.cc b/paludis/repositories/gems/installed_gems_repository.cc
index 517cb6803..fee24f583 100644
--- a/paludis/repositories/gems/installed_gems_repository.cc
+++ b/paludis/repositories/gems/installed_gems_repository.cc
@@ -73,7 +73,6 @@ namespace paludis
InstalledGemsRepository::InstalledGemsRepository(const gems::InstalledRepositoryParams & params) :
Repository(RepositoryName("installed-gems"),
RepositoryCapabilities::create()
- .mask_interface(0)
.installed_interface(this)
.sets_interface(0)
.syncable_interface(0)
@@ -212,7 +211,8 @@ InstalledGemsRepository::need_ids() const
if (_imp->ids.end() == _imp->ids.find(gems + p))
_imp->ids.insert(std::make_pair(gems + p, make_shared_ptr(new PackageIDSequence)));
- _imp->ids.find(gems + p)->second->push_back(make_shared_ptr(new gems::GemSpecification(shared_from_this(), p, v, *d)));
+ _imp->ids.find(gems + p)->second->push_back(make_shared_ptr(new gems::GemSpecification(
+ _imp->params.environment, shared_from_this(), p, v, *d)));
}
}
diff --git a/paludis/repositories/virtuals/installed_virtuals_repository.cc b/paludis/repositories/virtuals/installed_virtuals_repository.cc
index bcbda23c9..625afefed 100644
--- a/paludis/repositories/virtuals/installed_virtuals_repository.cc
+++ b/paludis/repositories/virtuals/installed_virtuals_repository.cc
@@ -100,7 +100,6 @@ namespace
InstalledVirtualsRepository::InstalledVirtualsRepository(const Environment * const env,
const FSEntry & r) :
Repository(RepositoryName(make_name(r)), RepositoryCapabilities::create()
- .mask_interface(0)
.installed_interface(this)
.use_interface(0)
.sets_interface(0)
diff --git a/paludis/repositories/virtuals/package_id.cc b/paludis/repositories/virtuals/package_id.cc
index e4b8bf940..2198e3c3f 100644
--- a/paludis/repositories/virtuals/package_id.cc
+++ b/paludis/repositories/virtuals/package_id.cc
@@ -31,6 +31,7 @@
#include <paludis/metadata_key.hh>
#include <paludis/hashed_containers.hh>
#include <paludis/action.hh>
+#include <paludis/mask.hh>
using namespace paludis;
using namespace paludis::virtuals;
@@ -120,6 +121,7 @@ namespace paludis
const tr1::shared_ptr<const MetadataPackageIDKey> virtual_for;
const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > bdep;
const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > rdep;
+ mutable bool has_masks;
Implementation(
const tr1::shared_ptr<const Repository> & o,
@@ -131,7 +133,8 @@ namespace paludis
version(p->version()),
virtual_for(new virtuals::VirtualsPackageIDKey(p)),
bdep(new virtuals::VirtualsDepKey("DEPEND", "Build dependencies", p, b)),
- rdep(new virtuals::VirtualsDepKey("RDEPEND", "Run dependencies", p, b))
+ rdep(new virtuals::VirtualsDepKey("RDEPEND", "Run dependencies", p, b)),
+ has_masks(false)
{
}
};
@@ -415,3 +418,46 @@ VirtualsPackageID::supports_action(const SupportsActionTestBase & b) const
return repository()->some_ids_might_support_action(b);
}
+namespace
+{
+ class VirtualsAssociationMask :
+ public AssociationMask
+ {
+ private:
+ const tr1::shared_ptr<const PackageID> _id;
+
+ public:
+ VirtualsAssociationMask(const tr1::shared_ptr<const PackageID> & i) :
+ _id(i)
+ {
+ }
+
+ const char key() const
+ {
+ return 'A';
+ }
+
+ const std::string description() const
+ {
+ return "by association";
+ }
+
+ const tr1::shared_ptr<const PackageID> associated_package() const
+ {
+ return _id;
+ }
+ };
+}
+
+void
+VirtualsPackageID::need_masks_added() const
+{
+ if (_imp->has_masks)
+ return;
+
+ if (_imp->virtual_for->value()->masked())
+ add_mask(make_shared_ptr(new VirtualsAssociationMask(_imp->virtual_for->value())));
+
+ _imp->has_masks = true;
+}
+
diff --git a/paludis/repositories/virtuals/package_id.hh b/paludis/repositories/virtuals/package_id.hh
index 71344518a..80e7f175f 100644
--- a/paludis/repositories/virtuals/package_id.hh
+++ b/paludis/repositories/virtuals/package_id.hh
@@ -68,6 +68,7 @@ namespace paludis
protected:
virtual void need_keys_added() const;
+ virtual void need_masks_added() const;
public:
VirtualsPackageID(
diff --git a/paludis/repositories/virtuals/virtuals_repository.cc b/paludis/repositories/virtuals/virtuals_repository.cc
index 3b2617ab7..217c7ee1a 100644
--- a/paludis/repositories/virtuals/virtuals_repository.cc
+++ b/paludis/repositories/virtuals/virtuals_repository.cc
@@ -95,7 +95,6 @@ namespace
VirtualsRepository::VirtualsRepository(const Environment * const env) :
Repository(RepositoryName("virtuals"), RepositoryCapabilities::create()
- .mask_interface(0)
.installed_interface(0)
.use_interface(0)
.sets_interface(0)