aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-13 20:08:32 +0100
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2010-08-13 20:08:59 +0100
commita645e704e18e1d7baa64fe2d7e3cdf91534c14bb (patch)
treea9f3d3d8a9132d8b51106e794252a7ae6c33a63e
parent363aac6ff2a9db9d279669d544fdd3656d03b3a8 (diff)
downloadpaludis-a645e704e18e1d7baa64fe2d7e3cdf91534c14bb.tar.gz
paludis-a645e704e18e1d7baa64fe2d7e3cdf91534c14bb.tar.xz
cave report
Fixes: ticket:835
-rw-r--r--.gitignore1
-rw-r--r--doc/clients/Makefile.am1
-rw-r--r--src/clients/cave/Makefile.am2
-rw-r--r--src/clients/cave/cmd_report.cc260
-rw-r--r--src/clients/cave/cmd_report.hh45
-rw-r--r--src/clients/cave/command_factory.cc2
-rw-r--r--src/clients/cave/formats.cc36
-rw-r--r--src/clients/cave/formats.hh7
8 files changed, 354 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 5395239..2743b05 100644
--- a/.gitignore
+++ b/.gitignore
@@ -113,6 +113,7 @@ paludis-*.*.*.tar.bz2
/doc/clients/cave-print-sets.html
/doc/clients/cave-print-sync-protocols.html
/doc/clients/cave-purge.html
+/doc/clients/cave-report.html
/doc/clients/cave-resolve.html
/doc/clients/cave-resume.html
/doc/clients/cave-search.html
diff --git a/doc/clients/Makefile.am b/doc/clients/Makefile.am
index 2a1d4cf..546c919 100644
--- a/doc/clients/Makefile.am
+++ b/doc/clients/Makefile.am
@@ -58,6 +58,7 @@ CAVE_COMMANDS_HTML = \
cave-print-sets.html \
cave-print-sync-protocols.html \
cave-purge.html \
+ cave-report.html \
cave-resolve.html \
cave-resume.html \
cave-search.html \
diff --git a/src/clients/cave/Makefile.am b/src/clients/cave/Makefile.am
index b52d9c9..0f08970 100644
--- a/src/clients/cave/Makefile.am
+++ b/src/clients/cave/Makefile.am
@@ -51,6 +51,7 @@ command_MANS = \
cave-print-sets.1 \
cave-print-sync-protocols.1 \
cave-purge.1 \
+ cave-report.1 \
cave-resolve.1 \
cave-resume.1 \
cave-search.1 \
@@ -133,6 +134,7 @@ libcave_a_SOURCES = \
cmd_print_sets.cc cmd_print_sets.hh \
cmd_print_sync_protocols.cc cmd_print_sync_protocols.hh \
cmd_purge.cc cmd_purge.hh \
+ cmd_report.cc cmd_report.hh \
cmd_resolve.cc cmd_resolve.hh \
cmd_resolve_cmdline.cc cmd_resolve_cmdline.hh \
cmd_resolve_display_callback.cc cmd_resolve_display_callback.hh \
diff --git a/src/clients/cave/cmd_report.cc b/src/clients/cave/cmd_report.cc
new file mode 100644
index 0000000..c901540
--- /dev/null
+++ b/src/clients/cave/cmd_report.cc
@@ -0,0 +1,260 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * 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 "cmd_report.hh"
+#include "colour_formatter.hh"
+#include "format_general.hh"
+#include "formats.hh"
+#include "exceptions.hh"
+
+#include <paludis/args/args.hh>
+#include <paludis/args/do_help.hh>
+
+#include <paludis/name.hh>
+#include <paludis/environment.hh>
+#include <paludis/package_database.hh>
+#include <paludis/repository.hh>
+#include <paludis/user_dep_spec.hh>
+#include <paludis/filter.hh>
+#include <paludis/generator.hh>
+#include <paludis/filtered_generator.hh>
+#include <paludis/selection.hh>
+#include <paludis/package_id.hh>
+#include <paludis/metadata_key.hh>
+#include <paludis/mask.hh>
+#include <paludis/match_package.hh>
+#include <paludis/partially_made_package_dep_spec.hh>
+#include <paludis/version_requirements.hh>
+#include <paludis/action.hh>
+
+#include <paludis/util/set.hh>
+#include <paludis/util/wrapped_forward_iterator.hh>
+#include <paludis/util/wrapped_output_iterator.hh>
+#include <paludis/util/simple_visitor_cast.hh>
+#include <paludis/util/indirect_iterator-impl.hh>
+#include <paludis/util/make_null_shared_ptr.hh>
+#include <paludis/util/accept_visitor.hh>
+#include <paludis/util/make_named_values.hh>
+
+#include <paludis/resolver/collect_purges.hh>
+#include <paludis/resolver/collect_installed.hh>
+
+#include <cstdlib>
+#include <iostream>
+#include <algorithm>
+#include <set>
+
+#include "command_command_line.hh"
+
+using namespace paludis;
+using namespace cave;
+using std::cout;
+using std::endl;
+
+namespace
+{
+ struct ReportCommandLine :
+ CaveCommandCommandLine
+ {
+ virtual std::string app_name() const
+ {
+ return "cave report";
+ }
+
+ virtual std::string app_synopsis() const
+ {
+ return "Display a summary of potential problems with installed packages.";
+ }
+
+ virtual std::string app_description() const
+ {
+ return "Displays a formatted summary of potential problems with installed packages.";
+ }
+
+ ReportCommandLine()
+ {
+ add_usage_line("");
+ }
+ };
+
+ const std::shared_ptr<const PackageID> find_origin_for(
+ const std::shared_ptr<Environment> & env,
+ const std::shared_ptr<const PackageID> & id)
+ {
+ if (id->from_repositories_key())
+ {
+ for (auto r(id->from_repositories_key()->value()->begin()), r_end(id->from_repositories_key()->value()->end()) ;
+ r != r_end ; ++r)
+ {
+ auto ids((*env)[selection::BestVersionOnly((
+ generator::InRepository(RepositoryName(*r)) &
+ generator::Matches(make_package_dep_spec({ })
+ .package(id->name())
+ .version_requirement(make_named_values<VersionRequirement>(
+ n::version_operator() = vo_equal,
+ n::version_spec() = id->version())),
+ { })) |
+ filter::SupportsAction<InstallAction>())]);
+
+ if (! ids->empty())
+ return *ids->begin();
+ }
+ }
+
+ return make_null_shared_ptr();
+ }
+
+ void need_heading(
+ bool & already,
+ const std::shared_ptr<const PackageID> & id)
+ {
+ if (! already)
+ {
+ cout << format_general_s(f::report_package_id(), stringify(*id));
+ already = true;
+ }
+ }
+
+ void need_heading_origin(
+ bool & already,
+ bool & already_origin,
+ const std::shared_ptr<const PackageID> & id,
+ const std::shared_ptr<const PackageID> & origin_id)
+ {
+ need_heading(already, id);
+
+ if (! already_origin)
+ {
+ cout << format_general_s(f::report_package_origin(), stringify(*origin_id));
+ already_origin = true;
+ }
+ }
+
+ void do_nothing()
+ {
+ }
+}
+
+bool
+ReportCommand::important() const
+{
+ return true;
+}
+
+int
+ReportCommand::run(
+ const std::shared_ptr<Environment> & env,
+ const std::shared_ptr<const Sequence<std::string > > & args
+ )
+{
+ ReportCommandLine cmdline;
+ cmdline.run(args, "CAVE", "CAVE_REPORT_OPTIONS", "CAVE_REPORT_CMDLINE");
+
+ if (cmdline.a_help.specified())
+ {
+ cout << cmdline;
+ return EXIT_SUCCESS;
+ }
+
+ if (cmdline.begin_parameters() != cmdline.end_parameters())
+ throw args::DoHelp("report takes no parameters");
+
+ auto ids((*env)[selection::AllVersionsSorted(
+ generator::All() | filter::InstalledAtRoot(env->preferred_root_key()->value()))]);
+
+ auto insecurity(env->set(SetName("insecurity")));
+
+ auto have_now(resolver::collect_installed(env.get()));
+ auto have_now_seq(std::make_shared<PackageIDSequence>());
+ std::copy(have_now->begin(), have_now->end(), have_now_seq->back_inserter());
+ auto unused(resolver::collect_purges(env.get(), have_now, have_now_seq, do_nothing));
+
+ bool errors(false);
+
+ for (auto i(ids->begin()), i_end(ids->end()) ;
+ i != i_end ; ++i)
+ {
+ if ((*i)->virtual_for_key())
+ {
+ /* too weird */
+ continue;
+ }
+
+ bool done_heading(false), done_heading_origin(false);
+
+ auto origin(find_origin_for(env, *i));
+ if (! origin)
+ {
+ if ((*i)->behaviours_key() &&
+ (*i)->behaviours_key()->value()->end() != (*i)->behaviours_key()->value()->find("transient"))
+ {
+ /* that's ok */
+ }
+ else
+ {
+ need_heading(done_heading, *i);
+ std::string repos;
+ if ((*i)->from_repositories_key())
+ repos = join((*i)->from_repositories_key()->value()->begin(), (*i)->from_repositories_key()->value()->end(), ", ");
+ cout << format_general_s(f::report_package_no_origin(), repos);
+ }
+ }
+ else
+ {
+ if (origin->masked())
+ {
+ need_heading_origin(done_heading, done_heading_origin, *i, origin);
+ cout << format_general_s(f::report_package_origin_masked(), "");
+ }
+
+ if (insecurity && match_package_in_set(*env, *insecurity, *origin, { }))
+ {
+ need_heading_origin(done_heading, done_heading_origin, *i, origin);
+ cout << format_general_s(f::report_package_origin_insecure(), "");
+ }
+ }
+
+ if (unused->end() != unused->find(*i))
+ {
+ if (((*i)->behaviours_key() && (*i)->behaviours_key()->value()->end() !=
+ (*i)->behaviours_key()->value()->find("used")) ||
+ (! (*i)->supports_action(SupportsActionTest<UninstallAction>())))
+ {
+ /* ok, or weird */
+ }
+ else
+ {
+ need_heading(done_heading, *i);
+ cout << format_general_s(f::report_package_unused(), "");
+ }
+ }
+
+ if (done_heading)
+ errors = true;
+ }
+
+ return errors ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
+std::shared_ptr<args::ArgsHandler>
+ReportCommand::make_doc_cmdline()
+{
+ return std::make_shared<ReportCommandLine>();
+}
+
diff --git a/src/clients/cave/cmd_report.hh b/src/clients/cave/cmd_report.hh
new file mode 100644
index 0000000..ca9d925
--- /dev/null
+++ b/src/clients/cave/cmd_report.hh
@@ -0,0 +1,45 @@
+/* vim: set sw=4 sts=4 et foldmethod=syntax : */
+
+/*
+ * Copyright (c) 2010 Ciaran McCreesh
+ *
+ * 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_CLIENTS_CAVE_CMD_REPORT_HH
+#define PALUDIS_GUARD_SRC_CLIENTS_CAVE_CMD_REPORT_HH 1
+
+#include "command.hh"
+
+namespace paludis
+{
+ namespace cave
+ {
+ class PALUDIS_VISIBLE ReportCommand :
+ public Command
+ {
+ public:
+ bool important() const;
+
+ int run(
+ const std::shared_ptr<Environment> &,
+ const std::shared_ptr<const Sequence<std::string > > & args
+ );
+
+ std::shared_ptr<args::ArgsHandler> make_doc_cmdline();
+ };
+ }
+}
+
+#endif
diff --git a/src/clients/cave/command_factory.cc b/src/clients/cave/command_factory.cc
index 321d5c1..efea695 100644
--- a/src/clients/cave/command_factory.cc
+++ b/src/clients/cave/command_factory.cc
@@ -65,6 +65,7 @@
#include "cmd_print_sets.hh"
#include "cmd_print_sync_protocols.hh"
#include "cmd_purge.hh"
+#include "cmd_report.hh"
#include "cmd_resolve.hh"
#include "cmd_resume.hh"
#include "cmd_search.hh"
@@ -169,6 +170,7 @@ CommandFactory::CommandFactory() :
_imp->handlers.insert(std::make_pair("print-set", std::bind(&make_command<PrintSetCommand>)));
_imp->handlers.insert(std::make_pair("print-sets", std::bind(&make_command<PrintSetsCommand>)));
_imp->handlers.insert(std::make_pair("print-sync-protocols", std::bind(&make_command<PrintSyncProtocolsCommand>)));
+ _imp->handlers.insert(std::make_pair("report", std::bind(&make_command<ReportCommand>)));
_imp->handlers.insert(std::make_pair("resolve", std::bind(&make_command<ResolveCommand>)));
_imp->handlers.insert(std::make_pair("resume", std::bind(&make_command<ResumeCommand>)));
_imp->handlers.insert(std::make_pair("search", std::bind(&make_command<SearchCommand>)));
diff --git a/src/clients/cave/formats.cc b/src/clients/cave/formats.cc
index 0cd515c..0b09682 100644
--- a/src/clients/cave/formats.cc
+++ b/src/clients/cave/formats.cc
@@ -687,3 +687,39 @@ paludis::cave::f::verify_error()
return c::bold_red() + " %s:" + c::normal() + "%{column 32}%r\\n";
}
+const std::string
+paludis::cave::f::report_package_id()
+{
+ return c::bold_blue() + "%s" + c::normal() + "\\n";
+}
+
+const std::string
+paludis::cave::f::report_package_no_origin()
+{
+ return " No longer exists in original repository %s\\n";
+}
+
+const std::string
+paludis::cave::f::report_package_origin()
+{
+ return " Origin %s:\\n";
+}
+
+const std::string
+paludis::cave::f::report_package_origin_masked()
+{
+ return " Masked in original repository\\n";
+}
+
+const std::string
+paludis::cave::f::report_package_origin_insecure()
+{
+ return " Marked as insecure\\n";
+}
+
+const std::string
+paludis::cave::f::report_package_unused()
+{
+ return " Not used by any package in world\\n";
+}
+
diff --git a/src/clients/cave/formats.hh b/src/clients/cave/formats.hh
index 66ade0f..4ff8adc 100644
--- a/src/clients/cave/formats.hh
+++ b/src/clients/cave/formats.hh
@@ -172,6 +172,13 @@ namespace paludis
const std::string verify_package();
const std::string verify_error();
+
+ const std::string report_package_id();
+ const std::string report_package_no_origin();
+ const std::string report_package_origin();
+ const std::string report_package_origin_masked();
+ const std::string report_package_origin_insecure();
+ const std::string report_package_unused();
}
}
}