aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Danny van Dyk <dvandyk@exherbo.org> 2006-09-26 21:54:21 +0000
committerAvatar Danny van Dyk <dvandyk@exherbo.org> 2006-09-26 21:54:21 +0000
commitda2ecbd408ce1a6160b1a7097f4214c1352a6c06 (patch)
treef731558899294cef5802708a7023c5a9cc8b7ada
parent1dd82ca7634cc9e8921693e52faa104c4085da96 (diff)
downloadpaludis-da2ecbd408ce1a6160b1a7097f4214c1352a6c06.tar.gz
paludis-da2ecbd408ce1a6160b1a7097f4214c1352a6c06.tar.xz
Add action to find all packages depending on a given atom.
-rw-r--r--src/adjutrix/Makefile.am1
-rw-r--r--src/adjutrix/adjutrix.cc11
-rw-r--r--src/adjutrix/command_line.cc2
-rw-r--r--src/adjutrix/command_line.hh1
-rw-r--r--src/adjutrix/find_reverse_deps.cc269
-rw-r--r--src/adjutrix/find_reverse_deps.hh28
6 files changed, 312 insertions, 0 deletions
diff --git a/src/adjutrix/Makefile.am b/src/adjutrix/Makefile.am
index 2fdd9b4..04e9f01 100644
--- a/src/adjutrix/Makefile.am
+++ b/src/adjutrix/Makefile.am
@@ -30,6 +30,7 @@ adjutrix_SOURCES = \
command_line.hh command_line.cc \
find_stable_candidates.hh find_stable_candidates.cc \
find_dropped_keywords.hh find_dropped_keywords.cc \
+ find_reverse_deps.hh find_reverse_deps.cc \
keywords_graph.hh keywords_graph.cc \
adjutrix_environment.hh adjutrix_environment.cc \
display_profiles_use.hh display_profiles_use.cc \
diff --git a/src/adjutrix/adjutrix.cc b/src/adjutrix/adjutrix.cc
index e4e8294..fc7c755 100644
--- a/src/adjutrix/adjutrix.cc
+++ b/src/adjutrix/adjutrix.cc
@@ -21,6 +21,7 @@
#include "command_line.hh"
#include "find_stable_candidates.hh"
#include "find_dropped_keywords.hh"
+#include "find_reverse_deps.hh"
#include "keywords_graph.hh"
#include "display_profiles_use.hh"
#include "display_default_system_resolution.hh"
@@ -136,6 +137,7 @@ main(int argc, char *argv[])
CommandLine::get_instance()->a_find_stable_candidates.specified() +
CommandLine::get_instance()->a_find_dropped_keywords.specified() +
CommandLine::get_instance()->a_keywords_graph.specified() +
+ CommandLine::get_instance()->a_reverse_deps.specified() +
CommandLine::get_instance()->a_display_profiles_use.specified() +
CommandLine::get_instance()->a_display_default_system_resolution.specified()
))
@@ -173,6 +175,15 @@ main(int argc, char *argv[])
return EXIT_SUCCESS;
}
+ if (CommandLine::get_instance()->a_reverse_deps.specified())
+ {
+ if (1 != std::distance(CommandLine::get_instance()->begin_parameters(),
+ CommandLine::get_instance()->end_parameters()))
+ throw DoHelp("reverse-deps action takes exactly one parameter (the target dep)");
+
+ return do_find_reverse_deps(env);
+ }
+
if (CommandLine::get_instance()->a_display_profiles_use.specified())
{
if (CommandLine::get_instance()->begin_parameters() !=
diff --git a/src/adjutrix/command_line.cc b/src/adjutrix/command_line.cc
index f2ec58d..5306bd7 100644
--- a/src/adjutrix/command_line.cc
+++ b/src/adjutrix/command_line.cc
@@ -32,6 +32,8 @@ CommandLine::CommandLine() :
"find-dropped-keywords", 'd', "Search for packages where keywords have been dropped"),
a_keywords_graph(&tree_action_args,
"keyword-graph", 'k', "Display keywords graphically"),
+ a_reverse_deps(&tree_action_args,
+ "reverse-deps", 'r', "Find all package that depend on a given dep atom"),
profile_action_args(this, "Profile-Oriented Actions",
"Selects which basic profile-oriented action to perform. Exactly one action should "
diff --git a/src/adjutrix/command_line.hh b/src/adjutrix/command_line.hh
index 7401777..66e4553 100644
--- a/src/adjutrix/command_line.hh
+++ b/src/adjutrix/command_line.hh
@@ -62,6 +62,7 @@ class CommandLine :
paludis::args::SwitchArg a_find_stable_candidates;
paludis::args::SwitchArg a_find_dropped_keywords;
paludis::args::SwitchArg a_keywords_graph;
+ paludis::args::SwitchArg a_reverse_deps;
paludis::args::ArgsGroup profile_action_args;
paludis::args::SwitchArg a_display_profiles_use;
diff --git a/src/adjutrix/find_reverse_deps.cc b/src/adjutrix/find_reverse_deps.cc
new file mode 100644
index 0000000..7e9ec6e
--- /dev/null
+++ b/src/adjutrix/find_reverse_deps.cc
@@ -0,0 +1,269 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * 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 "find_reverse_deps.hh"
+#include "command_line.hh"
+
+#include <paludis/util/compare.hh>
+#include <paludis/util/collection_concrete.hh>
+#include <paludis/util/save.hh>
+
+#include <set>
+#include <map>
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+
+using namespace paludis;
+using std::cout;
+using std::cerr;
+using std::endl;
+
+namespace
+{
+ class ReverseDepChecker :
+ public DepAtomVisitorTypes::ConstVisitor
+ {
+ private:
+ PackageDatabase::ConstPointer _db;
+ PackageDatabaseEntryCollection::ConstPointer _entries;
+ std::string _depname;
+ std::string _p;
+
+ bool _in_any;
+ bool _in_use;
+ std::string _flags;
+
+ bool _found_matches;
+
+ public:
+ ReverseDepChecker(PackageDatabase::ConstPointer db, PackageDatabaseEntryCollection::ConstPointer entries,
+ const std::string & p) :
+ _db(db),
+ _entries(entries),
+ _depname(""),
+ _p(p),
+ _in_any(false),
+ _in_use(false),
+ _found_matches(false)
+ {
+ }
+
+ void check(DepAtom::ConstPointer atom, const std::string & depname)
+ {
+ _depname = depname;
+ atom->accept(this);
+ }
+
+ int found_matches()
+ {
+ return _found_matches;
+ }
+
+ void visit(const AllDepAtom * const);
+
+ void visit(const AnyDepAtom * const);
+
+ void visit(const UseDepAtom * const);
+
+ void visit(const PackageDepAtom * const);
+
+ void visit(const PlainTextDepAtom * const);
+
+ void visit(const BlockDepAtom * const);
+ };
+
+ void
+ ReverseDepChecker::visit(const AllDepAtom * const a)
+ {
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void
+ ReverseDepChecker::visit(const AnyDepAtom * const a)
+ {
+ Save<bool> in_any_save(&_in_any, true);
+
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void
+ ReverseDepChecker::visit(const UseDepAtom * const a)
+ {
+ Save<bool> in_use_save(&_in_use, true);
+ Save<std::string> flag_save(&_flags);
+
+ if (! _flags.empty())
+ _flags += " ";
+ _flags += (a->inverse() ? "!" : "") + stringify(a->flag());
+
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+ }
+
+ void
+ ReverseDepChecker::visit(const PackageDepAtom * const a)
+ {
+ PackageDatabaseEntryCollection::ConstPointer dep_entries(
+ _db->query(*a, is_uninstalled_only));
+ PackageDatabaseEntryCollection::Pointer matches(new PackageDatabaseEntryCollection::Concrete);
+
+ bool header_written = false;
+
+ for (PackageDatabaseEntryCollection::Iterator e(dep_entries->begin()), e_end(dep_entries->end()) ;
+ e != e_end ; ++e)
+ {
+ if (_entries->find(*e) != _entries->end())
+ {
+ _found_matches |= true;
+
+ if (! header_written)
+ {
+ std::cout << " " << _p << " " + _depname + " on one of:" << std::endl;
+ header_written = true;
+ }
+ std::cout << " " << stringify(*e);
+
+ if (_in_use || _in_any)
+ {
+ std::cout << " (";
+
+ if (_in_any)
+ std::cout << "any-of";
+
+ if (_in_use && _in_any)
+ std::cout << ", ";
+
+ if (_in_use)
+ std::cout << "condition USE='" << _flags << "'";
+
+ std::cout << ")";
+ }
+ std::cout << std::endl;
+ }
+ }
+ }
+
+ void
+ ReverseDepChecker::visit(const PlainTextDepAtom * const)
+ {
+ }
+
+ void
+ ReverseDepChecker::visit(const BlockDepAtom * const)
+ {
+ }
+
+ void write_repository_header(std::string atom, const std::string &)
+ {
+ cout << "Reverse dependencies for '" << atom << "':" << std::endl;
+ }
+
+ int check_one_package(const Environment & env, const Repository & r,
+ const PackageDatabaseEntryCollection & entries, const QualifiedPackageName & p)
+ {
+ Context context("When checking package '" + stringify(p) + "':");
+
+ PackageDatabaseEntryCollection::Pointer p_entries(env.package_database()->query(
+ PackageDepAtom::Pointer(new PackageDepAtom(stringify(p))), is_uninstalled_only));
+
+ bool found_matches(false);
+
+ if (p_entries->empty())
+ return found_matches ? EXIT_SUCCESS: EXIT_FAILURE;
+
+ for (PackageDatabaseEntryCollection::Iterator e(p_entries->begin()), e_end(p_entries->end()) ;
+ e != e_end ; ++e)
+ {
+ try
+ {
+ VersionMetadata::ConstPointer metadata(r.version_metadata(e->name, e->version));
+ ReverseDepChecker checker(env.package_database(), PackageDatabaseEntryCollection::ConstPointer(&entries),
+ stringify(p) + "-" + stringify(e->version));
+
+ checker.check(metadata->deps.parser(metadata->deps.build_depend_string), std::string("DEPEND"));
+ checker.check(metadata->deps.parser(metadata->deps.run_depend_string), std::string("RDEPEND"));
+ checker.check(metadata->deps.parser(metadata->deps.post_depend_string), std::string("PDEPEND"));
+
+ found_matches |= checker.found_matches();
+ }
+ catch (Exception & exception)
+ {
+ std::cout << "Caught Exception (" << exception.what() << ")" << std::endl;
+ return (found_matches ? EXIT_SUCCESS : EXIT_FAILURE) | 2;
+ }
+ }
+
+ return found_matches ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
+}
+
+int do_find_reverse_deps(AdjutrixEnvironment & env)
+{
+ Context context("When performing find-reverse-deps action:");
+
+ env.set_profile(env.main_repository_dir() / "profiles" / "default-linux" / "amd64" / "2006.1");
+
+ PackageDepAtom::Pointer atom(new PackageDepAtom(*CommandLine::get_instance()->begin_parameters()));
+ PackageDatabaseEntryCollection::Pointer entries(env.package_database()->query(atom, is_either));
+ int ret(EXIT_FAILURE);
+
+ if (entries->empty())
+ return ret;
+
+ for (IndirectIterator<PackageDatabase::RepositoryIterator, const Repository>
+ r(env.package_database()->begin_repositories()),
+ r_end(env.package_database()->end_repositories()) ; r != r_end ; ++r)
+ {
+ if (r->name() == RepositoryName("virtuals"))
+ continue;
+
+
+ write_repository_header(stringify(*atom), stringify(r->name()));
+
+ CategoryNamePartCollection::ConstPointer cat_names(r->category_names());
+ for (CategoryNamePartCollection::Iterator c(cat_names->begin()), c_end(cat_names->end()) ;
+ c != c_end ; ++c)
+ {
+ if (CommandLine::get_instance()->a_category.specified())
+ if (CommandLine::get_instance()->a_category.args_end() == std::find(
+ CommandLine::get_instance()->a_category.args_begin(),
+ CommandLine::get_instance()->a_category.args_end(),
+ stringify(*c)))
+ continue;
+
+ QualifiedPackageNameCollection::ConstPointer pkg_names(r->package_names(*c));
+ for (QualifiedPackageNameCollection::Iterator p(pkg_names->begin()), p_end(pkg_names->end()) ;
+ p != p_end ; ++p)
+ {
+ if (CommandLine::get_instance()->a_package.specified())
+ if (CommandLine::get_instance()->a_package.args_end() == std::find(
+ CommandLine::get_instance()->a_package.args_begin(),
+ CommandLine::get_instance()->a_package.args_end(),
+ stringify(p->package)))
+ continue;
+
+ ret |= check_one_package(env, *r, *entries, *p);
+ }
+ }
+ }
+
+ return ret;
+}
+
+
diff --git a/src/adjutrix/find_reverse_deps.hh b/src/adjutrix/find_reverse_deps.hh
new file mode 100644
index 0000000..f7e4ec4
--- /dev/null
+++ b/src/adjutrix/find_reverse_deps.hh
@@ -0,0 +1,28 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * 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_SRC_ARCHTOOL_FIND_REVERSE_DEPS_HH
+#define PALUDIS_GUARD_SRC_ARCHTOOL_FIND_REVERSE_DEPS_HH 1
+
+#include <adjutrix_environment.hh>
+
+int do_find_reverse_deps(paludis::AdjutrixEnvironment & env);
+
+#endif
+