aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-07-28 19:50:51 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-07-28 19:50:51 +0000
commitf5e5425a91baba4b851a99d5fdf7de68f1df3cfc (patch)
treeed0da1eeca7c044d6c59aeb3b4213dcb081b6b0b
parent0419f9776ce67c25cbde1203dc7b8cfc1a77895a (diff)
downloadpaludis-f5e5425a91baba4b851a99d5fdf7de68f1df3cfc.tar.gz
paludis-f5e5425a91baba4b851a99d5fdf7de68f1df3cfc.tar.xz
r1209@snowdrop: ciaranm | 2006-07-28 20:50:37 +0100
Split up PortageRepository some more. Move the news and advisory config file implementations from the main library into the Portage repository library.
-rw-r--r--paludis/repositories/portage/Makefile.am6
-rw-r--r--paludis/repositories/portage/portage_repository.cc125
-rw-r--r--paludis/repositories/portage/portage_repository_ebuild_metadata.cc180
-rw-r--r--paludis/repositories/portage/portage_repository_ebuild_metadata.hh50
-rw-r--r--paludis/repositories/portage/portage_repository_metadata.cc32
-rw-r--r--paludis/repositories/portage/portage_repository_metadata.hh60
-rw-r--r--paludis/repositories/portage/portage_repository_news.cc263
-rw-r--r--paludis/repositories/portage/portage_repository_news.hh133
-rw-r--r--paludis/repositories/portage/portage_repository_sets.cc442
-rw-r--r--paludis/repositories/portage/portage_repository_sets.hh74
10 files changed, 1249 insertions, 116 deletions
diff --git a/paludis/repositories/portage/Makefile.am b/paludis/repositories/portage/Makefile.am
index 54e153b..9cd9938 100644
--- a/paludis/repositories/portage/Makefile.am
+++ b/paludis/repositories/portage/Makefile.am
@@ -18,7 +18,9 @@ paludis_repositories_portage_include_HEADERS = \
portage_repository_profile.hh \
portage_repository_exceptions.hh \
portage_repository_news.hh \
- portage_repository_sets.hh
+ portage_repository_sets.hh \
+ portage_repository_metadata.hh \
+ portage_repository_ebuild_metadata.hh
libpaludisportagerepository_la_SOURCES = \
portage_repository.cc \
@@ -26,6 +28,8 @@ libpaludisportagerepository_la_SOURCES = \
portage_repository_exceptions.cc \
portage_repository_news.cc \
portage_repository_sets.cc \
+ portage_repository_metadata.cc \
+ portage_repository_ebuild_metadata.cc \
$(paludis_repositories_portage_include_HEADERS)
TESTS = portage_repository_TEST
diff --git a/paludis/repositories/portage/portage_repository.cc b/paludis/repositories/portage/portage_repository.cc
index de582d5..ad856ae 100644
--- a/paludis/repositories/portage/portage_repository.cc
+++ b/paludis/repositories/portage/portage_repository.cc
@@ -25,6 +25,7 @@
#include <paludis/repositories/portage/portage_repository_news.hh>
#include <paludis/repositories/portage/portage_repository_sets.hh>
#include <paludis/repositories/portage/portage_repository_exceptions.hh>
+#include <paludis/repositories/portage/portage_repository_ebuild_metadata.hh>
#include <paludis/config_file.hh>
#include <paludis/dep_atom.hh>
@@ -208,6 +209,9 @@ namespace paludis
/// Our sets handler.
mutable PortageRepositorySets::Pointer sets_ptr;
+ /// Our metadata handler.
+ mutable PortageRepositoryMetadata::Pointer metadata_ptr;
+
/// Our virtuals
mutable VirtualsMap our_virtuals;
@@ -238,6 +242,7 @@ namespace paludis
profile_ptr(0),
news_ptr(0),
sets_ptr(0),
+ metadata_ptr(new PortageRepositoryEbuildMetadata(cache, location)),
has_our_virtuals(false)
{
}
@@ -428,7 +433,7 @@ PortageRepository::do_package_names(const CategoryNamePart & c) const
if (! d->is_directory())
continue;
if (DirIterator() == std::find_if(DirIterator(*d), DirIterator(),
- IsFileWithExtension(".ebuild")))
+ IsFileWithExtension(_imp->metadata_ptr->file_extension())))
continue;
try
@@ -539,13 +544,14 @@ PortageRepository::need_version_names(const QualifiedPackageName & n) const
{
for (DirIterator e(path), e_end ; e != e_end ; ++e)
{
- if (! IsFileWithExtension(stringify(n.get<qpn_package>()) + "-", ".ebuild")(*e))
+ if (! IsFileWithExtension(stringify(n.get<qpn_package>()) + "-",
+ _imp->metadata_ptr->file_extension())(*e))
continue;
try
{
v->insert(strip_leading_string(
- strip_trailing_string(e->basename(), ".ebuild"),
+ strip_trailing_string(e->basename(), _imp->metadata_ptr->file_extension()),
stringify(n.get<qpn_package>()) + "-"));
}
catch (const NameError &)
@@ -613,118 +619,7 @@ PortageRepository::do_version_metadata(
PortageDepParser::parse_depend));
}
- VersionMetadata::Pointer result(new VersionMetadata::Ebuild(PortageDepParser::parse_depend));
-
- FSEntry cache_file(_imp->cache);
- cache_file /= stringify(q.get<qpn_category>());
- cache_file /= stringify(q.get<qpn_package>()) + "-" + stringify(v);
-
- bool ok(false);
- VirtualsMap::iterator vi(_imp->our_virtuals.end());
- if (cache_file.is_regular_file())
- {
- std::ifstream cache(stringify(cache_file).c_str());
- std::string line;
-
- if (cache)
- {
- std::getline(cache, line); result->get<vm_deps>().set<vmd_build_depend_string>(line);
- std::getline(cache, line); result->get<vm_deps>().set<vmd_run_depend_string>(line);
- std::getline(cache, line); result->set<vm_slot>(SlotName(line));
- std::getline(cache, line); result->get_ebuild_interface()->set<evm_src_uri>(line);
- std::getline(cache, line); result->get_ebuild_interface()->set<evm_restrict>(line);
- std::getline(cache, line); result->set<vm_homepage>(line);
- std::getline(cache, line); result->set<vm_license>(line);
- std::getline(cache, line); result->set<vm_description>(line);
- std::getline(cache, line); result->get_ebuild_interface()->set<evm_keywords>(line);
- std::getline(cache, line); result->get_ebuild_interface()->set<evm_inherited>(line);
- std::getline(cache, line); result->get_ebuild_interface()->set<evm_iuse>(line);
- std::getline(cache, line);
- std::getline(cache, line); result->get<vm_deps>().set<vmd_post_depend_string>(line);
- std::getline(cache, line); result->get_ebuild_interface()->set<evm_provide>(line);
- std::getline(cache, line); result->set<vm_eapi>(line);
- result->get_ebuild_interface()->set<evm_virtual>("");
-
- // check mtimes
- time_t cache_time(cache_file.mtime());
- ok = true;
-
- if ((_imp->location / stringify(q.get<qpn_category>()) /
- stringify(q.get<qpn_package>()) /
- (stringify(q.get<qpn_package>()) + "-" + stringify(v)
- + ".ebuild")).mtime() > cache_time)
- ok = false;
- else
- {
- FSEntry timestamp(_imp->location / "metadata" / "timestamp");
- if (timestamp.exists())
- cache_time = timestamp.mtime();
-
- std::list<std::string> inherits;
- WhitespaceTokeniser::get_instance()->tokenise(
- stringify(result->get_ebuild_interface()->get<evm_inherited>()),
- std::back_inserter(inherits));
- for (FSEntryCollection::Iterator e(_imp->eclassdirs->begin()),
- e_end(_imp->eclassdirs->end()) ; e != e_end ; ++e)
- for (std::list<std::string>::const_iterator i(inherits.begin()),
- i_end(inherits.end()) ; i != i_end ; ++i)
- {
- if ((*e / (*i + ".eclass")).exists())
- if (((*e / (*i + ".eclass"))).mtime() > cache_time)
- ok = false;
- }
- }
-
- if (! ok)
- Log::get_instance()->message(ll_warning, lc_no_context, "Stale cache file at '"
- + stringify(cache_file) + "'");
- }
- else
- Log::get_instance()->message(ll_warning, lc_no_context,
- "Couldn't read the cache file at '"
- + stringify(cache_file) + "'");
- }
- else if (_imp->our_virtuals.end() != ((vi = _imp->our_virtuals.find(q))))
- {
- VersionMetadata::ConstPointer m(version_metadata(vi->second->package(), v));
- result->set<vm_slot>(m->get<vm_slot>());
- result->get_ebuild_interface()->set<evm_keywords>(m->get_ebuild_interface()->get<evm_keywords>());
- result->set<vm_eapi>(m->get<vm_eapi>());
- result->get_ebuild_interface()->set<evm_virtual>(stringify(vi->second->package()));
- result->get<vm_deps>().set<vmd_build_depend_string>(
- "=" + stringify(vi->second->package()) + "-" + stringify(v));
- ok = true;
- }
-
- if (! ok)
- {
- if (_imp->cache.basename() != "empty")
- Log::get_instance()->message(ll_warning, lc_no_context,
- "No usable cache entry for '" + stringify(q) +
- "-" + stringify(v) + "' in '" + stringify(name()) + "'");
-
- PackageDatabaseEntry e(q, v, name());
- EbuildMetadataCommand cmd(EbuildCommandParams::create((
- param<ecpk_environment>(_imp->env),
- param<ecpk_db_entry>(&e),
- param<ecpk_ebuild_dir>(_imp->location / stringify(q.get<qpn_category>()) /
- stringify(q.get<qpn_package>())),
- param<ecpk_files_dir>(_imp->location / stringify(q.get<qpn_category>()) /
- stringify(q.get<qpn_package>()) / "files"),
- param<ecpk_eclassdirs>(_imp->eclassdirs),
- param<ecpk_portdir>(_imp->location),
- param<ecpk_distdir>(_imp->distdir),
- param<ecpk_buildroot>(_imp->buildroot)
- )));
- if (! cmd())
- Log::get_instance()->message(ll_warning, lc_no_context,
- "No usable metadata for '" + stringify(q)
- + "-" + stringify(v) + "' in '" + stringify(name()) + "'");
-
- if (0 == ((result = cmd.metadata())))
- throw InternalError(PALUDIS_HERE, "cmd.metadata() is zero pointer???");
- }
-
+ VersionMetadata::Pointer result(_imp->metadata_ptr->generate_version_metadata(q, v));
_imp->metadata.insert(std::make_pair(std::make_pair(q, v), result));
return result;
}
diff --git a/paludis/repositories/portage/portage_repository_ebuild_metadata.cc b/paludis/repositories/portage/portage_repository_ebuild_metadata.cc
new file mode 100644
index 0000000..29ef011
--- /dev/null
+++ b/paludis/repositories/portage/portage_repository_ebuild_metadata.cc
@@ -0,0 +1,180 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * 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/portage/portage_repository_ebuild_metadata.hh>
+
+#include <paludis/portage_dep_parser.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/tokeniser.hh>
+
+#include <fstream>
+#include <list>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template<>
+ struct Implementation<PortageRepositoryEbuildMetadata> :
+ InternalCounted<Implementation<PortageRepositoryEbuildMetadata> >
+ {
+ FSEntry cache_dir;
+ FSEntry ebuild_dir;
+
+ Implementation(const FSEntry & c, const FSEntry & e) :
+ cache_dir(c),
+ ebuild_dir(e)
+ {
+ }
+ };
+}
+
+PortageRepositoryEbuildMetadata::PortageRepositoryEbuildMetadata(const FSEntry & c,
+ const FSEntry & e) :
+ PortageRepositoryMetadata(".ebuild"),
+ PrivateImplementationPattern<PortageRepositoryEbuildMetadata>(new
+ Implementation<PortageRepositoryEbuildMetadata>(c, e))
+{
+}
+
+PortageRepositoryEbuildMetadata::~PortageRepositoryEbuildMetadata()
+{
+}
+
+VersionMetadata::Pointer
+PortageRepositoryEbuildMetadata::generate_version_metadata(const QualifiedPackageName & q,
+ const VersionSpec & v) const
+{
+ VersionMetadata::Pointer result(new VersionMetadata::Ebuild(PortageDepParser::parse_depend));
+
+ FSEntry cache_file(_imp->cache_dir);
+ cache_file /= stringify(q.get<qpn_category>());
+ cache_file /= stringify(q.get<qpn_package>()) + "-" + stringify(v);
+
+ bool ok(false);
+ VirtualsMap::iterator vi(_imp->our_virtuals.end());
+ if (cache_file.is_regular_file())
+ {
+ std::ifstream cache(stringify(cache_file).c_str());
+ std::string line;
+
+ if (cache)
+ {
+ std::getline(cache, line); result->get<vm_deps>().set<vmd_build_depend_string>(line);
+ std::getline(cache, line); result->get<vm_deps>().set<vmd_run_depend_string>(line);
+ std::getline(cache, line); result->set<vm_slot>(SlotName(line));
+ std::getline(cache, line); result->get_ebuild_interface()->set<evm_src_uri>(line);
+ std::getline(cache, line); result->get_ebuild_interface()->set<evm_restrict>(line);
+ std::getline(cache, line); result->set<vm_homepage>(line);
+ std::getline(cache, line); result->set<vm_license>(line);
+ std::getline(cache, line); result->set<vm_description>(line);
+ std::getline(cache, line); result->get_ebuild_interface()->set<evm_keywords>(line);
+ std::getline(cache, line); result->get_ebuild_interface()->set<evm_inherited>(line);
+ std::getline(cache, line); result->get_ebuild_interface()->set<evm_iuse>(line);
+ std::getline(cache, line);
+ std::getline(cache, line); result->get<vm_deps>().set<vmd_post_depend_string>(line);
+ std::getline(cache, line); result->get_ebuild_interface()->set<evm_provide>(line);
+ std::getline(cache, line); result->set<vm_eapi>(line);
+ result->get_ebuild_interface()->set<evm_virtual>("");
+
+ // check mtimes
+ time_t cache_time(cache_file.mtime());
+ ok = true;
+
+ if ((_imp->ebuild_dir / stringify(q.get<qpn_category>()) /
+ stringify(q.get<qpn_package>()) /
+ (stringify(q.get<qpn_package>()) + "-" + stringify(v)
+ + ".ebuild")).mtime() > cache_time)
+ ok = false;
+ else
+ {
+ FSEntry timestamp(_imp->ebuild_dir / "metadata" / "timestamp");
+ if (timestamp.exists())
+ cache_time = timestamp.mtime();
+
+ std::list<std::string> inherits;
+ WhitespaceTokeniser::get_instance()->tokenise(
+ stringify(result->get_ebuild_interface()->get<evm_inherited>()),
+ std::back_inserter(inherits));
+ for (FSEntryCollection::Iterator e(_imp->eclassdirs->begin()),
+ e_end(_imp->eclassdirs->end()) ; e != e_end ; ++e)
+ for (std::list<std::string>::const_iterator i(inherits.begin()),
+ i_end(inherits.end()) ; i != i_end ; ++i)
+ {
+ if ((*e / (*i + ".eclass")).exists())
+ if (((*e / (*i + ".eclass"))).mtime() > cache_time)
+ ok = false;
+ }
+ }
+
+ if (! ok)
+ Log::get_instance()->message(ll_warning, lc_no_context, "Stale cache file at '"
+ + stringify(cache_file) + "'");
+ }
+ else
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Couldn't read the cache file at '"
+ + stringify(cache_file) + "'");
+ }
+ else if (_imp->our_virtuals.end() != ((vi = _imp->our_virtuals.find(q))))
+ {
+ VersionMetadata::ConstPointer m(version_metadata(vi->second->package(), v));
+ result->set<vm_slot>(m->get<vm_slot>());
+ result->get_ebuild_interface()->set<evm_keywords>(m->get_ebuild_interface()->get<evm_keywords>());
+ result->set<vm_eapi>(m->get<vm_eapi>());
+ result->get_ebuild_interface()->set<evm_virtual>(stringify(vi->second->package()));
+ result->get<vm_deps>().set<vmd_build_depend_string>(
+ "=" + stringify(vi->second->package()) + "-" + stringify(v));
+ ok = true;
+ }
+
+ if (! ok)
+ {
+ if (_imp->cache.basename() != "empty")
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "No usable cache entry for '" + stringify(q) +
+ "-" + stringify(v) + "' in '" + stringify(name()) + "'");
+
+ PackageDatabaseEntry e(q, v, name());
+ EbuildMetadataCommand cmd(EbuildCommandParams::create((
+ param<ecpk_environment>(_imp->env),
+ param<ecpk_db_entry>(&e),
+ param<ecpk_ebuild_dir>(_imp->location / stringify(q.get<qpn_category>()) /
+ stringify(q.get<qpn_package>())),
+ param<ecpk_files_dir>(_imp->location / stringify(q.get<qpn_category>()) /
+ stringify(q.get<qpn_package>()) / "files"),
+ param<ecpk_eclassdirs>(_imp->eclassdirs),
+ param<ecpk_portdir>(_imp->location),
+ param<ecpk_distdir>(_imp->distdir),
+ param<ecpk_buildroot>(_imp->buildroot)
+ )));
+ if (! cmd())
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "No usable metadata for '" + stringify(q)
+ + "-" + stringify(v) + "' in '" + stringify(name()) + "'");
+
+ if (0 == ((result = cmd.metadata())))
+ throw InternalError(PALUDIS_HERE, "cmd.metadata() is zero pointer???");
+ }
+
+ return result;
+
+}
+
diff --git a/paludis/repositories/portage/portage_repository_ebuild_metadata.hh b/paludis/repositories/portage/portage_repository_ebuild_metadata.hh
new file mode 100644
index 0000000..38864af
--- /dev/null
+++ b/paludis/repositories/portage/portage_repository_ebuild_metadata.hh
@@ -0,0 +1,50 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * 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_PORTAGE_PORTAGE_REPOSITORY_EBUILD_METADATA_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_PORTAGE_PORTAGE_REPOSITORY_EBUILD_METADATA_HH 1
+
+#include <paludis/repositories/portage/portage_repository_metadata.hh>
+#include <paludis/util/private_implementation_pattern.hh>
+
+/** \file
+ * Declaration for the PortageRepositoryEbuildMetadata class.
+ *
+ * \ingroup grpportagerepository
+ */
+
+namespace paludis
+{
+ class FSEntry;
+
+ class PortageRepositoryEbuildMetadata :
+ public PortageRepositoryMetadata,
+ private PrivateImplementationPattern<PortageRepositoryEbuildMetadata>
+ {
+ public:
+ PortageRepositoryEbuildMetadata(const FSEntry & cache_dir, const FSEntry & ebuild_dir);
+
+ virtual ~PortageRepositoryEbuildMetadata();
+
+ virtual VersionMetadata::Pointer generate_version_metadata(const QualifiedPackageName &,
+ const VersionSpec &) const;
+ };
+}
+
+#endif
diff --git a/paludis/repositories/portage/portage_repository_metadata.cc b/paludis/repositories/portage/portage_repository_metadata.cc
new file mode 100644
index 0000000..3b7e81d
--- /dev/null
+++ b/paludis/repositories/portage/portage_repository_metadata.cc
@@ -0,0 +1,32 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * 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 "portage_repository_metadata.hh"
+
+using namespace paludis;
+
+PortageRepositoryMetadata::PortageRepositoryMetadata(const std::string & ext) :
+ _ext(ext)
+{
+}
+
+PortageRepositoryMetadata::~PortageRepositoryMetadata()
+{
+}
+
diff --git a/paludis/repositories/portage/portage_repository_metadata.hh b/paludis/repositories/portage/portage_repository_metadata.hh
new file mode 100644
index 0000000..18d2f09
--- /dev/null
+++ b/paludis/repositories/portage/portage_repository_metadata.hh
@@ -0,0 +1,60 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * 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_PORTAGE_PORTAGE_REPOSITORY_METADATA_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_PORTAGE_PORTAGE_REPOSITORY_METADATA_HH 1
+
+#include <paludis/name.hh>
+#include <paludis/version_spec.hh>
+#include <paludis/version_metadata.hh>
+#include <paludis/util/counted_ptr.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <string>
+
+/** \file
+ * Declaration for the PortageRepositoryMetadata class.
+ *
+ * \ingroup grpportagerepository
+ */
+
+namespace paludis
+{
+ class PortageRepositoryMetadata :
+ public InternalCounted<PortageRepositoryMetadata>
+ {
+ private:
+ const std::string & _ext;
+
+ protected:
+ PortageRepositoryMetadata(const std::string & ext);
+
+ public:
+ virtual ~PortageRepositoryMetadata();
+
+ std::string file_extension() const
+ {
+ return _ext;
+ }
+
+ virtual VersionMetadata::Pointer generate_version_metadata(const QualifiedPackageName &,
+ const VersionSpec &) const = 0;
+ };
+}
+
+#endif
diff --git a/paludis/repositories/portage/portage_repository_news.cc b/paludis/repositories/portage/portage_repository_news.cc
new file mode 100644
index 0000000..d74ee33
--- /dev/null
+++ b/paludis/repositories/portage/portage_repository_news.cc
@@ -0,0 +1,263 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * 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/portage/portage_repository.hh>
+#include <paludis/repositories/portage/portage_repository_news.hh>
+
+#include <paludis/config_file.hh>
+#include <paludis/environment.hh>
+#include <paludis/util/dir_iterator.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/strip.hh>
+
+#include <set>
+#include <ostream>
+#include <fstream>
+#include <list>
+
+using namespace paludis;
+
+namespace paludis
+{
+ template<>
+ struct Implementation<PortageRepositoryNews> :
+ InternalCounted<Implementation<PortageRepositoryNews> >
+ {
+ const Environment * const environment;
+ const PortageRepository * const portage_repository;
+
+ Implementation(const Environment * const e, const PortageRepository * const p) :
+ environment(e),
+ portage_repository(p)
+ {
+ }
+ };
+}
+
+PortageRepositoryNews::PortageRepositoryNews(const Environment * const e, const PortageRepository * const p) :
+ PrivateImplementationPattern<PortageRepositoryNews>(new Implementation<PortageRepositoryNews>(e, p))
+{
+}
+
+PortageRepositoryNews::~PortageRepositoryNews()
+{
+}
+
+void
+PortageRepositoryNews::update_news() const
+{
+ Context context("When updating news at location '" +
+ stringify(_imp->portage_repository->news_dir()) + "' for repository '" +
+ stringify(_imp->portage_repository->name()) + "':");
+
+ if (! _imp->portage_repository->news_dir().is_directory())
+ return;
+
+ std::set<std::string> skip;
+
+ if (_imp->portage_repository->news_skip_file().is_regular_file())
+ {
+ Context local_context("When handling news skip file '" + stringify(
+ _imp->portage_repository->news_skip_file()) + "':");
+ LineConfigFile s(_imp->portage_repository->news_skip_file());
+ std::copy(s.begin(), s.end(), std::inserter(skip, skip.end()));
+ }
+
+ for (DirIterator d(_imp->portage_repository->news_dir()), d_end ; d != d_end ; ++d)
+ {
+ Context local_context("When handling news entry '" + stringify(*d) + "':");
+
+ if (! d->is_directory())
+ continue;
+ if (! (*d / (d->basename() + ".en.txt")).is_regular_file())
+ continue;
+
+ if (skip.end() != skip.find(d->basename()))
+ continue;
+
+ try
+ {
+ NewsFile news(*d / (d->basename() + ".en.txt"));
+ bool show(true);
+
+ if (news.begin_display_if_installed() != news.end_display_if_installed())
+ {
+ bool local_show(false);
+ for (NewsFile::DisplayIfInstalledIterator i(news.begin_display_if_installed()),
+ i_end(news.end_display_if_installed()) ; i != i_end ; ++i)
+ if (! _imp->environment->package_database()->query(PackageDepAtom::Pointer(
+ new PackageDepAtom(*i)), is_installed_only)->empty())
+ local_show = true;
+ show &= local_show;
+ }
+
+ if (news.begin_display_if_keyword() != news.end_display_if_keyword())
+ {
+ bool local_show(false);
+ for (NewsFile::DisplayIfKeywordIterator i(news.begin_display_if_keyword()),
+ i_end(news.end_display_if_keyword()) ; i != i_end && ! local_show ; ++i)
+ if (*i == _imp->portage_repository->profile_variable("ARCH"))
+ local_show = true;
+ show &= local_show;
+ }
+
+ if (news.begin_display_if_profile() != news.end_display_if_profile())
+ {
+ bool local_show(false);
+ FSEntryCollection::ConstPointer c(_imp->portage_repository->profile_locations());
+ for (FSEntryCollection::Iterator p(c->begin()), p_end(c->end()) ; p != p_end ; ++p)
+ {
+ std::string profile(strip_leading_string(strip_trailing_string(
+ strip_leading_string(stringify(p->realpath()),
+ stringify(p->realpath())), "/"), "/"));
+ Log::get_instance()->message(ll_debug, lc_no_context,
+ "Profile path is '" + profile + "'");
+ for (NewsFile::DisplayIfProfileIterator i(news.begin_display_if_profile()),
+ i_end(news.end_display_if_profile()) ; i != i_end ; ++i)
+ if (profile == *i)
+ local_show = true;
+ }
+ show &= local_show;
+ }
+
+ if (show)
+ {
+ std::ofstream s(stringify(_imp->portage_repository->news_skip_file()).c_str(),
+ std::ios::out | std::ios::app);
+ if (! s)
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Cannot append to news skip file '"
+ + stringify(_imp->portage_repository->news_skip_file()) +
+ "', skipping news item '" + stringify(*d) + "'");
+
+ std::ofstream t(stringify(_imp->portage_repository->news_unread_file()).c_str(),
+ std::ios::out | std::ios::app);
+ if (! t)
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Cannot append to unread file '"
+ + stringify(_imp->portage_repository->news_unread_file()) +
+ "', skipping news item '" + stringify(*d) + "'");
+
+ if (s && t)
+ {
+ s << d->basename() << std::endl;
+ t << d->basename() << std::endl;
+ }
+ }
+ }
+ catch (const ConfigFileError & e)
+ {
+ Log::get_instance()->message(ll_warning, lc_no_context,
+ "Skipping news item '"
+ + stringify(*d) + "' because of exception '" + e.message() + "' ("
+ + e.what() + ")");
+ }
+ }
+
+}
+
+namespace paludis
+{
+ template<>
+ struct Implementation<NewsFile> :
+ InternalCounted<Implementation<NewsFile> >
+ {
+ mutable bool in_header;
+ mutable std::list<std::string> display_if_installed;
+ mutable std::list<std::string> display_if_keyword;
+ mutable std::list<std::string> display_if_profile;
+
+ Implementation() :
+ in_header(true)
+ {
+ }
+ };
+}
+
+NewsFile::NewsFile(const FSEntry & filename) :
+ ConfigFile(filename),
+ PrivateImplementationPattern<NewsFile>(new Implementation<NewsFile>)
+{
+ need_lines();
+}
+
+NewsFile::~NewsFile()
+{
+}
+
+void
+NewsFile::accept_line(const std::string & line) const
+{
+ if (_imp->in_header)
+ {
+ std::string::size_type p(line.find(':'));
+ if (std::string::npos == p)
+ _imp->in_header = false;
+ else
+ {
+ std::string k(strip_leading(strip_trailing(line.substr(0, p), " \t\n"), " \t\n"));
+ std::string v(strip_leading(strip_trailing(line.substr(p + 1), " \t\n"), " \t\n"));
+ if (k == "Display-If-Installed")
+ _imp->display_if_installed.push_back(v);
+ else if (k == "Display-If-Keyword")
+ _imp->display_if_keyword.push_back(v);
+ if (k == "Display-If-Profile")
+ _imp->display_if_profile.push_back(v);
+ }
+ }
+}
+
+NewsFile::DisplayIfInstalledIterator
+NewsFile::begin_display_if_installed() const
+{
+ return DisplayIfInstalledIterator(_imp->display_if_installed.begin());
+}
+
+NewsFile::DisplayIfInstalledIterator
+NewsFile::end_display_if_installed() const
+{
+ return DisplayIfInstalledIterator(_imp->display_if_installed.end());
+}
+
+NewsFile::DisplayIfKeywordIterator
+NewsFile::begin_display_if_keyword() const
+{
+ return DisplayIfKeywordIterator(_imp->display_if_keyword.begin());
+}
+
+NewsFile::DisplayIfKeywordIterator
+NewsFile::end_display_if_keyword() const
+{
+ return DisplayIfKeywordIterator(_imp->display_if_keyword.end());
+}
+
+NewsFile::DisplayIfProfileIterator
+NewsFile::begin_display_if_profile() const
+{
+ return DisplayIfProfileIterator(_imp->display_if_profile.begin());
+}
+
+NewsFile::DisplayIfProfileIterator
+NewsFile::end_display_if_profile() const
+{
+ return DisplayIfProfileIterator(_imp->display_if_profile.end());
+}
+
+
diff --git a/paludis/repositories/portage/portage_repository_news.hh b/paludis/repositories/portage/portage_repository_news.hh
new file mode 100644
index 0000000..ad8ac89
--- /dev/null
+++ b/paludis/repositories/portage/portage_repository_news.hh
@@ -0,0 +1,133 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ *
+ * 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_PORTAGE_PORTAGE_REPOSITORY_NEWS_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_PORTAGE_PORTAGE_REPOSITORY_NEWS_HH 1
+
+#include <paludis/util/private_implementation_pattern.hh>
+#include <paludis/util/instantiation_policy.hh>
+#include <paludis/config_file.hh>
+
+/** \file
+ * Declaration for the PortageRepositoryNews class.
+ *
+ * \ingroup grpportagerepository
+ */
+
+namespace paludis
+{
+ class Environment;
+ class FSEntry;
+ class PortageRepository;
+
+ /**
+ * Holds the news/ data for a PortageRepository instance.
+ *
+ * \ingroup grpportagerepository
+ */
+ class PortageRepositoryNews :
+ private PrivateImplementationPattern<PortageRepositoryNews>,
+ private InstantiationPolicy<PortageRepositoryNews, instantiation_method::NonCopyableTag>,
+ public InternalCounted<PortageRepositoryNews>
+ {
+ public:
+ ///\name Basic operations
+ ///\{
+
+ PortageRepositoryNews(const Environment * const, const PortageRepository * const);
+ ~PortageRepositoryNews();
+
+ ///\}
+
+ void update_news() const;
+ };
+
+ /**
+ * A NewsFile represents a GLEP 42 news file.
+ *
+ * \ingroup grpnewsconfigfile
+ */
+ class NewsFile :
+ protected ConfigFile,
+ private PrivateImplementationPattern<NewsFile>
+ {
+ protected:
+ void accept_line(const std::string &) const;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ /**
+ * Constructor, from a filename.
+ */
+ NewsFile(const FSEntry & filename);
+
+ ~NewsFile();
+
+ ///\}
+
+ ///\name Iterate over our Display-If-Installed headers
+ ///\{
+
+ /// Tag for DisplayIfInstalledIterator.
+ struct DisplayIfInstalledIteratorTag;
+
+ typedef libwrapiter::ForwardIterator<DisplayIfInstalledIteratorTag,
+ const std::string> DisplayIfInstalledIterator;
+
+ DisplayIfInstalledIterator begin_display_if_installed() const;
+
+ DisplayIfInstalledIterator end_display_if_installed() const;
+
+ ///\}
+
+ ///\name Iterate over our Display-If-Keyword headers
+ ///\{
+
+ /// Tag for DisplayIfKeywordIterator.
+ struct DisplayIfKeywordIteratorTag;
+
+ typedef libwrapiter::ForwardIterator<DisplayIfKeywordIteratorTag,
+ const std::string> DisplayIfKeywordIterator;
+
+ DisplayIfKeywordIterator begin_display_if_keyword() const;
+
+ DisplayIfKeywordIterator end_display_if_keyword() const;
+
+ ///\}
+
+ ///\name Iterate over our Display-If-Profile headers
+ ///\{
+
+ /// Tag for DisplayIfProfileIterator.
+ struct DisplayIfProfileIteratorTag;
+
+ typedef libwrapiter::ForwardIterator<DisplayIfProfileIteratorTag,
+ const std::string> DisplayIfProfileIterator;
+
+ DisplayIfProfileIterator begin_display_if_profile() const;
+
+ DisplayIfProfileIterator end_display_if_profile() const;
+
+ ///\}
+ };
+}
+
+#endif
diff --git a/paludis/repositories/portage/portage_repository_sets.cc b/paludis/repositories/portage/portage_repository_sets.cc
new file mode 100644
index 0000000..12e287c
--- /dev/null
+++ b/paludis/repositories/portage/portage_repository_sets.cc
@@ -0,0 +1,442 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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/portage/portage_repository.hh>
+#include <paludis/repositories/portage/portage_repository_sets.hh>
+
+#include <paludis/dep_list.hh>
+#include <paludis/environment.hh>
+#include <paludis/config_file.hh>
+#include <paludis/portage_dep_parser.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <paludis/util/dir_iterator.hh>
+#include <paludis/util/fs_entry.hh>
+#include <paludis/util/is_file_with_extension.hh>
+#include <paludis/util/log.hh>
+#include <paludis/util/tokeniser.hh>
+
+#include <list>
+#include <set>
+
+using namespace paludis;
+
+namespace
+{
+ class AdvisoryVisitor :
+ private InstantiationPolicy<AdvisoryVisitor, instantiation_method::NonCopyableTag>,
+ public DepAtomVisitorTypes::ConstVisitor
+ {
+ private:
+ const Environment * const _env;
+
+ mutable const CompositeDepAtom & _a;
+
+ mutable std::vector<const PackageDepAtom *> _atoms;
+
+ protected:
+ ///\name Visit methods
+ ///{
+ void visit(const AllDepAtom *);
+ void visit(const AnyDepAtom *) PALUDIS_ATTRIBUTE((noreturn));
+ void visit(const UseDepAtom *);
+ void visit(const PlainTextDepAtom *);
+ void visit(const PackageDepAtom *);
+ void visit(const BlockDepAtom *);
+ ///}
+
+ public:
+ /**
+ * Constructor.
+ */
+ AdvisoryVisitor(const Environment * const env, const CompositeDepAtom & a);
+
+ /**
+ * Destructor.
+ */
+ ~AdvisoryVisitor()
+ {
+ }
+
+ /**
+ * Iterate over our dep atoms.
+ */
+ typedef std::vector<const PackageDepAtom *>::iterator Iterator;
+
+ /**
+ * Grab element by index.
+ */
+ const PackageDepAtom * at(std::vector<const PackageDepAtom *>::size_type n) const
+ {
+ return _atoms[n];
+ }
+
+ /**
+ * Return the number of atoms.
+ */
+ std::vector<const PackageDepAtom *>::size_type size() const
+ {
+ return _atoms.size();
+ }
+ };
+}
+
+AdvisoryVisitor::AdvisoryVisitor(const Environment * const env, const CompositeDepAtom & a) :
+ _env(env),
+ _a(a)
+{
+ Context c("When flattening the AdvisoryFile line:");
+ std::for_each(a.begin(), a.end(), accept_visitor(this));
+ if (_atoms.size() == 2)
+ {
+ VersionOperatorValue v1(_atoms[0]->version_operator().value()),
+ v2(_atoms[1]->version_operator().value());
+
+ if ((v1 == vo_equal) || (v2 == vo_equal))
+ throw AdvisoryFileError("Broken line: Forbidden 'equal' atom in range");
+ }
+}
+
+void
+AdvisoryVisitor::visit(const AllDepAtom * a)
+{
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+}
+
+void
+AdvisoryVisitor::visit(const AnyDepAtom *)
+{
+ throw AdvisoryFileError("Unexpected AnyDepAtom in line");
+}
+
+void
+AdvisoryVisitor::visit(const UseDepAtom * a)
+{
+ if (_env->query_use(a->flag(), 0) ^ a->inverse())
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+}
+
+void
+AdvisoryVisitor::visit(const PackageDepAtom * a)
+{
+ _atoms.push_back(a);
+}
+
+void
+AdvisoryVisitor::visit(const PlainTextDepAtom *)
+{
+}
+
+void
+AdvisoryVisitor::visit(const BlockDepAtom *)
+{
+}
+
+
+namespace paludis
+{
+ template<>
+ struct Implementation<PortageRepositorySets> :
+ InternalCounted<Implementation<PortageRepositorySets> >
+ {
+ const Environment * const environment;
+ const PortageRepository * const portage_repository;
+
+ Implementation(const Environment * const e, const PortageRepository * const p) :
+ environment(e),
+ portage_repository(p)
+ {
+ }
+ };
+}
+
+PortageRepositorySets::PortageRepositorySets(const Environment * const e, const PortageRepository * const p) :
+ PrivateImplementationPattern<PortageRepositorySets>(new Implementation<PortageRepositorySets>(e, p))
+{
+}
+
+PortageRepositorySets::~PortageRepositorySets()
+{
+}
+
+
+DepAtom::Pointer
+PortageRepositorySets::package_set(const std::string & s, const PackageSetOptions & o) const
+{
+ if ("system" == s)
+ throw InternalError(PALUDIS_HERE, "system set should've been handled by PortageRepository");
+ else if ("security" == s)
+ return security_set(o);
+ else if ((_imp->portage_repository->sets_dir() / (s + ".conf")).exists())
+ {
+ GeneralSetDepTag::Pointer tag(new GeneralSetDepTag(s));
+
+ FSEntry ff(_imp->portage_repository->sets_dir() / (s + ".conf"));
+ Context context("When loading package set '" + s + "' from '" + stringify(ff) + "':");
+
+ AllDepAtom::Pointer result(new AllDepAtom);
+ LineConfigFile f(ff);
+ for (LineConfigFile::Iterator line(f.begin()), line_end(f.end()) ;
+ line != line_end ; ++line)
+ {
+ std::vector<std::string> tokens;
+ WhitespaceTokeniser::get_instance()->tokenise(*line, std::back_inserter(tokens));
+ if (tokens.empty())
+ continue;
+
+ if (1 == tokens.size())
+ {
+ Log::get_instance()->message(ll_warning, lc_context,
+ "Line '" + *line + "' in set file '"
+ + stringify(ff) + "' does not specify '*' or '?', assuming '*'");
+ PackageDepAtom::Pointer atom(new PackageDepAtom(tokens.at(0)));
+ atom->set_tag(tag);
+ result->add_child(atom);
+ }
+ else if ("*" == tokens.at(0))
+ {
+ PackageDepAtom::Pointer atom(new PackageDepAtom(tokens.at(1)));
+ atom->set_tag(tag);
+ result->add_child(atom);
+ }
+ else if ("?" == tokens.at(0))
+ {
+ PackageDepAtom::Pointer p(new PackageDepAtom(tokens.at(1)));
+ p->set_tag(tag);
+ if (! _imp->environment->package_database()->query(
+ PackageDepAtom::Pointer(new PackageDepAtom(p->package())),
+ is_installed_only)->empty())
+ result->add_child(p);
+ }
+ else
+ Log::get_instance()->message(ll_warning, lc_context,
+ "Line '" + *line + "' in set file '"
+ + stringify(ff) + "' does not start with '*' or '?' token, skipping");
+
+ if (tokens.size() > 2)
+ Log::get_instance()->message(ll_warning, lc_context,
+ "Line '" + *line + "' in set file '"
+ + stringify(ff) + "' has trailing garbage");
+ }
+
+ return result;
+ }
+ else
+ return DepAtom::Pointer(0);
+}
+
+namespace
+{
+ inline
+ PackageDepAtom::Pointer make_atom(const PackageDatabaseEntry & e)
+ {
+ QualifiedPackageName n(e.get<pde_name>());
+ VersionSpec v(e.get<pde_version>());
+
+ std::string s("=" + stringify(n) + "-" + stringify(v));
+ return PackageDepAtom::Pointer(new PackageDepAtom(s));
+ }
+}
+
+PackageDatabaseEntryCollection::Iterator
+PortageRepositorySets::find_best(PackageDatabaseEntryCollection & c, const PackageDatabaseEntry & e) const
+{
+ Context local("When finding best update for '" + stringify(e.get<pde_name>()) + "-" +
+ stringify(e.get<pde_version>()) + "':");
+ // Find an entry in c that matches e best. e is not in c.
+ QualifiedPackageName n(e.get<pde_name>());
+ SlotName s(_imp->environment->package_database()->fetch_repository(
+ e.get<pde_repository>())->version_metadata(e.get<pde_name>(), e.get<pde_version>())->get<vm_slot>());
+ PackageDatabaseEntryCollection::Iterator i(c.begin()), i_end(c.end()), i_best(c.end());
+ for ( ; i != i_end; ++i)
+ {
+ if (n != i->get<pde_name>())
+ continue;
+ if (s != _imp->environment->package_database()->fetch_repository(
+ i->get<pde_repository>())->version_metadata(
+ i->get<pde_name>(), i->get<pde_version>())->get<vm_slot>())
+ continue;
+
+ i_best = i;
+ }
+
+ return i_best;
+}
+
+
+DepAtom::Pointer
+PortageRepositorySets::security_set(const PackageSetOptions & o) const
+{
+ Context c("When building security package set:");
+ AllDepAtom::Pointer security_packages(new AllDepAtom);
+
+ bool list_affected_only(o.get<pso_list_affected_only>());
+ InstallState affected_state(list_affected_only ? is_either : is_installed_only);
+
+ if (!_imp->portage_repository->security_dir().is_directory())
+ return DepAtom::Pointer(new AllDepAtom);
+
+ std::list<FSEntry> advisories;
+ std::copy(DirIterator(_imp->portage_repository->security_dir()), DirIterator(),
+ filter_inserter(std::back_inserter(advisories),
+ IsFileWithExtension("advisory-", ".conf")));
+
+ std::list<FSEntry>::const_iterator f(advisories.begin()),
+ f_end(advisories.end());
+
+ std::set<std::pair<PackageDatabaseEntry, std::string> > affected;
+ PackageDatabaseEntryCollection::Concrete unaffected;
+ std::map<std::string, std::string> advisory_map;
+
+ for ( ; f != f_end; ++f)
+ {
+ Context c("When parsing security advisory '" + stringify(*f) + "':");
+
+ try
+ {
+ AdvisoryFile advisory(*f);
+ std::string advisory_id(advisory.get("Id"));
+ advisory_map[advisory_id] = advisory.get("Title");
+
+
+ AdvisoryFile::LineIterator a(advisory.begin_affected()), a_end(advisory.end_affected());
+ for ( ; a != a_end ; ++a)
+ {
+ Context c("When parsing line 'Affected: " + *a + "':");
+
+ CompositeDepAtom::ConstPointer line(PortageDepParser::parse(*a));
+ AdvisoryVisitor atoms(_imp->environment, *line);
+
+ if ((0 == atoms.size()) || (2 < atoms.size()))
+ {
+ continue;
+ }
+
+ bool is_range(2 == atoms.size());
+
+ PackageDatabaseEntryCollection::ConstPointer affected_collection1(
+ _imp->environment->package_database()->query(*atoms.at(0), affected_state));
+ PackageDatabaseEntryCollection::ConstPointer affected_collection2(
+ new PackageDatabaseEntryCollection::Concrete);
+ PackageDatabaseEntryCollection::Iterator p(affected_collection1->begin()),
+ p_end(affected_collection1->end());
+
+ if (is_range)
+ affected_collection2 = _imp->environment->package_database()->query(
+ *atoms.at(1), affected_state);
+
+ for ( ; p != p_end ; ++p)
+ {
+ if ((affected.end() != affected.find(std::make_pair(*p, advisory_id))))
+ continue;
+ if ((! is_range) || (affected_collection2->end() != affected_collection2->find(*p)))
+ affected.insert(std::make_pair(*p, advisory_id));
+ }
+ }
+
+ AdvisoryFile::LineIterator u(advisory.begin_unaffected()), u_end(advisory.end_unaffected());
+ for ( ; u != u_end ; ++u)
+ {
+ Context c("When parsing line 'Unaffected: " + *u + "':");
+
+ CompositeDepAtom::ConstPointer line(PortageDepParser::parse(*u));
+ AdvisoryVisitor atoms(_imp->environment, *line);
+
+ if ((0 == atoms.size()) || (2 < atoms.size()))
+ {
+ continue;
+ }
+
+ bool is_range(2 == atoms.size());
+
+ PackageDatabaseEntryCollection::ConstPointer unaffected_collection1(
+ _imp->environment->package_database()->query(*atoms.at(0), is_either));
+ PackageDatabaseEntryCollection::ConstPointer unaffected_collection2(
+ new PackageDatabaseEntryCollection::Concrete);
+ PackageDatabaseEntryCollection::Iterator p(unaffected_collection1->begin()),
+ p_end(unaffected_collection1->end());
+
+ if (is_range)
+ unaffected_collection2 = _imp->environment->package_database()->query(
+ *atoms.at(1), is_either);
+
+ for ( ; p != p_end ; ++p)
+ {
+ if ((! is_range) || (unaffected_collection2->end() != unaffected_collection2->find(*p)))
+ {
+ unaffected.insert(*p);
+ std::set<std::pair<PackageDatabaseEntry, std::string> >::iterator
+ a(affected.find(std::make_pair(*p, advisory_id)));
+ if (a != affected.end())
+ affected.erase(a);
+ }
+ }
+ }
+ }
+ catch (const AdvisoryFileError & e)
+ {
+ Log::get_instance()->message(ll_warning, lc_context,
+ "Malformed advisory file '" + stringify(*f) + "': " + e.message());
+ }
+ catch (const InternalError & e)
+ {
+ throw;
+ }
+ catch (const Exception & e)
+ {
+ Log::get_instance()->message(ll_warning, lc_context,
+ "Exception caught while parsing advisory '" + stringify(*f) +
+ "': " + e.message());
+ }
+
+ }
+
+ std::set<std::pair<PackageDatabaseEntry, std::string> >::const_iterator
+ i(affected.begin()), i_end(affected.end());
+ if (list_affected_only)
+ {
+ for ( ; i != i_end ; ++i)
+ {
+ Context c("When creating adding vulnerable package '" + stringify(i->first) + "':");
+
+ PackageDepAtom::Pointer p(make_atom(i->first));
+ p->set_tag(GLSADepTag::Pointer(new GLSADepTag(i->second, advisory_map[i->second])));
+ security_packages->add_child(p);
+ }
+ }
+ else
+ {
+ for ( ; i != i_end ; ++i)
+ {
+ Context c("When finding best update for package '" + stringify(i->first) +
+ "', affected by '" + i->second + "':");
+
+ PackageDatabaseEntryCollection::Iterator best = find_best(unaffected, i->first);
+ if (best == unaffected.end())
+ throw AllMaskedError("No best update available for package '" + stringify(i->first) + "':");
+
+ PackageDepAtom::Pointer p(make_atom(*best));
+ p->set_tag(GLSADepTag::Pointer(new GLSADepTag(i->second, advisory_map[i->second])));
+ security_packages->add_child(p);
+ }
+ }
+
+ return security_packages;
+}
+
diff --git a/paludis/repositories/portage/portage_repository_sets.hh b/paludis/repositories/portage/portage_repository_sets.hh
new file mode 100644
index 0000000..fd4865c
--- /dev/null
+++ b/paludis/repositories/portage/portage_repository_sets.hh
@@ -0,0 +1,74 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2005, 2006 Ciaran McCreesh <ciaran.mccreesh@blueyonder.co.uk>
+ * Copyright (c) 2006 Danny van Dyk <kugelfang@gentoo.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_PORTAGE_PORTAGE_REPOSITORY_SETS_HH
+#define PALUDIS_GUARD_PALUDIS_REPOSITORIES_PORTAGE_PORTAGE_REPOSITORY_SETS_HH 1
+
+#include <paludis/dep_atom.hh>
+#include <paludis/repository.hh>
+
+/** \file
+ * Declaration for the PortageRepositorySets class.
+ *
+ * \ingroup grpportagerepository
+ */
+
+namespace paludis
+{
+ class Environment;
+ class PortageRepository;
+
+ /**
+ * Holds the information about sets, except system, for a PortageRepository.
+ *
+ * \ingroup grpportagerepository
+ */
+ class PortageRepositorySets :
+ private PrivateImplementationPattern<PortageRepositorySets>,
+ private InstantiationPolicy<PortageRepositorySets, instantiation_method::NonCopyableTag>,
+ public InternalCounted<PortageRepositorySets>
+ {
+ private:
+ PackageDatabaseEntryCollection::Iterator
+ find_best(PackageDatabaseEntryCollection & c, const PackageDatabaseEntry & e) const;
+
+ public:
+ ///\name Basic operations
+ ///\{
+
+ PortageRepositorySets(const Environment * const env, const PortageRepository * const);
+ ~PortageRepositorySets();
+
+ ///\}
+
+ /**
+ * Fetch a package set other than system.
+ */
+ DepAtom::Pointer package_set(const std::string & s, const PackageSetOptions & o) const;
+
+ /**
+ * Fetch the security set.
+ */
+ DepAtom::Pointer security_set(const PackageSetOptions & o) const;
+ };
+}
+
+
+#endif