aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Richard Brown <rbrown@exherbo.org> 2008-03-22 20:38:38 +0000
committerAvatar Richard Brown <rbrown@exherbo.org> 2008-03-22 20:38:38 +0000
commited69621d97b88e665ef17ea1ec725c7b841fcbf0 (patch)
treeff9778e361c40b3b20358a9fc0a6c674feb78905
parent327167532760d84b825f311e16a7772ae52f0216 (diff)
downloadpaludis-ed69621d97b88e665ef17ea1ec725c7b841fcbf0.tar.gz
paludis-ed69621d97b88e665ef17ea1ec725c7b841fcbf0.tar.xz
Add --executables command line option to paludis.
-rw-r--r--NEWS3
-rw-r--r--src/clients/paludis/Makefile.am1
-rw-r--r--src/clients/paludis/command_line.cc2
-rw-r--r--src/clients/paludis/command_line.hh3
-rw-r--r--src/clients/paludis/do_executables.cc218
-rw-r--r--src/clients/paludis/do_executables.hh37
-rw-r--r--src/clients/paludis/paludis.cc10
7 files changed, 274 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 013e97d..25e2664 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,9 @@ This file lists the major changes between versions. For a more detailed list
of every change, see the ChangeLog.
trunk/:
+ * paludis now has an --executables option, this will show all executables
+ installed by a package that are in $PATH.
+
* Installation details for pretend_resume demo hook have changed. Please
remove any old symlinks and see the comments at the start of the file
for new instructions.
diff --git a/src/clients/paludis/Makefile.am b/src/clients/paludis/Makefile.am
index a29a1da..d3a6ee5 100644
--- a/src/clients/paludis/Makefile.am
+++ b/src/clients/paludis/Makefile.am
@@ -40,6 +40,7 @@ paludis_SOURCES = \
query.hh query.cc \
sync.hh sync.cc \
do_contents.hh do_contents.cc \
+ do_executables.hh do_executables.cc \
do_config.hh do_config.cc \
owner.hh owner.cc \
report.hh report.cc \
diff --git a/src/clients/paludis/command_line.cc b/src/clients/paludis/command_line.cc
index 56ef014..fc32510 100644
--- a/src/clients/paludis/command_line.cc
+++ b/src/clients/paludis/command_line.cc
@@ -37,6 +37,7 @@ CommandLine::CommandLine() :
a_sync(&action_args, "sync", 's', "Sync all or specified repositories", false),
a_report(&action_args, "report", 'r', "Report the current state of the system", false),
a_contents(&action_args, "contents", 'k', "Display contents of a package", false),
+ a_executables(&action_args,"executables", '\0', "Display executable contents of a package", false),
a_owner(&action_args, "owner", 'o', "Display the owner of a file", false),
a_config(&action_args, "config", '\0', "Run post-install configuration for a package", false),
a_version(&action_args, "version", 'V', "Display program version", false),
@@ -150,6 +151,7 @@ CommandLine::CommandLine() :
add_usage_line("--sync [target (leave blank for all)]");
add_usage_line("--report");
add_usage_line("--contents target ...");
+ add_usage_line("--executables target ...");
add_usage_line("--owner [owner options] files ...");
add_usage_line("--config target ...");
add_usage_line("--version");
diff --git a/src/clients/paludis/command_line.hh b/src/clients/paludis/command_line.hh
index 0a28672..153a735 100644
--- a/src/clients/paludis/command_line.hh
+++ b/src/clients/paludis/command_line.hh
@@ -83,6 +83,9 @@ class CommandLine :
/// --contents
paludis::args::SwitchArg a_contents;
+ /// --executables
+ paludis::args::SwitchArg a_executables;
+
/// --owner
paludis::args::SwitchArg a_owner;
diff --git a/src/clients/paludis/do_executables.cc b/src/clients/paludis/do_executables.cc
new file mode 100644
index 0000000..c8747f9
--- /dev/null
+++ b/src/clients/paludis/do_executables.cc
@@ -0,0 +1,218 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Richard Brown
+ *
+ * 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 "do_executables.hh"
+#include "paludis/util/fs_entry-fwd.hh"
+#include "paludis/util/tokeniser.hh"
+#include <src/output/colour.hh>
+#include "command_line.hh"
+#include <paludis/paludis.hh>
+#include <paludis/util/visitor-impl.hh>
+#include <paludis/fuzzy_finder.hh>
+#include <iostream>
+#include <algorithm>
+
+using namespace paludis;
+using std::cout;
+using std::cerr;
+using std::endl;
+
+namespace
+{
+ struct ExecutablesDisplayer :
+ ConstVisitor<ContentsVisitorTypes>
+ {
+ private:
+ const std::list<std::string> _paths;
+
+ bool is_file_in_path(FSEntry file)
+ {
+ if (file.has_permission(fs_ug_others, fs_perm_execute))
+ {
+ FSEntry dirname(file.dirname());
+ for (std::list<std::string>::const_iterator it(_paths.begin()),
+ it_end(_paths.end()); it_end != it; ++it)
+ {
+ if (dirname == *it)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public:
+ ExecutablesDisplayer(std::list<std::string> p) :
+ _paths(p)
+ {
+ }
+
+ void visit(const ContentsFileEntry & e)
+ {
+ if (is_file_in_path(FSEntry(e.name())))
+ cout << " " << colour(cl_file, e.name()) << endl;
+ }
+
+ void visit(const ContentsDirEntry &)
+ {
+ }
+
+ void visit(const ContentsSymEntry & e)
+ {
+ FSEntry sym(e.name());
+ FSEntry real(sym.realpath_if_exists());
+ if (sym != real)
+ if (is_file_in_path(real))
+ cout << " " << colour(cl_sym, e.name()) << endl;
+ }
+
+ void visit(const ContentsMiscEntry &)
+ {
+ }
+
+ void visit(const ContentsFifoEntry &)
+ {
+ }
+
+ void visit(const ContentsDevEntry &)
+ {
+ }
+ };
+}
+
+void
+do_one_executables_entry(
+ const tr1::shared_ptr<Environment>,
+ const PackageID & e)
+{
+ cout << "* " << colour(cl_package_name, e) << endl;
+
+ if (e.contents_key())
+ {
+ tr1::shared_ptr<const Contents> contents(e.contents_key()->value());
+ std::string path(getenv("PATH"));
+ std::list<std::string> paths;
+ tokenise<delim_kind::AnyOfTag, delim_mode::DelimiterTag>(path, ":", "", std::back_inserter(paths));
+ ExecutablesDisplayer d(paths);
+ std::for_each(indirect_iterator(contents->begin()), indirect_iterator(contents->end()), accept_visitor(d));
+ }
+ else
+ cout << " " << colour(cl_error, "(unknown)") << endl;
+
+ cout << endl;
+}
+
+void
+do_one_executables(
+ const tr1::shared_ptr<Environment> env,
+ const std::string & q)
+{
+ Context local_context("When handling query '" + q + "':");
+
+ /* we might have a dep spec, but we might just have a simple package name
+ * without a category. either should work. */
+ tr1::shared_ptr<PackageDepSpec> spec(std::string::npos == q.find('/') ?
+ new PackageDepSpec(make_package_dep_spec().package(
+ env->package_database()->fetch_unique_qualified_package_name(PackageNamePart(q)))) :
+ new PackageDepSpec(parse_user_package_dep_spec(q, UserPackageDepSpecOptions())));
+
+ tr1::shared_ptr<const PackageIDSequence>
+ entries(env->package_database()->query(query::Matches(*spec) & query::InstalledAtRoot(
+ env->root()), qo_order_by_version));
+
+ if (entries->empty())
+ throw NoSuchPackageError(q);
+
+ for (PackageIDSequence::ConstIterator i(entries->begin()),
+ i_end(entries->end()) ; i != i_end ; ++i)
+ do_one_executables_entry(env, **i);
+}
+
+int
+do_executables(tr1::shared_ptr<Environment> env)
+{
+ int return_code(0);
+
+ Context context("When performing executables action from command line:");
+
+ CommandLine::ParametersConstIterator q(CommandLine::get_instance()->begin_parameters()),
+ q_end(CommandLine::get_instance()->end_parameters());
+ for ( ; q != q_end ; ++q)
+ {
+ try
+ {
+ do_one_executables(env, *q);
+ }
+ catch (const AmbiguousPackageNameError & e)
+ {
+ cout << endl;
+ cerr << "Query error:" << endl;
+ cerr << " * " << e.backtrace("\n * ");
+ cerr << "Ambiguous package name '" << e.name() << "'. Did you mean:" << endl;
+ for (AmbiguousPackageNameError::OptionsConstIterator o(e.begin_options()),
+ o_end(e.end_options()) ; o != o_end ; ++o)
+ cerr << " * " << colour(cl_package_name, *o) << endl;
+ cerr << endl;
+ }
+ catch (const NameError & e)
+ {
+ return_code |= 1;
+ cout << endl;
+ cerr << "Query error:" << endl;
+ cerr << " * " << e.backtrace("\n * ") << e.message() << endl;
+ cerr << endl;
+ }
+ catch (const NoSuchPackageError & e)
+ {
+ return_code |= 1;
+ cout << endl;
+ cerr << "Query error:" << endl;
+ cerr << " * " << e.backtrace("\n * ");
+ cerr << "Could not find '" << e.name() << "'.";
+
+ if (! CommandLine::get_instance()->a_no_suggestions.specified())
+ {
+ cerr << " Looking for suggestions:" << endl;
+
+ FuzzyCandidatesFinder f(*env, e.name(), query::InstalledAtRoot(env->root()));
+
+ if (f.begin() == f.end())
+ cerr << "No suggestions found." << endl;
+ else
+ cerr << "Suggestions:" << endl;
+
+ for (FuzzyCandidatesFinder::CandidatesConstIterator c(f.begin()),
+ c_end(f.end()) ; c != c_end ; ++c)
+ cerr << " * " << colour(cl_package_name, *c) << endl;
+ }
+
+ cerr << endl;
+ }
+ catch (const PackageDatabaseLookupError & e)
+ {
+ return_code |= 1;
+ cout << endl;
+ cerr << "Query error:" << endl;
+ cerr << " * " << e.backtrace("\n * ") << e.message() << endl;
+ cerr << endl;
+ }
+ }
+
+ return return_code;
+}
+
diff --git a/src/clients/paludis/do_executables.hh b/src/clients/paludis/do_executables.hh
new file mode 100644
index 0000000..cbdad5b
--- /dev/null
+++ b/src/clients/paludis/do_executables.hh
@@ -0,0 +1,37 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2008 Richard Brown
+ *
+ * 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_EXECUTABLES_HH
+#define PALUDIS_GUARD_SRC_EXECUTABLES_HH 1
+
+/** \file
+ * Declaration for the do_contents function.
+ */
+
+#include <paludis/util/tr1_memory.hh>
+
+namespace paludis
+{
+ class Environment;
+}
+
+/// Handle --executables.
+int do_executables(paludis::tr1::shared_ptr<paludis::Environment>);
+
+#endif
diff --git a/src/clients/paludis/paludis.cc b/src/clients/paludis/paludis.cc
index 6ffa456..835a016 100644
--- a/src/clients/paludis/paludis.cc
+++ b/src/clients/paludis/paludis.cc
@@ -21,6 +21,7 @@
#include "command_line.hh"
#include "config.h"
#include "do_contents.hh"
+#include "do_executables.hh"
#include "do_config.hh"
#include "install.hh"
#include "list.hh"
@@ -180,6 +181,7 @@ main(int argc, char *argv[])
CommandLine::get_instance()->a_list_repository_formats.specified() +
CommandLine::get_instance()->a_list_dep_tag_categories.specified() +
CommandLine::get_instance()->a_contents.specified() +
+ CommandLine::get_instance()->a_executables.specified() +
CommandLine::get_instance()->a_owner.specified() +
CommandLine::get_instance()->a_config.specified() +
CommandLine::get_instance()->a_has_version.specified() +
@@ -402,6 +404,14 @@ main(int argc, char *argv[])
return do_contents(env);
}
+ if (CommandLine::get_instance()->a_executables.specified())
+ {
+ if (CommandLine::get_instance()->empty())
+ throw args::DoHelp("executables action requires at least one parameter");
+
+ return do_executables(env);
+ }
+
if (CommandLine::get_instance()->a_owner.specified())
{
if (CommandLine::get_instance()->empty())