aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-04-13 21:24:35 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-04-13 21:24:35 +0000
commit7877f458e1d72ce41217b57cc4a80e14eec4f0b8 (patch)
tree241c420fb87b5bee03896ffb6681b618ea412de2
parentf2f75671015cbdc48dd0b286c531b638692e1462 (diff)
downloadpaludis-7877f458e1d72ce41217b57cc4a80e14eec4f0b8.tar.gz
paludis-7877f458e1d72ce41217b57cc4a80e14eec4f0b8.tar.xz
World target support, rework how we handle sets internally to make this kind of thing easier
-rw-r--r--paludis/environment.cc120
-rw-r--r--paludis/environment.hh5
-rw-r--r--paludis/fake_repository.cc2
-rw-r--r--paludis/fake_repository.hh8
-rw-r--r--paludis/portage_repository.cc2
-rw-r--r--paludis/portage_repository.hh8
-rw-r--r--paludis/repository.hh3
-rw-r--r--paludis/vdb_repository.cc117
-rw-r--r--paludis/vdb_repository.hh7
-rw-r--r--src/install.cc12
-rw-r--r--src/uninstall.cc8
11 files changed, 274 insertions, 18 deletions
diff --git a/paludis/environment.cc b/paludis/environment.cc
index 8783c84..c671719 100644
--- a/paludis/environment.cc
+++ b/paludis/environment.cc
@@ -20,7 +20,8 @@
#include <paludis/package_database.hh>
#include <paludis/dep_atom.hh>
#include <paludis/dep_parser.hh>
-#include <paludis/qa/environment.hh>
+#include <paludis/environment.hh>
+#include <paludis/util/log.hh>
using namespace paludis;
@@ -189,3 +190,120 @@ Environment::end_provide_map() const
return _provide_map.end();
}
+DepAtom::Pointer
+Environment::package_set(const std::string & s) const
+{
+ if (s == "everything" || s == "system" || s == "world")
+ {
+ AllDepAtom::Pointer result(new AllDepAtom);
+
+ for (PackageDatabase::RepositoryIterator r(package_database()->begin_repositories()),
+ r_end(package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ {
+ DepAtom::Pointer add((*r)->package_set(s));
+ if (0 != add)
+ result->add_child(add);
+
+ if ("system" != s)
+ {
+ add = (*r)->package_set("system");
+ if (0 != add)
+ result->add_child(add);
+ }
+ }
+
+ return result;
+ }
+ else
+ {
+ for (PackageDatabase::RepositoryIterator r(package_database()->begin_repositories()),
+ r_end(package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ {
+ DepAtom::Pointer result((*r)->package_set(s));
+ if (0 != result)
+ return result;
+ }
+
+ return DepAtom::Pointer(0);
+ }
+}
+
+namespace
+{
+ struct WorldTargetFinder :
+ DepAtomVisitorTypes::ConstVisitor
+ {
+ std::list<const PackageDepAtom *> items;
+
+ ///\name Visit methods
+ ///{
+ void visit(const AllDepAtom * a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void visit(const AnyDepAtom *)
+ {
+ }
+
+ void visit(const UseDepAtom *)
+ {
+ }
+
+ void visit(const PlainTextDepAtom *)
+ {
+ }
+
+ void visit(const PackageDepAtom * a)
+ {
+ if (! (a->slot_ptr() || a->version_spec_ptr()))
+ items.push_back(a);
+ }
+
+ void visit(const BlockDepAtom *)
+ {
+ }
+ ///}
+
+ };
+}
+
+void
+Environment::add_appropriate_to_world(DepAtom::ConstPointer a) const
+{
+ WorldTargetFinder w;
+ a->accept(&w);
+ for (std::list<const PackageDepAtom *>::const_iterator i(w.items.begin()),
+ i_end(w.items.end()) ; i != i_end ; ++i)
+ {
+ if (! package_database()->query(*i, is_installed_only)->empty())
+ Log::get_instance()->message(ll_debug, "Not adding '" + stringify(**i) +
+ "' to world, because it is already installed");
+ else
+ {
+ for (PackageDatabase::RepositoryIterator r(package_database()->begin_repositories()),
+ r_end(package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ (*r)->add_to_world((*i)->package());
+ }
+ }
+}
+
+
+void
+Environment::remove_appropriate_from_world(DepAtom::ConstPointer a) const
+{
+ WorldTargetFinder w;
+ a->accept(&w);
+ for (std::list<const PackageDepAtom *>::const_iterator i(w.items.begin()),
+ i_end(w.items.end()) ; i != i_end ; ++i)
+ {
+ for (PackageDatabase::RepositoryIterator r(package_database()->begin_repositories()),
+ r_end(package_database()->end_repositories()) ;
+ r != r_end ; ++r)
+ (*r)->remove_from_world((*i)->package());
+ }
+}
+
diff --git a/paludis/environment.hh b/paludis/environment.hh
index ca39137..9a5f071 100644
--- a/paludis/environment.hh
+++ b/paludis/environment.hh
@@ -117,6 +117,11 @@ namespace paludis
ProvideMapIterator begin_provide_map() const;
ProvideMapIterator end_provide_map() const;
+
+ DepAtom::Pointer package_set(const std::string &) const;
+
+ void add_appropriate_to_world(DepAtom::ConstPointer) const;
+ void remove_appropriate_from_world(DepAtom::ConstPointer) const;
};
}
diff --git a/paludis/fake_repository.cc b/paludis/fake_repository.cc
index 3f6cc7a..56ff934 100644
--- a/paludis/fake_repository.cc
+++ b/paludis/fake_repository.cc
@@ -227,7 +227,7 @@ FakeRepository::do_uninstall(const QualifiedPackageName &, const VersionSpec &)
DepAtom::Pointer
FakeRepository::do_package_set(const std::string &) const
{
- AllDepAtom::Pointer result(new AllDepAtom);
+ AllDepAtom::Pointer result(0);
return result;
}
diff --git a/paludis/fake_repository.hh b/paludis/fake_repository.hh
index c640d21..d4dab25 100644
--- a/paludis/fake_repository.hh
+++ b/paludis/fake_repository.hh
@@ -140,6 +140,14 @@ namespace paludis
virtual ProvideMapIterator begin_provide_map() const;
virtual ProvideMapIterator end_provide_map() const;
+
+ virtual void remove_from_world(const QualifiedPackageName &) const
+ {
+ }
+
+ virtual void add_to_world(const QualifiedPackageName &) const
+ {
+ }
};
}
diff --git a/paludis/portage_repository.cc b/paludis/portage_repository.cc
index 59ef4af..fab8c6c 100644
--- a/paludis/portage_repository.cc
+++ b/paludis/portage_repository.cc
@@ -1268,7 +1268,7 @@ PortageRepository::do_package_set(const std::string & s) const
return _imp->system_packages;
}
else
- return DepAtom::Pointer(new AllDepAtom);
+ return DepAtom::Pointer(0);
}
bool
diff --git a/paludis/portage_repository.hh b/paludis/portage_repository.hh
index 085d8f5..a61263d 100644
--- a/paludis/portage_repository.hh
+++ b/paludis/portage_repository.hh
@@ -133,6 +133,14 @@ namespace paludis
virtual ProvideMapIterator begin_provide_map() const;
virtual ProvideMapIterator end_provide_map() const;
+
+ virtual void add_to_world(const QualifiedPackageName &) const
+ {
+ }
+
+ virtual void remove_from_world(const QualifiedPackageName &) const
+ {
+ }
};
/**
diff --git a/paludis/repository.hh b/paludis/repository.hh
index d57b49b..e04ebc3 100644
--- a/paludis/repository.hh
+++ b/paludis/repository.hh
@@ -434,6 +434,9 @@ namespace paludis
virtual ProvideMapIterator begin_provide_map() const = 0;
virtual ProvideMapIterator end_provide_map() const = 0;
+
+ virtual void add_to_world(const QualifiedPackageName &) const = 0;
+ virtual void remove_from_world(const QualifiedPackageName &) const = 0;
};
/**
diff --git a/paludis/vdb_repository.cc b/paludis/vdb_repository.cc
index 3ea8edb..0963f09 100644
--- a/paludis/vdb_repository.cc
+++ b/paludis/vdb_repository.cc
@@ -144,6 +144,9 @@ namespace paludis
/// Root location
FSEntry root;
+ /// World file
+ FSEntry world_file;
+
/// Do we have entries loaded?
mutable bool entries_valid;
@@ -165,7 +168,7 @@ namespace paludis
/// Constructor.
Implementation(const Environment * const,
const PackageDatabase * const d, const FSEntry & l,
- const FSEntry & r);
+ const FSEntry & r, const FSEntry &);
/// Destructor.
~Implementation();
@@ -177,11 +180,12 @@ namespace paludis
Implementation<VDBRepository>::Implementation(const Environment * const env,
const PackageDatabase * const d,
- const FSEntry & l, const FSEntry & r) :
+ const FSEntry & l, const FSEntry & r, const FSEntry & w) :
db(d),
env(env),
location(l),
root(r),
+ world_file(w),
entries_valid(false),
has_provide_map(false)
{
@@ -203,6 +207,9 @@ Implementation<VDBRepository>::load_entries() const
{
for (DirIterator cat_i(location), cat_iend ; cat_i != cat_iend ; ++cat_i)
{
+ if (! cat_i->is_directory())
+ continue;
+
for (DirIterator pkg_i(*cat_i), pkg_iend ; pkg_i != pkg_iend ; ++pkg_i)
{
PackageDepAtom atom("=" + cat_i->basename() + "/" + pkg_i->basename());
@@ -287,14 +294,15 @@ Implementation<VDBRepository>::load_entry(std::vector<VDBEntry>::iterator p) con
VDBRepository::VDBRepository(
const Environment * const e, const PackageDatabase * const d,
- const FSEntry & location, const FSEntry & root) :
+ const FSEntry & location, const FSEntry & root, const FSEntry & world) :
Repository(RepositoryName("installed")),
PrivateImplementationPattern<VDBRepository>(new Implementation<VDBRepository>(e,
- d, location, root))
+ d, location, root, world))
{
_info.insert(std::make_pair(std::string("location"), location));
_info.insert(std::make_pair(std::string("root"), root));
_info.insert(std::make_pair(std::string("format"), std::string("vdb")));
+ _info.insert(std::make_pair(std::string("world"), world));
}
VDBRepository::~VDBRepository()
@@ -469,7 +477,11 @@ VDBRepository::make_vdb_repository(
if (m.end() == m.find("root") || ((root = m.find("root")->second)).empty())
root = "/";
- return CountedPtr<Repository>(new VDBRepository(env, db, location, root));
+ std::string world;
+ if (m.end() == m.find("world") || ((world = m.find("world")->second)).empty())
+ world = location + "/world";
+
+ return CountedPtr<Repository>(new VDBRepository(env, db, location, root, world));
}
VDBRepositoryConfigurationError::VDBRepositoryConfigurationError(
@@ -569,19 +581,40 @@ VDBRepository::do_package_set(const std::string & s) const
Context context("When fetching package set '" + s + "' from '" +
stringify(name()) + "':");
- AllDepAtom::Pointer result(new AllDepAtom);
-
if ("everything" == s)
{
+ AllDepAtom::Pointer result(new AllDepAtom);
+
if (! _imp->entries_valid)
_imp->load_entries();
for (std::vector<VDBEntry>::const_iterator p(_imp->entries.begin()),
p_end(_imp->entries.end()) ; p != p_end ; ++p)
result->add_child(PackageDepAtom::Pointer(new PackageDepAtom(p->name)));
+
+ return result;
}
+ else if ("world" == s)
+ {
+ AllDepAtom::Pointer result(new AllDepAtom);
- return result;
+ if (_imp->world_file.exists())
+ {
+ LineConfigFile world(_imp->world_file);
+
+ for (LineConfigFile::Iterator line(world.begin()), line_end(world.end()) ;
+ line != line_end ; ++line)
+ result->add_child(PackageDepAtom::Pointer(new PackageDepAtom(
+ QualifiedPackageName(*line))));
+ }
+ else
+ Log::get_instance()->message(ll_warning, "World file '" + stringify(_imp->world_file) +
+ "' doesn't exist");
+
+ return result;
+ }
+ else
+ return DepAtom::Pointer(0);
}
bool
@@ -662,3 +695,71 @@ VDBRepository::end_provide_map() const
return _imp->provide_map.end();
}
+void
+VDBRepository::add_to_world(const QualifiedPackageName & n) const
+{
+ bool found(false);
+
+ if (_imp->world_file.exists())
+ {
+ LineConfigFile world(_imp->world_file);
+
+ for (LineConfigFile::Iterator line(world.begin()), line_end(world.end()) ;
+ line != line_end ; ++line)
+ if (QualifiedPackageName(*line) == n)
+ {
+ found = true;
+ break;
+ }
+ }
+
+ if (! found)
+ {
+ std::ofstream world(stringify(_imp->world_file).c_str(), std::ios::out | std::ios::app);
+ if (! world)
+ Log::get_instance()->message(ll_warning, "Cannot append to world file '"
+ + stringify(_imp->world_file) + "', skipping world update");
+ else
+ world << n << std::endl;
+ }
+}
+
+void
+VDBRepository::remove_from_world(const QualifiedPackageName & n) const
+{
+ std::list<std::string> world_lines;
+
+ if (_imp->world_file.exists())
+ {
+ std::ifstream world_file(stringify(_imp->world_file).c_str());
+
+ if (! world_file)
+ {
+ Log::get_instance()->message(ll_warning, "Cannot read world file '"
+ + stringify(_imp->world_file) + "', skipping world update");
+ return;
+ }
+
+ std::string line;
+ while (std::getline(world_file, line))
+ {
+ if (strip_leading(strip_trailing(line, " \t"), "\t") != stringify(n))
+ world_lines.push_back(line);
+ else
+ Log::get_instance()->message(ll_debug, "Removing line '"
+ + line + "' from world file '" + stringify(_imp->world_file));
+ }
+ }
+
+ std::ofstream world_file(stringify(_imp->world_file).c_str());
+
+ if (! world_file)
+ {
+ Log::get_instance()->message(ll_warning, "Cannot write world file '"
+ + stringify(_imp->world_file) + "', skipping world update");
+ return;
+ }
+
+ std::copy(world_lines.begin(), world_lines.end(),
+ std::ostream_iterator<std::string>(world_file, "\n"));
+}
diff --git a/paludis/vdb_repository.hh b/paludis/vdb_repository.hh
index c923740..6708582 100644
--- a/paludis/vdb_repository.hh
+++ b/paludis/vdb_repository.hh
@@ -85,7 +85,8 @@ namespace paludis
VDBRepository(const Environment * const env,
const PackageDatabase * const db,
const FSEntry & location,
- const FSEntry & root);
+ const FSEntry & root,
+ const FSEntry & world);
/**
* Virtual constructor.
@@ -110,6 +111,10 @@ namespace paludis
virtual ProvideMapIterator begin_provide_map() const;
virtual ProvideMapIterator end_provide_map() const;
+
+ virtual void add_to_world(const QualifiedPackageName &) const;
+
+ virtual void remove_from_world(const QualifiedPackageName &) const;
};
/**
diff --git a/src/install.cc b/src/install.cc
index 1107e7a..a3e3deb 100644
--- a/src/install.cc
+++ b/src/install.cc
@@ -54,17 +54,14 @@ do_install()
bool had_set_targets(false), had_pkg_targets(false);
for ( ; q != q_end ; ++q)
{
- if (*q == "system" || *q == "everything")
+ DepAtom::Pointer s(0);
+ if (s = ((env->package_set(*q))))
{
if (had_set_targets)
throw DoHelp("You should not specify more than one set target.");
had_set_targets = true;
-
- for (p::PackageDatabase::RepositoryIterator r(
- env->package_database()->begin_repositories()),
- r_end(env->package_database()->end_repositories()) ; r != r_end ; ++r)
- targets->add_child((*r)->package_set(*q));
+ targets->add_child(s);
}
else
{
@@ -87,6 +84,8 @@ do_install()
if (had_set_targets)
dep_list.set_reinstall(false);
+ else if (! CommandLine::get_instance()->a_pretend.specified())
+ env->add_appropriate_to_world(targets);
}
catch (const p::AmbiguousPackageNameError & e)
{
@@ -352,3 +351,4 @@ do_install()
return return_code;
}
+
diff --git a/src/uninstall.cc b/src/uninstall.cc
index 9bdd857..b64f270 100644
--- a/src/uninstall.cc
+++ b/src/uninstall.cc
@@ -97,6 +97,14 @@ do_uninstall()
if (CommandLine::get_instance()->a_pretend.specified())
return return_code;
+ {
+ p::AllDepAtom::Pointer all(new p::AllDepAtom);
+ for (std::list<p::PackageDepAtom::Pointer>::const_iterator t(targets.begin()),
+ t_end(targets.end()) ; t != t_end ; ++t)
+ all->add_child(*t);
+ env->remove_appropriate_from_world(all);
+ }
+
for (p::PackageDatabaseEntryCollection::Iterator pkg(unmerge->begin()), pkg_end(unmerge->end()) ;
pkg != pkg_end ; ++pkg)
{