/* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* * Copyright (c) 2010, 2011 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 "format_user_config.hh" #include "colours.hh" #include "exceptions.hh" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "command_command_line.hh" using namespace paludis; using namespace cave; using std::cout; using std::endl; namespace { #include "cmd_report-fmt.hh" 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 find_origin_for( const std::shared_ptr & env, const std::shared_ptr & id) { if (id->from_repositories_key()) { auto from_repositories(id->from_repositories_key()->parse_value()); for (auto r(from_repositories->begin()), r_end(from_repositories->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( n::version_operator() = vo_equal, n::version_spec() = id->version())), nullptr, { })) | filter::SupportsAction())]); if (! ids->empty()) return *ids->begin(); } } return nullptr; } void need_heading( bool & already, const std::shared_ptr & id) { if (! already) { cout << fuc(fs_package_id(), fv<'s'>(stringify(*id))); already = true; } } void need_heading_origin( bool & already, bool & already_origin, const std::shared_ptr & id, const std::shared_ptr & origin_id) { need_heading(already, id); if (! already_origin) { cout << fuc(fs_package_origin(), fv<'s'>(stringify(*origin_id))); already_origin = true; } } void do_nothing() { } } int ReportCommand::run( const std::shared_ptr & env, const std::shared_ptr > & 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()->parse_value()))]); auto insecurity(env->set(SetName("insecurity"))); auto have_now(resolver::collect_installed(env.get())); auto have_now_seq(std::make_shared()); 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) { bool done_heading(false), done_heading_origin(false); auto origin(find_origin_for(env, *i)); if (! origin) { bool is_transient(false); if ((*i)->behaviours_key()) { auto behaviours((*i)->behaviours_key()->parse_value()); is_transient = behaviours->end() != behaviours->find("transient"); } if (is_transient) { /* that's ok */ } else { need_heading(done_heading, *i); std::string repos; if ((*i)->from_repositories_key()) { auto from_repositories((*i)->from_repositories_key()->parse_value()); repos = join(from_repositories->begin(), from_repositories->end(), ", "); } cout << fuc(fs_package_no_origin(), fv<'s'>(repos)); } } else { if (origin->masked()) { need_heading_origin(done_heading, done_heading_origin, *i, origin); cout << fuc(fs_package_origin_masked()); } } if (insecurity && match_package_in_set(*env, *insecurity, *i, { })) { need_heading(done_heading, *i); cout << fuc(fs_package_insecure()); } if (unused->end() != unused->find(*i)) { bool is_used(false); if ((*i)->behaviours_key()) { auto behaviours((*i)->behaviours_key()->parse_value()); is_used = behaviours->end() != behaviours->find("used"); } if (is_used || (! (*i)->supports_action(SupportsActionTest()))) { /* ok, or weird */ } else { need_heading(done_heading, *i); cout << fuc(fs_package_unused()); } } if (done_heading) errors = true; } return errors ? EXIT_FAILURE : EXIT_SUCCESS; } std::shared_ptr ReportCommand::make_doc_cmdline() { return std::make_shared(); } CommandImportance ReportCommand::importance() const { return ci_core; }