aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-06-10 12:27:53 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-06-10 12:27:53 +0000
commit010519e00248eb502e7ec5c501f0f5843953445c (patch)
tree958be75fc996eaaa3183ba2beb6f5442c408ba5f
parent5ceb0ff235f07df3b5f057ec7f68fcdb7c774631 (diff)
downloadpaludis-010519e00248eb502e7ec5c501f0f5843953445c.tar.gz
paludis-010519e00248eb502e7ec5c501f0f5843953445c.tar.xz
Experimental UnavailableRepository support, undocumented until it's had more testing.
-rw-r--r--configure.ac4
-rw-r--r--paludis/repositories/unavailable/Makefile.am91
-rw-r--r--paludis/repositories/unavailable/registration.cc71
-rw-r--r--paludis/repositories/unavailable/unavailable_id.cc304
-rw-r--r--paludis/repositories/unavailable/unavailable_id.hh105
-rw-r--r--paludis/repositories/unavailable/unavailable_mask.cc42
-rw-r--r--paludis/repositories/unavailable/unavailable_mask.hh40
-rw-r--r--paludis/repositories/unavailable/unavailable_repository-fwd.hh31
-rw-r--r--paludis/repositories/unavailable/unavailable_repository.cc291
-rw-r--r--paludis/repositories/unavailable/unavailable_repository.hh90
-rw-r--r--paludis/repositories/unavailable/unavailable_repository_TEST.cc116
-rwxr-xr-xpaludis/repositories/unavailable/unavailable_repository_TEST_cleanup.sh9
-rwxr-xr-xpaludis/repositories/unavailable/unavailable_repository_TEST_setup.sh37
-rw-r--r--paludis/repositories/unavailable/unavailable_repository_file-fwd.hh47
-rw-r--r--paludis/repositories/unavailable/unavailable_repository_file.cc209
-rw-r--r--paludis/repositories/unavailable/unavailable_repository_file.hh56
-rw-r--r--paludis/repositories/unavailable/unavailable_repository_store.cc216
-rw-r--r--paludis/repositories/unavailable/unavailable_repository_store.hh74
-rw-r--r--paludis/util/active_object_ptr-fwd.hh31
-rw-r--r--paludis/util/active_object_ptr.cc21
-rw-r--r--paludis/util/active_object_ptr.hh93
-rw-r--r--paludis/util/active_object_ptr_TEST.cc51
-rw-r--r--paludis/util/deferred_construction_ptr-fwd.hh29
-rw-r--r--paludis/util/deferred_construction_ptr.cc21
-rw-r--r--paludis/util/deferred_construction_ptr.hh76
-rw-r--r--paludis/util/deferred_construction_ptr_TEST.cc90
-rw-r--r--paludis/util/files.m42
-rw-r--r--paludis/util/keys.hh5
28 files changed, 2251 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index 0ae7854..c3990ec 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1051,7 +1051,7 @@ AC_SUBST([VIM_INSTALL_DIR])
dnl }}}
dnl {{{ repositories
-ALL_REPOSITORIES="cran e fake gems unpackaged virtuals"
+ALL_REPOSITORIES="cran e fake gems unavailable unpackaged virtuals"
DEFAULT_REPOSITORIES="e fake virtuals"
AC_MSG_CHECKING([which repositories to build...])
AC_ARG_WITH([repositories],
@@ -1064,6 +1064,7 @@ AC_ARG_WITH([repositories],
e Ebuild, Ebin, Exheres, VDB etc
fake A fake repository for test cases and adjutrix
gems Ruby gems (experimental)
+ unavailable Unavailable (experimental)
unpackaged Unpackaged (experimental, for importare)
virtuals Old style Gentoo virtuals],
[repositories="`echo $with_repositories | tr ',' ' '`"],
@@ -1339,6 +1340,7 @@ AC_OUTPUT(
paludis/repositories/e/qa/Makefile
paludis/repositories/fake/Makefile
paludis/repositories/gems/Makefile
+ paludis/repositories/unavailable/Makefile
paludis/repositories/unpackaged/Makefile
paludis/repositories/virtuals/Makefile
paludis/selinux/Makefile
diff --git a/paludis/repositories/unavailable/Makefile.am b/paludis/repositories/unavailable/Makefile.am
new file mode 100644
index 0000000..d7d7cd8
--- /dev/null
+++ b/paludis/repositories/unavailable/Makefile.am
@@ -0,0 +1,91 @@
+SUBDIRS = .
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda
+DISTCLEANFILES =
+
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CXXFLAGS = -I$(top_srcdir) -I$(top_builddir) @PALUDIS_CXXFLAGS@ @PALUDIS_CXXFLAGS_VISIBILITY@
+DEFS= \
+ -DSYSCONFDIR=\"$(sysconfdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
+ -DDATADIR=\"$(datadir)\" \
+ -DLIBDIR=\"$(libdir)\"
+
+paludis_repositories_libdir = $(libdir)/paludis/repositories
+paludis_repositories_lib_LTLIBRARIES = libpaludisunavailablerepository.la
+
+paludis_repositories_unavailable_includedir = $(includedir)/paludis-$(PALUDIS_PC_SLOT)/paludis/repositories/unavailable/
+libpaludisunavailablerepository_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+
+paludis_repositories_unavailable_include_HEADERS = \
+ unavailable_repository.hh unavailable_repository-fwd.hh \
+ unavailable_id.hh \
+ unavailable_mask.hh \
+ unavailable_repository_store.hh \
+ unavailable_repository_file.hh unavailable_repository_file-fwd.hh
+
+libpaludisunavailablerepository_la_SOURCES = \
+ unavailable_repository.cc \
+ unavailable_id.cc \
+ unavailable_mask.cc \
+ unavailable_repository_store.cc \
+ unavailable_repository_file.cc \
+ registration.cc \
+ $(paludis_repositories_unavailable_include_HEADERS)
+
+libpaludisunavailablerepository_la_LIBADD = \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(DYNAMIC_LD_LIBS)
+
+unavailable_repository_TEST_SOURCES = unavailable_repository_TEST.cc
+
+unavailable_repository_TEST_LDADD = \
+ libpaludisunavailablerepository.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/environments/test/libpaludistestenvironment.la \
+ $(top_builddir)/paludis/repositories/fake/libpaludisfakerepository.la \
+ $(top_builddir)/test/libtest.a \
+ $(DYNAMIC_LD_LIBS)
+
+EXTRA_DIST = \
+ unavailable_repository_TEST.cc \
+ unavailable_repository_TEST_setup.sh \
+ unavailable_repository_TEST_cleanup.sh
+
+check_SCRIPTS = \
+ unavailable_repository_TEST_setup.sh \
+ unavailable_repository_TEST_cleanup.sh
+
+TESTS_ENVIRONMENT = env \
+ TEST_OUTPUT_WRAPPER="`$(top_srcdir)/paludis/repositories/e/ebuild/utils/canonicalise $(top_builddir)/paludis/util/outputwrapper`" \
+ PALUDIS_OUTPUTWRAPPER_DIR="`$(top_srcdir)/paludis/repositories/e/ebuild/utils/canonicalise $(top_builddir)/paludis/util/`" \
+ PALUDIS_EBUILD_DIR="`$(top_srcdir)/paludis/repositories/e/ebuild/utils/canonicalise $(top_srcdir)/paludis/repositories/e/ebuild/`" \
+ PALUDIS_EAPIS_DIR="$(top_srcdir)/paludis/repositories/e/eapis/" \
+ PALUDIS_DISTRIBUTIONS_DIR="$(top_srcdir)/paludis/distributions/" \
+ PALUDIS_DISTRIBUTION="gentoo" \
+ PALUDIS_FETCHERS_DIR="$(top_srcdir)/paludis/fetchers/" \
+ PALUDIS_SKIP_CONFIG="yes" \
+ TEST_SCRIPT_DIR="$(srcdir)/" \
+ PALUDIS_REPOSITORY_SO_DIR="$(top_builddir)/paludis/repositories" \
+ PALUDIS_NO_CHOWN="yes" \
+ bash $(top_srcdir)/test/run_test.sh
+
+TESTS = \
+ unavailable_repository_TEST
+
+check_PROGRAMS = $(TESTS)
+
+built-sources : $(BUILT_SOURCES)
+ for s in `echo $(SUBDIRS) | tr -d .` ; do $(MAKE) -C $$s built-sources || exit 1 ; done
+
+distcheck-deps-local : $(DISTCHECK_DEPS)
+
+distcheck-deps : distcheck-deps-subdirs
+
+distcheck-deps-subdirs :
+ for s in $(SUBDIRS) . ; do if test x$$s = x. ; then $(MAKE) distcheck-deps-local || exit 1 ; \
+ else $(MAKE) -C $$s distcheck-deps || exit 1 ; fi ; done
+
diff --git a/paludis/repositories/unavailable/registration.cc b/paludis/repositories/unavailable/registration.cc
new file mode 100644
index 0000000..c21b247
--- /dev/null
+++ b/paludis/repositories/unavailable/registration.cc
@@ -0,0 +1,71 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/repository_maker.hh>
+#include <paludis/repositories/unavailable/unavailable_repository.hh>
+#include <paludis/util/map.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+
+using namespace paludis;
+using namespace paludis::unavailable_repository;
+
+extern "C"
+{
+ void PALUDIS_VISIBLE register_repositories(RepositoryMaker * maker);
+}
+
+namespace
+{
+ std::tr1::shared_ptr<Repository>
+ make_unavailable_repository(
+ Environment * const env,
+ std::tr1::shared_ptr<const Map<std::string, std::string> > m)
+ {
+ std::string repo_file(m->end() == m->find("repo_file") ? std::string("?") :
+ m->find("repo_file")->second);
+
+ Context context("When making unavailable repository from repo_file '" + repo_file + "':");
+
+ std::string location;
+ if (m->end() == m->find("location") || ((location = m->find("location")->second)).empty())
+ throw UnavailableRepositoryConfigurationError("Key 'location' not specified or empty");
+
+ std::string sync;
+ if (m->end() != m->find("sync"))
+ sync = m->find("sync")->second;
+
+ std::string sync_options;
+ if (m->end() != m->find("sync_options"))
+ sync_options = m->find("sync_options")->second;
+
+ return std::tr1::shared_ptr<UnavailableRepository>(new UnavailableRepository(
+ UnavailableRepositoryParams::named_create()
+ (k::location(), location)
+ (k::sync(), sync)
+ (k::sync_options(), sync_options)
+ (k::environment(), env)
+ ));
+ }
+}
+
+void register_repositories(RepositoryMaker * maker)
+{
+ maker->register_maker("unavailable", &make_unavailable_repository);
+}
+
diff --git a/paludis/repositories/unavailable/unavailable_id.cc b/paludis/repositories/unavailable/unavailable_id.cc
new file mode 100644
index 0000000..47fb60c
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_id.cc
@@ -0,0 +1,304 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/unavailable/unavailable_id.hh>
+#include <paludis/repositories/unavailable/unavailable_repository.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/kc.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/visitor_cast.hh>
+#include <paludis/util/set.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/hashes.hh>
+#include <paludis/name.hh>
+#include <paludis/version_spec.hh>
+#include <paludis/metadata_key.hh>
+#include <paludis/action.hh>
+
+using namespace paludis;
+using namespace paludis::unavailable_repository;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<UnavailableID>
+ {
+ const QualifiedPackageName name;
+ const VersionSpec version;
+ const SlotName slot;
+ const UnavailableRepository * const repo;
+
+ const std::tr1::shared_ptr<const MetadataKey> description_key;
+ const std::tr1::shared_ptr<const MetadataValueKey<std::string> > owning_repository_key;
+ const std::tr1::shared_ptr<const Mask> mask;
+
+ Implementation(
+ const UnavailableIDParams & e) :
+ name(e[k::name()]),
+ version(e[k::version()]),
+ slot(e[k::slot()]),
+ repo(e[k::repository()]),
+ description_key(e[k::description()]),
+ owning_repository_key(e[k::owning_repository()]),
+ mask(e[k::mask()])
+ {
+ }
+ };
+}
+
+UnavailableID::UnavailableID(const UnavailableIDParams & entry) :
+ PrivateImplementationPattern<UnavailableID>(new Implementation<UnavailableID>(entry)),
+ _imp(PrivateImplementationPattern<UnavailableID>::_imp)
+{
+ add_metadata_key(_imp->description_key);
+ add_metadata_key(_imp->owning_repository_key);
+ add_mask(_imp->mask);
+}
+
+UnavailableID::~UnavailableID()
+{
+}
+
+void
+UnavailableID::need_keys_added() const
+{
+}
+
+void
+UnavailableID::need_masks_added() const
+{
+}
+
+const std::string
+UnavailableID::canonical_form(const PackageIDCanonicalForm f) const
+{
+ switch (f)
+ {
+ case idcf_full:
+ return stringify(_imp->name) + "-" + stringify(_imp->version) +
+ ":" + stringify(_imp->slot) + "::" + stringify(_imp->repo->name()) +
+ " (in ::" + stringify(_imp->owning_repository_key->value()) + ")";
+
+ case idcf_no_version:
+ return stringify(_imp->name) + ":" + stringify(_imp->slot) +
+ "::" + stringify(_imp->repo->name()) +
+ " (in ::" + stringify(_imp->owning_repository_key->value()) + ")";
+
+ case idcf_version:
+ return stringify(_imp->version) +
+ " (in ::" + stringify(_imp->owning_repository_key->value()) + ")";
+
+ case last_idcf:
+ break;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad PackageIDCanonicalForm");
+}
+
+const QualifiedPackageName
+UnavailableID::name() const
+{
+ return _imp->name;
+}
+
+const VersionSpec
+UnavailableID::version() const
+{
+ return _imp->version;
+}
+
+const SlotName
+UnavailableID::slot() const
+{
+ return _imp->slot;
+}
+
+const std::tr1::shared_ptr<const Repository>
+UnavailableID::repository() const
+{
+ return _imp->repo->shared_from_this();
+}
+
+bool
+UnavailableID::supports_action(const SupportsActionTestBase & a) const
+{
+ return visitor_cast<const SupportsActionTest<InstallAction> >(a);
+}
+
+void
+UnavailableID::perform_action(Action & a) const
+{
+ throw UnsupportedActionError(*this, a);
+}
+
+std::tr1::shared_ptr<const Set<std::string> >
+UnavailableID::breaks_portage() const
+{
+ return make_shared_ptr(new Set<std::string>);
+}
+
+bool
+UnavailableID::arbitrary_less_than_comparison(const PackageID & other) const
+{
+ if (slot() < other.slot())
+ return true;
+ if (slot() > other.slot())
+ return false;
+
+ UnavailableID::MetadataConstIterator k(other.find_metadata("OWNING_REPOSITORY"));
+ if (other.end_metadata() == k)
+ throw InternalError(PALUDIS_HERE, "other has no OWNING_REPOSITORY");
+
+ const MetadataValueKey<std::string> * const kk(visitor_cast<const MetadataValueKey<std::string> >(**k));
+ if (! kk)
+ throw InternalError(PALUDIS_HERE, "other has bad OWNING_REPOSITORY");
+
+ return _imp->owning_repository_key->value() < kk->value();
+}
+
+std::size_t
+UnavailableID::extra_hash_value() const
+{
+ return Hash<std::pair<SlotName, std::string> >()(std::make_pair(
+ slot(), _imp->owning_repository_key->value()));
+}
+
+const std::tr1::shared_ptr<const MetadataCollectionKey<PackageIDSequence> >
+UnavailableID::contains_key() const
+{
+ return std::tr1::shared_ptr<const MetadataCollectionKey<PackageIDSequence> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
+UnavailableID::contained_in_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >
+UnavailableID::fs_location_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<bool> >
+UnavailableID::transient_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<bool> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
+UnavailableID::virtual_for_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >();
+}
+
+const std::tr1::shared_ptr<const MetadataCollectionKey<KeywordNameSet> >
+UnavailableID::keywords_key() const
+{
+ return std::tr1::shared_ptr<const MetadataCollectionKey<KeywordNameSet> >();
+}
+
+const std::tr1::shared_ptr<const MetadataCollectionKey<IUseFlagSet> >
+UnavailableID::iuse_key() const
+{
+ return std::tr1::shared_ptr<const MetadataCollectionKey<IUseFlagSet> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> >
+UnavailableID::provide_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+UnavailableID::build_dependencies_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+UnavailableID::run_dependencies_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+UnavailableID::post_dependencies_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+UnavailableID::suggested_dependencies_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
+UnavailableID::short_description_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<std::string> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
+UnavailableID::long_description_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<std::string> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> >
+UnavailableID::fetches_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> >
+UnavailableID::homepage_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Contents> > >
+UnavailableID::contents_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Contents> > >();
+}
+
+const std::tr1::shared_ptr<const MetadataTimeKey>
+UnavailableID::installed_time_key() const
+{
+ return std::tr1::shared_ptr<const MetadataTimeKey>();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
+UnavailableID::source_origin_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<std::string> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
+UnavailableID::binary_origin_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<std::string> >();
+}
+
+template class PrivateImplementationPattern<UnavailableID>;
+
diff --git a/paludis/repositories/unavailable/unavailable_id.hh b/paludis/repositories/unavailable/unavailable_id.hh
new file mode 100644
index 0000000..001e01a
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_id.hh
@@ -0,0 +1,105 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UNAVAILABLE_UNAVAILABLE_ID_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNAVAILABLE_UNAVAILABLE_ID_HH 1
+
+#include <paludis/package_id.hh>
+#include <paludis/repositories/unavailable/unavailable_repository_file-fwd.hh>
+#include <paludis/repositories/unavailable/unavailable_repository-fwd.hh>
+
+namespace paludis
+{
+ namespace unavailable_repository
+ {
+ typedef kc::KeyedClass<
+ kc::Field<k::name, QualifiedPackageName>,
+ kc::Field<k::version, VersionSpec>,
+ kc::Field<k::slot, SlotName>,
+ kc::Field<k::repository, const UnavailableRepository *>,
+ kc::Field<k::owning_repository, std::tr1::shared_ptr<const MetadataValueKey<std::string> > >,
+ kc::Field<k::description, std::tr1::shared_ptr<const MetadataValueKey<std::string> > >,
+ kc::Field<k::mask, std::tr1::shared_ptr<const Mask> >
+ > UnavailableIDParams;
+
+ class PALUDIS_VISIBLE UnavailableID :
+ public PackageID,
+ private PrivateImplementationPattern<UnavailableID>
+ {
+ private:
+ PrivateImplementationPattern<UnavailableID>::ImpPtr & _imp;
+
+ protected:
+ void need_keys_added() const;
+ void need_masks_added() const;
+
+ public:
+ UnavailableID(const UnavailableIDParams &);
+ ~UnavailableID();
+
+ const std::string canonical_form(const PackageIDCanonicalForm) const;
+ const QualifiedPackageName name() const;
+ const VersionSpec version() const;
+ const SlotName slot() const;
+ const std::tr1::shared_ptr<const Repository> repository() const;
+
+ const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
+ virtual_for_key() const;
+ const std::tr1::shared_ptr<const MetadataCollectionKey<KeywordNameSet> > keywords_key() const;
+ const std::tr1::shared_ptr<const MetadataCollectionKey<IUseFlagSet> > iuse_key() const;
+ const std::tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> > provide_key() const;
+ const std::tr1::shared_ptr<const MetadataCollectionKey<PackageIDSequence> > contains_key() const;
+ const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
+ contained_in_key() const;
+ const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+ build_dependencies_key() const;
+ const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+ run_dependencies_key() const;
+ const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+ post_dependencies_key() const;
+ const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+ suggested_dependencies_key() const;
+ const std::tr1::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> > fetches_key() const;
+ const std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> > homepage_key() const;
+ const std::tr1::shared_ptr<const MetadataValueKey<std::string> > short_description_key() const;
+ const std::tr1::shared_ptr<const MetadataValueKey<std::string> > long_description_key() const;
+ const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Contents> > >
+ contents_key() const;
+ const std::tr1::shared_ptr<const MetadataTimeKey> installed_time_key() const;
+ const std::tr1::shared_ptr<const MetadataValueKey<std::string> > source_origin_key() const;
+ const std::tr1::shared_ptr<const MetadataValueKey<std::string> > binary_origin_key() const;
+ const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> > fs_location_key() const;
+ const std::tr1::shared_ptr<const MetadataValueKey<bool> > transient_key() const;
+
+ bool supports_action(const SupportsActionTestBase &) const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ void perform_action(Action &) const PALUDIS_ATTRIBUTE((noreturn));
+
+ std::tr1::shared_ptr<const Set<std::string> > breaks_portage() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ bool arbitrary_less_than_comparison(const PackageID &) const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ std::size_t extra_hash_value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+ }
+}
+
+#endif
diff --git a/paludis/repositories/unavailable/unavailable_mask.cc b/paludis/repositories/unavailable/unavailable_mask.cc
new file mode 100644
index 0000000..0f84e7c
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_mask.cc
@@ -0,0 +1,42 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/unavailable/unavailable_mask.hh>
+
+using namespace paludis;
+using namespace paludis::unavailable_repository;
+
+char
+UnavailableMask::key() const
+{
+ return 'X';
+}
+
+const std::string
+UnavailableMask::description() const
+{
+ return "unavailable";
+}
+
+const std::string
+UnavailableMask::explanation() const
+{
+ return "In a repository which is unavailable";
+}
+
diff --git a/paludis/repositories/unavailable/unavailable_mask.hh b/paludis/repositories/unavailable/unavailable_mask.hh
new file mode 100644
index 0000000..6e3f194
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_mask.hh
@@ -0,0 +1,40 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UNAVAILABLE_UNAVAILABLE_MASK_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNAVAILABLE_UNAVAILABLE_MASK_HH 1
+
+#include <paludis/mask.hh>
+
+namespace paludis
+{
+ namespace unavailable_repository
+ {
+ class UnavailableMask :
+ public UnsupportedMask
+ {
+ public:
+ virtual const std::string explanation() const;
+ virtual char key() const;
+ virtual const std::string description() const;
+ };
+ }
+}
+
+#endif
diff --git a/paludis/repositories/unavailable/unavailable_repository-fwd.hh b/paludis/repositories/unavailable/unavailable_repository-fwd.hh
new file mode 100644
index 0000000..ad9785c
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository-fwd.hh
@@ -0,0 +1,31 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UNAVAILABLE_UNAVAILABLE_REPOSITORY_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNAVAILABLE_UNAVAILABLE_REPOSITORY_FWD_HH 1
+
+namespace paludis
+{
+ namespace unavailable_repository
+ {
+ class UnavailableRepository;
+ }
+}
+
+#endif
diff --git a/paludis/repositories/unavailable/unavailable_repository.cc b/paludis/repositories/unavailable/unavailable_repository.cc
new file mode 100644
index 0000000..a834f7b
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository.cc
@@ -0,0 +1,291 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/unavailable/unavailable_repository.hh>
+#include <paludis/repositories/unavailable/unavailable_repository_store.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/active_object_ptr.hh>
+#include <paludis/util/deferred_construction_ptr.hh>
+#include <paludis/util/visitor-impl.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/tokeniser.hh>
+#include <paludis/literal_metadata_key.hh>
+#include <paludis/action.hh>
+#include <paludis/syncer.hh>
+#include <list>
+
+using namespace paludis;
+using namespace paludis::unavailable_repository;
+
+namespace
+{
+ std::tr1::shared_ptr<UnavailableRepositoryStore>
+ make_store(const UnavailableRepository * const repo, const UnavailableRepositoryParams & p)
+ {
+ return make_shared_ptr(new UnavailableRepositoryStore(p[k::environment()], repo, p[k::location()]));
+ }
+}
+
+namespace paludis
+{
+ template <>
+ struct Implementation<UnavailableRepository>
+ {
+ const UnavailableRepositoryParams params;
+
+ const std::tr1::shared_ptr<LiteralMetadataValueKey<std::string> > format_key;
+ const std::tr1::shared_ptr<LiteralMetadataValueKey<FSEntry> > location_key;
+ const std::tr1::shared_ptr<LiteralMetadataValueKey<std::string> > sync_key;
+ const std::tr1::shared_ptr<LiteralMetadataValueKey<std::string> > sync_options_key;
+
+ const ActiveObjectPtr<DeferredConstructionPtr<
+ std::tr1::shared_ptr<UnavailableRepositoryStore> > > store;
+
+ Implementation(const UnavailableRepository * const repo, const UnavailableRepositoryParams & p) :
+ params(p),
+ format_key(new LiteralMetadataValueKey<std::string> ("format", "format",
+ mkt_significant, "unavailable")),
+ location_key(new LiteralMetadataValueKey<FSEntry> ("location", "location",
+ mkt_significant, params[k::location()])),
+ sync_key(new LiteralMetadataValueKey<std::string> (
+ "sync", "sync", mkt_normal, params[k::sync()])),
+ sync_options_key(new LiteralMetadataValueKey<std::string> (
+ "sync_options", "sync_options", mkt_normal, params[k::sync_options()])),
+ store(DeferredConstructionPtr<std::tr1::shared_ptr<UnavailableRepositoryStore> > (
+ std::tr1::bind(&make_store, repo, std::tr1::cref(params))))
+ {
+ }
+ };
+}
+
+UnavailableRepositoryConfigurationError::UnavailableRepositoryConfigurationError(const std::string & s) throw () :
+ ConfigurationError("UnavailableRepository configuration error: " + s)
+{
+}
+
+UnavailableRepository::UnavailableRepository(const UnavailableRepositoryParams & p) :
+ PrivateImplementationPattern<UnavailableRepository>(new Implementation<UnavailableRepository>(this, p)),
+ Repository(
+ RepositoryName("unavailable"),
+ RepositoryCapabilities::named_create()
+ (k::sets_interface(), static_cast<RepositorySetsInterface *>(0))
+ (k::syncable_interface(), this)
+ (k::use_interface(), static_cast<RepositoryUseInterface *>(0))
+ (k::environment_variable_interface(), static_cast<RepositoryEnvironmentVariableInterface *>(0))
+ (k::mirrors_interface(), static_cast<RepositoryMirrorsInterface *>(0))
+ (k::virtuals_interface(), static_cast<RepositoryVirtualsInterface *>(0))
+ (k::provides_interface(), static_cast<RepositoryProvidesInterface *>(0))
+ (k::destination_interface(), static_cast<RepositoryDestinationInterface *>(0))
+ (k::make_virtuals_interface(), static_cast<RepositoryMakeVirtualsInterface *>(0))
+ (k::e_interface(), static_cast<RepositoryEInterface *>(0))
+ (k::qa_interface(), static_cast<RepositoryQAInterface *>(0))
+ (k::hook_interface(), static_cast<RepositoryHookInterface *>(0))
+ (k::manifest_interface(), static_cast<RepositoryManifestInterface *>(0))
+ ),
+ _imp(PrivateImplementationPattern<UnavailableRepository>::_imp)
+{
+ _add_metadata_keys();
+}
+
+UnavailableRepository::~UnavailableRepository()
+{
+}
+
+void
+UnavailableRepository::_add_metadata_keys()
+{
+ clear_metadata_keys();
+ add_metadata_key(_imp->format_key);
+ add_metadata_key(_imp->location_key);
+ add_metadata_key(_imp->sync_key);
+ add_metadata_key(_imp->sync_options_key);
+}
+
+void
+UnavailableRepository::need_keys_added() const
+{
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
+UnavailableRepository::format_key() const
+{
+ return _imp->format_key;
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >
+UnavailableRepository::installed_root_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >();
+}
+
+void
+UnavailableRepository::invalidate()
+{
+ _imp.reset(new Implementation<UnavailableRepository>(this, _imp->params));
+ _add_metadata_keys();
+}
+
+void
+UnavailableRepository::invalidate_masks()
+{
+}
+
+bool
+UnavailableRepository::has_category_named(const CategoryNamePart & c) const
+{
+ return _imp->store->has_category_named(c);
+}
+
+bool
+UnavailableRepository::has_package_named(const QualifiedPackageName & q) const
+{
+ return _imp->store->has_package_named(q);
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnavailableRepository::category_names() const
+{
+ return _imp->store->category_names();
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnavailableRepository::unimportant_category_names() const
+{
+ return _imp->store->unimportant_category_names();
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnavailableRepository::category_names_containing_package(const PackageNamePart & p) const
+{
+ return Repository::category_names_containing_package(p);
+}
+
+std::tr1::shared_ptr<const QualifiedPackageNameSet>
+UnavailableRepository::package_names(const CategoryNamePart & c) const
+{
+ return _imp->store->package_names(c);
+}
+
+std::tr1::shared_ptr<const PackageIDSequence>
+UnavailableRepository::package_ids(const QualifiedPackageName & p) const
+{
+ return _imp->store->package_ids(p);
+}
+
+namespace
+{
+ struct SupportsActionQuery :
+ ConstVisitor<SupportsActionTestVisitorTypes>
+ {
+ bool result;
+
+ SupportsActionQuery() :
+ result(false)
+ {
+ }
+
+ void visit(const SupportsActionTest<InstalledAction> &)
+ {
+ }
+
+ void visit(const SupportsActionTest<InstallAction> &)
+ {
+ result = true;
+ }
+
+ void visit(const SupportsActionTest<FetchAction> &)
+ {
+ }
+
+ void visit(const SupportsActionTest<PretendFetchAction> &)
+ {
+ }
+
+ void visit(const SupportsActionTest<ConfigAction> &)
+ {
+ }
+
+ void visit(const SupportsActionTest<PretendAction> &)
+ {
+ }
+
+ void visit(const SupportsActionTest<InfoAction> &)
+ {
+ }
+
+ void visit(const SupportsActionTest<UninstallAction> &)
+ {
+ }
+ };
+}
+
+bool
+UnavailableRepository::some_ids_might_support_action(const SupportsActionTestBase & a) const
+{
+ SupportsActionQuery q;
+ a.accept(q);
+ return q.result;
+}
+
+bool
+UnavailableRepository::sync() const
+{
+ Context context("When syncing repository '" + stringify(name()) + "':");
+
+ if (_imp->params[k::sync()].empty())
+ return false;
+
+ std::list<std::string> sync_list;
+ tokenise_whitespace(_imp->params[k::sync()], std::back_inserter(sync_list));
+
+ bool ok(false);
+ for (std::list<std::string>::const_iterator s(sync_list.begin()),
+ s_end(sync_list.end()) ; s != s_end ; ++s)
+ {
+ DefaultSyncer syncer(SyncerParams::named_create()
+ (k::environment(), _imp->params[k::environment()])
+ (k::local(), stringify(_imp->params[k::location()]))
+ (k::remote(), *s)
+ );
+ SyncOptions opts(
+ _imp->params[k::sync_options()],
+ FSEntry("/dev/null"),
+ "sync " + stringify(name()) + "> "
+ );
+ try
+ {
+ syncer.sync(opts);
+ }
+ catch (const SyncFailedError &)
+ {
+ continue;
+ }
+
+ ok = true;
+ break;
+ }
+
+ if (! ok)
+ throw SyncFailedError(stringify(_imp->params[k::location()]), _imp->params[k::sync()]);
+
+ return true;
+}
+
+template class PrivateImplementationPattern<unavailable_repository::UnavailableRepository>;
+
diff --git a/paludis/repositories/unavailable/unavailable_repository.hh b/paludis/repositories/unavailable/unavailable_repository.hh
new file mode 100644
index 0000000..48d4da8
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository.hh
@@ -0,0 +1,90 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UNAVAILABLE_UNAVAILABLE_REPOSITORY_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNAVAILABLE_UNAVAILABLE_REPOSITORY_HH 1
+
+#include <paludis/repositories/unavailable/unavailable_repository-fwd.hh>
+#include <paludis/repository.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/attributes.hh>
+
+namespace paludis
+{
+ namespace unavailable_repository
+ {
+ class PALUDIS_VISIBLE UnavailableRepositoryConfigurationError :
+ public ConfigurationError
+ {
+ public:
+ UnavailableRepositoryConfigurationError(const std::string &) throw ();
+ };
+
+ typedef kc::KeyedClass<
+ kc::Field<k::environment, Environment *>,
+ kc::Field<k::location, FSEntry>,
+ kc::Field<k::sync, std::string>,
+ kc::Field<k::sync_options, std::string>
+ > UnavailableRepositoryParams;
+
+ class PALUDIS_VISIBLE UnavailableRepository :
+ private PrivateImplementationPattern<UnavailableRepository>,
+ public Repository,
+ public RepositorySyncableInterface,
+ public std::tr1::enable_shared_from_this<UnavailableRepository>
+ {
+ private:
+ PrivateImplementationPattern<UnavailableRepository>::ImpPtr & _imp;
+
+ void _add_metadata_keys();
+
+ protected:
+ virtual void need_keys_added() const;
+
+ public:
+ UnavailableRepository(const UnavailableRepositoryParams &);
+ ~UnavailableRepository();
+
+ virtual const std::tr1::shared_ptr<const MetadataValueKey<std::string> > format_key() const;
+ virtual const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> > installed_root_key() const;
+
+ virtual bool has_category_named(const CategoryNamePart & c) const;
+ virtual bool has_package_named(const QualifiedPackageName & q) const;
+ virtual std::tr1::shared_ptr<const CategoryNamePartSet> category_names() const;
+ virtual std::tr1::shared_ptr<const CategoryNamePartSet> unimportant_category_names() const;
+ virtual std::tr1::shared_ptr<const CategoryNamePartSet> category_names_containing_package(
+ const PackageNamePart & p) const;
+ virtual std::tr1::shared_ptr<const QualifiedPackageNameSet> package_names(
+ const CategoryNamePart & c) const;
+ virtual std::tr1::shared_ptr<const PackageIDSequence> package_ids(const QualifiedPackageName & p) const;
+
+ virtual bool some_ids_might_support_action(const SupportsActionTestBase &) const;
+ virtual void invalidate();
+ virtual void invalidate_masks();
+
+ virtual bool sync() const;
+ };
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<unavailable_repository::UnavailableRepository>;
+#endif
+}
+
+#endif
diff --git a/paludis/repositories/unavailable/unavailable_repository_TEST.cc b/paludis/repositories/unavailable/unavailable_repository_TEST.cc
new file mode 100644
index 0000000..311be29
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository_TEST.cc
@@ -0,0 +1,116 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/unavailable/unavailable_repository.hh>
+#include <paludis/repositories/fake/fake_repository.hh>
+#include <paludis/environments/test/test_environment.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/join.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/generator.hh>
+#include <paludis/selection.hh>
+#include <paludis/filtered_generator.hh>
+#include <paludis/filter.hh>
+#include <paludis/package_id.hh>
+#include <paludis/package_database.hh>
+#include <test/test_framework.hh>
+#include <test/test_runner.hh>
+#include <tr1/memory>
+
+using namespace paludis;
+using namespace paludis::unavailable_repository;
+using namespace test;
+
+namespace test_cases
+{
+ struct UnavailableRepositoryCreationTest : TestCase
+ {
+ UnavailableRepositoryCreationTest() : TestCase("creation") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ std::tr1::shared_ptr<UnavailableRepository> repo(new UnavailableRepository(
+ UnavailableRepositoryParams::named_create()
+ (k::sync(), "")
+ (k::sync_options(), "")
+ (k::location(), FSEntry::cwd() / "unavailable_repository_TEST_dir" / "repo1")
+ (k::environment(), &env)
+ ));
+ env.package_database()->add_repository(1, repo);
+ TEST_CHECK_STRINGIFY_EQUAL(repo->name(), "unavailable");
+ }
+ } test_creation;
+
+ struct UnavailableRepositoryContentsTest : TestCase
+ {
+ UnavailableRepositoryContentsTest() : TestCase("contents") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ std::tr1::shared_ptr<UnavailableRepository> repo(new UnavailableRepository(
+ UnavailableRepositoryParams::named_create()
+ (k::sync(), "")
+ (k::sync_options(), "")
+ (k::location(), FSEntry::cwd() / "unavailable_repository_TEST_dir" / "repo2")
+ (k::environment(), &env)
+ ));
+ env.package_database()->add_repository(1, repo);
+ TEST_CHECK_STRINGIFY_EQUAL(repo->name(), "unavailable");
+
+ std::tr1::shared_ptr<const PackageIDSequence> contents(
+ env[selection::AllVersionsSorted(generator::All())]);
+ TEST_CHECK(contents);
+
+ TEST_CHECK_EQUAL(
+ join(indirect_iterator(contents->begin()), indirect_iterator(contents->end()), " "),
+ "cat-one/pkg-one-1:0::unavailable (in ::bar) "
+ "cat-one/pkg-one-1:0::unavailable (in ::foo) "
+ "cat-one/pkg-one-2:0::unavailable (in ::foo) "
+ "cat-one/pkg-one-3:0::unavailable (in ::foo) "
+ "cat-one/pkg-one-3:3::unavailable (in ::bar) "
+ "cat-one/pkg-six-3:0::unavailable (in ::bar) "
+ "cat-one/pkg-two-1:1::unavailable (in ::foo) "
+ "cat-one/pkg-two-2:2::unavailable (in ::foo) "
+ "cat-two/pkg-six-1:0::unavailable (in ::bar)"
+ );
+
+ std::tr1::shared_ptr<FakeRepository> hide_bar(new FakeRepository(&env, RepositoryName("bar")));
+ env.package_database()->add_repository(2, hide_bar);
+ repo->invalidate();
+
+ std::tr1::shared_ptr<const PackageIDSequence> contents_without_bar(
+ env[selection::AllVersionsSorted(generator::All())]);
+ TEST_CHECK(contents);
+
+ TEST_CHECK_EQUAL(
+ join(indirect_iterator(contents_without_bar->begin()),
+ indirect_iterator(contents_without_bar->end()), " "),
+ "cat-one/pkg-one-1:0::unavailable (in ::foo) "
+ "cat-one/pkg-one-2:0::unavailable (in ::foo) "
+ "cat-one/pkg-one-3:0::unavailable (in ::foo) "
+ "cat-one/pkg-two-1:1::unavailable (in ::foo) "
+ "cat-one/pkg-two-2:2::unavailable (in ::foo)"
+ );
+ }
+ } test_contents;
+}
+
diff --git a/paludis/repositories/unavailable/unavailable_repository_TEST_cleanup.sh b/paludis/repositories/unavailable/unavailable_repository_TEST_cleanup.sh
new file mode 100755
index 0000000..93760c0
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository_TEST_cleanup.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d unavailable_repository_TEST_dir ] ; then
+ rm -fr unavailable_repository_TEST_dir
+else
+ true
+fi
+
diff --git a/paludis/repositories/unavailable/unavailable_repository_TEST_setup.sh b/paludis/repositories/unavailable/unavailable_repository_TEST_setup.sh
new file mode 100755
index 0000000..ae6501d
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository_TEST_setup.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir unavailable_repository_TEST_dir || exit 1
+cd unavailable_repository_TEST_dir || exit 1
+
+mkdir -p repo1
+cat <<"END" > repo1/foo.repository
+END
+
+mkdir -p repo2
+cat <<"END" > repo2/foo.repository
+repo_name = foo
+
+cat-one/
+ pkg-one/
+ :0 1 2 3 ; Monkey
+ pkg-two/
+ :1 1 ; One
+ :2 2 ; Two
+END
+cat <<"END" > repo2/bar.repository
+repo_name = bar
+
+cat-one/
+ pkg-one/
+ :0 1 ; Chimp
+ :3 3 ; Banana
+ pkg-six/
+ :0 3 ; Three
+cat-two/
+ pkg-six/
+ :0 1 ; Cheese on toast
+END
+
+cd ..
+
diff --git a/paludis/repositories/unavailable/unavailable_repository_file-fwd.hh b/paludis/repositories/unavailable/unavailable_repository_file-fwd.hh
new file mode 100644
index 0000000..b779c32
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository_file-fwd.hh
@@ -0,0 +1,47 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UNAVAILABLE_UNAVAILABLE_REPOSITORY_FILE_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNAVAILABLE_UNAVAILABLE_REPOSITORY_FILE_FWD_HH 1
+
+#include <paludis/util/attributes.hh>
+#include <paludis/util/keys.hh>
+#include <paludis/util/kc-fwd.hh>
+#include <paludis/name-fwd.hh>
+#include <paludis/version_spec-fwd.hh>
+#include <paludis/metadata_key-fwd.hh>
+#include <tr1/memory>
+
+namespace paludis
+{
+ namespace unavailable_repository
+ {
+ class UnavailableRepositoryFile;
+
+ typedef kc::KeyedClass<
+ kc::Field<k::name, QualifiedPackageName>,
+ kc::Field<k::version, VersionSpec>,
+ kc::Field<k::slot, SlotName>,
+ kc::Field<k::description, std::tr1::shared_ptr<const MetadataValueKey<std::string> > >
+ > UnavailableRepositoryFileEntry;
+ }
+}
+
+
+#endif
diff --git a/paludis/repositories/unavailable/unavailable_repository_file.cc b/paludis/repositories/unavailable/unavailable_repository_file.cc
new file mode 100644
index 0000000..d6103c9
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository_file.cc
@@ -0,0 +1,209 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/unavailable/unavailable_repository_file.hh>
+#include <paludis/repositories/unavailable/unavailable_repository.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/kc.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/simple_parser.hh>
+#include <paludis/name.hh>
+#include <paludis/version_spec.hh>
+#include <paludis/literal_metadata_key.hh>
+#include <list>
+#include <fstream>
+
+using namespace paludis;
+using namespace paludis::unavailable_repository;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<UnavailableRepositoryFile>
+ {
+ std::string repo_name;
+ std::list<UnavailableRepositoryFileEntry> entries;
+ };
+}
+
+UnavailableRepositoryFile::UnavailableRepositoryFile(const FSEntry & f) :
+ PrivateImplementationPattern<UnavailableRepositoryFile>(new Implementation<UnavailableRepositoryFile>)
+{
+ _load(f);
+}
+
+UnavailableRepositoryFile::~UnavailableRepositoryFile()
+{
+}
+
+UnavailableRepositoryFile::ConstIterator
+UnavailableRepositoryFile::begin() const
+{
+ return ConstIterator(_imp->entries.begin());
+}
+
+UnavailableRepositoryFile::ConstIterator
+UnavailableRepositoryFile::end() const
+{
+ return ConstIterator(_imp->entries.end());
+}
+
+void
+UnavailableRepositoryFile::_load(const FSEntry & f)
+{
+ std::ifstream file(stringify(f).c_str());
+ if (! file)
+ throw UnavailableRepositoryConfigurationError("Cannot read '" + stringify(f) + "'");
+
+ std::string line;
+ while (std::getline(file, line))
+ {
+ if (line.empty())
+ break;
+
+ std::string key, value;
+ SimpleParser line_parser(line);
+ if (line_parser.consume(
+ (+simple_parser::any_except(" \t") >> key) &
+ (*simple_parser::any_of(" \t")) &
+ (simple_parser::exact("=")) &
+ (*simple_parser::any_of(" \t")) &
+ (*simple_parser::any_except("") >> value)
+ ))
+ {
+ if (key == "format")
+ {
+ if (value != "unavailable-1")
+ throw UnavailableRepositoryConfigurationError(
+ "Unsupported format '" + value + "' in '" + stringify(f) + "'");
+ }
+ else if (key == "repo_name")
+ _imp->repo_name = value;
+ else
+ Log::get_instance()->message("unavailable_repository.file.unknown_key", ll_warning, lc_context)
+ << "Ignoring unknown key '" << key << "' with value '" << value << "'";
+ }
+ else
+ throw UnavailableRepositoryConfigurationError(
+ "Cannot parse header line '" + line + "' in '" + stringify(f) + "'");
+ }
+
+ CategoryNamePart category("x");
+ PackageNamePart package("x");
+ SlotName slot("x");
+ while (std::getline(file, line))
+ {
+ SimpleParser line_parser(line);
+
+ std::string token;
+ if (line_parser.consume(
+ (+simple_parser::any_except(" \t/") >> token) &
+ (simple_parser::exact("/"))
+ ))
+ {
+ if (! line_parser.eof())
+ throw UnavailableRepositoryConfigurationError(
+ "Cannot parse body category line '" + line + " in '" + stringify(f) + "'");
+
+ category = CategoryNamePart(token);
+ }
+ else if (line_parser.consume(
+ (+simple_parser::any_of(" \t")) &
+ (+simple_parser::any_except(" \t/") >> token) &
+ (simple_parser::exact("/"))
+ ))
+ {
+ if (! line_parser.eof())
+ throw UnavailableRepositoryConfigurationError(
+ "Cannot parse body package line '" + line + " in '" + stringify(f) + "'");
+
+ package = PackageNamePart(token);
+ }
+ else if (line_parser.consume(
+ (+simple_parser::any_of(" \t")) &
+ (+simple_parser::exact(":")) &
+ (+simple_parser::any_except(" \t") >> token) &
+ (+simple_parser::any_of(" \t"))
+ ))
+ {
+ slot = SlotName(token);
+
+ std::list<VersionSpec> versions;
+ while (true)
+ {
+ if (line_parser.consume(
+ (+simple_parser::exact(";")) &
+ (*simple_parser::any_of(" \t"))
+ ))
+ break;
+ else if (line_parser.consume(
+ (+simple_parser::any_except(" \t") >> token) &
+ (+simple_parser::any_of(" \t"))
+ ))
+ versions.push_back(VersionSpec(token));
+ else
+ throw UnavailableRepositoryConfigurationError(
+ "Cannot parse body version line '" + line + " in '" + stringify(f) + "'");
+ }
+
+ if (versions.empty())
+ throw UnavailableRepositoryConfigurationError(
+ "Cannot parse body version line '" + line + " in '" + stringify(f) + "'");
+
+ if (! line_parser.consume(
+ (*simple_parser::any_of(" \t")) &
+ (+simple_parser::any_except("") >> token)
+ ))
+ throw UnavailableRepositoryConfigurationError(
+ "Cannot parse body description line '" + line + " in '" + stringify(f) + "'");
+
+ if (! line_parser.eof())
+ throw UnavailableRepositoryConfigurationError(
+ "Cannot parse body description line '" + line + " in '" + stringify(f) + "'");
+
+ std::tr1::shared_ptr<LiteralMetadataValueKey<std::string> > description(
+ new LiteralMetadataValueKey<std::string>("DESCRIPTION", "Description", mkt_significant,
+ token));
+ for (std::list<VersionSpec>::const_iterator v(versions.begin()), v_end(versions.end()) ;
+ v != v_end ; ++v)
+ _imp->entries.push_back(UnavailableRepositoryFileEntry::named_create()
+ (k::name(), category + package)
+ (k::version(), *v)
+ (k::slot(), slot)
+ (k::description(), description)
+ );
+ }
+ else
+ throw UnavailableRepositoryConfigurationError(
+ "Cannot parse body line '" + line + " in '" + stringify(f) + "'");
+ }
+}
+
+std::string
+UnavailableRepositoryFile::repo_name() const
+{
+ return _imp->repo_name;
+}
+
+template class PrivateImplementationPattern<UnavailableRepositoryFile>;
+template class WrappedForwardIterator<UnavailableRepositoryFile::ConstIteratorTag,
+ const UnavailableRepositoryFileEntry>;
+
diff --git a/paludis/repositories/unavailable/unavailable_repository_file.hh b/paludis/repositories/unavailable/unavailable_repository_file.hh
new file mode 100644
index 0000000..331b72a
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository_file.hh
@@ -0,0 +1,56 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UNAVAILABLE_UNAVAILABLE_REPOSITORY_FILE_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNAVAILABLE_UNAVAILABLE_REPOSITORY_FILE_HH 1
+
+#include <paludis/repositories/unavailable/unavailable_repository_file-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/fs_entry.hh>
+
+namespace paludis
+{
+ namespace unavailable_repository
+ {
+ class PALUDIS_VISIBLE UnavailableRepositoryFile :
+ private PrivateImplementationPattern<UnavailableRepositoryFile>
+ {
+ private:
+ void _load(const FSEntry &);
+
+ public:
+ UnavailableRepositoryFile(const FSEntry &);
+ ~UnavailableRepositoryFile();
+
+ struct ConstIteratorTag;
+ typedef WrappedForwardIterator<ConstIteratorTag, const UnavailableRepositoryFileEntry> ConstIterator;
+ ConstIterator begin() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ std::string repo_name() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<unavailable_repository::UnavailableRepositoryFile>;
+#endif
+}
+
+#endif
diff --git a/paludis/repositories/unavailable/unavailable_repository_store.cc b/paludis/repositories/unavailable/unavailable_repository_store.cc
new file mode 100644
index 0000000..6795a17
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository_store.cc
@@ -0,0 +1,216 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/unavailable/unavailable_repository_store.hh>
+#include <paludis/repositories/unavailable/unavailable_repository_file.hh>
+#include <paludis/repositories/unavailable/unavailable_id.hh>
+#include <paludis/repositories/unavailable/unavailable_mask.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/dir_iterator.hh>
+#include <paludis/util/set.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/util/hashes.hh>
+#include <paludis/util/kc.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/is_file_with_extension.hh>
+#include <paludis/util/log.hh>
+#include <paludis/name.hh>
+#include <paludis/version_spec.hh>
+#include <paludis/literal_metadata_key.hh>
+#include <paludis/environment.hh>
+#include <paludis/package_database.hh>
+#include <tr1/functional>
+#include <tr1/unordered_map>
+#include <algorithm>
+#include <set>
+
+using namespace paludis;
+using namespace paludis::unavailable_repository;
+
+typedef std::tr1::unordered_map<CategoryNamePart,
+ std::tr1::shared_ptr<QualifiedPackageNameSet>,
+ Hash<CategoryNamePart> > PackageNames;
+
+typedef std::tr1::unordered_map<QualifiedPackageName,
+ std::tr1::shared_ptr<PackageIDSequence>,
+ Hash<QualifiedPackageName> > IDs;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<UnavailableRepositoryStore>
+ {
+ const UnavailableRepository * const repo;
+ mutable std::tr1::shared_ptr<CategoryNamePartSet> categories;
+ mutable PackageNames package_names;
+ mutable IDs ids;
+
+ std::set<std::string> seen_repo_names;
+
+ Implementation(const UnavailableRepository * const r) :
+ repo(r),
+ categories(new CategoryNamePartSet)
+ {
+ }
+ };
+}
+
+UnavailableRepositoryStore::UnavailableRepositoryStore(
+ const Environment * const env,
+ const UnavailableRepository * const repo,
+ const FSEntry & f) :
+ PrivateImplementationPattern<UnavailableRepositoryStore>(new Implementation<UnavailableRepositoryStore>(repo))
+{
+ _populate(env, f);
+}
+
+UnavailableRepositoryStore::~UnavailableRepositoryStore()
+{
+}
+
+void
+UnavailableRepositoryStore::_populate(const Environment * const env, const FSEntry & f)
+{
+ Context context("When populating UnavailableRepository from directory '" + stringify(f) + "':");
+
+ using namespace std::tr1::placeholders;
+ std::for_each(DirIterator(f), DirIterator(), std::tr1::bind(
+ &UnavailableRepositoryStore::_populate_one, this, env, _1));
+}
+
+void
+UnavailableRepositoryStore::_populate_one(const Environment * const env, const FSEntry & f)
+{
+ if (! is_file_with_extension(f, ".repository", IsFileWithOptions()))
+ return;
+
+ Context context("When populating UnavailableRepository from file '" + stringify(f) + "':");
+
+ UnavailableRepositoryFile file(f);
+
+ if (env->package_database()->has_repository_named(RepositoryName(file.repo_name())))
+ {
+ Log::get_instance()->message("unavailable_repository.file.present", ll_debug, lc_context)
+ << "Skipping file '" << f << "' due to present repo_name '" << file.repo_name() << "'";
+ return;
+ }
+
+ if (! _imp->seen_repo_names.insert(file.repo_name()).second)
+ {
+ Log::get_instance()->message("unavailable_repository.file.duplicate", ll_warning, lc_context)
+ << "Skipping file '" << f << "' due to duplicate repo_name '" << file.repo_name() << "'";
+ return;
+ }
+
+ std::tr1::shared_ptr<Mask> mask(new UnavailableMask);
+ std::tr1::shared_ptr<MetadataValueKey<std::string> > owning_repository(
+ new LiteralMetadataValueKey<std::string>("OWNING_REPOSITORY", "Owning repository",
+ mkt_significant, file.repo_name()));
+
+ QualifiedPackageName old_name("x/x");
+ std::tr1::shared_ptr<QualifiedPackageNameSet> pkgs;
+ std::tr1::shared_ptr<PackageIDSequence> ids;
+ for (UnavailableRepositoryFile::ConstIterator i(file.begin()), i_end(file.end()) ;
+ i != i_end ; ++i)
+ {
+ if (old_name.category != (*i)[k::name()].category)
+ {
+ _imp->categories->insert((*i)[k::name()].category);
+ PackageNames::iterator p(_imp->package_names.find((*i)[k::name()].category));
+ if (_imp->package_names.end() == p)
+ p = _imp->package_names.insert(std::make_pair((*i)[k::name()].category,
+ make_shared_ptr(new QualifiedPackageNameSet))).first;
+ pkgs = p->second;
+ }
+
+ if (old_name != (*i)[k::name()])
+ {
+ pkgs->insert((*i)[k::name()]);
+ IDs::iterator p(_imp->ids.find((*i)[k::name()]));
+ if (_imp->ids.end() == p)
+ p = _imp->ids.insert(std::make_pair((*i)[k::name()],
+ make_shared_ptr(new PackageIDSequence))).first;
+
+ ids = p->second;
+ }
+
+ ids->push_back(make_shared_ptr(new UnavailableID(UnavailableIDParams::named_create()
+ (k::repository(), _imp->repo)
+ (k::name(), (*i)[k::name()])
+ (k::version(), (*i)[k::version()])
+ (k::slot(), (*i)[k::slot()])
+ (k::description(), (*i)[k::description()])
+ (k::owning_repository(), owning_repository)
+ (k::mask(), mask)
+ )));
+
+ old_name = (*i)[k::name()];
+ }
+}
+
+bool
+UnavailableRepositoryStore::has_category_named(const CategoryNamePart & c) const
+{
+ return _imp->categories->end() != _imp->categories->find(c);
+}
+
+bool
+UnavailableRepositoryStore::has_package_named(const QualifiedPackageName & q) const
+{
+ return _imp->ids.end() != _imp->ids.find(q);
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnavailableRepositoryStore::category_names() const
+{
+ return _imp->categories;
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnavailableRepositoryStore::unimportant_category_names() const
+{
+ std::tr1::shared_ptr<CategoryNamePartSet> result(make_shared_ptr(new CategoryNamePartSet));
+ result->insert(CategoryNamePart("virtual"));
+ return result;
+}
+
+std::tr1::shared_ptr<const QualifiedPackageNameSet>
+UnavailableRepositoryStore::package_names(const CategoryNamePart & c) const
+{
+ PackageNames::iterator p(_imp->package_names.find(c));
+ if (_imp->package_names.end() == p)
+ return make_shared_ptr(new QualifiedPackageNameSet);
+ else
+ return p->second;
+}
+
+std::tr1::shared_ptr<const PackageIDSequence>
+UnavailableRepositoryStore::package_ids(const QualifiedPackageName & p) const
+{
+ IDs::iterator i(_imp->ids.find(p));
+ if (_imp->ids.end() == i)
+ return make_shared_ptr(new PackageIDSequence);
+ else
+ return i->second;
+}
+
+template class PrivateImplementationPattern<unavailable_repository::UnavailableRepositoryStore>;
+
diff --git a/paludis/repositories/unavailable/unavailable_repository_store.hh b/paludis/repositories/unavailable/unavailable_repository_store.hh
new file mode 100644
index 0000000..94746d2
--- /dev/null
+++ b/paludis/repositories/unavailable/unavailable_repository_store.hh
@@ -0,0 +1,74 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UNAVAILABLE_UNAVAILABLE_REPOSITORY_STORE_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNAVAILABLE_UNAVAILABLE_REPOSITORY_STORE_HH 1
+
+#include <paludis/repositories/unavailable/unavailable_repository-fwd.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/fs_entry-fwd.hh>
+#include <paludis/name-fwd.hh>
+#include <paludis/package_id-fwd.hh>
+#include <paludis/environment-fwd.hh>
+#include <tr1/memory>
+
+namespace paludis
+{
+ namespace unavailable_repository
+ {
+ class PALUDIS_VISIBLE UnavailableRepositoryStore :
+ private PrivateImplementationPattern<UnavailableRepositoryStore>
+ {
+ private:
+ void _populate_one(const Environment * const env, const FSEntry & f);
+ void _populate(const Environment * const env, const FSEntry & f);
+
+ public:
+ UnavailableRepositoryStore(
+ const Environment * const,
+ const UnavailableRepository * const,
+ const FSEntry &);
+ ~UnavailableRepositoryStore();
+
+ bool has_category_named(const CategoryNamePart &) const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ bool has_package_named(const QualifiedPackageName & q) const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ std::tr1::shared_ptr<const CategoryNamePartSet> category_names() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ std::tr1::shared_ptr<const CategoryNamePartSet> unimportant_category_names() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ std::tr1::shared_ptr<const QualifiedPackageNameSet> package_names(
+ const CategoryNamePart & c) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ std::tr1::shared_ptr<const PackageIDSequence> package_ids(
+ const QualifiedPackageName & p) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<unavailable_repository::UnavailableRepositoryStore>;
+#endif
+}
+
+#endif
diff --git a/paludis/util/active_object_ptr-fwd.hh b/paludis/util/active_object_ptr-fwd.hh
new file mode 100644
index 0000000..7930392
--- /dev/null
+++ b/paludis/util/active_object_ptr-fwd.hh
@@ -0,0 +1,31 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UTIL_ACTIVE_OBJECT_PTR_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_ACTIVE_OBJECT_PTR_FWD_HH 1
+
+#include <paludis/util/attributes.hh>
+
+namespace paludis
+{
+ template <typename T_>
+ struct ActiveObjectPtr;
+}
+
+#endif
diff --git a/paludis/util/active_object_ptr.cc b/paludis/util/active_object_ptr.cc
new file mode 100644
index 0000000..55ba9cd
--- /dev/null
+++ b/paludis/util/active_object_ptr.cc
@@ -0,0 +1,21 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/util/active_object_ptr.hh>
+
diff --git a/paludis/util/active_object_ptr.hh b/paludis/util/active_object_ptr.hh
new file mode 100644
index 0000000..b8a65ca
--- /dev/null
+++ b/paludis/util/active_object_ptr.hh
@@ -0,0 +1,93 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UTIL_ACTIVE_OBJECT_PTR_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_ACTIVE_OBJECT_PTR_HH 1
+
+#include <paludis/util/active_object_ptr-fwd.hh>
+#include <paludis/util/mutex.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <tr1/memory>
+
+namespace paludis
+{
+ template <typename T_>
+ class ActiveObjectPtr
+ {
+ private:
+ T_ _ptr;
+ std::tr1::shared_ptr<Mutex> _mutex;
+
+ class Deref
+ {
+ private:
+ const ActiveObjectPtr * _ptr;
+ std::tr1::shared_ptr<Lock> _lock;
+
+ public:
+ Deref(const ActiveObjectPtr * p) :
+ _ptr(p),
+ _lock(make_shared_ptr(new Lock(*p->_mutex)))
+ {
+ }
+
+ T_ operator-> () const
+ {
+ return _ptr->_ptr;
+ }
+ };
+
+ friend class Deref;
+
+ public:
+ ActiveObjectPtr(const T_ & t) :
+ _ptr(t),
+ _mutex(new Mutex)
+ {
+ }
+
+ ActiveObjectPtr(const ActiveObjectPtr & other) :
+ _ptr(other._ptr),
+ _mutex(other._mutex)
+ {
+ }
+
+ ~ActiveObjectPtr()
+ {
+ }
+
+ ActiveObjectPtr &
+ operator= (const ActiveObjectPtr & other)
+ {
+ if (this != &other)
+ {
+ _ptr = other._ptr;
+ _mutex = other._mutex;
+ }
+ return *this;
+ }
+
+ Deref operator-> () const
+ {
+ return Deref(this);
+ }
+ };
+}
+
+#endif
diff --git a/paludis/util/active_object_ptr_TEST.cc b/paludis/util/active_object_ptr_TEST.cc
new file mode 100644
index 0000000..c88dd89
--- /dev/null
+++ b/paludis/util/active_object_ptr_TEST.cc
@@ -0,0 +1,51 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/util/active_object_ptr.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+#include <test/test_concepts.hh>
+
+using namespace paludis;
+using namespace test;
+
+namespace test_cases
+{
+ typedef ActiveObjectPtr<int *> ActiveIntPtr;
+ TESTCASE_SEMIREGULAR(ActiveIntPtr, ActiveIntPtr(new int(10)));
+
+ typedef ActiveObjectPtr<std::tr1::shared_ptr<int> > ActiveSharedIntPtr;
+ TESTCASE_SEMIREGULAR(ActiveSharedIntPtr, ActiveSharedIntPtr(make_shared_ptr(new int(10))));
+
+ struct TestDereference : TestCase
+ {
+ TestDereference() : TestCase("dereference") { }
+
+ void run()
+ {
+ ActiveObjectPtr<std::string *> p(new std::string("monkey"));
+ TEST_CHECK_EQUAL(p->length(), 6u);
+
+ ActiveObjectPtr<std::tr1::shared_ptr<std::string> > q(
+ make_shared_ptr(new std::string("chimp")));
+ TEST_CHECK_EQUAL(q->length(), 5u);
+ }
+ } test_dereference;
+}
+
diff --git a/paludis/util/deferred_construction_ptr-fwd.hh b/paludis/util/deferred_construction_ptr-fwd.hh
new file mode 100644
index 0000000..a84e7e6
--- /dev/null
+++ b/paludis/util/deferred_construction_ptr-fwd.hh
@@ -0,0 +1,29 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UTIL_DEFERRED_CONSTRUCTION_PTR_FWD_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_DEFERRED_CONSTRUCTION_PTR_FWD_HH 1
+
+namespace paludis
+{
+ template <typename>
+ struct DeferredConstructionPtr;
+}
+
+#endif
diff --git a/paludis/util/deferred_construction_ptr.cc b/paludis/util/deferred_construction_ptr.cc
new file mode 100644
index 0000000..187ae70
--- /dev/null
+++ b/paludis/util/deferred_construction_ptr.cc
@@ -0,0 +1,21 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/util/deferred_construction_ptr.hh>
+
diff --git a/paludis/util/deferred_construction_ptr.hh b/paludis/util/deferred_construction_ptr.hh
new file mode 100644
index 0000000..f84b909
--- /dev/null
+++ b/paludis/util/deferred_construction_ptr.hh
@@ -0,0 +1,76 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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_UTIL_DEFERRED_CONSTRUCTION_PTR_HH
+#define PALUDIS_GUARD_PALUDIS_UTIL_DEFERRED_CONSTRUCTION_PTR_HH 1
+
+#include <paludis/util/deferred_construction_ptr-fwd.hh>
+#include <tr1/functional>
+
+namespace paludis
+{
+ template <typename T_>
+ class DeferredConstructionPtr
+ {
+ private:
+ mutable T_ _ptr;
+ std::tr1::function<T_ ()> _f;
+ mutable bool _done;
+
+ public:
+ DeferredConstructionPtr(const std::tr1::function<T_ ()> & f) :
+ _ptr(),
+ _f(f),
+ _done(false)
+ {
+ }
+
+ DeferredConstructionPtr(const DeferredConstructionPtr & other) :
+ _ptr(other._ptr),
+ _f(other._f),
+ _done(other._done)
+ {
+ }
+
+ DeferredConstructionPtr &
+ operator= (const DeferredConstructionPtr & other)
+ {
+ if (this != &other)
+ {
+ _ptr = other._ptr;
+ _f = other._f;
+ _done = other._done;
+ }
+ return *this;
+ }
+
+ T_ operator-> () const
+ {
+ if (! _done)
+ {
+ _ptr = _f();
+ _done = true;
+ }
+
+ return _ptr;
+ }
+ };
+}
+
+#endif
diff --git a/paludis/util/deferred_construction_ptr_TEST.cc b/paludis/util/deferred_construction_ptr_TEST.cc
new file mode 100644
index 0000000..f04f976
--- /dev/null
+++ b/paludis/util/deferred_construction_ptr_TEST.cc
@@ -0,0 +1,90 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Ciaran McCreesh
+ *
+ * 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/util/deferred_construction_ptr.hh>
+#include <paludis/util/active_object_ptr.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+#include <test/test_concepts.hh>
+
+using namespace paludis;
+using namespace test;
+
+namespace
+{
+ int * make_ten()
+ {
+ return new int(10);
+ }
+
+ std::tr1::shared_ptr<int> make_ten_shared()
+ {
+ return make_shared_ptr(new int(10));
+ }
+
+ std::string * make_monkey()
+ {
+ return new std::string("monkey");
+ }
+
+ std::tr1::shared_ptr<std::string> make_chimp_shared()
+ {
+ return make_shared_ptr(new std::string("chimp"));
+ }
+}
+
+namespace test_cases
+{
+ typedef DeferredConstructionPtr<int *> DeferredIntPtr;
+ TESTCASE_SEMIREGULAR(DeferredIntPtr, DeferredIntPtr(make_ten));
+
+ typedef DeferredConstructionPtr<std::tr1::shared_ptr<int> > DeferredSharedIntPtr;
+ TESTCASE_SEMIREGULAR(DeferredSharedIntPtr, DeferredSharedIntPtr(make_ten_shared));
+
+ struct TestDereference : TestCase
+ {
+ TestDereference() : TestCase("dereference") { }
+
+ void run()
+ {
+ DeferredConstructionPtr<std::string *> p(make_monkey);
+ TEST_CHECK_EQUAL(p->length(), 6u);
+
+ DeferredConstructionPtr<std::tr1::shared_ptr<std::string> > q(make_chimp_shared);
+ TEST_CHECK_EQUAL(q->length(), 5u);
+ }
+ } test_dereference;
+
+ struct TestDeferredActive : TestCase
+ {
+ TestDeferredActive() : TestCase("dereferred active") { }
+
+ void run()
+ {
+ ActiveObjectPtr<DeferredConstructionPtr<std::string *> > p((
+ DeferredConstructionPtr<std::string *>(make_monkey)));
+ TEST_CHECK_EQUAL(p->length(), 6u);
+
+ ActiveObjectPtr<DeferredConstructionPtr<std::tr1::shared_ptr<std::string> > > q((
+ DeferredConstructionPtr<std::tr1::shared_ptr<std::string> >(make_chimp_shared)));
+ TEST_CHECK_EQUAL(q->length(), 5u);
+ }
+ } test_dereferred_active;
+}
+
diff --git a/paludis/util/files.m4 b/paludis/util/files.m4
index 743568c..65ea02c 100644
--- a/paludis/util/files.m4
+++ b/paludis/util/files.m4
@@ -9,6 +9,7 @@ dnl `test', `impl', `testscript'. Note that there isn't much error checking done
dnl on this file at present...
add(`action_queue', `hh', `cc', `test')
+add(`active_object_ptr', `hh', `cc', `fwd', `test')
add(`attributes', `hh')
add(`byte_swap', `hh', `test')
add(`config_file', `hh', `cc', `fwd', `se', `test', `testscript')
@@ -18,6 +19,7 @@ add(`cookie', `hh', `cc')
add(`create_iterator', `hh', `fwd', `impl', `test')
add(`damerau_levenshtein', `hh', `cc', `test')
add(`destringify', `hh', `cc', `test')
+add(`deferred_construction_ptr', `hh', `cc', `fwd', `test')
add(`dir_iterator', `hh', `cc', `fwd', `se', `test', `testscript')
add(`exception', `hh', `cc')
add(`fast_unique_copy', `hh', `test')
diff --git a/paludis/util/keys.hh b/paludis/util/keys.hh
index b388438..9b77d2e 100644
--- a/paludis/util/keys.hh
+++ b/paludis/util/keys.hh
@@ -176,6 +176,11 @@ namespace paludis
typedef kc::Key<147> item;
typedef kc::Key<148> on_use_under_any;
typedef kc::Key<149> on_annotations;
+ typedef kc::Key<150> sync;
+ typedef kc::Key<151> sync_options;
+ typedef kc::Key<152> owning_repository;
+ typedef kc::Key<153> mask;
+ typedef kc::Key<154> repository;
}
}