aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-07-31 22:51:40 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-07-31 22:51:40 +0000
commit986635d5e98ef46e24716bbcb1556fa88cafdbc9 (patch)
tree9c32e797938cd1b4e95a04fd710fd5e5e3c854cc
parent7e614e0bcdb4730761aea814dcecc2b801514bd0 (diff)
downloadpaludis-986635d5e98ef46e24716bbcb1556fa88cafdbc9.tar.gz
paludis-986635d5e98ef46e24716bbcb1556fa88cafdbc9.tar.xz
Start to unbreak CRAN some more
-rw-r--r--paludis/dep_list/override_functions.cc12
-rw-r--r--paludis/metadata_key.cc1
-rw-r--r--paludis/metadata_key.hh1
-rw-r--r--paludis/package_id.hh2
-rw-r--r--paludis/repositories/cran/Makefile.am23
-rw-r--r--paludis/repositories/cran/cran_dep_parser.cc4
-rw-r--r--paludis/repositories/cran/cran_installed_repository.cc5
-rw-r--r--paludis/repositories/cran/cran_package_id.cc445
-rw-r--r--paludis/repositories/cran/cran_package_id.hh73
-rw-r--r--paludis/repositories/cran/cran_repository.cc23
-rw-r--r--paludis/repositories/cran/cran_repository.hh4
-rw-r--r--paludis/repositories/cran/cran_repository_TEST.cc25
-rw-r--r--paludis/repositories/cran/description_file.cc113
-rw-r--r--paludis/repositories/cran/description_file.hh49
-rw-r--r--paludis/repositories/cran/description_file_TEST.cc49
-rw-r--r--paludis/repositories/cran/keys.cc95
-rw-r--r--paludis/repositories/cran/keys.hh94
-rw-r--r--paludis/repositories/cran/masks.cc70
-rw-r--r--paludis/repositories/cran/masks.hh45
-rw-r--r--paludis/repositories/cran/normalise.cc16
-rw-r--r--paludis/repositories/cran/normalise.hh5
-rw-r--r--paludis/repositories/e/ebuild_id.cc12
-rw-r--r--paludis/repositories/e/ebuild_id.hh2
-rw-r--r--paludis/repositories/e/vdb_id.cc12
-rw-r--r--paludis/repositories/e/vdb_id.hh2
-rw-r--r--paludis/repositories/fake/fake_package_id.cc12
-rw-r--r--paludis/repositories/fake/fake_package_id.hh2
-rw-r--r--paludis/repositories/gems/gem_specification.cc12
-rw-r--r--paludis/repositories/gems/gem_specification.hh2
-rw-r--r--paludis/repositories/gems/gem_specification_TEST.cc4
-rw-r--r--paludis/repositories/virtuals/package_id.cc11
-rw-r--r--paludis/repositories/virtuals/package_id.hh2
-rw-r--r--python/metadata_key.cc5
-rw-r--r--ruby/package_id.cc31
-rw-r--r--src/output/console_query_task.cc27
35 files changed, 1176 insertions, 114 deletions
diff --git a/paludis/dep_list/override_functions.cc b/paludis/dep_list/override_functions.cc
index e48d1f7..3eac36d 100644
--- a/paludis/dep_list/override_functions.cc
+++ b/paludis/dep_list/override_functions.cc
@@ -89,6 +89,10 @@ namespace
{
}
+ void visit(const MetadataSetKey<PackageIDSequence> &)
+ {
+ }
+
void visit(const MetadataSetKey<KeywordNameSet> & k)
{
tr1::shared_ptr<KeywordNameSet> kk(new KeywordNameSet);
@@ -226,6 +230,10 @@ namespace
void visit(const MetadataSetKey<UseFlagNameSet> &)
{
}
+
+ void visit(const MetadataSetKey<PackageIDSequence> &)
+ {
+ }
};
struct OverrideUnkeywordedMaskVisitor :
@@ -361,6 +369,10 @@ namespace
{
}
+ void visit(const MetadataSetKey<PackageIDSequence> &)
+ {
+ }
+
void visit(const MetadataSetKey<UseFlagNameSet> &)
{
}
diff --git a/paludis/metadata_key.cc b/paludis/metadata_key.cc
index 869dc99..4e5a94a 100644
--- a/paludis/metadata_key.cc
+++ b/paludis/metadata_key.cc
@@ -113,6 +113,7 @@ template class MetadataSetKey<KeywordNameSet>;
template class MetadataSetKey<IUseFlagSet>;
template class MetadataSetKey<InheritedSet>;
template class MetadataSetKey<UseFlagNameSet>;
+template class MetadataSetKey<PackageIDSequence>;
template class MetadataSpecTreeKey<LicenseSpecTree>;
template class MetadataSpecTreeKey<ProvideSpecTree>;
diff --git a/paludis/metadata_key.hh b/paludis/metadata_key.hh
index 8ace96d..da813de 100644
--- a/paludis/metadata_key.hh
+++ b/paludis/metadata_key.hh
@@ -44,6 +44,7 @@ namespace paludis
MetadataSetKey<IUseFlagSet>,
MetadataSetKey<KeywordNameSet>,
MetadataSetKey<InheritedSet>,
+ MetadataSetKey<PackageIDSequence>,
MetadataSpecTreeKey<DependencySpecTree>,
MetadataSpecTreeKey<LicenseSpecTree>,
MetadataSpecTreeKey<URISpecTree>,
diff --git a/paludis/package_id.hh b/paludis/package_id.hh
index a447ec5..7681429 100644
--- a/paludis/package_id.hh
+++ b/paludis/package_id.hh
@@ -73,6 +73,8 @@ namespace paludis
virtual const tr1::shared_ptr<const MetadataSetKey<InheritedSet> > inherited_key() const = 0;
virtual const tr1::shared_ptr<const MetadataSpecTreeKey<LicenseSpecTree> > license_key() const = 0;
virtual const tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> > provide_key() const = 0;
+ virtual const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> > contains_key() const = 0;
+ virtual const tr1::shared_ptr<const MetadataPackageIDKey> contained_in_key() const = 0;
virtual const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > build_dependencies_key() const = 0;
virtual const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > run_dependencies_key() const = 0;
virtual const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > post_dependencies_key() const = 0;
diff --git a/paludis/repositories/cran/Makefile.am b/paludis/repositories/cran/Makefile.am
index 4f83c6e..41420cc 100644
--- a/paludis/repositories/cran/Makefile.am
+++ b/paludis/repositories/cran/Makefile.am
@@ -32,6 +32,9 @@ paludis_repositories_cran_include_HEADERS = \
cran_repository-sr.hh \
cran_installed_repository.hh \
cran_installed_repository-sr.hh \
+ description_file.hh \
+ masks.hh \
+ keys.hh \
normalise.hh
libpaludiscranrepository_la_SOURCES = \
@@ -39,8 +42,11 @@ libpaludiscranrepository_la_SOURCES = \
cran_dep_parser.cc \
cran_repository.cc \
cran_installed_repository.cc \
+ description_file.cc \
registration.cc \
normalise.cc \
+ masks.cc \
+ keys.cc \
$(paludis_repositories_cran_include_HEADERS)
libpaludiscranrepository_la_LIBADD = \
@@ -49,7 +55,11 @@ libpaludiscranrepository_la_LIBADD = \
$(top_builddir)/paludis/util/libpaludisutil.la \
$(DYNAMIC_LD_LIBS)
-TESTS = cran_dep_parser_TEST cran_repository_TEST cran_installed_repository_TEST
+TESTS = \
+ cran_dep_parser_TEST \
+ cran_repository_TEST \
+ cran_installed_repository_TEST \
+ description_file_TEST
cran_dep_parser_TEST_SOURCES = cran_dep_parser_TEST.cc
@@ -80,6 +90,17 @@ cran_repository_TEST_LDADD = \
$(top_builddir)/paludis/environments/test/libpaludistestenvironment.la \
$(DYNAMIC_LD_LIBS)
+description_file_TEST_SOURCES = description_file_TEST.cc
+
+description_file_TEST_LDADD = \
+ $(top_builddir)/paludis/util/test_extras.o \
+ $(top_builddir)/test/libtest.a \
+ libpaludiscranrepository.la \
+ $(top_builddir)/paludis/libpaludis.la \
+ $(top_builddir)/paludis/util/libpaludisutil.la \
+ $(top_builddir)/paludis/environments/test/libpaludistestenvironment.la \
+ $(DYNAMIC_LD_LIBS)
+
EXTRA_DIST = \
cran_repository_TEST.cc \
cran_repository_TEST_setup.sh \
diff --git a/paludis/repositories/cran/cran_dep_parser.cc b/paludis/repositories/cran/cran_dep_parser.cc
index 79d3bd2..e9216d0 100644
--- a/paludis/repositories/cran/cran_dep_parser.cc
+++ b/paludis/repositories/cran/cran_dep_parser.cc
@@ -65,8 +65,8 @@ cranrepository::parse_depends(const std::string & s)
else
name = strip_leading(strip_trailing(aa, " \t"), " \t");
- cranrepository::normalise_name(name);
- cranrepository::normalise_version(version);
+ name = cran_name_to_internal(name);
+ version = cran_version_to_internal(version);
if ("R" == name)
name = "dev-lang/R";
diff --git a/paludis/repositories/cran/cran_installed_repository.cc b/paludis/repositories/cran/cran_installed_repository.cc
index 359689e..031ae38 100644
--- a/paludis/repositories/cran/cran_installed_repository.cc
+++ b/paludis/repositories/cran/cran_installed_repository.cc
@@ -56,7 +56,7 @@ using namespace paludis;
#include <paludis/repositories/cran/cran_installed_repository-sr.cc>
-typedef MakeHashedMap<QualifiedPackageName, tr1::shared_ptr<const CRANPackageID> >::Type IDMap;
+typedef MakeHashedMap<QualifiedPackageName, tr1::shared_ptr<const cranrepository::CRANPackageID> >::Type IDMap;
namespace paludis
{
@@ -225,7 +225,7 @@ CRANInstalledRepository::do_package_names(const CategoryNamePart & c) const
need_ids();
std::copy(_imp->ids.begin(), _imp->ids.end(), transform_inserter(result->inserter(),
- tr1::mem_fn(&std::pair<const QualifiedPackageName, tr1::shared_ptr<const CRANPackageID> >::first)));
+ tr1::mem_fn(&std::pair<const QualifiedPackageName, tr1::shared_ptr<const cranrepository::CRANPackageID> >::first)));
return result;
}
@@ -496,7 +496,6 @@ CRANInstalledRepository::invalidate()
void
CRANInstalledRepository::invalidate_masks()
{
- _imp.reset(new Implementation<CRANInstalledRepository>(_imp->params));
}
void
diff --git a/paludis/repositories/cran/cran_package_id.cc b/paludis/repositories/cran/cran_package_id.cc
index 438b17d..713309b 100644
--- a/paludis/repositories/cran/cran_package_id.cc
+++ b/paludis/repositories/cran/cran_package_id.cc
@@ -20,107 +20,198 @@
#include <paludis/repositories/cran/cran_package_id.hh>
#include <paludis/repositories/cran/cran_dep_parser.hh>
+#include <paludis/repositories/cran/description_file.hh>
+#include <paludis/repositories/cran/masks.hh>
+#include <paludis/repositories/cran/keys.hh>
+#include <paludis/repositories/cran/normalise.hh>
#include <paludis/config_file.hh>
+#include <paludis/repository.hh>
#include <paludis/util/log.hh>
#include <paludis/util/strip.hh>
#include <paludis/util/stringify.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/name.hh>
+#include <paludis/version_spec.hh>
+#include <paludis/action.hh>
+#include <paludis/util/tokeniser.hh>
#include <string>
#include <algorithm>
+#include <list>
+
#include <paludis/util/tr1_functional.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
#include <libwrapiter/libwrapiter_output_iterator.hh>
using namespace paludis;
+using namespace paludis::cranrepository;
-namespace
+namespace paludis
{
- void
- normalise_name(std::string & s)
+ template <>
+ struct Implementation<CRANPackageID>
{
- using namespace tr1::placeholders;
- std::replace_if(s.begin(), s.end(), tr1::bind(std::equal_to<char>(), _1, '.'), '-');
- }
+ const tr1::shared_ptr<const Repository> repository;
+ QualifiedPackageName name;
+ VersionSpec version;
- void
- denormalise_name(std::string & s)
- {
- using namespace tr1::placeholders;
- std::replace_if(s.begin(), s.end(), tr1::bind(std::equal_to<char>(), _1, '-'), '.');
- }
+ tr1::shared_ptr<URIKey> homepage_key;
+ tr1::shared_ptr<StringKey> short_description_key;
+ tr1::shared_ptr<StringKey> long_description_key;
+ tr1::shared_ptr<PackageIDKey> contained_in_key;
+ tr1::shared_ptr<PackageIDSequenceKey> contains_key;
- void
- normalise_version(std::string & s)
- {
- using namespace tr1::placeholders;
- std::replace_if(s.begin(), s.end(), tr1::bind(std::equal_to<char>(), _1, '-'), '.');
- }
+ Implementation(const tr1::shared_ptr<const Repository> & r, const FSEntry & f) :
+ repository(r),
+ name("cran/" + cran_name_to_internal(strip_trailing_string(f.basename(), ".DESCRIPTION"))),
+ version("0")
+ {
+ }
+
+ Implementation(const CRANPackageID * const r, const std::string & t) :
+ repository(r->repository()),
+ name("cran/" + cran_name_to_internal(t)),
+ version(r->version()),
+ contained_in_key(new PackageIDKey("Contained", "Contained in", mkt_normal, r))
+ {
+ }
+ };
}
-#if 0
-CRANDescription::CRANDescription() :
- name("cran/" + n),
- version("0"),
- metadata(new CRANVersionMetadata(installed))
+CRANPackageID::CRANPackageID(const tr1::shared_ptr<const Repository> & r, const FSEntry & f) :
+ PrivateImplementationPattern<CRANPackageID>(new Implementation<CRANPackageID>(r, f)),
+ _imp(PrivateImplementationPattern<CRANPackageID>::_imp.get())
{
- Context context("When parsing file '" + stringify(f) + "' for package '" + n + "':");
+ Context context("When parsing file '" + stringify(f) + "' to create a CRAN Package ID:");
if (! f.is_regular_file())
{
- metadata->eapi = EAPIData::get_instance()->unknown_eapi();
- Log::get_instance()->message(ll_warning, lc_context, "Unexpected irregular file: '" + stringify(f) + "'.");
+ add_mask(make_shared_ptr(new BrokenMask('B', "Broken", "DESCRIPTION file not a file")));
+ Log::get_instance()->message(ll_warning, lc_context) << "Unexpected irregular file: '" << stringify(f) << "'";
return;
}
- LineConfigFile file(f, LineConfigFileOptions());
- LineConfigFile::Iterator l(file.begin()), l_end(file.end());
-
- // Fill in default values
- metadata->slot = SlotName("0");
- metadata->cran_interface->set_keywords("*");
- metadata->eapi = EAPIData::get_instance()->eapi_from_string("CRAN-1");
-
- std::string key;
- for ( ; l != l_end ; ++l)
+ try
{
- Context local_context("When parsing line '" + *l + "':");
+ DescriptionFile file(f);
+
+ std::string raw_name;
+ if (! file.get("Package").empty())
+ {
+ Context local_context("When handling Package: key:");
+ raw_name = file.get("Package");
+ _imp->name = QualifiedPackageName(CategoryNamePart("cran"), PackageNamePart(cran_name_to_internal(raw_name)));
+ }
+ else if (! file.get("Bundle").empty())
+ {
+ Context local_context("When handling Bundle: key:");
+ raw_name = file.get("Bundle");
+ _imp->name = QualifiedPackageName(CategoryNamePart("cran"), PackageNamePart(cran_name_to_internal(raw_name)));
+ }
+ else
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "No Package: or Bundle: key in '" << stringify(f) << "'";
+ add_mask(make_shared_ptr(new BrokenMask('B', "Broken", "No Package: or Bundle: key")));
+ return;
+ }
- std::string line(strip_leading(strip_trailing(*l, " \t\r\n"), " \t\r\n")), value;
- std::string::size_type pos(line.find(':'));
- if (std::string::npos == pos)
+ if (file.get("Version").empty())
{
- value = strip_leading(strip_trailing(line, " \t"), " \t");
+ Context local_context("When handling Version: key:");
+ Log::get_instance()->message(ll_warning, lc_context) << "No Version: key in '" << stringify(f) << "'";
+ _imp->version = VersionSpec("0");
+ add_mask(make_shared_ptr(new BrokenMask('B', "Broken", "No Version: key")));
+ return;
}
else
{
- key = strip_leading(strip_trailing(line.substr(0, pos), " \t"), " \t");
- value = strip_leading(strip_trailing(line.substr(pos + 1), " \t\r\n"), " \t\r\n");
+ Context local_context("When handling Version: key:");
+ _imp->version = VersionSpec(cran_version_to_internal(file.get("Version")));
+ }
+
+ if (! file.get("URL").empty())
+ {
+ Context local_context("When handling URL: key:");
+ _imp->homepage_key.reset(new URIKey("URL", "URL", file.get("URL"), mkt_significant));
+ add_metadata_key(_imp->homepage_key);
+ }
+
+ if (! file.get("Title").empty())
+ {
+ Context local_context("When handling Title: key:");
+ _imp->short_description_key.reset(new StringKey("Title", "Title", file.get("Title"), mkt_significant));
+ add_metadata_key(_imp->short_description_key);
+ }
+
+ if (! file.get("Description").empty())
+ {
+ Context local_context("When handling Description: key:");
+ _imp->long_description_key.reset(new StringKey("Description", "Description", file.get("Description"), mkt_normal));
+ add_metadata_key(_imp->long_description_key);
+ }
+ else if (! file.get("BundleDescription").empty())
+ {
+ Context local_context("When handling BundleDescription: key:");
+ _imp->long_description_key.reset(new StringKey("BundleDescription", "Bundle Description",
+ file.get("BundleDescription"), mkt_normal));
+ }
+
+ if (! file.get("Author").empty())
+ {
+ Context local_context("When handling Author: key:");
+ add_metadata_key(make_shared_ptr(new StringKey("Author", "Author", file.get("Author"), mkt_normal)));
+ }
+
+ if (! file.get("Maintainer").empty())
+ {
+ Context local_context("When handling Maintainer: key:");
+ add_metadata_key(make_shared_ptr(new StringKey("Maintainer", "Maintainer", file.get("Maintainer"), mkt_normal)));
+ }
+
+ if (! file.get("Contains").empty())
+ {
+ Context local_context("When handling Contains: key:");
+ std::list<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(file.get("Contains"), std::back_inserter(tokens));
+ _imp->contains_key.reset(new PackageIDSequenceKey("Contains", "Contains", mkt_normal));
+ add_metadata_key(_imp->contains_key);
+ for (std::list<std::string>::const_iterator t(tokens.begin()), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ {
+ if (*t != stringify(name().package))
+ _imp->contains_key->push_back(make_shared_ptr(new CRANPackageID(this, *t)));
+ else
+ {
+ /* yay CRAN... */
+ Log::get_instance()->message(ll_qa, lc_context) << "Bundle '" << stringify(*this) << "' contains itself, but is "
+ "not a Klein bundle";
+ }
+ }
}
+ }
+ catch (const Exception & e)
+ {
+ Log::get_instance()->message(ll_warning, lc_context) << "Broken CRAN description file '" << stringify(f) << "': '"
+ << e.message() << "' (" << e.what() << ")";
+ add_mask(make_shared_ptr(new BrokenMask('B', "Broken", "Got exception '" + stringify(e.message()) + "' (" + e.what() + "')")));
+ }
+#if 0
+ for (cranrepository::DescriptionFile::Iterator i(file.begin()), i_end(file.end()) ;
+ i != i_end ; ++i)
+ {
if (("Package" == key) || ("Bundle" == key))
{
- metadata->cran_interface->package = value;
metadata->set_homepage("http://cran.r-project.org/src/contrib/Descriptions/" + value + ".html");
if ("Package" == key)
{
CRANDescription::normalise_name(value);
if (n != value)
- Log::get_instance()->message(ll_warning, lc_context, "Inconsistent package name in file '" +
- stringify(name) + "': '" + n + "', '" + value + "':");
+ Log::get_instance()->message(ll_warning, lc_context) << "Inconsistent package name in file '" <<
+ f << "': '" << value << "'";
}
else
- {
metadata->cran_interface->is_bundle = true;
- }
- }
- else if ("Version" == key)
- {
- metadata->cran_interface->version = value;
- normalise_version(value);
- version = VersionSpec(value);
- }
- else if ("Title" == key)
- {
- metadata->description = value;
}
else if ("Depends" == key)
{
@@ -134,7 +225,243 @@ CRANDescription::CRANDescription() :
else if ("Suggests" == key)
metadata->deps_interface->set_suggested_depend(value);
}
+#endif
}
-#endif
+CRANPackageID::CRANPackageID(const CRANPackageID * const r, const std::string & t) :
+ PrivateImplementationPattern<CRANPackageID>(new Implementation<CRANPackageID>(r, t)),
+ _imp(PrivateImplementationPattern<CRANPackageID>::_imp.get())
+{
+ Context context("When creating contained ID '" + stringify(t) + "' in " + stringify(*r) + "':");
+
+ add_metadata_key(_imp->contained_in_key);
+}
+
+CRANPackageID::~CRANPackageID()
+{
+}
+
+void
+CRANPackageID::need_keys_added() const
+{
+}
+
+void
+CRANPackageID::need_masks_added() const
+{
+}
+
+
+const QualifiedPackageName
+CRANPackageID::name() const
+{
+ return _imp->name;
+}
+
+const VersionSpec
+CRANPackageID::version() const
+{
+ return _imp->version;
+}
+
+const SlotName
+CRANPackageID::slot() const
+{
+ return SlotName("0");
+}
+
+const tr1::shared_ptr<const Repository>
+CRANPackageID::repository() const
+{
+ return _imp->repository;
+}
+
+const tr1::shared_ptr<const MetadataPackageIDKey>
+CRANPackageID::virtual_for_key() const
+{
+ return tr1::shared_ptr<const MetadataPackageIDKey>();
+}
+
+const tr1::shared_ptr<const MetadataSetKey<KeywordNameSet> >
+CRANPackageID::keywords_key() const
+{
+ return tr1::shared_ptr<const MetadataSetKey<KeywordNameSet> >();
+}
+
+const tr1::shared_ptr<const MetadataSetKey<UseFlagNameSet> >
+CRANPackageID::use_key() const
+{
+ return tr1::shared_ptr<const MetadataSetKey<UseFlagNameSet> >();
+}
+
+const tr1::shared_ptr<const MetadataSetKey<IUseFlagSet> >
+CRANPackageID::iuse_key() const
+{
+ return tr1::shared_ptr<const MetadataSetKey<IUseFlagSet> >();
+}
+
+const tr1::shared_ptr<const MetadataSetKey<InheritedSet> >
+CRANPackageID::inherited_key() const
+{
+ return tr1::shared_ptr<const MetadataSetKey<InheritedSet> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<LicenseSpecTree> >
+CRANPackageID::license_key() const
+{
+ return tr1::shared_ptr<const MetadataSpecTreeKey<LicenseSpecTree> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> >
+CRANPackageID::provide_key() const
+{
+ return tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+CRANPackageID::build_dependencies_key() const
+{
+ return tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+CRANPackageID::run_dependencies_key() const
+{
+ return tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+CRANPackageID::post_dependencies_key() const
+{
+ return tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
+CRANPackageID::suggested_dependencies_key() const
+{
+ return tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<RestrictSpecTree> >
+CRANPackageID::restrict_key() const
+{
+ return tr1::shared_ptr<const MetadataSpecTreeKey<RestrictSpecTree> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<URISpecTree> >
+CRANPackageID::src_uri_key() const
+{
+ return tr1::shared_ptr<const MetadataSpecTreeKey<URISpecTree> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<URISpecTree> >
+CRANPackageID::bin_uri_key() const
+{
+ return tr1::shared_ptr<const MetadataSpecTreeKey<URISpecTree> >();
+}
+
+const tr1::shared_ptr<const MetadataSpecTreeKey<URISpecTree> >
+CRANPackageID::homepage_key() const
+{
+ return _imp->homepage_key;
+}
+
+const tr1::shared_ptr<const MetadataStringKey>
+CRANPackageID::short_description_key() const
+{
+ return _imp->short_description_key;
+}
+
+const tr1::shared_ptr<const MetadataStringKey>
+CRANPackageID::long_description_key() const
+{
+ return _imp->long_description_key;
+}
+
+const tr1::shared_ptr<const MetadataContentsKey>
+CRANPackageID::contents_key() const
+{
+ return tr1::shared_ptr<const MetadataContentsKey>();
+}
+
+const tr1::shared_ptr<const MetadataTimeKey>
+CRANPackageID::installed_time_key() const
+{
+ return tr1::shared_ptr<const MetadataTimeKey>();
+}
+
+const tr1::shared_ptr<const MetadataStringKey>
+CRANPackageID::source_origin_key() const
+{
+ return tr1::shared_ptr<const MetadataStringKey>();
+}
+
+const tr1::shared_ptr<const MetadataStringKey>
+CRANPackageID::binary_origin_key() const
+{
+ return tr1::shared_ptr<const MetadataStringKey>();
+}
+
+std::size_t
+CRANPackageID::extra_hash_value() const
+{
+ return 0;
+}
+
+bool
+CRANPackageID::arbitrary_less_than_comparison(const PackageID &) const
+{
+ return false;
+}
+
+bool
+CRANPackageID::breaks_portage() const
+{
+ return true;
+}
+
+const std::string
+CRANPackageID::canonical_form(const PackageIDCanonicalForm f) const
+{
+ switch (f)
+ {
+ case idcf_full:
+ return stringify(_imp->name) + "-" + stringify(_imp->version) + ":" + stringify(slot()) + "::" + stringify(_imp->repository->name());
+
+ case idcf_version:
+ return stringify(_imp->version);
+
+ case idcf_no_version:
+ return stringify(_imp->name) + ":" + stringify(slot()) + "::" + stringify(_imp->repository->name());
+
+ case last_idcf:
+ break;
+ }
+
+ throw InternalError(PALUDIS_HERE, "Bad PackageIDCanonicalForm");
+}
+
+bool
+CRANPackageID::supports_action(const SupportsActionTestBase &) const
+{
+ return false;
+}
+
+void
+CRANPackageID::perform_action(Action & a) const
+{
+ throw UnsupportedActionError(*this, a);
+}
+
+const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >
+CRANPackageID::contains_key() const
+{
+ return _imp->contains_key;
+}
+
+const tr1::shared_ptr<const MetadataPackageIDKey>
+CRANPackageID::contained_in_key() const
+{
+ return _imp->contained_in_key;
+}
diff --git a/paludis/repositories/cran/cran_package_id.hh b/paludis/repositories/cran/cran_package_id.hh
index 245d484..7f09d4f 100644
--- a/paludis/repositories/cran/cran_package_id.hh
+++ b/paludis/repositories/cran/cran_package_id.hh
@@ -26,19 +26,68 @@
namespace paludis
{
- class PALUDIS_VISIBLE CRANPackageID :
- public PackageID
+ namespace cranrepository
{
- public:
- static void normalise_name(std::string & s);
- static void denormalise_name(std::string & s);
- static void normalise_version(std::string & s);
-
- const std::string native_package() const PALUDIS_ATTRIBUTE((warn_unused_result));
- const std::string native_version() const PALUDIS_ATTRIBUTE((warn_unused_result));
- const tr1::shared_ptr<const MetadataPackageIDKey> bundle_key() const PALUDIS_ATTRIBUTE((warn_unused_result));
- const tr1::shared_ptr<const MetadataPackageIDKey> bundle_member_key() const PALUDIS_ATTRIBUTE((warn_unused_result));
- };
+ class PALUDIS_VISIBLE CRANPackageID :
+ public PackageID,
+ private PrivateImplementationPattern<CRANPackageID>,
+ public tr1::enable_shared_from_this<CRANPackageID>
+ {
+ private:
+ Implementation<CRANPackageID> * const _imp;
+
+ protected:
+ virtual void need_keys_added() const;
+ virtual void need_masks_added() const;
+
+ public:
+ CRANPackageID(const tr1::shared_ptr<const Repository> & r, const FSEntry &);
+ CRANPackageID(const CRANPackageID * const, const std::string &);
+ ~CRANPackageID();
+
+ virtual const std::string canonical_form(const PackageIDCanonicalForm) const;
+
+ virtual const QualifiedPackageName name() const;
+ virtual const VersionSpec version() const;
+ virtual const SlotName slot() const;
+ virtual const tr1::shared_ptr<const Repository> repository() const;
+
+ virtual const tr1::shared_ptr<const MetadataPackageIDKey> virtual_for_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<KeywordNameSet> > keywords_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<UseFlagNameSet> > use_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<IUseFlagSet> > iuse_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<InheritedSet> > inherited_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<LicenseSpecTree> > license_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> > provide_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > build_dependencies_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > run_dependencies_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > post_dependencies_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> > suggested_dependencies_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<RestrictSpecTree> > restrict_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<URISpecTree> > src_uri_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<URISpecTree> > bin_uri_key() const;
+ virtual const tr1::shared_ptr<const MetadataSpecTreeKey<URISpecTree> > homepage_key() const;
+ virtual const tr1::shared_ptr<const MetadataStringKey> short_description_key() const;
+ virtual const tr1::shared_ptr<const MetadataStringKey> long_description_key() const;
+ virtual const tr1::shared_ptr<const MetadataContentsKey> contents_key() const;
+ virtual const tr1::shared_ptr<const MetadataTimeKey> installed_time_key() const;
+ virtual const tr1::shared_ptr<const MetadataStringKey> source_origin_key() const;
+ virtual const tr1::shared_ptr<const MetadataStringKey> binary_origin_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> > contains_key() const;
+ virtual const tr1::shared_ptr<const MetadataPackageIDKey> contained_in_key() const;
+
+ virtual bool supports_action(const SupportsActionTestBase &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ virtual void perform_action(Action &) const;
+
+ virtual bool breaks_portage() const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual bool arbitrary_less_than_comparison(const PackageID &) const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual std::size_t extra_hash_value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+ }
}
#endif
diff --git a/paludis/repositories/cran/cran_repository.cc b/paludis/repositories/cran/cran_repository.cc
index 83e9c2a..09b16fa 100644
--- a/paludis/repositories/cran/cran_repository.cc
+++ b/paludis/repositories/cran/cran_repository.cc
@@ -23,6 +23,7 @@
#include <paludis/dep_spec.hh>
#include <paludis/environment.hh>
#include <paludis/action.hh>
+#include <paludis/metadata_key.hh>
#include <paludis/repositories/cran/cran_package_id.hh>
#include <paludis/repositories/cran/cran_repository.hh>
#include <paludis/repositories/repository_maker.hh>
@@ -42,6 +43,7 @@
#include <paludis/util/system.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/is_file_with_extension.hh>
#include <paludis/util/visitor-impl.hh>
#include <libwrapiter/libwrapiter_forward_iterator.hh>
@@ -60,7 +62,7 @@ using namespace paludis;
#include <paludis/repositories/cran/cran_repository-sr.cc>
-typedef MakeHashedMap<QualifiedPackageName, tr1::shared_ptr<const CRANPackageID> >::Type IDMap;
+typedef MakeHashedMap<QualifiedPackageName, tr1::shared_ptr<const cranrepository::CRANPackageID> >::Type IDMap;
namespace paludis
{
@@ -173,7 +175,7 @@ CRANRepository::do_package_names(const CategoryNamePart & c) const
need_ids();
std::copy(_imp->ids.begin(), _imp->ids.end(), transform_inserter(result->inserter(),
- tr1::mem_fn(&std::pair<const QualifiedPackageName, tr1::shared_ptr<const CRANPackageID> >::first)));
+ tr1::mem_fn(&std::pair<const QualifiedPackageName, tr1::shared_ptr<const cranrepository::CRANPackageID> >::first)));
return result;
}
@@ -204,7 +206,21 @@ CRANRepository::need_ids() const
Context context("When loading IDs for " + stringify(name()) + ":");
- LineConfigFile packages(FSEntry(_imp->params.location / "PACKAGES"), LineConfigFileOptions());
+ for (DirIterator d(_imp->params.location), d_end ; d != d_end ; ++d)
+ if (is_file_with_extension(*d, ".DESCRIPTION", IsFileWithOptions()))
+ {
+ tr1::shared_ptr<cranrepository::CRANPackageID> id(new cranrepository::CRANPackageID(shared_from_this(), *d));
+ if (! _imp->ids.insert(std::make_pair(id->name(), id)).second)
+ Log::get_instance()->message(ll_warning, lc_context) << "Couldn't insert package '" << *id << "' due to name collision";
+
+ if (id->contains_key())
+ for (PackageIDSequence::Iterator i(id->contains_key()->value()->begin()),
+ i_end(id->contains_key()->value()->end()) ; i != i_end ; ++i)
+ if (! _imp->ids.insert(std::make_pair((*i)->name(),
+ tr1::static_pointer_cast<const cranrepository::CRANPackageID>(*i))).second)
+ Log::get_instance()->message(ll_warning, lc_context) << "Couldn't insert package '" << **i
+ << "', which is contained in '" << *id << "', due to name collision";
+ }
_imp->has_ids = true;
}
@@ -411,7 +427,6 @@ CRANRepository::invalidate()
void
CRANRepository::invalidate_masks()
{
- _imp.reset(new Implementation<CRANRepository>(_imp->params));
}
namespace
diff --git a/paludis/repositories/cran/cran_repository.hh b/paludis/repositories/cran/cran_repository.hh
index 8872152..08dacff 100644
--- a/paludis/repositories/cran/cran_repository.hh
+++ b/paludis/repositories/cran/cran_repository.hh
@@ -25,6 +25,7 @@
#include <paludis/util/fs_entry.hh>
#include <paludis/util/private_implementation_pattern.hh>
#include <paludis/util/map-fwd.hh>
+#include <paludis/util/tr1_memory.hh>
#include <paludis/environment-fwd.hh>
#include <string>
@@ -50,7 +51,8 @@ namespace paludis
public Repository,
public RepositorySyncableInterface,
public RepositorySetsInterface,
- private PrivateImplementationPattern<CRANRepository>
+ private PrivateImplementationPattern<CRANRepository>,
+ public tr1::enable_shared_from_this<CRANRepository>
{
private:
void need_ids() const;
diff --git a/paludis/repositories/cran/cran_repository_TEST.cc b/paludis/repositories/cran/cran_repository_TEST.cc
index b8d02ef..be1d2cf 100644
--- a/paludis/repositories/cran/cran_repository_TEST.cc
+++ b/paludis/repositories/cran/cran_repository_TEST.cc
@@ -34,19 +34,8 @@
using namespace test;
using namespace paludis;
-/** \file
- * Test cases for CRANRepository.
- *
- * \ingroup grptestcases
- */
-
namespace test_cases
{
- /**
- * \test Test CRANRepository to parse a well formed PACKAGES file.
- *
- * \ingroup grptestcases
- */
struct CRANRepositoryPackagesTest : TestCase
{
CRANRepositoryPackagesTest() : TestCase("PACKAGES") { }
@@ -62,18 +51,11 @@ namespace test_cases
tr1::shared_ptr<Repository> repo(CRANRepository::make_cran_repository(
&env, keys));
TEST_CHECK(repo->has_category_named(CategoryNamePart("cran")));
-#if 0
TEST_CHECK(repo->has_package_named(QualifiedPackageName("cran/testpackage1")));
TEST_CHECK(repo->has_package_named(QualifiedPackageName("cran/testpackage2")));
-#endif
}
} test_cran_repository_packages;
- /**
- * \test Test CRANRepository to handly 'Bundle:'s correctly.
- *
- * \ingroup grptestcases
- */
struct CRANRepositoryBundleTest: TestCase
{
CRANRepositoryBundleTest() : TestCase("Bundle") { }
@@ -88,15 +70,10 @@ namespace test_cases
keys->insert("buildroot", "cran_repository_TEST_dir/tmp");
tr1::shared_ptr<Repository> repo(CRANRepository::make_cran_repository(
&env, keys));
-#if 0
TEST_CHECK(repo->has_package_named(QualifiedPackageName("cran/testbundle")));
TEST_CHECK(repo->has_package_named(QualifiedPackageName("cran/bundlepkg1")));
TEST_CHECK(repo->has_package_named(QualifiedPackageName("cran/bundlepkg2")));
-#endif
}
} test_cran_repository_bundle;
-
- /** \todo in repo1
- * \todo test case for DESCRIPTION files
- */
}
+
diff --git a/paludis/repositories/cran/description_file.cc b/paludis/repositories/cran/description_file.cc
new file mode 100644
index 0000000..cc70f1f
--- /dev/null
+++ b/paludis/repositories/cran/description_file.cc
@@ -0,0 +1,113 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "description_file.hh"
+#include <paludis/util/private_implementation_pattern-impl.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/strip.hh>
+#include <paludis/util/stringify.hh>
+#include <istream>
+#include <map>
+
+using namespace paludis;
+using namespace paludis::cranrepository;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<DescriptionFile>
+ {
+ std::map<std::string, std::string> values;
+ };
+}
+
+DescriptionFile::DescriptionFile(const Source & s) :
+ ConfigFile(s),
+ PrivateImplementationPattern<DescriptionFile>(new Implementation<DescriptionFile>)
+{
+ Context c("When parsing CRAN description file '" + s.filename() + "':");
+
+ if (! s.stream())
+ throw ConfigFileError(s.filename(), "Cannot read input");
+
+ std::string line, line_full;
+ while (std::getline(s.stream(), line))
+ {
+ /* cran needs to be taken out and shot in the nuts for this... */
+ line = strip_trailing(line, "\r");
+
+ if ((! line.empty()) && (std::string::npos != std::string(" \t").find_first_of(line.at(0))))
+ {
+ if (line_full.empty())
+ throw ConfigFileError(s.filename(), "Unexpected continuation");
+
+ line_full += " ";
+ line_full += strip_leading(strip_trailing(line, " \t"), " \t");
+ }
+ else
+ {
+ if (! line_full.empty())
+ _line(line_full);
+
+ line_full = strip_leading(strip_trailing(line, " \t"), " \t");
+ }
+ }
+
+ if (! line_full.empty())
+ _line(line_full);
+}
+
+DescriptionFile::~DescriptionFile()
+{
+}
+
+void
+DescriptionFile::_line(const std::string & l)
+{
+ std::string::size_type p(l.find(':'));
+ if (std::string::npos == p)
+ Log::get_instance()->message(ll_warning, lc_context) << "No colon on line '" << l << "'";
+ else
+ {
+ std::string key(strip_leading(strip_trailing(l.substr(0, p), " \t"), " \t")),
+ value(strip_leading(strip_trailing(l.substr(p + 1), " \t"), " \t"));
+
+ if (key.empty())
+ ;
+ else if (value.empty())
+ ;
+ else
+ {
+ std::pair<std::map<std::string, std::string>::iterator, bool> r(_imp->values.insert(std::make_pair(key, value)));
+ if ((! r.second) && (r.first->second != value))
+ Log::get_instance()->message(ll_qa, lc_context) << "Key '" << key << "' already set to '"
+ << r.first->second << "', ignoring duplicate key value '" << value << "'";
+ }
+ }
+}
+
+std::string
+DescriptionFile::get(const std::string & k) const
+{
+ std::map<std::string, std::string>::const_iterator i(_imp->values.find(k));
+ if (i == _imp->values.end())
+ return "";
+ return i->second;
+}
+
diff --git a/paludis/repositories/cran/description_file.hh b/paludis/repositories/cran/description_file.hh
new file mode 100644
index 0000000..853280e
--- /dev/null
+++ b/paludis/repositories/cran/description_file.hh
@@ -0,0 +1,49 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_REPOSITORIES_CRAN_DESCRIPTION_FILE_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_CRAN_DESCRIPTION_FILE_HH 1
+
+#include <paludis/config_file.hh>
+#include <paludis/util/attributes.hh>
+
+namespace paludis
+{
+ namespace cranrepository
+ {
+ class PALUDIS_VISIBLE DescriptionFile :
+ public ConfigFile,
+ private PrivateImplementationPattern<DescriptionFile>
+ {
+ private:
+ void _line(const std::string &);
+
+ public:
+ DescriptionFile(const Source &);
+ ~DescriptionFile();
+
+ /**
+ * Fetch the value for a particular key, or an empty string.
+ */
+ std::string get(const std::string &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+ }
+}
+
+#endif
diff --git a/paludis/repositories/cran/description_file_TEST.cc b/paludis/repositories/cran/description_file_TEST.cc
new file mode 100644
index 0000000..2f5732f
--- /dev/null
+++ b/paludis/repositories/cran/description_file_TEST.cc
@@ -0,0 +1,49 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/repositories/cran/description_file.hh>
+#include <test/test_runner.hh>
+#include <test/test_framework.hh>
+#include <sstream>
+
+using namespace paludis;
+using namespace paludis::cranrepository;
+using namespace test;
+
+namespace test_cases
+{
+ struct DescriptionTest : TestCase
+ {
+ DescriptionTest() : TestCase("description test") { }
+
+ void run()
+ {
+ std::stringstream s;
+ s << "Foo: bar bar" << std::endl;
+ s << " black sheep" << std::endl;
+ s << "Moo: cow" << std::endl;
+
+ DescriptionFile f(s);
+ TEST_CHECK_EQUAL(f.get("Foo"), "bar bar black sheep");
+ TEST_CHECK_EQUAL(f.get("Moo"), "cow");
+ TEST_CHECK_EQUAL(f.get("Oink"), "");
+ }
+ } test_description;
+}
+
diff --git a/paludis/repositories/cran/keys.cc b/paludis/repositories/cran/keys.cc
new file mode 100644
index 0000000..64c51d6
--- /dev/null
+++ b/paludis/repositories/cran/keys.cc
@@ -0,0 +1,95 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <paludis/repositories/cran/keys.hh>
+#include <paludis/repositories/cran/cran_package_id.hh>
+#include <paludis/util/make_shared_ptr.hh>
+#include <paludis/util/sequence.hh>
+#include <paludis/dep_spec.hh>
+
+using namespace paludis;
+using namespace paludis::cranrepository;
+
+URIKey::URIKey(const std::string & r, const std::string & h, const std::string & v, const MetadataKeyType t) :
+ MetadataSpecTreeKey<URISpecTree>(r, h, t),
+ _v(v)
+{
+}
+
+const tr1::shared_ptr<const URISpecTree::ConstItem>
+URIKey::value() const
+{
+ return make_shared_ptr(new TreeLeaf<URISpecTree, URIDepSpec>(make_shared_ptr(new URIDepSpec(_v))));
+}
+
+std::string
+URIKey::pretty_print() const
+{
+ return _v;
+}
+
+std::string
+URIKey::pretty_print_flat() const
+{
+ return _v;
+}
+
+StringKey::StringKey(const std::string & r, const std::string & h, const std::string & v, const MetadataKeyType t) :
+ MetadataStringKey(r, h, t),
+ _v(v)
+{
+}
+
+const std::string
+StringKey::value() const
+{
+ return _v;
+}
+
+PackageIDSequenceKey::PackageIDSequenceKey(const std::string & r, const std::string & h, const MetadataKeyType t) :
+ MetadataSetKey<PackageIDSequence>(r, h, t),
+ _v(new PackageIDSequence)
+{
+}
+
+const tr1::shared_ptr<const PackageIDSequence>
+PackageIDSequenceKey::value() const
+{
+ return _v;
+}
+
+void
+PackageIDSequenceKey::push_back(const tr1::shared_ptr<const PackageID> & i)
+{
+ _v->push_back(i);
+}
+
+PackageIDKey::PackageIDKey(const std::string & r, const std::string & h, const MetadataKeyType t,
+ const CRANPackageID * const v) :
+ MetadataPackageIDKey(r, h, t),
+ _v(v)
+{
+}
+
+const tr1::shared_ptr<const PackageID>
+PackageIDKey::value() const
+{
+ return _v->shared_from_this();
+}
+
diff --git a/paludis/repositories/cran/keys.hh b/paludis/repositories/cran/keys.hh
new file mode 100644
index 0000000..ad1fd94
--- /dev/null
+++ b/paludis/repositories/cran/keys.hh
@@ -0,0 +1,94 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_PALUDIS_REPOSITORIES_CRAN_KEYS_HH
+#define PALUDIS_GUARD_PALUDIS_PALUDIS_REPOSITORIES_CRAN_KEYS_HH 1
+
+#include <paludis/metadata_key.hh>
+
+namespace paludis
+{
+ namespace cranrepository
+ {
+ class CRANPackageID;
+
+ class URIKey :
+ public MetadataSpecTreeKey<URISpecTree>
+ {
+ private:
+ const std::string _v;
+
+ public:
+ URIKey(const std::string &, const std::string &, const std::string &, const MetadataKeyType);
+
+ virtual const tr1::shared_ptr<const URISpecTree::ConstItem> value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual std::string pretty_print() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ virtual std::string pretty_print_flat() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class StringKey :
+ public MetadataStringKey
+ {
+ private:
+ const std::string _v;
+
+ public:
+ StringKey(const std::string &, const std::string &, const std::string &, const MetadataKeyType);
+
+ virtual const std::string value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+
+ class PackageIDSequenceKey :
+ public MetadataSetKey<PackageIDSequence>
+ {
+ private:
+ const tr1::shared_ptr<PackageIDSequence> _v;
+
+ public:
+ PackageIDSequenceKey(const std::string &, const std::string &, const MetadataKeyType);
+
+ virtual const tr1::shared_ptr<const PackageIDSequence> value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ void push_back(const tr1::shared_ptr<const PackageID> &);
+ };
+
+ class PackageIDKey :
+ public MetadataPackageIDKey
+ {
+ private:
+ const CRANPackageID * const _v;
+
+ public:
+ PackageIDKey(const std::string &, const std::string &, const MetadataKeyType,
+ const CRANPackageID * const);
+
+ virtual const tr1::shared_ptr<const PackageID> value() const
+ PALUDIS_ATTRIBUTE((warn_unused_result));
+ };
+ }
+}
+
+#endif
diff --git a/paludis/repositories/cran/masks.cc b/paludis/repositories/cran/masks.cc
new file mode 100644
index 0000000..4d92ebb
--- /dev/null
+++ b/paludis/repositories/cran/masks.cc
@@ -0,0 +1,70 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "masks.hh"
+#include <paludis/util/private_implementation_pattern-impl.hh>
+
+using namespace paludis;
+using namespace paludis::cranrepository;
+
+namespace paludis
+{
+ template <>
+ struct Implementation<BrokenMask>
+ {
+ const char key;
+ const std::string description;
+ const std::string explanation;
+
+ Implementation(const char k, const std::string & d, const std::string & e) :
+ key(k),
+ description(d),
+ explanation(e)
+ {
+ }
+ };
+}
+
+BrokenMask::BrokenMask(const char c, const std::string & d, const std::string & e) :
+ PrivateImplementationPattern<BrokenMask>(new Implementation<BrokenMask>(c, d, e))
+{
+}
+
+BrokenMask::~BrokenMask()
+{
+}
+
+const char
+BrokenMask::key() const
+{
+ return _imp->key;
+}
+
+const std::string
+BrokenMask::description() const
+{
+ return _imp->description;
+}
+
+const std::string
+BrokenMask::explanation() const
+{
+ return _imp->explanation;
+}
+
diff --git a/paludis/repositories/cran/masks.hh b/paludis/repositories/cran/masks.hh
new file mode 100644
index 0000000..f09df88
--- /dev/null
+++ b/paludis/repositories/cran/masks.hh
@@ -0,0 +1,45 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2007 Ciaran McCreesh <ciaranm@ciaranm.org>
+ *
+ * This file is part of the Paludis package manager. Paludis is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU General
+ * Public License version 2, as published by the Free Software Foundation.
+ *
+ * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef PALUDIS_GUARD_PALUDIS_PALUDIS_REPOSITORIES_CRAN_MASKS_HH
+#define PALUDIS_GUARD_PALUDIS_PALUDIS_REPOSITORIES_CRAN_MASKS_HH 1
+
+#include <paludis/mask.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+
+namespace paludis
+{
+ namespace cranrepository
+ {
+ class BrokenMask :
+ public UnsupportedMask,
+ private PrivateImplementationPattern<BrokenMask>
+ {
+ public:
+ BrokenMask(const char, const std::string &, const std::string &);
+ ~BrokenMask();
+
+ virtual const char key() const;
+ virtual const std::string description() const;
+ virtual const std::string explanation() const;
+ };
+ }
+}
+
+#endif
diff --git a/paludis/repositories/cran/normalise.cc b/paludis/repositories/cran/normalise.cc
index aeb493b..116471b 100644
--- a/paludis/repositories/cran/normalise.cc
+++ b/paludis/repositories/cran/normalise.cc
@@ -22,15 +22,19 @@
using namespace paludis;
-void
-paludis::cranrepository::normalise_name(std::string & s)
+std::string
+paludis::cranrepository::cran_name_to_internal(const std::string & s)
{
- std::replace(s.begin(), s.end(), '.', '-');
+ std::string result(s);
+ std::replace(result.begin(),result.end(), '.', '-');
+ return result;
}
-void
-paludis::cranrepository::normalise_version(std::string & s)
+std::string
+paludis::cranrepository::cran_version_to_internal(const std::string & s)
{
- std::replace(s.begin(), s.end(), '-', '.');
+ std::string result(s);
+ std::replace(result.begin(), result.end(), '-', '.');
+ return result;
}
diff --git a/paludis/repositories/cran/normalise.hh b/paludis/repositories/cran/normalise.hh
index 3bedf8c..71e72cb 100644
--- a/paludis/repositories/cran/normalise.hh
+++ b/paludis/repositories/cran/normalise.hh
@@ -21,13 +21,14 @@
#define PALUDIS_GUARD_PALUDIS_PALUDIS_REPOSITORIES_CRAN_NORMALISE_HH 1
#include <string>
+#include <paludis/util/attributes.hh>
namespace paludis
{
namespace cranrepository
{
- void normalise_name(std::string &);
- void normalise_version(std::string &);
+ std::string cran_name_to_internal(const std::string &) PALUDIS_ATTRIBUTE((warn_unused_result));
+ std::string cran_version_to_internal(const std::string &) PALUDIS_ATTRIBUTE((warn_unused_result));
}
}
diff --git a/paludis/repositories/e/ebuild_id.cc b/paludis/repositories/e/ebuild_id.cc
index d7c2663..8eb407e 100644
--- a/paludis/repositories/e/ebuild_id.cc
+++ b/paludis/repositories/e/ebuild_id.cc
@@ -848,3 +848,15 @@ EbuildID::perform_action(Action & a) const
a.accept(b);
}
+const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >
+EbuildID::contains_key() const
+{
+ return tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >();
+}
+
+const tr1::shared_ptr<const MetadataPackageIDKey>
+EbuildID::contained_in_key() const
+{
+ return tr1::shared_ptr<const MetadataPackageIDKey>();
+}
+
diff --git a/paludis/repositories/e/ebuild_id.hh b/paludis/repositories/e/ebuild_id.hh
index 33f2d2c..23dcd9a 100644
--- a/paludis/repositories/e/ebuild_id.hh
+++ b/paludis/repositories/e/ebuild_id.hh
@@ -85,6 +85,8 @@ namespace paludis
virtual const tr1::shared_ptr<const MetadataTimeKey> installed_time_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> source_origin_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> binary_origin_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> > contains_key() const;
+ virtual const tr1::shared_ptr<const MetadataPackageIDKey> contained_in_key() const;
virtual bool arbitrary_less_than_comparison(const PackageID &) const
PALUDIS_ATTRIBUTE((warn_unused_result));
diff --git a/paludis/repositories/e/vdb_id.cc b/paludis/repositories/e/vdb_id.cc
index 397dd81..c991d7f 100644
--- a/paludis/repositories/e/vdb_id.cc
+++ b/paludis/repositories/e/vdb_id.cc
@@ -682,3 +682,15 @@ VDBID::perform_action(Action & a) const
a.accept(b);
}
+const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >
+VDBID::contains_key() const
+{
+ return tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >();
+}
+
+const tr1::shared_ptr<const MetadataPackageIDKey>
+VDBID::contained_in_key() const
+{
+ return tr1::shared_ptr<const MetadataPackageIDKey>();
+}
+
diff --git a/paludis/repositories/e/vdb_id.hh b/paludis/repositories/e/vdb_id.hh
index 192929a..d2da574 100644
--- a/paludis/repositories/e/vdb_id.hh
+++ b/paludis/repositories/e/vdb_id.hh
@@ -79,6 +79,8 @@ namespace paludis
virtual const tr1::shared_ptr<const MetadataTimeKey> installed_time_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> source_origin_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> binary_origin_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> > contains_key() const;
+ virtual const tr1::shared_ptr<const MetadataPackageIDKey> contained_in_key() const;
virtual bool supports_action(const SupportsActionTestBase &) const PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void perform_action(Action &) const;
diff --git a/paludis/repositories/fake/fake_package_id.cc b/paludis/repositories/fake/fake_package_id.cc
index 88ea773..3eb9341 100644
--- a/paludis/repositories/fake/fake_package_id.cc
+++ b/paludis/repositories/fake/fake_package_id.cc
@@ -745,6 +745,18 @@ FakePackageID::breaks_portage() const
return (version().has_try_part() || version().has_scm_part());
}
+const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >
+FakePackageID::contains_key() const
+{
+ return tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >();
+}
+
+const tr1::shared_ptr<const MetadataPackageIDKey>
+FakePackageID::contained_in_key() const
+{
+ return tr1::shared_ptr<const MetadataPackageIDKey>();
+}
+
template class FakeMetadataSpecTreeKey<LicenseSpecTree>;
template class FakeMetadataSpecTreeKey<ProvideSpecTree>;
template class FakeMetadataSpecTreeKey<DependencySpecTree>;
diff --git a/paludis/repositories/fake/fake_package_id.hh b/paludis/repositories/fake/fake_package_id.hh
index 276addc..da6dad4 100644
--- a/paludis/repositories/fake/fake_package_id.hh
+++ b/paludis/repositories/fake/fake_package_id.hh
@@ -163,6 +163,8 @@ namespace paludis
virtual const tr1::shared_ptr<const MetadataTimeKey> installed_time_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> source_origin_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> binary_origin_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> > contains_key() const;
+ virtual const tr1::shared_ptr<const MetadataPackageIDKey> contained_in_key() const;
const tr1::shared_ptr<FakeMetadataKeywordSetKey> keywords_key();
const tr1::shared_ptr<FakeMetadataIUseSetKey> iuse_key();
diff --git a/paludis/repositories/gems/gem_specification.cc b/paludis/repositories/gems/gem_specification.cc
index 8fe7138..990402a 100644
--- a/paludis/repositories/gems/gem_specification.cc
+++ b/paludis/repositories/gems/gem_specification.cc
@@ -486,6 +486,18 @@ GemSpecification::binary_origin_key() const
return tr1::shared_ptr<const MetadataStringKey>();
}
+const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >
+GemSpecification::contains_key() const
+{
+ return tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >();
+}
+
+const tr1::shared_ptr<const MetadataPackageIDKey>
+GemSpecification::contained_in_key() const
+{
+ return tr1::shared_ptr<const MetadataPackageIDKey>();
+}
+
bool
GemSpecification::arbitrary_less_than_comparison(const PackageID &) const
{
diff --git a/paludis/repositories/gems/gem_specification.hh b/paludis/repositories/gems/gem_specification.hh
index ffded7a..2e2dae8 100644
--- a/paludis/repositories/gems/gem_specification.hh
+++ b/paludis/repositories/gems/gem_specification.hh
@@ -107,6 +107,8 @@ namespace paludis
virtual const tr1::shared_ptr<const MetadataSpecTreeKey<URISpecTree> > bin_uri_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> short_description_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> long_description_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> > contains_key() const;
+ virtual const tr1::shared_ptr<const MetadataPackageIDKey> contained_in_key() const;
virtual const tr1::shared_ptr<const MetadataContentsKey> contents_key() const;
virtual const tr1::shared_ptr<const MetadataTimeKey> installed_time_key() const;
diff --git a/paludis/repositories/gems/gem_specification_TEST.cc b/paludis/repositories/gems/gem_specification_TEST.cc
index 7ac3349..1c373d9 100644
--- a/paludis/repositories/gems/gem_specification_TEST.cc
+++ b/paludis/repositories/gems/gem_specification_TEST.cc
@@ -64,6 +64,10 @@ namespace
{
}
+ void visit(const MetadataSetKey<PackageIDSequence> &)
+ {
+ }
+
void visit(const MetadataSpecTreeKey<DependencySpecTree> &)
{
}
diff --git a/paludis/repositories/virtuals/package_id.cc b/paludis/repositories/virtuals/package_id.cc
index 5d654ca..e43975d 100644
--- a/paludis/repositories/virtuals/package_id.cc
+++ b/paludis/repositories/virtuals/package_id.cc
@@ -496,4 +496,15 @@ VirtualsPackageID::breaks_portage() const
return (version().has_try_part() || version().has_scm_part());
}
+const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >
+VirtualsPackageID::contains_key() const
+{
+ return tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >();
+}
+
+const tr1::shared_ptr<const MetadataPackageIDKey>
+VirtualsPackageID::contained_in_key() const
+{
+ return tr1::shared_ptr<const MetadataPackageIDKey>();
+}
diff --git a/paludis/repositories/virtuals/package_id.hh b/paludis/repositories/virtuals/package_id.hh
index 77204dc..93d84c7 100644
--- a/paludis/repositories/virtuals/package_id.hh
+++ b/paludis/repositories/virtuals/package_id.hh
@@ -113,6 +113,8 @@ namespace paludis
virtual const tr1::shared_ptr<const MetadataTimeKey> installed_time_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> source_origin_key() const;
virtual const tr1::shared_ptr<const MetadataStringKey> binary_origin_key() const;
+ virtual const tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> > contains_key() const;
+ virtual const tr1::shared_ptr<const MetadataPackageIDKey> contained_in_key() const;
virtual bool supports_action(const SupportsActionTestBase &) const PALUDIS_ATTRIBUTE((warn_unused_result));
virtual void perform_action(Action &) const;
diff --git a/python/metadata_key.cc b/python/metadata_key.cc
index 7ca6dd5..c2b9645 100644
--- a/python/metadata_key.cc
+++ b/python/metadata_key.cc
@@ -140,6 +140,11 @@ struct MetadataKeyToPython :
{
value = bp::object(bp::ptr(&k));
}
+
+ void visit(const MetadataSetKey<PackageIDSequence> & k)
+ {
+ value = bp::object(bp::ptr(&k));
+ }
};
struct metadata_key_to_python
diff --git a/ruby/package_id.cc b/ruby/package_id.cc
index a4543c5..ecf7bda 100644
--- a/ruby/package_id.cc
+++ b/ruby/package_id.cc
@@ -43,6 +43,7 @@ namespace
static VALUE c_metadata_use_flag_name_set_key;
static VALUE c_metadata_iuse_flag_set_key;
static VALUE c_metadata_inherited_set_key;
+ static VALUE c_metadata_package_id_sequence_key;
static VALUE c_metadata_key_type;
struct V :
@@ -109,6 +110,12 @@ namespace
new tr1::shared_ptr<const MetadataSetKey<InheritedSet> >(tr1::static_pointer_cast<const MetadataSetKey<InheritedSet> >(mm)));
}
+ void visit(const MetadataSetKey<PackageIDSequence> &)
+ {
+ value = Data_Wrap_Struct(c_metadata_package_id_sequence_key, 0, &Common<tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> > >::free,
+ new tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >(tr1::static_pointer_cast<const MetadataSetKey<PackageIDSequence> >(mm)));
+ }
+
void visit(const MetadataSpecTreeKey<LicenseSpecTree> &)
{
value = Qnil;
@@ -407,6 +414,22 @@ namespace
}
};
+ template <>
+ struct SetValue<PackageIDSequence>
+ {
+ static VALUE
+ fetch(VALUE self)
+ {
+ tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> > * self_ptr;
+ Data_Get_Struct(self, tr1::shared_ptr<const MetadataSetKey<PackageIDSequence> >, self_ptr);
+ tr1::shared_ptr<const PackageIDSequence> c = (*self_ptr)->value();
+ VALUE result (rb_ary_new());
+ for (PackageIDSequence::Iterator i(c->begin()), i_end(c->end()) ; i != i_end ; ++i)
+ rb_ary_push(result, package_id_to_value(*i));
+ return result;
+ }
+ };
+
void do_register_package_id()
{
/*
@@ -505,6 +528,14 @@ namespace
rb_define_method(c_metadata_use_flag_name_set_key, "value", RUBY_FUNC_CAST((&SetValue<UseFlagNameSet>::fetch)), 0);
/*
+ * Document-class: Paludis::MetadataPackageIDSequenceKey
+ *
+ * Metadata class for Use flag names
+ */
+ c_metadata_package_id_sequence_key = rb_define_class_under(paludis_module(), "MetadataPackageIDSequenceKey", c_metadata_key);
+ rb_define_method(c_metadata_package_id_sequence_key, "value", RUBY_FUNC_CAST((&SetValue<PackageIDSequence>::fetch)), 0);
+
+ /*
* Document-class: Paludis::MetadataIUseFlagSetKey
*
* Metadata class for IUse flags
diff --git a/src/output/console_query_task.cc b/src/output/console_query_task.cc
index cf36a82..0616722 100644
--- a/src/output/console_query_task.cc
+++ b/src/output/console_query_task.cc
@@ -305,6 +305,33 @@ namespace
}
}
+ void visit(const MetadataSetKey<PackageIDSequence> & k)
+ {
+ if (k.type() == type)
+ {
+ if (k.value()->empty() || next(k.value()->begin()) == k.value()->end())
+ task->display_metadata_pde(k.human_name(), k.raw_name(), **k.value()->begin());
+ else if (task->want_raw())
+ {
+ task->output_left_column(k.raw_name() + ":");
+ task->output_right_column(join(indirect_iterator(k.value()->begin()), indirect_iterator(k.value()->end()), ", "));
+ }
+ else
+ {
+ for (PackageIDSequence::Iterator i(k.value()->begin()), i_end(k.value()->end()) ;
+ i != i_end ; ++i)
+ {
+ if (i == k.value()->begin())
+ task->output_left_column(k.human_name() + ":");
+ else
+ task->output_left_column("");
+
+ task->output_right_column(task->render_as_package_name(stringify(**i)));
+ }
+ }
+ }
+ }
+
void visit(const MetadataPackageIDKey & k)
{
if (k.type() == type)