diff options
author | 2010-08-13 20:08:32 +0100 | |
---|---|---|
committer | 2010-08-13 20:08:59 +0100 | |
commit | a645e704e18e1d7baa64fe2d7e3cdf91534c14bb (patch) | |
tree | a9f3d3d8a9132d8b51106e794252a7ae6c33a63e | |
parent | 363aac6ff2a9db9d279669d544fdd3656d03b3a8 (diff) | |
download | paludis-a645e704e18e1d7baa64fe2d7e3cdf91534c14bb.tar.gz paludis-a645e704e18e1d7baa64fe2d7e3cdf91534c14bb.tar.xz |
cave report
Fixes: ticket:835
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | doc/clients/Makefile.am | 1 | ||||
-rw-r--r-- | src/clients/cave/Makefile.am | 2 | ||||
-rw-r--r-- | src/clients/cave/cmd_report.cc | 260 | ||||
-rw-r--r-- | src/clients/cave/cmd_report.hh | 45 | ||||
-rw-r--r-- | src/clients/cave/command_factory.cc | 2 | ||||
-rw-r--r-- | src/clients/cave/formats.cc | 36 | ||||
-rw-r--r-- | src/clients/cave/formats.hh | 7 |
8 files changed, 354 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore index 5395239fb..2743b05e7 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 2a1d4cf2d..546c9196e 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 b52d9c98a..0f0897099 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 000000000..c901540fc --- /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 000000000..ca9d92529 --- /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 321d5c123..efea69577 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 0cd515c70..0b0968282 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 66ade0f31..4ff8adc39 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(); } } } |