aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-10-06 20:54:35 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-10-06 20:54:35 +0100
commitef08a256e4c922d7dbb3b34ee9e5e0dbb52088af (patch)
tree809bb2a04ca8e23cd4694890728030abe213a30a
parent785dc034032bfb54aefb8de00fe65b923fe3ba08 (diff)
downloadpaludis-ef08a256e4c922d7dbb3b34ee9e5e0dbb52088af.tar.gz
paludis-ef08a256e4c922d7dbb3b34ee9e5e0dbb52088af.tar.xz
Add UnwrittenRepository.
Fixes: ticket:640
-rw-r--r--configure.ac8
-rw-r--r--paludis/repositories/unwritten/Makefile.am92
-rw-r--r--paludis/repositories/unwritten/registration.cc53
-rw-r--r--paludis/repositories/unwritten/unwritten_id.cc302
-rw-r--r--paludis/repositories/unwritten/unwritten_id.hh127
-rw-r--r--paludis/repositories/unwritten/unwritten_mask.cc42
-rw-r--r--paludis/repositories/unwritten/unwritten_mask.hh40
-rw-r--r--paludis/repositories/unwritten/unwritten_repository.cc354
-rw-r--r--paludis/repositories/unwritten/unwritten_repository.hh120
-rw-r--r--paludis/repositories/unwritten/unwritten_repository_TEST.cc96
-rwxr-xr-xpaludis/repositories/unwritten/unwritten_repository_TEST_cleanup.sh9
-rwxr-xr-xpaludis/repositories/unwritten/unwritten_repository_TEST_setup.sh32
-rw-r--r--paludis/repositories/unwritten/unwritten_repository_file.cc332
-rw-r--r--paludis/repositories/unwritten/unwritten_repository_file.hh86
-rw-r--r--paludis/repositories/unwritten/unwritten_repository_store.cc201
-rw-r--r--paludis/repositories/unwritten/unwritten_repository_store.hh76
16 files changed, 1967 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index f372f2a..39bc3a9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1182,14 +1182,14 @@ AC_SUBST([VIM_INSTALL_DIR])
dnl }}}
dnl {{{ repositories
-ALL_REPOSITORIES="cran e fake gems unavailable unpackaged virtuals"
-DEFAULT_REPOSITORIES="e fake unavailable unpackaged virtuals"
+ALL_REPOSITORIES="cran e fake gems unavailable unpackaged unwritten virtuals"
+DEFAULT_REPOSITORIES="e fake unavailable unpackaged unwritten virtuals"
AC_MSG_CHECKING([which repositories to build...])
AC_ARG_WITH([repositories],
[ --with-repositories=foo,bar,...
Build the specified repositories:
all All available repositories
- default Equivalent to e,fake,virtuals
+ default Equivalent to e,fake,unavailable,unpackaged,unwritten,virtuals
cran The Comprehensive R Archive Network (unusable)
e Ebuild, Ebin, Exheres, VDB etc
@@ -1197,6 +1197,7 @@ AC_ARG_WITH([repositories],
gems Ruby gems (unusable)
unavailable Unavailable
unpackaged Unpackaged (for importare)
+ unwritten Unwritten
virtuals Old style Gentoo virtuals],
[repositories="`echo $with_repositories | tr ',' ' '`"],
[repositories="$DEFAULT_REPOSITORIES"])
@@ -1473,6 +1474,7 @@ AC_OUTPUT(
paludis/repositories/gems/Makefile
paludis/repositories/unavailable/Makefile
paludis/repositories/unpackaged/Makefile
+ paludis/repositories/unwritten/Makefile
paludis/repositories/virtuals/Makefile
paludis/selinux/Makefile
paludis/syncers/Makefile
diff --git a/paludis/repositories/unwritten/Makefile.am b/paludis/repositories/unwritten/Makefile.am
new file mode 100644
index 0000000..16a3c5b
--- /dev/null
+++ b/paludis/repositories/unwritten/Makefile.am
@@ -0,0 +1,92 @@
+SUBDIRS = .
+CLEANFILES = *~ gmon.out *.gcov *.gcno *.gcda *.loT
+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 = libpaludisunwrittenrepository_@PALUDIS_PC_SLOT@.la
+
+paludis_repositories_unwritten_includedir = $(includedir)/paludis-$(PALUDIS_PC_SLOT)/paludis/repositories/unwritten/
+libpaludisunwrittenrepository_@PALUDIS_PC_SLOT@_la_LDFLAGS = -version-info @VERSION_LIB_CURRENT@:@VERSION_LIB_REVISION@:0
+
+paludis_repositories_unwritten_include_HEADERS = \
+ unwritten_repository.hh unwritten_repository.hh \
+ unwritten_id.hh \
+ unwritten_mask.hh \
+ unwritten_repository_store.hh \
+ unwritten_repository_file.hh unwritten_repository_file.hh
+
+libpaludisunwrittenrepository_@PALUDIS_PC_SLOT@_la_SOURCES = \
+ unwritten_repository.cc \
+ unwritten_id.cc \
+ unwritten_mask.cc \
+ unwritten_repository_store.cc \
+ unwritten_repository_file.cc \
+ registration.cc \
+ $(paludis_repositories_unwritten_include_HEADERS)
+
+libpaludisunwrittenrepository_@PALUDIS_PC_SLOT@_la_LIBADD = \
+ $(top_builddir)/paludis/libpaludis_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/util/libpaludisutil_@PALUDIS_PC_SLOT@.la \
+ $(DYNAMIC_LD_LIBS)
+
+unwritten_repository_TEST_SOURCES = unwritten_repository_TEST.cc
+
+unwritten_repository_TEST_LDADD = \
+ libpaludisunwrittenrepository_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/util/libpaludisutil_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/paludis/libpaludis_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/paludis/environments/test/libpaludistestenvironment_@PALUDIS_PC_SLOT@.la \
+ $(top_builddir)/test/libtest.a \
+ $(DYNAMIC_LD_LIBS)
+
+EXTRA_DIST = \
+ unwritten_repository_TEST.cc \
+ unwritten_repository_TEST_setup.sh \
+ unwritten_repository_TEST_cleanup.sh
+
+check_SCRIPTS = \
+ unwritten_repository_TEST_setup.sh \
+ unwritten_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_OPTIONS="" \
+ 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 = \
+ unwritten_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/unwritten/registration.cc b/paludis/repositories/unwritten/registration.cc
new file mode 100644
index 0000000..fc5fa55
--- /dev/null
+++ b/paludis/repositories/unwritten/registration.cc
@@ -0,0 +1,53 @@
+/* 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_factory.hh>
+#include <paludis/repositories/unwritten/unwritten_repository.hh>
+#include <paludis/util/set.hh>
+#include <paludis/util/destringify.hh>
+
+using namespace paludis;
+using namespace paludis::unwritten_repository;
+
+namespace
+{
+ int generic_importance(const Environment * const, const std::tr1::function<std::string (const std::string &)> & f)
+ {
+ if (! f("importance").empty())
+ return destringify<int>(f("importance"));
+ else
+ return 1;
+ }
+}
+
+extern "C" void paludis_initialise_repository_so(RepositoryFactory * const factory) PALUDIS_VISIBLE;
+
+void paludis_initialise_repository_so(RepositoryFactory * const factory)
+{
+ std::tr1::shared_ptr<Set<std::string> > unwritten_formats(new Set<std::string>);
+ unwritten_formats->insert("unwritten");
+
+ factory->add_repository_format(unwritten_formats,
+ &UnwrittenRepository::repository_factory_name,
+ &generic_importance,
+ &UnwrittenRepository::repository_factory_create,
+ &UnwrittenRepository::repository_factory_dependencies
+ );
+}
+
diff --git a/paludis/repositories/unwritten/unwritten_id.cc b/paludis/repositories/unwritten/unwritten_id.cc
new file mode 100644
index 0000000..bac29c6
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_id.cc
@@ -0,0 +1,302 @@
+/* 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/unwritten/unwritten_id.hh>
+#include <paludis/repositories/unwritten/unwritten_repository.hh>
+#include <paludis/util/private_implementation_pattern-impl.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::unwritten_repository;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<UnwrittenID>
+ {
+ const QualifiedPackageName name;
+ const VersionSpec version;
+ const SlotName slot;
+ const UnwrittenRepository * const repo;
+
+ const std::tr1::shared_ptr<const MetadataValueKey<std::string> > description_key;
+ const std::tr1::shared_ptr<const MetadataValueKey<std::string> > added_by_key;
+ const std::tr1::shared_ptr<const MetadataValueKey<std::string> > comment_key;
+ const std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> > homepage_key;
+ const std::tr1::shared_ptr<const MetadataCollectionKey<Sequence<std::string> > > bug_ids_key;
+ const std::tr1::shared_ptr<const MetadataCollectionKey<Sequence<std::string> > > remote_ids_key;
+ const std::tr1::shared_ptr<const Mask> mask;
+
+ Implementation(
+ const UnwrittenIDParams & e) :
+ name(e.name()),
+ version(e.version()),
+ slot(e.slot()),
+ repo(e.repository()),
+ description_key(e.description()),
+ added_by_key(e.added_by()),
+ comment_key(e.comment()),
+ homepage_key(e.homepage()),
+ bug_ids_key(e.bug_ids()),
+ remote_ids_key(e.remote_ids()),
+ mask(e.mask())
+ {
+ }
+ };
+}
+
+UnwrittenID::UnwrittenID(const UnwrittenIDParams & entry) :
+ PrivateImplementationPattern<UnwrittenID>(new Implementation<UnwrittenID>(entry)),
+ _imp(PrivateImplementationPattern<UnwrittenID>::_imp)
+{
+ if (_imp->description_key)
+ add_metadata_key(_imp->description_key);
+ if (_imp->homepage_key)
+ add_metadata_key(_imp->homepage_key);
+ if (_imp->added_by_key)
+ add_metadata_key(_imp->added_by_key);
+ if (_imp->comment_key)
+ add_metadata_key(_imp->comment_key);
+ if (_imp->bug_ids_key)
+ add_metadata_key(_imp->bug_ids_key);
+ if (_imp->remote_ids_key)
+ add_metadata_key(_imp->remote_ids_key);
+ add_mask(_imp->mask);
+}
+
+UnwrittenID::~UnwrittenID()
+{
+}
+
+void
+UnwrittenID::need_keys_added() const
+{
+}
+
+void
+UnwrittenID::need_masks_added() const
+{
+}
+
+const std::string
+UnwrittenID::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());
+
+ case idcf_no_version:
+ return stringify(_imp->name) + ":" + stringify(_imp->slot) +
+ "::" + stringify(_imp->repo->name());
+
+ case idcf_version:
+ return stringify(_imp->version);
+
+ case last_idcf:
+ break;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad PackageIDCanonicalForm");
+}
+
+const QualifiedPackageName
+UnwrittenID::name() const
+{
+ return _imp->name;
+}
+
+const VersionSpec
+UnwrittenID::version() const
+{
+ return _imp->version;
+}
+
+const SlotName
+UnwrittenID::slot() const
+{
+ return _imp->slot;
+}
+
+const std::tr1::shared_ptr<const Repository>
+UnwrittenID::repository() const
+{
+ return _imp->repo->shared_from_this();
+}
+
+bool
+UnwrittenID::supports_action(const SupportsActionTestBase & a) const
+{
+ return visitor_cast<const SupportsActionTest<InstallAction> >(a);
+}
+
+void
+UnwrittenID::perform_action(Action & a) const
+{
+ throw UnsupportedActionError(*this, a);
+}
+
+std::tr1::shared_ptr<const Set<std::string> >
+UnwrittenID::breaks_portage() const
+{
+ return make_shared_ptr(new Set<std::string>);
+}
+
+bool
+UnwrittenID::arbitrary_less_than_comparison(const PackageID & other) const
+{
+ if (slot() < other.slot())
+ return true;
+
+ return false;
+}
+
+std::size_t
+UnwrittenID::extra_hash_value() const
+{
+ return Hash<SlotName>()(slot());
+}
+
+const std::tr1::shared_ptr<const MetadataCollectionKey<PackageIDSequence> >
+UnwrittenID::contains_key() const
+{
+ return std::tr1::shared_ptr<const MetadataCollectionKey<PackageIDSequence> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
+UnwrittenID::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> >
+UnwrittenID::fs_location_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<bool> >
+UnwrittenID::transient_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<bool> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
+UnwrittenID::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> >
+UnwrittenID::keywords_key() const
+{
+ return std::tr1::shared_ptr<const MetadataCollectionKey<KeywordNameSet> >();
+}
+
+const std::tr1::shared_ptr<const MetadataCollectionKey<IUseFlagSet> >
+UnwrittenID::iuse_key() const
+{
+ return std::tr1::shared_ptr<const MetadataCollectionKey<IUseFlagSet> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> >
+UnwrittenID::provide_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+UnwrittenID::build_dependencies_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+UnwrittenID::run_dependencies_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+UnwrittenID::post_dependencies_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+UnwrittenID::suggested_dependencies_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
+UnwrittenID::short_description_key() const
+{
+ return _imp->description_key;
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
+UnwrittenID::long_description_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<std::string> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> >
+UnwrittenID::fetches_key() const
+{
+ return std::tr1::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> >();
+}
+
+const std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> >
+UnwrittenID::homepage_key() const
+{
+ return _imp->homepage_key;
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Contents> > >
+UnwrittenID::contents_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Contents> > >();
+}
+
+const std::tr1::shared_ptr<const MetadataTimeKey>
+UnwrittenID::installed_time_key() const
+{
+ return std::tr1::shared_ptr<const MetadataTimeKey>();
+}
+
+const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > >
+UnwrittenID::from_repositories_key() const
+{
+ return std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > >();
+}
+
+
+template class PrivateImplementationPattern<UnwrittenID>;
+
diff --git a/paludis/repositories/unwritten/unwritten_id.hh b/paludis/repositories/unwritten/unwritten_id.hh
new file mode 100644
index 0000000..ff1bb31
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_id.hh
@@ -0,0 +1,127 @@
+/* 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_UNWRITTEN_UNWRITTEN_ID_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNWRITTEN_UNWRITTEN_ID_HH 1
+
+#include <paludis/util/named_value.hh>
+#include <paludis/package_id.hh>
+#include <paludis/name.hh>
+#include <paludis/version_spec.hh>
+
+namespace paludis
+{
+ namespace n
+ {
+ struct added_by;
+ struct bug_ids;
+ struct comment;
+ struct description;
+ struct homepage;
+ struct mask;
+ struct name;
+ struct remote_ids;
+ struct repository;
+ struct slot;
+ struct version;
+ }
+
+ namespace unwritten_repository
+ {
+ struct UnwrittenRepository;
+
+ struct UnwrittenIDParams
+ {
+ NamedValue<n::added_by, std::tr1::shared_ptr<const MetadataValueKey<std::string> > > added_by;
+ NamedValue<n::bug_ids, std::tr1::shared_ptr<const MetadataCollectionKey<Sequence<std::string> > > > bug_ids;
+ NamedValue<n::comment, std::tr1::shared_ptr<const MetadataValueKey<std::string> > > comment;
+ NamedValue<n::description, std::tr1::shared_ptr<const MetadataValueKey<std::string> > > description;
+ NamedValue<n::homepage, std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> > > homepage;
+ NamedValue<n::mask, std::tr1::shared_ptr<const Mask> > mask;
+ NamedValue<n::name, QualifiedPackageName> name;
+ NamedValue<n::remote_ids, std::tr1::shared_ptr<const MetadataCollectionKey<Sequence<std::string> > > > remote_ids;
+ NamedValue<n::repository, const UnwrittenRepository *> repository;
+ NamedValue<n::slot, SlotName> slot;
+ NamedValue<n::version, VersionSpec> version;
+ };
+
+ class PALUDIS_VISIBLE UnwrittenID :
+ public PackageID,
+ private PrivateImplementationPattern<UnwrittenID>
+ {
+ private:
+ PrivateImplementationPattern<UnwrittenID>::ImpPtr & _imp;
+
+ protected:
+ void need_keys_added() const;
+ void need_masks_added() const;
+
+ public:
+ UnwrittenID(const UnwrittenIDParams &);
+ ~UnwrittenID();
+
+ 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<FSEntry> > fs_location_key() const;
+ const std::tr1::shared_ptr<const MetadataValueKey<bool> > transient_key() const;
+ const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > from_repositories_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/unwritten/unwritten_mask.cc b/paludis/repositories/unwritten/unwritten_mask.cc
new file mode 100644
index 0000000..ed8ca34
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_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/unwritten/unwritten_mask.hh>
+
+using namespace paludis;
+using namespace paludis::unwritten_repository;
+
+char
+UnwrittenMask::key() const
+{
+ return 'X';
+}
+
+const std::string
+UnwrittenMask::description() const
+{
+ return "unwritten";
+}
+
+const std::string
+UnwrittenMask::explanation() const
+{
+ return "Package has not been written yet";
+}
+
diff --git a/paludis/repositories/unwritten/unwritten_mask.hh b/paludis/repositories/unwritten/unwritten_mask.hh
new file mode 100644
index 0000000..fc69823
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_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_UNWRITTEN_UNWRITTEN_MASK_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNWRITTEN_UNWRITTEN_MASK_HH 1
+
+#include <paludis/mask.hh>
+
+namespace paludis
+{
+ namespace unwritten_repository
+ {
+ class UnwrittenMask :
+ 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/unwritten/unwritten_repository.cc b/paludis/repositories/unwritten/unwritten_repository.cc
new file mode 100644
index 0000000..468a136
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_repository.cc
@@ -0,0 +1,354 @@
+/* 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/unwritten/unwritten_repository.hh>
+#include <paludis/repositories/unwritten/unwritten_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/util/make_named_values.hh>
+#include <paludis/literal_metadata_key.hh>
+#include <paludis/action.hh>
+#include <paludis/syncer.hh>
+#include <list>
+
+using namespace paludis;
+using namespace paludis::unwritten_repository;
+
+namespace
+{
+ std::tr1::shared_ptr<UnwrittenRepositoryStore>
+ make_store(const UnwrittenRepository * const repo, const UnwrittenRepositoryParams & p)
+ {
+ return make_shared_ptr(new UnwrittenRepositoryStore(p.environment(), repo, p.location()));
+ }
+}
+
+namespace paludis
+{
+ template <>
+ struct Implementation<UnwrittenRepository>
+ {
+ const UnwrittenRepositoryParams 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<UnwrittenRepositoryStore> > > store;
+
+ Implementation(const UnwrittenRepository * const repo, const UnwrittenRepositoryParams & p) :
+ params(p),
+ format_key(new LiteralMetadataValueKey<std::string> ("format", "format",
+ mkt_significant, "unwritten")),
+ location_key(new LiteralMetadataValueKey<FSEntry> ("location", "location",
+ mkt_significant, params.location())),
+ sync_key(new LiteralMetadataValueKey<std::string> (
+ "sync", "sync", mkt_normal, params.sync())),
+ sync_options_key(new LiteralMetadataValueKey<std::string> (
+ "sync_options", "sync_options", mkt_normal, params.sync_options())),
+ store(DeferredConstructionPtr<std::tr1::shared_ptr<UnwrittenRepositoryStore> > (
+ std::tr1::bind(&make_store, repo, std::tr1::cref(params))))
+ {
+ }
+ };
+}
+
+UnwrittenRepositoryConfigurationError::UnwrittenRepositoryConfigurationError(const std::string & s) throw () :
+ ConfigurationError("UnwrittenRepository configuration error: " + s)
+{
+}
+
+UnwrittenRepository::UnwrittenRepository(const UnwrittenRepositoryParams & p) :
+ PrivateImplementationPattern<UnwrittenRepository>(new Implementation<UnwrittenRepository>(this, p)),
+ Repository(
+ p.environment(),
+ p.name(),
+ make_named_values<RepositoryCapabilities>(
+ value_for<n::destination_interface>(static_cast<RepositoryDestinationInterface *>(0)),
+ value_for<n::e_interface>(static_cast<RepositoryEInterface *>(0)),
+ value_for<n::environment_variable_interface>(static_cast<RepositoryEnvironmentVariableInterface *>(0)),
+ value_for<n::hook_interface>(static_cast<RepositoryHookInterface *>(0)),
+ value_for<n::make_virtuals_interface>(static_cast<RepositoryMakeVirtualsInterface *>(0)),
+ value_for<n::manifest_interface>(static_cast<RepositoryManifestInterface *>(0)),
+ value_for<n::mirrors_interface>(static_cast<RepositoryMirrorsInterface *>(0)),
+ value_for<n::provides_interface>(static_cast<RepositoryProvidesInterface *>(0)),
+ value_for<n::qa_interface>(static_cast<RepositoryQAInterface *>(0)),
+ value_for<n::sets_interface>(static_cast<RepositorySetsInterface *>(0)),
+ value_for<n::syncable_interface>(this),
+ value_for<n::use_interface>(static_cast<RepositoryUseInterface *>(0)),
+ value_for<n::virtuals_interface>(static_cast<RepositoryVirtualsInterface *>(0))
+ )),
+ _imp(PrivateImplementationPattern<UnwrittenRepository>::_imp)
+{
+ _add_metadata_keys();
+}
+
+UnwrittenRepository::~UnwrittenRepository()
+{
+}
+
+bool
+UnwrittenRepository::can_be_favourite_repository() const
+{
+ return false;
+}
+
+void
+UnwrittenRepository::_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
+UnwrittenRepository::need_keys_added() const
+{
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
+UnwrittenRepository::format_key() const
+{
+ return _imp->format_key;
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >
+UnwrittenRepository::location_key() const
+{
+ return _imp->location_key;
+}
+
+const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >
+UnwrittenRepository::installed_root_key() const
+{
+ return std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >();
+}
+
+void
+UnwrittenRepository::invalidate()
+{
+ _imp.reset(new Implementation<UnwrittenRepository>(this, _imp->params));
+ _add_metadata_keys();
+}
+
+void
+UnwrittenRepository::invalidate_masks()
+{
+}
+
+bool
+UnwrittenRepository::has_category_named(const CategoryNamePart & c) const
+{
+ return _imp->store->has_category_named(c);
+}
+
+bool
+UnwrittenRepository::has_package_named(const QualifiedPackageName & q) const
+{
+ return _imp->store->has_package_named(q);
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnwrittenRepository::category_names() const
+{
+ return _imp->store->category_names();
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnwrittenRepository::unimportant_category_names() const
+{
+ return _imp->store->unimportant_category_names();
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnwrittenRepository::category_names_containing_package(const PackageNamePart & p) const
+{
+ return Repository::category_names_containing_package(p);
+}
+
+std::tr1::shared_ptr<const QualifiedPackageNameSet>
+UnwrittenRepository::package_names(const CategoryNamePart & c) const
+{
+ return _imp->store->package_names(c);
+}
+
+std::tr1::shared_ptr<const PackageIDSequence>
+UnwrittenRepository::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
+UnwrittenRepository::some_ids_might_support_action(const SupportsActionTestBase & a) const
+{
+ SupportsActionQuery q;
+ a.accept(q);
+ return q.result;
+}
+
+bool
+UnwrittenRepository::sync() const
+{
+ Context context("When syncing repository '" + stringify(name()) + "':");
+
+ if (_imp->params.sync().empty())
+ return false;
+
+ std::list<std::string> sync_list;
+ tokenise_whitespace(_imp->params.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(make_named_values<SyncerParams>(
+ value_for<n::environment>(_imp->params.environment()),
+ value_for<n::local>(stringify(_imp->params.location())),
+ value_for<n::remote>(*s)
+ ));
+ SyncOptions opts(make_named_values<SyncOptions>(
+ value_for<n::filter_file>(FSEntry("/dev/null")),
+ value_for<n::options>(_imp->params.sync_options()),
+ value_for<n::output_prefix>("sync " + stringify(name()) + "> ")
+ ));
+ try
+ {
+ syncer.sync(opts);
+ }
+ catch (const SyncFailedError &)
+ {
+ continue;
+ }
+
+ ok = true;
+ break;
+ }
+
+ if (! ok)
+ throw SyncFailedError(stringify(_imp->params.location()), _imp->params.sync());
+
+ return true;
+}
+
+std::tr1::shared_ptr<Repository>
+UnwrittenRepository::repository_factory_create(
+ Environment * const env,
+ const std::tr1::function<std::string (const std::string &)> & f)
+{
+ Context context("When making unwritten repository from repo_file '" + f("repo_file") + "':");
+
+ std::string name_str(f("name"));
+ if (name_str.empty())
+ name_str = "unwritten";
+
+ std::string location(f("location"));
+ if (location.empty())
+ throw UnwrittenRepositoryConfigurationError("Key 'location' not specified or empty");
+
+ std::string sync(f("sync"));
+
+ std::string sync_options(f("sync_options"));
+
+ return std::tr1::shared_ptr<UnwrittenRepository>(new UnwrittenRepository(
+ make_named_values<UnwrittenRepositoryParams>(
+ value_for<n::environment>(env),
+ value_for<n::location>(location),
+ value_for<n::name>(RepositoryName(name_str)),
+ value_for<n::sync>(sync),
+ value_for<n::sync_options>(sync_options)
+ )));
+}
+
+RepositoryName
+UnwrittenRepository::repository_factory_name(
+ const Environment * const,
+ const std::tr1::function<std::string (const std::string &)> & f)
+{
+ if (f("name").empty())
+ return RepositoryName("unwritten");
+ else
+ return RepositoryName(f("name"));
+}
+
+std::tr1::shared_ptr<const RepositoryNameSet>
+UnwrittenRepository::repository_factory_dependencies(
+ const Environment * const,
+ const std::tr1::function<std::string (const std::string &)> &)
+{
+ return make_shared_ptr(new RepositoryNameSet);
+}
+
+template class PrivateImplementationPattern<unwritten_repository::UnwrittenRepository>;
+
+
diff --git a/paludis/repositories/unwritten/unwritten_repository.hh b/paludis/repositories/unwritten/unwritten_repository.hh
new file mode 100644
index 0000000..e9da71b
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_repository.hh
@@ -0,0 +1,120 @@
+/* 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_UNWRITTEN_UNWRITTEN_REPOSITORY_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNWRITTEN_UNWRITTEN_REPOSITORY_HH 1
+
+#include <paludis/repository.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/attributes.hh>
+
+namespace paludis
+{
+ namespace n
+ {
+ struct environment;
+ struct location;
+ struct name;
+ struct sync;
+ struct sync_options;
+ }
+
+ namespace unwritten_repository
+ {
+ class PALUDIS_VISIBLE UnwrittenRepositoryConfigurationError :
+ public ConfigurationError
+ {
+ public:
+ UnwrittenRepositoryConfigurationError(const std::string &) throw ();
+ };
+
+ struct UnwrittenRepositoryParams
+ {
+ NamedValue<n::environment, Environment *> environment;
+ NamedValue<n::location, FSEntry> location;
+ NamedValue<n::name, RepositoryName> name;
+ NamedValue<n::sync, std::string> sync;
+ NamedValue<n::sync_options, std::string> sync_options;
+ };
+
+ class PALUDIS_VISIBLE UnwrittenRepository :
+ private PrivateImplementationPattern<UnwrittenRepository>,
+ public Repository,
+ public RepositorySyncableInterface,
+ public std::tr1::enable_shared_from_this<UnwrittenRepository>
+ {
+ private:
+ PrivateImplementationPattern<UnwrittenRepository>::ImpPtr & _imp;
+
+ void _add_metadata_keys();
+
+ protected:
+ virtual void need_keys_added() const;
+
+ public:
+ UnwrittenRepository(const UnwrittenRepositoryParams &);
+ ~UnwrittenRepository();
+
+ virtual bool can_be_favourite_repository() const;
+
+ virtual const std::tr1::shared_ptr<const MetadataValueKey<std::string> > format_key() const;
+ virtual const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> > location_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;
+
+ ///\name RepositoryFactory functions
+ ///\{
+
+ static RepositoryName repository_factory_name(
+ const Environment * const env,
+ const std::tr1::function<std::string (const std::string &)> &);
+
+ static std::tr1::shared_ptr<Repository> repository_factory_create(
+ Environment * const env,
+ const std::tr1::function<std::string (const std::string &)> &);
+
+ static std::tr1::shared_ptr<const RepositoryNameSet> repository_factory_dependencies(
+ const Environment * const env,
+ const std::tr1::function<std::string (const std::string &)> &);
+
+ ///\}
+ };
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<unwritten_repository::UnwrittenRepository>;
+#endif
+}
+
+#endif
diff --git a/paludis/repositories/unwritten/unwritten_repository_TEST.cc b/paludis/repositories/unwritten/unwritten_repository_TEST.cc
new file mode 100644
index 0000000..149d126
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_repository_TEST.cc
@@ -0,0 +1,96 @@
+/* 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/unwritten/unwritten_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/util/make_named_values.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::unwritten_repository;
+using namespace test;
+
+namespace test_cases
+{
+ struct UnwrittenRepositoryCreationTest : TestCase
+ {
+ UnwrittenRepositoryCreationTest() : TestCase("creation") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ std::tr1::shared_ptr<UnwrittenRepository> repo(new UnwrittenRepository(
+ make_named_values<UnwrittenRepositoryParams>(
+ value_for<n::environment>(&env),
+ value_for<n::location>(FSEntry::cwd() / "unwritten_repository_TEST_dir" / "repo1"),
+ value_for<n::name>(RepositoryName("unwritten")),
+ value_for<n::sync>(""),
+ value_for<n::sync_options>("")
+ )));
+ env.package_database()->add_repository(1, repo);
+ TEST_CHECK_STRINGIFY_EQUAL(repo->name(), "unwritten");
+ }
+ } test_creation;
+
+ struct UnwrittenRepositoryContentsTest : TestCase
+ {
+ UnwrittenRepositoryContentsTest() : TestCase("contents") { }
+
+ void run()
+ {
+ TestEnvironment env;
+ std::tr1::shared_ptr<UnwrittenRepository> repo(new UnwrittenRepository(
+ make_named_values<UnwrittenRepositoryParams>(
+ value_for<n::environment>(&env),
+ value_for<n::location>(FSEntry::cwd() / "unwritten_repository_TEST_dir" / "repo2"),
+ value_for<n::name>(RepositoryName("unwritten")),
+ value_for<n::sync>(""),
+ value_for<n::sync_options>("")
+ )));
+ env.package_database()->add_repository(1, repo);
+ TEST_CHECK_STRINGIFY_EQUAL(repo->name(), "unwritten");
+
+ 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::unwritten "
+ "cat-one/pkg-one-2:0::unwritten "
+ "cat-one/pkg-one-3:0::unwritten "
+ "cat-one/pkg-two-1:1::unwritten "
+ "cat-one/pkg-two-2:2::unwritten"
+ );
+ }
+ } test_contents;
+}
+
diff --git a/paludis/repositories/unwritten/unwritten_repository_TEST_cleanup.sh b/paludis/repositories/unwritten/unwritten_repository_TEST_cleanup.sh
new file mode 100755
index 0000000..375283c
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_repository_TEST_cleanup.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+if [ -d unwritten_repository_TEST_dir ] ; then
+ rm -fr unwritten_repository_TEST_dir
+else
+ true
+fi
+
diff --git a/paludis/repositories/unwritten/unwritten_repository_TEST_setup.sh b/paludis/repositories/unwritten/unwritten_repository_TEST_setup.sh
new file mode 100755
index 0000000..820c61c
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_repository_TEST_setup.sh
@@ -0,0 +1,32 @@
+#!/usr/bin/env bash
+# vim: set ft=sh sw=4 sts=4 et :
+
+mkdir unwritten_repository_TEST_dir || exit 1
+cd unwritten_repository_TEST_dir || exit 1
+
+mkdir -p repo1
+cat <<"END" > repo1/foo.conf
+format = unwritten-1
+END
+
+mkdir -p repo2
+cat <<"END" > repo2/foo.conf
+format = unwritten-1
+
+cat-one/
+ pkg-one/
+ :0 1
+ description = Monkey
+ :0 2
+ description = Monkey
+ :0 3
+ description = Monkey
+ pkg-two/
+ :1 1
+ description = Monkey
+ :2 2
+ description = Monkey
+END
+
+cd ..
+
diff --git a/paludis/repositories/unwritten/unwritten_repository_file.cc b/paludis/repositories/unwritten/unwritten_repository_file.cc
new file mode 100644
index 0000000..646a1b2
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_repository_file.cc
@@ -0,0 +1,332 @@
+/* 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/unwritten/unwritten_repository_file.hh>
+#include <paludis/repositories/unwritten/unwritten_repository.hh>
+#include <paludis/util/wrapped_forward_iterator-impl.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/stringify.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/simple_parser.hh>
+#include <paludis/util/make_named_values.hh>
+#include <paludis/util/tokeniser.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/join.hh>
+#include <paludis/util/visitor-impl.hh>
+#include <paludis/name.hh>
+#include <paludis/version_spec.hh>
+#include <paludis/literal_metadata_key.hh>
+#include <paludis/metadata_key-fwd.hh>
+#include <paludis/dep_spec.hh>
+#include <paludis/formatter.hh>
+#include <list>
+#include <fstream>
+
+using namespace paludis;
+using namespace paludis::unwritten_repository;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<UnwrittenRepositoryFile>
+ {
+ std::list<UnwrittenRepositoryFileEntry> entries;
+ };
+}
+
+UnwrittenRepositoryFile::UnwrittenRepositoryFile(const FSEntry & f) :
+ PrivateImplementationPattern<UnwrittenRepositoryFile>(new Implementation<UnwrittenRepositoryFile>)
+{
+ _load(f);
+}
+
+UnwrittenRepositoryFile::~UnwrittenRepositoryFile()
+{
+}
+
+UnwrittenRepositoryFile::ConstIterator
+UnwrittenRepositoryFile::begin() const
+{
+ return ConstIterator(_imp->entries.begin());
+}
+
+UnwrittenRepositoryFile::ConstIterator
+UnwrittenRepositoryFile::end() const
+{
+ return ConstIterator(_imp->entries.end());
+}
+
+namespace
+{
+ struct UnwrittenHomepagePrinter :
+ ConstVisitor<SimpleURISpecTree>
+ {
+ std::stringstream s;
+ const SimpleURISpecTree::ItemFormatter & formatter;
+
+ UnwrittenHomepagePrinter(const SimpleURISpecTree::ItemFormatter & f) :
+ formatter(f)
+ {
+ }
+
+ void visit_sequence(
+ const AllDepSpec &,
+ SimpleURISpecTree::ConstSequenceIterator cur,
+ SimpleURISpecTree::ConstSequenceIterator end)
+ {
+ std::for_each(cur, end, accept_visitor(*this));
+ }
+
+ void visit_sequence(
+ const ConditionalDepSpec &,
+ SimpleURISpecTree::ConstSequenceIterator cur,
+ SimpleURISpecTree::ConstSequenceIterator end)
+ {
+ std::for_each(cur, end, accept_visitor(*this));
+ }
+
+ void visit_leaf(const SimpleURIDepSpec & u)
+ {
+ if (! s.str().empty())
+ s << " ";
+ s << formatter.format(u, format::Plain());
+ }
+ };
+
+ struct UnwrittenHomepageKey :
+ MetadataSpecTreeKey<SimpleURISpecTree>
+ {
+ const std::tr1::shared_ptr<const SimpleURISpecTree::ConstItem> vv;
+
+ UnwrittenHomepageKey(const std::string & r, const std::string & h, const MetadataKeyType t,
+ const std::tr1::shared_ptr<const SimpleURISpecTree::ConstItem> & v) :
+ MetadataSpecTreeKey<SimpleURISpecTree>(r, h, t),
+ vv(v)
+ {
+ }
+
+ const std::tr1::shared_ptr<const SimpleURISpecTree::ConstItem> value() const
+ {
+ return vv;
+ }
+
+ std::string pretty_print(const SimpleURISpecTree::ItemFormatter & f) const
+ {
+ UnwrittenHomepagePrinter p(f);
+ value()->accept(p);
+ return p.s.str();
+ }
+
+ std::string pretty_print_flat(const SimpleURISpecTree::ItemFormatter & f) const
+ {
+ UnwrittenHomepagePrinter p(f);
+ value()->accept(p);
+ return p.s.str();
+ }
+ };
+}
+
+void
+UnwrittenRepositoryFile::_load(const FSEntry & f)
+{
+ std::ifstream file(stringify(f).c_str());
+ if (! file)
+ throw UnwrittenRepositoryConfigurationError("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 != "unwritten-1")
+ throw UnwrittenRepositoryConfigurationError(
+ "Unsupported format '" + value + "' in '" + stringify(f) + "'");
+ }
+ else
+ Log::get_instance()->message("unwritten_repository.file.unknown_key", ll_warning, lc_context)
+ << "Ignoring unknown key '" << key << "' with value '" << value << "'";
+ }
+ else
+ throw UnwrittenRepositoryConfigurationError(
+ "Cannot parse header line '" + line + "' in '" + stringify(f) + "'");
+ }
+
+ CategoryNamePart category("x");
+ PackageNamePart package("x");
+ SlotName slot("x");
+ VersionSpec version("0");
+ std::tr1::shared_ptr<UnwrittenRepositoryFileEntry> entry;
+ while (std::getline(file, line))
+ {
+ SimpleParser line_parser(line);
+
+ std::string token, token2;
+ if (line.empty())
+ {
+ }
+ else if (line_parser.consume(
+ (*simple_parser::any_of(" \t")) &
+ (simple_parser::exact("#")) &
+ (*simple_parser::any_except(""))))
+ {
+ }
+ else if (line_parser.consume(
+ (+simple_parser::any_except(" \t/") >> token) &
+ (simple_parser::exact("/"))
+ ))
+ {
+ if (! line_parser.eof())
+ throw UnwrittenRepositoryConfigurationError(
+ "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 UnwrittenRepositoryConfigurationError(
+ "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);
+
+ if (line_parser.consume(
+ (+simple_parser::any_except(" \t") >> token)
+ ))
+ version = VersionSpec(token);
+ else
+ throw UnwrittenRepositoryConfigurationError(
+ "Cannot parse body slot+version line '" + line + " in '" + stringify(f) + "'");
+
+ if (! line_parser.eof())
+ throw UnwrittenRepositoryConfigurationError(
+ "Cannot parse body slot+version line '" + line + " in '" + stringify(f) + "'");
+
+ if (entry)
+ {
+ _imp->entries.push_back(*entry);
+ entry.reset();
+ }
+ }
+ else if (line_parser.consume(
+ (+simple_parser::any_of(" \t")) &
+ (+simple_parser::any_except(" \t") >> token) &
+ (+simple_parser::any_of(" \t")) &
+ (+simple_parser::exact("=")) &
+ (+simple_parser::any_of(" \t")) &
+ (+simple_parser::any_except("") >> token2)
+ ))
+ {
+ if (! line_parser.eof())
+ throw UnwrittenRepositoryConfigurationError(
+ "Cannot parse body key = value line '" + line + " in '" + stringify(f) + "'");
+
+ if (! entry)
+ entry.reset(new UnwrittenRepositoryFileEntry(make_named_values<UnwrittenRepositoryFileEntry>(
+ value_for<n::added_by>(std::tr1::shared_ptr<const MetadataValueKey<std::string> >()),
+ value_for<n::bug_ids>(std::tr1::shared_ptr<const MetadataCollectionKey<Sequence<std::string> > >()),
+ value_for<n::comment>(std::tr1::shared_ptr<const MetadataValueKey<std::string> >()),
+ value_for<n::description>(std::tr1::shared_ptr<const MetadataValueKey<std::string> >()),
+ value_for<n::homepage>(std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> >()),
+ value_for<n::name>(category + package),
+ value_for<n::remote_ids>(std::tr1::shared_ptr<const MetadataCollectionKey<Sequence<std::string> > >()),
+ value_for<n::slot>(slot),
+ value_for<n::version>(version)
+ )));
+
+ if (token == "description")
+ entry->description().reset(new LiteralMetadataValueKey<std::string>("description", "Description", mkt_significant, token2));
+ else if (token == "homepage")
+ {
+ std::tr1::shared_ptr<AllDepSpec> all_spec(new AllDepSpec);
+ std::tr1::shared_ptr<ConstTreeSequence<SimpleURISpecTree, AllDepSpec> > spec(
+ new ConstTreeSequence<SimpleURISpecTree, AllDepSpec>(all_spec));
+ std::list<std::string> tokens;
+ tokenise_whitespace(token2, std::back_inserter(tokens));
+ for (std::list<std::string>::const_iterator t(tokens.begin()), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ spec->add(make_shared_ptr(new TreeLeaf<SimpleURISpecTree, SimpleURIDepSpec>(make_shared_ptr(new SimpleURIDepSpec(*t)))));
+ entry->homepage().reset(new UnwrittenHomepageKey("homepage", "Homepage", mkt_normal, spec));
+ }
+ else if (token == "comment")
+ entry->comment().reset(new LiteralMetadataValueKey<std::string>("comment", "Comment", mkt_normal, token2));
+ else if (token == "added-by")
+ entry->added_by().reset(new LiteralMetadataValueKey<std::string>("added-by", "Description", mkt_author, token2));
+ else if (token == "bug-ids")
+ {
+ std::tr1::shared_ptr<Sequence<std::string> > seq(new Sequence<std::string>);
+ std::list<std::string> tokens;
+ tokenise_whitespace(token2, std::back_inserter(tokens));
+ for (std::list<std::string>::const_iterator t(tokens.begin()), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ seq->push_back(*t);
+ entry->bug_ids().reset(new LiteralMetadataStringSequenceKey("bug-ids", "Bug IDs", mkt_normal, seq));
+ }
+ else if (token == "remote-ids")
+ {
+ std::tr1::shared_ptr<Sequence<std::string> > seq(new Sequence<std::string>);
+ std::list<std::string> tokens;
+ tokenise_whitespace(token2, std::back_inserter(tokens));
+ for (std::list<std::string>::const_iterator t(tokens.begin()), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ seq->push_back(*t);
+ entry->remote_ids().reset(new LiteralMetadataStringSequenceKey("remote-ids", "Remote IDs", mkt_internal, seq));
+ }
+ else
+ Log::get_instance()->message("unwritten_repository.file.unknown_key", ll_warning, lc_context)
+ << "Ignoring unknown key '" << token << "' with value '" << token2 << "'";
+ }
+ else
+ throw UnwrittenRepositoryConfigurationError(
+ "Cannot parse body line '" + line + " in '" + stringify(f) + "'");
+ }
+
+ if (entry)
+ _imp->entries.push_back(*entry);
+}
+
+template class PrivateImplementationPattern<UnwrittenRepositoryFile>;
+template class WrappedForwardIterator<UnwrittenRepositoryFile::ConstIteratorTag,
+ const UnwrittenRepositoryFileEntry>;
+
diff --git a/paludis/repositories/unwritten/unwritten_repository_file.hh b/paludis/repositories/unwritten/unwritten_repository_file.hh
new file mode 100644
index 0000000..44b9ad0
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_repository_file.hh
@@ -0,0 +1,86 @@
+/* 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_UNWRITTEN_UNWRITTEN_REPOSITORY_FILE_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNWRITTEN_UNWRITTEN_REPOSITORY_FILE_HH 1
+
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/named_value.hh>
+#include <paludis/metadata_key-fwd.hh>
+#include <paludis/name.hh>
+#include <paludis/version_spec.hh>
+#include <paludis/dep_tree-fwd.hh>
+
+namespace paludis
+{
+ namespace n
+ {
+ struct added_by;
+ struct bug_ids;
+ struct comment;
+ struct description;
+ struct homepage;
+ struct name;
+ struct remote_ids;
+ struct slot;
+ struct version;
+ }
+
+ namespace unwritten_repository
+ {
+ class UnwrittenRepositoryFile;
+
+ struct UnwrittenRepositoryFileEntry
+ {
+ NamedValue<n::added_by, std::tr1::shared_ptr<const MetadataValueKey<std::string> > > added_by;
+ NamedValue<n::bug_ids, std::tr1::shared_ptr<const MetadataCollectionKey<Sequence<std::string> > > > bug_ids;
+ NamedValue<n::comment, std::tr1::shared_ptr<const MetadataValueKey<std::string> > > comment;
+ NamedValue<n::description, std::tr1::shared_ptr<const MetadataValueKey<std::string> > > description;
+ NamedValue<n::homepage, std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> > > homepage;
+ NamedValue<n::name, QualifiedPackageName> name;
+ NamedValue<n::remote_ids, std::tr1::shared_ptr<const MetadataCollectionKey<Sequence<std::string> > > > remote_ids;
+ NamedValue<n::slot, SlotName> slot;
+ NamedValue<n::version, VersionSpec> version;
+ };
+
+ class PALUDIS_VISIBLE UnwrittenRepositoryFile :
+ private PrivateImplementationPattern<UnwrittenRepositoryFile>
+ {
+ private:
+ void _load(const FSEntry &);
+
+ public:
+ UnwrittenRepositoryFile(const FSEntry &);
+ ~UnwrittenRepositoryFile();
+
+ struct ConstIteratorTag;
+ typedef WrappedForwardIterator<ConstIteratorTag, const UnwrittenRepositoryFileEntry> ConstIterator;
+ ConstIterator begin() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ ConstIterator end() const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+ }
+
+#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE
+ extern template class PrivateImplementationPattern<unwritten_repository::UnwrittenRepositoryFile>;
+#endif
+}
+
+#endif
diff --git a/paludis/repositories/unwritten/unwritten_repository_store.cc b/paludis/repositories/unwritten/unwritten_repository_store.cc
new file mode 100644
index 0000000..4d98e72
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_repository_store.cc
@@ -0,0 +1,201 @@
+/* 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/unwritten/unwritten_repository_store.hh>
+#include <paludis/repositories/unwritten/unwritten_repository_file.hh>
+#include <paludis/repositories/unwritten/unwritten_id.hh>
+#include <paludis/repositories/unwritten/unwritten_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/make_shared_ptr.hh>
+#include <paludis/util/is_file_with_extension.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/make_named_values.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::unwritten_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<UnwrittenRepositoryStore>
+ {
+ const UnwrittenRepository * const repo;
+ mutable std::tr1::shared_ptr<CategoryNamePartSet> categories;
+ mutable PackageNames package_names;
+ mutable IDs ids;
+
+ Implementation(const UnwrittenRepository * const r) :
+ repo(r),
+ categories(new CategoryNamePartSet)
+ {
+ }
+ };
+}
+
+UnwrittenRepositoryStore::UnwrittenRepositoryStore(
+ const Environment * const env,
+ const UnwrittenRepository * const repo,
+ const FSEntry & f) :
+ PrivateImplementationPattern<UnwrittenRepositoryStore>(new Implementation<UnwrittenRepositoryStore>(repo))
+{
+ _populate(env, f);
+}
+
+UnwrittenRepositoryStore::~UnwrittenRepositoryStore()
+{
+}
+
+void
+UnwrittenRepositoryStore::_populate(const Environment * const env, const FSEntry & f)
+{
+ Context context("When populating UnwrittenRepository from directory '" + stringify(f) + "':");
+
+ using namespace std::tr1::placeholders;
+ std::for_each(DirIterator(f), DirIterator(), std::tr1::bind(
+ &UnwrittenRepositoryStore::_populate_one, this, env, _1));
+}
+
+void
+UnwrittenRepositoryStore::_populate_one(const Environment * const, const FSEntry & f)
+{
+ if (! is_file_with_extension(f, ".conf", IsFileWithOptions()))
+ return;
+
+ Context context("When populating UnwrittenRepository from file '" + stringify(f) + "':");
+
+ UnwrittenRepositoryFile file(f);
+
+ std::tr1::shared_ptr<Mask> mask(new UnwrittenMask);
+
+ QualifiedPackageName old_name("x/x");
+ std::tr1::shared_ptr<QualifiedPackageNameSet> pkgs;
+ std::tr1::shared_ptr<PackageIDSequence> ids;
+ for (UnwrittenRepositoryFile::ConstIterator i(file.begin()), i_end(file.end()) ;
+ i != i_end ; ++i)
+ {
+ if (old_name.category != (*i).name().category)
+ {
+ _imp->categories->insert((*i).name().category);
+ PackageNames::iterator p(_imp->package_names.find((*i).name().category));
+ if (_imp->package_names.end() == p)
+ p = _imp->package_names.insert(std::make_pair((*i).name().category,
+ make_shared_ptr(new QualifiedPackageNameSet))).first;
+ pkgs = p->second;
+ }
+
+ if (old_name != (*i).name())
+ {
+ pkgs->insert((*i).name());
+ IDs::iterator p(_imp->ids.find((*i).name()));
+ if (_imp->ids.end() == p)
+ p = _imp->ids.insert(std::make_pair((*i).name(),
+ make_shared_ptr(new PackageIDSequence))).first;
+
+ ids = p->second;
+ }
+
+ ids->push_back(make_shared_ptr(new UnwrittenID(make_named_values<UnwrittenIDParams>(
+ value_for<n::added_by>((*i).added_by()),
+ value_for<n::bug_ids>((*i).bug_ids()),
+ value_for<n::comment>((*i).comment()),
+ value_for<n::description>((*i).description()),
+ value_for<n::homepage>((*i).homepage()),
+ value_for<n::mask>(mask),
+ value_for<n::name>((*i).name()),
+ value_for<n::remote_ids>((*i).remote_ids()),
+ value_for<n::repository>(_imp->repo),
+ value_for<n::slot>((*i).slot()),
+ value_for<n::version>((*i).version())
+ ))));
+
+ old_name = (*i).name();
+ }
+}
+
+bool
+UnwrittenRepositoryStore::has_category_named(const CategoryNamePart & c) const
+{
+ return _imp->categories->end() != _imp->categories->find(c);
+}
+
+bool
+UnwrittenRepositoryStore::has_package_named(const QualifiedPackageName & q) const
+{
+ return _imp->ids.end() != _imp->ids.find(q);
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnwrittenRepositoryStore::category_names() const
+{
+ return _imp->categories;
+}
+
+std::tr1::shared_ptr<const CategoryNamePartSet>
+UnwrittenRepositoryStore::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>
+UnwrittenRepositoryStore::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>
+UnwrittenRepositoryStore::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<unwritten_repository::UnwrittenRepositoryStore>;
+
diff --git a/paludis/repositories/unwritten/unwritten_repository_store.hh b/paludis/repositories/unwritten/unwritten_repository_store.hh
new file mode 100644
index 0000000..eb0d2c9
--- /dev/null
+++ b/paludis/repositories/unwritten/unwritten_repository_store.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_REPOSITORIES_UNWRITTEN_UNWRITTEN_REPOSITORY_STORE_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_UNWRITTEN_UNWRITTEN_REPOSITORY_STORE_HH 1
+
+#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 unwritten_repository
+ {
+ struct UnwrittenRepository;
+
+ class PALUDIS_VISIBLE UnwrittenRepositoryStore :
+ private PrivateImplementationPattern<UnwrittenRepositoryStore>
+ {
+ private:
+ void _populate_one(const Environment * const env, const FSEntry & f);
+ void _populate(const Environment * const env, const FSEntry & f);
+
+ public:
+ UnwrittenRepositoryStore(
+ const Environment * const,
+ const UnwrittenRepository * const,
+ const FSEntry &);
+ ~UnwrittenRepositoryStore();
+
+ 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<unwritten_repository::UnwrittenRepositoryStore>;
+#endif
+}
+
+
+#endif