aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-01-16 16:01:36 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2007-01-16 16:01:36 +0000
commitb23a44f186036018f9ec490f2d8b956f5277be51 (patch)
tree8ba434f2e40ca8ac7e2eff5d8013ddf016547576
parent195acc92b7a34d2caf6bb3f661a2e404190fd0cb (diff)
downloadpaludis-b23a44f186036018f9ec490f2d8b956f5277be51.tar.gz
paludis-b23a44f186036018f9ec490f2d8b956f5277be51.tar.xz
Add suggested deps to the deplist. Fixes: ticket:12
-rw-r--r--paludis/dep_list/dep_list.cc118
-rw-r--r--paludis/dep_list/dep_list.hh3
-rw-r--r--paludis/dep_list/dep_list.sr2
-rw-r--r--paludis/dep_list/options.cc4
-rw-r--r--paludis/dep_list/options.hh14
-rw-r--r--paludis/dep_list/uninstall_list.cc2
-rw-r--r--paludis/repositories/cran/cran_description.cc2
-rw-r--r--src/clients/paludis/command_line.cc9
-rw-r--r--src/clients/paludis/command_line.hh2
-rw-r--r--src/clients/paludis/install.cc16
-rw-r--r--src/output/console_install_task.cc61
-rw-r--r--src/output/console_install_task.hh6
12 files changed, 226 insertions, 13 deletions
diff --git a/paludis/dep_list/dep_list.cc b/paludis/dep_list/dep_list.cc
index c81f3c0..41a745f 100644
--- a/paludis/dep_list/dep_list.cc
+++ b/paludis/dep_list/dep_list.cc
@@ -53,6 +53,8 @@ DepListOptions::DepListOptions() :
uninstalled_deps_pre(dl_deps_pre),
uninstalled_deps_runtime(dl_deps_pre_or_post),
uninstalled_deps_post(dl_deps_post),
+ uninstalled_deps_suggested(dl_deps_try_post),
+ suggested(dl_suggested_show),
circular(dl_circular_error),
blocks(dl_blocks_accumulate),
dependency_tags(false)
@@ -224,6 +226,7 @@ namespace
case dlk_block:
case dlk_masked:
+ case dlk_suggested:
return false;
case last_dlk:
@@ -779,6 +782,70 @@ DepList::AddVisitor::visit(const BlockDepAtom * const a)
}
}
+struct DepList::ShowSuggestVisitor :
+ DepAtomVisitorTypes::ConstVisitor,
+ DepAtomVisitorTypes::ConstVisitor::VisitChildren<ShowSuggestVisitor, AllDepAtom>,
+ DepAtomVisitorTypes::ConstVisitor::VisitChildren<ShowSuggestVisitor, AnyDepAtom>
+{
+ DepList * const d;
+
+ ShowSuggestVisitor(DepList * const dd) :
+ d(dd)
+ {
+ }
+
+ void visit(const PlainTextDepAtom * const) PALUDIS_ATTRIBUTE((noreturn));
+ void visit(const PackageDepAtom * const);
+ void visit(const UseDepAtom * const);
+ void visit(const BlockDepAtom * const);
+ using DepAtomVisitorTypes::ConstVisitor::VisitChildren<ShowSuggestVisitor, AllDepAtom>::visit;
+ using DepAtomVisitorTypes::ConstVisitor::VisitChildren<ShowSuggestVisitor, AnyDepAtom>::visit;
+};
+
+void
+DepList::ShowSuggestVisitor::visit(const PlainTextDepAtom * const)
+{
+ throw InternalError(PALUDIS_HERE, "Got PlainTextDepAtom?");
+}
+
+void
+DepList::ShowSuggestVisitor::visit(const UseDepAtom * const a)
+{
+ if (d->_imp->env->query_use(a->flag(), d->_imp->current_pde()) ^ a->inverse())
+ std::for_each(a->begin(), a->end(), accept_visitor(this));
+}
+
+void
+DepList::ShowSuggestVisitor::visit(const BlockDepAtom * const)
+{
+}
+
+void
+DepList::ShowSuggestVisitor::visit(const PackageDepAtom * const a)
+{
+ Context context("When adding suggested dep '" + stringify(*a) + "':");
+
+ PackageDatabaseEntryCollection::ConstPointer matches(d->_imp->env->package_database()->query(
+ *a, is_installable_only, qo_order_by_version));
+ if (matches->empty())
+ {
+ Log::get_instance()->message(ll_warning, lc_context, "Nothing found for '" + stringify(*a) + "'");
+ return;
+ }
+
+ for (PackageDatabaseEntryCollection::Iterator m(matches->begin()), m_end(matches->end()) ;
+ m != m_end ; ++m)
+ {
+ if (d->_imp->env->mask_reasons(*m).any())
+ continue;
+
+ d->add_suggested_package(*m);
+ return;
+ }
+
+ Log::get_instance()->message(ll_warning, lc_context, "Nothing visible found for '" + stringify(*a) + "'");
+}
+
DepList::DepList(const Environment * const e, const DepListOptions & o) :
PrivateImplementationPattern<DepList>(new Implementation<DepList>(e, o)),
options(_imp->opts)
@@ -901,18 +968,34 @@ DepList::add_package(const PackageDatabaseEntry & p, DepTag::ConstPointer tag)
}
}
+ /* add suggests */
+ if (_imp->opts.suggested == dl_suggested_show)
+ {
+ Context c("When showing suggestions:");
+ Save<MergeList::iterator> suggest_save_merge_list_insert_position(&_imp->merge_list_insert_position,
+ next(our_merge_entry_position));
+ ShowSuggestVisitor visitor(this);
+ metadata->deps.suggested_depend()->accept(&visitor);
+ }
+
/* add pre dependencies */
add_predeps(metadata->deps.build_depend(), _imp->opts.uninstalled_deps_pre, "build");
add_predeps(metadata->deps.run_depend(), _imp->opts.uninstalled_deps_runtime, "run");
add_predeps(metadata->deps.post_depend(), _imp->opts.uninstalled_deps_post, "post");
+ if (_imp->opts.suggested == dl_suggested_install)
+ add_predeps(metadata->deps.suggested_depend(), _imp->opts.uninstalled_deps_suggested, "suggest");
our_merge_entry_position->state = dle_has_pre_deps;
_imp->merge_list_insert_position = next(our_merge_entry_post_position);
+ /* add post dependencies */
add_postdeps(metadata->deps.build_depend(), _imp->opts.uninstalled_deps_pre, "build");
add_postdeps(metadata->deps.run_depend(), _imp->opts.uninstalled_deps_runtime, "run");
add_postdeps(metadata->deps.post_depend(), _imp->opts.uninstalled_deps_post, "post");
+ if (_imp->opts.suggested == dl_suggested_install)
+ add_postdeps(metadata->deps.suggested_depend(), _imp->opts.uninstalled_deps_suggested, "suggest");
+
our_merge_entry_position->state = dle_has_all_deps;
}
@@ -955,6 +1038,40 @@ DepList::add_error_package(const PackageDatabaseEntry & p, const DepListEntryKin
}
void
+DepList::add_suggested_package(const PackageDatabaseEntry & p)
+{
+ std::pair<MergeListIndex::iterator, MergeListIndex::const_iterator> pp(
+ _imp->merge_list_index.equal_range(p.name));
+
+ for ( ; pp.first != pp.second ; ++pp.first)
+ {
+ if ((pp.first->second->kind == dlk_suggested || pp.first->second->kind == dlk_already_installed
+ || pp.first->second->kind == dlk_package || pp.first->second->kind == dlk_provided
+ || pp.first->second->kind == dlk_subpackage) && pp.first->second->package == p)
+ return;
+ }
+
+ MergeList::iterator our_merge_entry_position(
+ _imp->merge_list.insert(_imp->merge_list_insert_position,
+ DepListEntry::create()
+ .package(p)
+ .metadata(_imp->env->package_database()->fetch_repository(
+ p.repository)->version_metadata(p.name, p.version))
+ .generation(_imp->merge_list_generation)
+ .state(dle_has_all_deps)
+ .tags(DepListEntryTags::Pointer(new DepListEntryTags::Concrete))
+ .destinations(RepositoryNameCollection::Pointer(new RepositoryNameCollection::Concrete))
+ .kind(dlk_suggested)));
+
+ if (_imp->current_pde())
+ our_merge_entry_position->tags->insert(DepTagEntry::create()
+ .tag(DepTag::Pointer(new DependencyDepTag(*_imp->current_pde())))
+ .generation(_imp->merge_list_generation));
+
+ _imp->merge_list_index.insert(std::make_pair(p.name, our_merge_entry_position));
+}
+
+void
DepList::add_predeps(DepAtom::ConstPointer d, const DepListDepsOption opt, const std::string & s)
{
if (dl_deps_pre == opt || dl_deps_pre_or_post == opt)
@@ -1294,6 +1411,7 @@ namespace
case dlk_provided:
case dlk_already_installed:
case dlk_subpackage:
+ case dlk_suggested:
return false;
case dlk_block:
diff --git a/paludis/dep_list/dep_list.hh b/paludis/dep_list/dep_list.hh
index 527535d..cf4c4dc 100644
--- a/paludis/dep_list/dep_list.hh
+++ b/paludis/dep_list/dep_list.hh
@@ -52,9 +52,11 @@ namespace paludis
protected:
class AddVisitor;
class QueryVisitor;
+ class ShowSuggestVisitor;
friend class AddVisitor;
friend class QueryVisitor;
+ friend class ShowSuggestVisitor;
void add_in_role(DepAtom::ConstPointer, const std::string & role);
bool prefer_installed_over_uninstalled(const PackageDatabaseEntry &,
@@ -63,6 +65,7 @@ namespace paludis
void add_package(const PackageDatabaseEntry &, DepTag::ConstPointer);
void add_already_installed_package(const PackageDatabaseEntry &, DepTag::ConstPointer);
void add_error_package(const PackageDatabaseEntry &, const DepListEntryKind);
+ void add_suggested_package(const PackageDatabaseEntry &);
void add_predeps(DepAtom::ConstPointer, const DepListDepsOption, const std::string &);
void add_postdeps(DepAtom::ConstPointer, const DepListDepsOption, const std::string &);
diff --git a/paludis/dep_list/dep_list.sr b/paludis/dep_list/dep_list.sr
index 21d57ed..b99af1c 100644
--- a/paludis/dep_list/dep_list.sr
+++ b/paludis/dep_list/dep_list.sr
@@ -17,7 +17,9 @@ make_class_DepListOptions()
key uninstalled_deps_pre DepListDepsOption
key uninstalled_deps_runtime DepListDepsOption
key uninstalled_deps_post DepListDepsOption
+ key uninstalled_deps_suggested DepListDepsOption
+ key suggested DepListSuggestedOption
key circular DepListCircularOption
key blocks DepListBlocksOption
key override_masks DepListOverrideMasks
diff --git a/paludis/dep_list/options.cc b/paludis/dep_list/options.cc
index 9a19852..a791a60 100644
--- a/paludis/dep_list/options.cc
+++ b/paludis/dep_list/options.cc
@@ -324,6 +324,10 @@ paludis::operator<< (std::ostream & o, const DepListEntryKind & s)
o << "sub_package";
continue;
+ case dlk_suggested:
+ o << "suggested";
+ continue;
+
case dlk_already_installed:
o << "already_installed";
continue;
diff --git a/paludis/dep_list/options.hh b/paludis/dep_list/options.hh
index c3732a9..53fba50 100644
--- a/paludis/dep_list/options.hh
+++ b/paludis/dep_list/options.hh
@@ -118,6 +118,19 @@ namespace paludis
};
/**
+ * How should we handle suggested deps.
+ *
+ * \ingroup grpdepresolver
+ */
+ enum DepListSuggestedOption
+ {
+ dl_suggested_show, ///< Show
+ dl_suggested_discard, ///< Discard
+ dl_suggested_install, ///< Install
+ last_dl_suggested
+ };
+
+ /**
* How we handle circular deps.
*
* \ingroup grpdepresolver
@@ -167,6 +180,7 @@ namespace paludis
dlk_already_installed, ///< An already installed package
dlk_virtual, ///< A virtual package
dlk_provided, ///< A package provided by the previous dlk_package
+ dlk_suggested, ///< A package suggested by the previous dlk_package
dlk_block, ///< A blocked package that must be removed
dlk_masked, ///< A masked package that must be unmasked
last_dlk
diff --git a/paludis/dep_list/uninstall_list.cc b/paludis/dep_list/uninstall_list.cc
index f3d449e..b5ab02c 100644
--- a/paludis/dep_list/uninstall_list.cc
+++ b/paludis/dep_list/uninstall_list.cc
@@ -369,6 +369,7 @@ UninstallList::collect_depped_upon(ArbitrarilyOrderedPackageDatabaseEntryCollect
metadata->deps.build_depend()->accept(&c);
metadata->deps.run_depend()->accept(&c);
metadata->deps.post_depend()->accept(&c);
+ metadata->deps.suggested_depend()->accept(&c);
cache = _imp->dep_collector_cache.insert(std::make_pair(*i,
ArbitrarilyOrderedPackageDatabaseEntryCollection::ConstPointer(c.matches))).first;
}
@@ -461,6 +462,7 @@ UninstallList::add_dependencies(const PackageDatabaseEntry & e)
metadata->deps.build_depend()->accept(&c);
metadata->deps.run_depend()->accept(&c);
metadata->deps.post_depend()->accept(&c);
+ metadata->deps.suggested_depend()->accept(&c);
cache = _imp->dep_collector_cache.insert(std::make_pair(*i,
ArbitrarilyOrderedPackageDatabaseEntryCollection::ConstPointer(c.matches))).first;
}
diff --git a/paludis/repositories/cran/cran_description.cc b/paludis/repositories/cran/cran_description.cc
index d77aa8e..f0d2847 100644
--- a/paludis/repositories/cran/cran_description.cc
+++ b/paludis/repositories/cran/cran_description.cc
@@ -101,6 +101,8 @@ CRANDescription::CRANDescription(const std::string & n, const FSEntry & f) :
metadata->deps.build_depend_string = value;
metadata->deps.run_depend_string = value;
}
+ else if ("Suggests" == key)
+ metadata->deps.suggested_depend_string = value;
}
}
diff --git a/src/clients/paludis/command_line.cc b/src/clients/paludis/command_line.cc
index 9296c7c..bb5fd07 100644
--- a/src/clients/paludis/command_line.cc
+++ b/src/clients/paludis/command_line.cc
@@ -157,7 +157,16 @@ CommandLine::CommandLine() :
dl_uninstalled_deps_post(&dl_args, "dl-uninstalled-deps-post", '\0',
"How to handle post dependencies for uninstalled packages",
dl_deps_post),
+ dl_uninstalled_deps_suggested(&dl_args, "dl-uninstalled-deps-suggested", '\0',
+ "How to handle suggested dependencies for uninstalled packages (only with --dl-suggested install)",
+ dl_deps_post),
+ dl_suggested(&dl_args, "dl-suggested", '\0', "How to handle suggested dependencies",
+ args::EnumArg::EnumArgOptions
+ ("show", "Display, but do not install")
+ ("install", "Install")
+ ("discard", "Discard"),
+ "show"),
dl_circular(&dl_args, "dl-circular", '\0', "How to handle circular dependencies",
args::EnumArg::EnumArgOptions
("error", "Raise an error")
diff --git a/src/clients/paludis/command_line.hh b/src/clients/paludis/command_line.hh
index d4c1ff1..4363564 100644
--- a/src/clients/paludis/command_line.hh
+++ b/src/clients/paludis/command_line.hh
@@ -250,7 +250,9 @@ class CommandLine :
paludis::args::DepsOptionArg dl_uninstalled_deps_pre;
paludis::args::DepsOptionArg dl_uninstalled_deps_runtime;
paludis::args::DepsOptionArg dl_uninstalled_deps_post;
+ paludis::args::DepsOptionArg dl_uninstalled_deps_suggested;
+ paludis::args::EnumArg dl_suggested;
paludis::args::EnumArg dl_circular;
paludis::args::EnumArg dl_blocks;
paludis::args::StringSetArg dl_override_masks;
diff --git a/src/clients/paludis/install.cc b/src/clients/paludis/install.cc
index 11b99f9..50aeb5c 100644
--- a/src/clients/paludis/install.cc
+++ b/src/clients/paludis/install.cc
@@ -352,6 +352,18 @@ do_install()
throw args::DoHelp("bad value for --dl-circular");
}
+ if (CommandLine::get_instance()->dl_suggested.specified())
+ {
+ if (CommandLine::get_instance()->dl_suggested.argument() == "show")
+ options.suggested = dl_suggested_show;
+ else if (CommandLine::get_instance()->dl_suggested.argument() == "discard")
+ options.suggested = dl_suggested_discard;
+ else if (CommandLine::get_instance()->dl_suggested.argument() == "install")
+ options.suggested = dl_suggested_install;
+ else
+ throw args::DoHelp("bad value for --dl-suggested");
+ }
+
if (CommandLine::get_instance()->dl_blocks.specified())
{
if (CommandLine::get_instance()->dl_blocks.argument() == "discard")
@@ -405,6 +417,7 @@ do_install()
options.uninstalled_deps_pre = x;
options.uninstalled_deps_post = x;
options.uninstalled_deps_runtime = x;
+ options.uninstalled_deps_suggested = x;
}
if (CommandLine::get_instance()->dl_installed_deps_pre.specified())
@@ -426,6 +439,9 @@ do_install()
if (CommandLine::get_instance()->dl_uninstalled_deps_post.specified())
options.uninstalled_deps_post = enum_arg_to_dep_list_deps_option(
CommandLine::get_instance()->dl_uninstalled_deps_post);
+ if (CommandLine::get_instance()->dl_uninstalled_deps_suggested.specified())
+ options.uninstalled_deps_suggested = enum_arg_to_dep_list_deps_option(
+ CommandLine::get_instance()->dl_uninstalled_deps_suggested);
if ((CommandLine::get_instance()->a_show_reasons.argument() == "summary") ||
(CommandLine::get_instance()->a_show_reasons.argument() == "full"))
diff --git a/src/output/console_install_task.cc b/src/output/console_install_task.cc
index 4750fe5..1dd0865 100644
--- a/src/output/console_install_task.cc
+++ b/src/output/console_install_task.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.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
@@ -183,6 +183,10 @@ ConsoleInstallTask::on_display_merge_list_entry(const DepListEntry & d)
m = normal_entry;
continue;
+ case dlk_suggested:
+ m = suggested_entry;
+ continue;
+
case dlk_masked:
case dlk_block:
m = error_entry;
@@ -370,12 +374,23 @@ ConsoleInstallTask::display_merge_list_post_counts()
}
if (count<max_count>() && count<error_count>())
- s << " and ";
+ {
+ if (count<suggested_count>())
+ s << " and ";
+ else
+ s << ", ";
+ }
if (count<error_count>())
s << render_as_error(stringify(count<error_count>()) +
render_plural(count<error_count>(), " error", " errors"));
+ if ((count<max_count>() || count<error_count>()) && count<suggested_count>())
+ s << " and ";
+
+ if (count<suggested_count>())
+ s << count<suggested_count>() << render_plural(count<suggested_count>(), " suggestion", " suggestions");
+
output_unstarred_item(s.str());
}
@@ -622,8 +637,25 @@ DepTagSummaryDisplayer::visit(const GeneralSetDepTag * const tag)
}
void
-ConsoleInstallTask::display_merge_list_entry_start(const DepListEntry &, const DisplayMode)
+ConsoleInstallTask::display_merge_list_entry_start(const DepListEntry & e, const DisplayMode)
{
+ switch (e.kind)
+ {
+ case dlk_subpackage:
+ case dlk_suggested:
+ case dlk_provided:
+ output_no_endl(" ");
+ break;
+
+ case dlk_virtual:
+ case dlk_masked:
+ case dlk_block:
+ case dlk_already_installed:
+ case dlk_package:
+ case last_dlk:
+ break;
+ }
+
output_starred_item_no_endl("");
}
@@ -633,6 +665,7 @@ ConsoleInstallTask::display_merge_list_entry_package_name(const DepListEntry & d
switch (m)
{
case normal_entry:
+ case suggested_entry:
output_no_endl(render_as_package_name(stringify(d.package.name)));
break;
@@ -667,6 +700,7 @@ ConsoleInstallTask::display_merge_list_entry_slot(const DepListEntry & d, const
switch (m)
{
case normal_entry:
+ case suggested_entry:
output_no_endl(render_as_slot_name(" {:" + stringify(d.metadata->slot) + "}"));
break;
@@ -689,7 +723,15 @@ ConsoleInstallTask::display_merge_list_entry_status_and_update_counts(const DepL
switch (m)
{
case unimportant_entry:
- output_no_endl(render_as_unimportant(" [-]"));
+ if (d.kind == dlk_provided)
+ output_no_endl(render_as_unimportant(" [provided]"));
+ else
+ output_no_endl(render_as_unimportant(" [-]"));
+ break;
+
+ case suggested_entry:
+ output_no_endl(render_as_update_mode(" [suggestion]"));
+ set_count<suggested_count>(count<suggested_count>() + 1);
break;
case normal_entry:
@@ -746,6 +788,7 @@ ConsoleInstallTask::display_merge_list_entry_status_and_update_counts(const DepL
case dlk_already_installed:
case dlk_package:
case dlk_subpackage:
+ case dlk_suggested:
case last_dlk:
;
}
@@ -784,7 +827,7 @@ ConsoleInstallTask::display_merge_list_entry_use(const DepListEntry & d,
PackageDatabaseEntryCollection::ConstPointer,
const DisplayMode m)
{
- if (normal_entry != m)
+ if (normal_entry != m && suggested_entry != m)
return;
output_no_endl(" ");
@@ -830,9 +873,7 @@ ConsoleInstallTask::display_merge_list_entry_tags(const DepListEntry & d, const
switch (m)
{
case normal_entry:
- output_no_endl(" " + render_as_tag("<" + tag_titles + ">"));
- break;
-
+ case suggested_entry:
case error_entry:
output_no_endl(" " + render_as_tag("<" + tag_titles + ">"));
break;
@@ -876,9 +917,7 @@ ConsoleInstallTask::display_merge_list_entry_tags(const DepListEntry & d, const
switch (m)
{
case normal_entry:
- output_no_endl(" " + render_as_tag("<" + deps + ">"));
- break;
-
+ case suggested_entry:
case error_entry:
output_no_endl(" " + render_as_tag("<" + deps + ">"));
break;
diff --git a/src/output/console_install_task.hh b/src/output/console_install_task.hh
index 0e72053..0108557 100644
--- a/src/output/console_install_task.hh
+++ b/src/output/console_install_task.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006 Ciaran McCreesh <ciaranm@ciaranm.org>
+ * Copyright (c) 2006, 2007 Ciaran McCreesh <ciaranm@ciaranm.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
@@ -99,6 +99,7 @@ namespace paludis
new_slot_count,
rebuild_count,
error_count,
+ suggested_count,
last_count
};
@@ -106,7 +107,8 @@ namespace paludis
{
normal_entry,
unimportant_entry,
- error_entry
+ error_entry,
+ suggested_entry
};
private: