aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-03-04 15:12:44 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2008-03-04 15:12:44 +0000
commite35ba062c861a990f43e92ec6331fc02a09342d7 (patch)
tree273fa8f277fcaf43818d4baa0ed8a88c254b369c
parent02a6cdfe59cac0843085a430052613c27d07e72a (diff)
downloadpaludis-e35ba062c861a990f43e92ec6331fc02a09342d7.tar.gz
paludis-e35ba062c861a990f43e92ec6331fc02a09342d7.tar.xz
Serialise rather than rebuilding the dep list for resume and exec(). Fixes: ticket:432
-rw-r--r--paludis/args/dep_list_args_group.cc4
-rw-r--r--paludis/args/install_args_group.cc10
-rw-r--r--paludis/dep_list.cc8
-rw-r--r--paludis/dep_list.hh45
-rw-r--r--paludis/dep_list_options.se2
-rw-r--r--paludis/handled_information-fwd.hh2
-rw-r--r--paludis/install_task.cc412
-rw-r--r--paludis/install_task.hh27
-rw-r--r--paludis/util/iterator_funcs.hh23
-rw-r--r--paludis/util/iterator_funcs_TEST.cc47
-rw-r--r--src/clients/contrarius/install.cc8
-rw-r--r--src/clients/importare/install.cc8
-rw-r--r--src/clients/paludis/command_line.cc7
-rw-r--r--src/clients/paludis/command_line.hh4
-rw-r--r--src/clients/paludis/install.cc28
-rwxr-xr-xsrc/clients/paludis/install_TEST_setup.sh6
-rw-r--r--src/clients/reconcilio/install.cc21
-rw-r--r--src/output/console_install_task.cc35
-rw-r--r--src/output/console_install_task.hh9
19 files changed, 521 insertions, 185 deletions
diff --git a/paludis/args/dep_list_args_group.cc b/paludis/args/dep_list_args_group.cc
index 8d74c17..6241e6d 100644
--- a/paludis/args/dep_list_args_group.cc
+++ b/paludis/args/dep_list_args_group.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2005, 2006, 2007, 2008 Ciaran McCreesh
* Copyright (c) 2007 David Leverton
*
* This file is part of the Paludis package manager. Paludis is free software;
@@ -332,6 +332,6 @@ DepListArgsGroup::paludis_command_fragment() const
std::string
DepListArgsGroup::resume_command_fragment(const InstallTask &) const
{
- return " --" + dl_deps_default.long_name() + " discard";
+ return "";
}
diff --git a/paludis/args/install_args_group.cc b/paludis/args/install_args_group.cc
index 1497783..3b42256 100644
--- a/paludis/args/install_args_group.cc
+++ b/paludis/args/install_args_group.cc
@@ -22,6 +22,7 @@
#include <paludis/environment-fwd.hh>
#include <paludis/args/do_help.hh>
+#include <paludis/util/iterator_funcs.hh>
using namespace paludis;
using namespace paludis::args;
@@ -225,14 +226,19 @@ InstallArgsGroup::resume_command_fragment(const InstallTask & task) const
+ " '" + a_add_to_world_spec.argument() + "'";
else if (! a_preserve_world.specified())
{
- if (task.had_set_targets())
+ if (capped_distance(task.begin_targets(), task.end_targets(), 2) == 1)
+ {
resume_command = resume_command + " --" + a_add_to_world_spec.long_name()
- + " '( )'";
+ + " '" + *task.begin_targets() + "'";
+ }
else
resume_command = resume_command + " --" + a_add_to_world_spec.long_name()
+ " '( " + join(task.begin_targets(), task.end_targets(), " ") + " )'";
}
+ if (a_continue_on_failure.specified())
+ resume_command.append(" --" + a_continue_on_failure.long_name() + " " + a_continue_on_failure.argument());
+
if (a_destinations.specified())
for (args::StringSetArg::ConstIterator i(a_destinations.begin_args()),
i_end(a_destinations.end_args()) ; i != i_end ; ++i)
diff --git a/paludis/dep_list.cc b/paludis/dep_list.cc
index 599dde0..976418c 100644
--- a/paludis/dep_list.cc
+++ b/paludis/dep_list.cc
@@ -1525,6 +1525,14 @@ DepList::match_on_list(const PackageDepSpec & a) const
MatchDepListEntryAgainstPackageDepSpec(_imp->env, a));
}
+DepList::Iterator
+DepList::push_back(const DepListEntry & e)
+{
+ MergeList::iterator our_merge_entry_position(_imp->merge_list.insert(_imp->merge_list.end(), e));
+ _imp->merge_list_index.insert(std::make_pair(e.package_id->name(), our_merge_entry_position));
+ return Iterator(our_merge_entry_position);
+}
+
bool
paludis::is_viable_any_child(const DependencySpecTree::ConstItem & i)
{
diff --git a/paludis/dep_list.hh b/paludis/dep_list.hh
index 069bdc9..f02d80b 100644
--- a/paludis/dep_list.hh
+++ b/paludis/dep_list.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2005, 2006, 2007, 2008 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
@@ -142,6 +142,23 @@ namespace paludis
///\}
+ ///\name Iterate over our dependency list entries.
+ ///\{
+
+ struct IteratorTag;
+ typedef WrappedForwardIterator<IteratorTag, DepListEntry> Iterator;
+
+ struct ConstIteratorTag;
+ typedef WrappedForwardIterator<ConstIteratorTag, const DepListEntry> ConstIterator;
+
+ Iterator begin();
+ Iterator end();
+
+ ConstIterator begin() const;
+ ConstIterator end() const;
+
+ ///\}
+
/**
* Our options.
*/
@@ -167,6 +184,15 @@ namespace paludis
tr1::shared_ptr<const DestinationsSet> target_destinations);
/**
+ * Manually add a DepListEntry to the list.
+ *
+ * Does not work well with ordered resolution, and does not do much
+ * sanity checking. This is used by InstallTask to implement resume
+ * commands and the exec command.
+ */
+ Iterator push_back(const DepListEntry &);
+
+ /**
* Clear the list.
*/
void clear();
@@ -198,23 +224,6 @@ namespace paludis
void add_suggested_package(const tr1::shared_ptr<const PackageID> &,
const PackageDepSpec &, tr1::shared_ptr<DependencySpecTree::ConstItem>,
tr1::shared_ptr<const DestinationsSet> destinations);
-
- ///\name Iterate over our dependency list entries.
- ///\{
-
- struct IteratorTag;
- typedef WrappedForwardIterator<IteratorTag, DepListEntry> Iterator;
-
- struct ConstIteratorTag;
- typedef WrappedForwardIterator<ConstIteratorTag, const DepListEntry> ConstIterator;
-
- Iterator begin();
- Iterator end();
-
- ConstIterator begin() const;
- ConstIterator end() const;
-
- ///\}
};
}
diff --git a/paludis/dep_list_options.se b/paludis/dep_list_options.se
index ff2e602..c26d60e 100644
--- a/paludis/dep_list_options.se
+++ b/paludis/dep_list_options.se
@@ -217,6 +217,7 @@ END
make_enum_DepListEntryState()
{
prefix dle
+ want_destringify
key dle_no_deps "Dependencies have yet to be added"
key dle_has_pre_deps "Predependencies have been added"
@@ -234,6 +235,7 @@ END
make_enum_DepListEntryKind()
{
prefix dlk
+ want_destringify
key dlk_package "A package to be installed"
key dlk_subpackage "A package to be installed as part of the previous dlk_package"
diff --git a/paludis/handled_information-fwd.hh b/paludis/handled_information-fwd.hh
index f8ccc3d..ab835f7 100644
--- a/paludis/handled_information-fwd.hh
+++ b/paludis/handled_information-fwd.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 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
diff --git a/paludis/install_task.cc b/paludis/install_task.cc
index b975007..afaee57 100644
--- a/paludis/install_task.cc
+++ b/paludis/install_task.cc
@@ -17,7 +17,7 @@
* Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "install_task.hh"
+#include <paludis/install_task.hh>
#include <paludis/dep_spec.hh>
#include <paludis/action.hh>
#include <paludis/metadata_key.hh>
@@ -39,10 +39,15 @@
#include <paludis/util/iterator_funcs.hh>
#include <paludis/util/wrapped_forward_iterator-impl.hh>
#include <paludis/util/kc.hh>
+#include <paludis/util/tr1_functional.hh>
+#include <paludis/util/destringify.hh>
+#include <paludis/util/make_shared_ptr.hh>
#include <paludis/handled_information.hh>
+#include <sstream>
#include <functional>
#include <algorithm>
#include <list>
+#include <vector>
#include <set>
using namespace paludis;
@@ -77,7 +82,6 @@ namespace paludis
InstallTaskContinueOnFailure continue_on_failure;
- bool had_action_failures;
bool had_resolution_failures;
Implementation<InstallTask>(Environment * const e, const DepListOptions & o,
@@ -106,7 +110,6 @@ namespace paludis
had_package_targets(false),
override_target_type(false),
continue_on_failure(itcof_if_fetch_only),
- had_action_failures(false),
had_resolution_failures(false)
{
}
@@ -131,12 +134,237 @@ InstallTask::clear()
_imp->had_package_targets = false;
_imp->dep_list.clear();
_imp->raw_targets.clear();
- _imp->had_action_failures = false;
_imp->had_package_targets = false;
}
void
-InstallTask::add_target(const std::string & target)
+InstallTask::set_targets_from_user_specs(const tr1::shared_ptr<const Sequence<std::string> > & s)
+{
+ using namespace tr1::placeholders;
+ std::for_each(s->begin(), s->end(), tr1::bind(&InstallTask::_add_target, this, _1));
+}
+
+void
+InstallTask::set_targets_from_exact_packages(const tr1::shared_ptr<const PackageIDSequence> & s)
+{
+ using namespace tr1::placeholders;
+ std::for_each(s->begin(), s->end(), tr1::bind(&InstallTask::_add_package_id, this, _1));
+}
+
+namespace
+{
+ tr1::shared_ptr<DepListEntryHandled> handled_from_string(const std::string & s,
+ const Environment * const env)
+ {
+ Context context("When decoding DepListEntryHandled value '" + s + "':");
+
+ if (s.empty())
+ throw InternalError(PALUDIS_HERE, "Empty DepListEntryHandled value");
+
+ switch (s.at(0))
+ {
+ case 'S':
+ if (s.length() != 1)
+ throw InternalError(PALUDIS_HERE, "S takes no extra value");
+ return make_shared_ptr(new DepListEntryHandledSuccess);
+
+ case 'U':
+ return make_shared_ptr(new DepListEntryHandledSkippedUnsatisfied(
+ parse_user_package_dep_spec(s.substr(1), UserPackageDepSpecOptions())));
+
+ case 'D':
+ return make_shared_ptr(new DepListEntryHandledSkippedDependent(
+ *env->package_database()->query(query::Matches(
+ parse_user_package_dep_spec(s.substr(1), UserPackageDepSpecOptions())),
+ qo_require_exactly_one)->begin()));
+
+ case 'F':
+ if (s.length() != 1)
+ throw InternalError(PALUDIS_HERE, "F takes no extra value");
+ return make_shared_ptr(new DepListEntryHandledFailed);
+
+ case 'P':
+ if (s.length() != 1)
+ throw InternalError(PALUDIS_HERE, "P takes no extra value");
+ return make_shared_ptr(new DepListEntryUnhandled);
+
+ case 'N':
+ if (s.length() != 1)
+ throw InternalError(PALUDIS_HERE, "N takes no extra value");
+ return make_shared_ptr(new DepListEntryNoHandlingRequired);
+
+ default:
+ throw InternalError(PALUDIS_HERE, "Unknown value '" + s + "'");
+ }
+ }
+}
+
+void
+InstallTask::set_targets_from_serialisation(const std::string & format, const tr1::shared_ptr<const Sequence<std::string> > & ss)
+{
+ if (format != "0.25")
+ throw InternalError(PALUDIS_HERE, "Serialisation format '" + format + "' not supported by this version of Paludis");
+
+ for (Sequence<std::string>::ConstIterator s(ss->begin()), s_end(ss->end()) ;
+ s != s_end ; ++s)
+ {
+ Context context("When adding serialised entry '" + *s + "':");
+
+ std::list<std::string> tokens;
+ tokenise<delim_kind::AnyOfTag, delim_mode::DelimiterTag>(*s, ";", "", std::back_inserter(tokens));
+
+ if (tokens.empty())
+ throw InternalError(PALUDIS_HERE, "Serialised value '" + *s + "' too short: no kind");
+ const DepListEntryKind kind(destringify<DepListEntryKind>(*tokens.begin()));
+ tokens.pop_front();
+
+ if (tokens.empty())
+ throw InternalError(PALUDIS_HERE, "Serialised value '" + *s + "' too short: no package_id");
+ const tr1::shared_ptr<const PackageID> package_id(*_imp->env->package_database()->query(
+ query::Matches(parse_user_package_dep_spec(*tokens.begin(), UserPackageDepSpecOptions())), qo_require_exactly_one)->begin());
+ tokens.pop_front();
+
+ if (tokens.empty())
+ throw InternalError(PALUDIS_HERE, "Serialised value '" + *s + "' too short: no destination");
+ tr1::shared_ptr<Repository> destination;
+ if ("0" != *tokens.begin())
+ destination = _imp->env->package_database()->fetch_repository(RepositoryName(*tokens.begin()));
+ tokens.pop_front();
+
+ if (tokens.empty())
+ throw InternalError(PALUDIS_HERE, "Serialised value '" + *s + "' too short: no state");
+ const DepListEntryState state(destringify<DepListEntryState>(*tokens.begin()));
+ tokens.pop_front();
+
+ if (tokens.empty())
+ throw InternalError(PALUDIS_HERE, "Serialised value '" + *s + "' too short: no handled");
+ tr1::shared_ptr<DepListEntryHandled> handled(handled_from_string(*tokens.begin(), _imp->env));
+ tokens.pop_front();
+
+ if (! tokens.empty())
+ throw InternalError(PALUDIS_HERE, "Serialised value '" + *s + "' too long");
+
+ _imp->dep_list.push_back(DepListEntry::create()
+ .kind(kind)
+ .package_id(package_id)
+ .associated_entry(static_cast<DepListEntry *>(0))
+ .tags(make_shared_ptr(new DepListEntryTags))
+ .destination(destination)
+ .generation(0)
+ .state(state)
+ .handled(handled)
+ );
+ }
+}
+
+std::string
+InstallTask::serialised_format() const
+{
+ return "0.25";
+}
+
+namespace
+{
+ struct HandledDisplayer :
+ ConstVisitor<DepListEntryHandledVisitorTypes>
+ {
+ std::string result;
+ const bool undo_failures;
+
+ HandledDisplayer(const bool b) :
+ undo_failures(b)
+ {
+ }
+
+ void visit(const DepListEntryNoHandlingRequired &)
+ {
+ result = "N";
+ }
+
+ void visit(const DepListEntryHandledSuccess &)
+ {
+ result = "S";
+ }
+
+ void visit(const DepListEntryHandledFailed &)
+ {
+ if (undo_failures)
+ result = "P";
+ else
+ result = "F";
+ }
+
+ void visit(const DepListEntryUnhandled &)
+ {
+ result = "P";
+ }
+
+ void visit(const DepListEntryHandledSkippedUnsatisfied & s)
+ {
+ result = "U" + stringify(s.spec());
+ }
+
+ void visit(const DepListEntryHandledSkippedDependent & s)
+ {
+ result = "D=" + stringify(*s.id());
+ }
+ };
+}
+
+std::string
+InstallTask::serialise(const bool undo_failures) const
+{
+ std::ostringstream result;
+
+ for (DepList::ConstIterator d(_imp->dep_list.begin()), d_end(_imp->dep_list.end()) ;
+ d != d_end ; ++d)
+ {
+ switch (d->kind)
+ {
+ case dlk_already_installed:
+ case dlk_virtual:
+ case dlk_provided:
+ case dlk_block:
+ case dlk_masked:
+ case dlk_suggested:
+ continue;
+
+ case dlk_package:
+ case dlk_subpackage:
+ break;
+
+ case last_dlk:
+ throw InternalError(PALUDIS_HERE, "Bad d->kind");
+ }
+
+ if (! result.str().empty())
+ result << " ";
+
+ result << "'";
+
+ result << d->kind << ";";
+
+ result << "=" << *d->package_id << ";";
+
+ if (d->destination)
+ result << d->destination->name() << ";";
+ else
+ result << "0" << ";";
+
+ result << d->state << ";";
+
+ HandledDisplayer h(undo_failures);
+ d->handled->accept(h);
+ result << h.result;
+
+ result << "'";
+ }
+
+ return result.str();
+}
+
+void
+InstallTask::_add_target(const std::string & target)
{
Context context("When adding install target '" + target + "':");
@@ -216,7 +444,7 @@ InstallTask::add_target(const std::string & target)
}
void
-InstallTask::add_exact_package(const tr1::shared_ptr<const PackageID> & target)
+InstallTask::_add_package_id(const tr1::shared_ptr<const PackageID> & target)
{
Context context("When adding install target '" + stringify(*target) + "' from ID:");
@@ -296,7 +524,7 @@ namespace
struct SummaryVisitor :
ConstVisitor<DepListEntryHandledVisitorTypes>
{
- int total, successes, skipped, failures;
+ int total, successes, skipped, failures, unreached;
InstallTask & task;
const DepListEntry * entry;
@@ -305,6 +533,7 @@ namespace
successes(0),
skipped(0),
failures(0),
+ unreached(0),
task(t),
entry(0)
{
@@ -333,6 +562,8 @@ namespace
void visit(const DepListEntryUnhandled &)
{
+ ++unreached;
+ ++total;
}
void visit(const DepListEntryNoHandlingRequired &)
@@ -353,32 +584,9 @@ InstallTask::_display_failure_summary()
{
Context context("When displaying summary:");
- if (! _imp->had_action_failures)
+ if (! had_action_failures())
return;
- switch (_imp->continue_on_failure)
- {
- case itcof_if_fetch_only:
- if (! _imp->fetch_only)
- {
- on_display_failure_no_summary();
- return;
- }
- break;
-
- case itcof_always:
- case itcof_if_satisfied:
- case itcof_if_independent:
- break;
-
- case itcof_never:
- on_display_failure_no_summary();
- return;
-
- case last_itcof:
- throw InternalError(PALUDIS_HERE, "Bad continue_on_failure");
- }
-
on_display_failure_summary_pre();
/* display our summary */
@@ -391,7 +599,7 @@ InstallTask::_display_failure_summary()
}
/* we're done displaying our task list */
- on_display_failure_summary_totals(s.total, s.successes, s.skipped, s.failures);
+ on_display_failure_summary_totals(s.total, s.successes, s.skipped, s.failures, s.unreached);
on_display_failure_summary_post();
}
@@ -443,6 +651,12 @@ InstallTask::_one(const DepList::Iterator dep, const int x, const int y, const i
if ((*dep->destination)[k::destination_interface()] && (*dep->destination)[k::destination_interface()]->want_pre_post_phases())
live_destination = true;
+ if (already_done(*dep))
+ {
+ on_skip_already_done(*dep, x, y, s, f);
+ return;
+ }
+
/* we're about to fetch / install one item */
if (_imp->fetch_only)
{
@@ -646,7 +860,7 @@ InstallTask::_main_actions()
++x;
- if (_imp->had_action_failures)
+ if (had_action_failures())
{
switch (_imp->continue_on_failure)
{
@@ -696,14 +910,12 @@ InstallTask::_main_actions()
}
catch (const InstallActionError & e)
{
- _imp->had_action_failures = true;
dep->handled.reset(new DepListEntryHandledFailed);
on_install_action_error(e);
++f;
}
catch (const FetchActionError & e)
{
- _imp->had_action_failures = true;
dep->handled.reset(new DepListEntryHandledFailed);
on_fetch_action_error(e);
++f;
@@ -711,7 +923,7 @@ InstallTask::_main_actions()
}
/* go no further if we had failures */
- if (_imp->had_action_failures)
+ if (had_action_failures())
{
_display_failure_summary();
return;
@@ -724,36 +936,54 @@ InstallTask::_main_actions()
{
on_update_world_pre();
- if (_imp->had_package_targets)
+ if (_imp->add_to_world_spec)
{
+ bool s_had_package_targets(_imp->had_package_targets), s_had_set_targets(_imp->had_set_targets);
if (_imp->add_to_world_spec)
{
- tr1::shared_ptr<ConstTreeSequence<SetSpecTree, AllDepSpec> > all(new ConstTreeSequence<SetSpecTree, AllDepSpec>(
- tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
- std::list<std::string> tokens;
- tokenise_whitespace(*_imp->add_to_world_spec, std::back_inserter(tokens));
- if ((! tokens.empty()) && ("(" == *tokens.begin()) && (")" == *previous(tokens.end())))
- {
- tokens.erase(tokens.begin());
- tokens.erase(previous(tokens.end()));
- }
+ s_had_package_targets = ((std::string::npos != _imp->add_to_world_spec->find('/')));
+ s_had_set_targets = (! s_had_package_targets) && (std::string::npos != _imp->add_to_world_spec->find_first_not_of(
+ "() \t\r\n"));
+ }
- for (std::list<std::string>::const_iterator t(tokens.begin()), t_end(tokens.end()) ;
- t != t_end ; ++t)
+ tr1::shared_ptr<ConstTreeSequence<SetSpecTree, AllDepSpec> > all(new ConstTreeSequence<SetSpecTree, AllDepSpec>(
+ tr1::shared_ptr<AllDepSpec>(new AllDepSpec)));
+ std::list<std::string> tokens;
+ tokenise_whitespace(*_imp->add_to_world_spec, std::back_inserter(tokens));
+ if ((! tokens.empty()) && ("(" == *tokens.begin()) && (")" == *previous(tokens.end())))
+ {
+ tokens.erase(tokens.begin());
+ tokens.erase(previous(tokens.end()));
+ }
+
+ for (std::list<std::string>::const_iterator t(tokens.begin()), t_end(tokens.end()) ;
+ t != t_end ; ++t)
+ {
+ if (s_had_package_targets)
all->add(tr1::shared_ptr<TreeLeaf<SetSpecTree, PackageDepSpec> >(
new TreeLeaf<SetSpecTree, PackageDepSpec>(tr1::shared_ptr<PackageDepSpec>(
new PackageDepSpec(parse_user_package_dep_spec(*t, UserPackageDepSpecOptions()))))));
- world_update_packages(all);
+ else
+ all->add(tr1::shared_ptr<TreeLeaf<SetSpecTree, NamedSetDepSpec> >(
+ new TreeLeaf<SetSpecTree, NamedSetDepSpec>(tr1::shared_ptr<NamedSetDepSpec>(
+ new NamedSetDepSpec(SetName(*t))))));
}
- else
- world_update_packages(_imp->targets);
+
+ if (s_had_package_targets)
+ world_update_packages(all);
+ else if (s_had_set_targets)
+ world_update_set(SetName(*_imp->add_to_world_spec));
}
- else if (_imp->had_set_targets)
+ else
{
- if (_imp->add_to_world_spec)
- world_update_set(SetName(*_imp->add_to_world_spec));
- else if (! _imp->raw_targets.empty())
- world_update_set(SetName(*_imp->raw_targets.begin()));
+ if (_imp->had_package_targets)
+ world_update_packages(_imp->targets);
+ else if (_imp->had_set_targets)
+ {
+ for (std::list<std::string>::const_iterator t(_imp->raw_targets.begin()), t_end(_imp->raw_targets.end()) ;
+ t != t_end ; ++t)
+ world_update_set(SetName(*t));
+ }
}
on_update_world_post();
@@ -922,18 +1152,6 @@ InstallTask::on_installed_paludis()
{
}
-bool
-InstallTask::had_set_targets() const
-{
- return _imp->had_set_targets;
-}
-
-bool
-InstallTask::had_package_targets() const
-{
- return _imp->had_package_targets;
-}
-
void
InstallTask::set_safe_resume(const bool value)
{
@@ -1020,12 +1238,6 @@ InstallTask::world_update_packages(tr1::shared_ptr<const SetSpecTree::ConstItem>
}
bool
-InstallTask::had_action_failures() const
-{
- return _imp->had_action_failures;
-}
-
-bool
InstallTask::had_resolution_failures() const
{
return _imp->had_resolution_failures;
@@ -1331,6 +1543,21 @@ namespace
};
}
+bool
+InstallTask::had_action_failures() const
+{
+ for (DepList::ConstIterator dep(_imp->dep_list.begin()), dep_end(_imp->dep_list.end()) ;
+ dep != dep_end ; ++dep)
+ {
+ CheckHandledVisitor v;
+ dep->handled->accept(v);
+ if (v.failure)
+ return true;
+ }
+ return false;
+}
+
+
tr1::shared_ptr<const PackageID>
InstallTask::_dependent(const DepListEntry & e) const
{
@@ -1366,59 +1593,48 @@ InstallTask::_dependent(const DepListEntry & e) const
namespace
{
- struct NotYetInstalledVisitor :
+ struct AlreadyDoneVisitor :
ConstVisitor<DepListEntryHandledVisitorTypes>
{
- tr1::shared_ptr<const PackageID> id;
- tr1::shared_ptr<PackageIDSequence> result;
-
- NotYetInstalledVisitor() :
- result(new PackageIDSequence)
- {
- }
+ bool result;
void visit(const DepListEntryHandledSuccess &)
{
+ result = true;
}
void visit(const DepListEntryHandledSkippedUnsatisfied &)
{
- result->push_back(id);
+ result = true;
}
void visit(const DepListEntryHandledSkippedDependent &)
{
- result->push_back(id);
+ result = true;
}
void visit(const DepListEntryHandledFailed &)
{
- result->push_back(id);
+ result = true;
}
void visit(const DepListEntryUnhandled &)
{
- result->push_back(id);
+ result = false;
}
void visit(const DepListEntryNoHandlingRequired &)
{
+ result = false;
}
};
}
-const tr1::shared_ptr<const PackageIDSequence>
-InstallTask::packages_not_yet_installed_successfully() const
+bool
+InstallTask::already_done(const DepListEntry & e) const
{
- NotYetInstalledVisitor s;
-
- for (DepList::ConstIterator dep(_imp->dep_list.begin()), dep_end(_imp->dep_list.end()) ;
- dep != dep_end ; ++dep)
- {
- s.id = dep->package_id;
- dep->handled->accept(s);
- }
-
- return s.result;
+ AlreadyDoneVisitor v;
+ e.handled->accept(v);
+ return v.result;
}
diff --git a/paludis/install_task.hh b/paludis/install_task.hh
index 5839492..5e25b37 100644
--- a/paludis/install_task.hh
+++ b/paludis/install_task.hh
@@ -65,6 +65,9 @@ namespace paludis
void _one(const DepList::Iterator, const int, const int, const int, const int);
void _display_failure_summary();
+ void _add_target(const std::string &);
+ void _add_package_id(const tr1::shared_ptr<const PackageID> &);
+
tr1::shared_ptr<const PackageDepSpec> _unsatisfied(const DepListEntry &) const;
tr1::shared_ptr<const PackageID> _dependent(const DepListEntry &) const;
@@ -77,6 +80,8 @@ namespace paludis
///\}
+ bool already_done(const DepListEntry &) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
public:
///\name Basic operations
///\{
@@ -103,12 +108,11 @@ namespace paludis
///\name Targets
///\{
- void add_target(const std::string &);
- void add_exact_package(const tr1::shared_ptr<const PackageID> &);
+ void set_targets_from_user_specs(const tr1::shared_ptr<const Sequence<std::string> > &);
+ void set_targets_from_exact_packages(const tr1::shared_ptr<const PackageIDSequence> &);
+ void set_targets_from_serialisation(const std::string &, const tr1::shared_ptr<const Sequence<std::string> > &);
void clear();
- bool had_set_targets() const PALUDIS_ATTRIBUTE((warn_unused_result));
- bool had_package_targets() const PALUDIS_ATTRIBUTE((warn_unused_result));
void override_target_type(const DepListTargetType);
struct TargetsConstIteratorTag;
@@ -136,9 +140,8 @@ namespace paludis
virtual void on_display_failure_summary_failure(const DepListEntry &) = 0;
virtual void on_display_failure_summary_skipped_unsatisfied(const DepListEntry &, const PackageDepSpec &) = 0;
virtual void on_display_failure_summary_skipped_dependent(const DepListEntry &, const tr1::shared_ptr<const PackageID> &) = 0;
- virtual void on_display_failure_summary_totals(const int, const int, const int, const int) = 0;
+ virtual void on_display_failure_summary_totals(const int, const int, const int, const int, const int) = 0;
virtual void on_display_failure_summary_post() = 0;
- virtual void on_display_failure_no_summary() = 0;
virtual void on_not_continuing_due_to_errors() = 0;
@@ -162,6 +165,7 @@ namespace paludis
const int x, const int y, const int s, const int f) = 0;
virtual void on_skip_dependent(const DepListEntry &, const tr1::shared_ptr<const PackageID> &,
const int x, const int y, const int s, const int f) = 0;
+ virtual void on_skip_already_done(const DepListEntry &, const int, const int, const int, const int) = 0;
virtual void on_no_clean_needed(const DepListEntry &) = 0;
virtual void on_clean_all_pre(const DepListEntry &,
@@ -246,11 +250,14 @@ namespace paludis
virtual bool had_action_failures() const PALUDIS_ATTRIBUTE((warn_unused_result));
/**
- * Fetch packages (dlk_package) that have either not yet been installed, or that
- * were skipped or failed.
+ * Serialise the task.
*/
- virtual const tr1::shared_ptr<const PackageIDSequence> packages_not_yet_installed_successfully() const
- PALUDIS_ATTRIBUTE((warn_unused_result));
+ std::string serialise(const bool undo_failures) const PALUDIS_ATTRIBUTE((warn_unused_result));
+
+ /**
+ * The format for serialisation.
+ */
+ std::string serialised_format() const PALUDIS_ATTRIBUTE((warn_unused_result));
};
}
diff --git a/paludis/util/iterator_funcs.hh b/paludis/util/iterator_funcs.hh
index ad89900..dbc9e7a 100644
--- a/paludis/util/iterator_funcs.hh
+++ b/paludis/util/iterator_funcs.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 Ciaran McCreesh
* Copyright (c) 2007 David Leverton
*
* This file is part of the Paludis package manager. Paludis is free software;
@@ -74,6 +74,27 @@ namespace paludis
T_ result(i);
return --result;
}
+
+ /**
+ * Return the distance from a to b, except if it is greater than n,
+ * in which case return n instead.
+ *
+ * \ingroup g_iterator
+ */
+ template <typename T_>
+#ifdef PALUDIS_HAVE_CONCEPTS
+ requires std::ForwardIterator<T_>
+#endif
+ std::size_t capped_distance(T_ a, const T_ & b, unsigned n)
+ {
+ std::size_t x(0);
+ while ((x < n) && (a != b))
+ {
+ ++x;
+ ++a;
+ }
+ return x;
+ }
}
#endif
diff --git a/paludis/util/iterator_funcs_TEST.cc b/paludis/util/iterator_funcs_TEST.cc
index 71f3187..1cb556e 100644
--- a/paludis/util/iterator_funcs_TEST.cc
+++ b/paludis/util/iterator_funcs_TEST.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2005, 2006, 2007, 2008 Ciaran McCreesh
* Copyright (c) 2007 David Leverton
*
* This file is part of the Paludis package manager. Paludis is free software;
@@ -22,6 +22,7 @@
#include <test/test_runner.hh>
#include <test/test_framework.hh>
#include <vector>
+#include <list>
using namespace test;
using namespace paludis;
@@ -71,5 +72,49 @@ namespace test_cases
TEST_CHECK(--iter == v.begin());
}
} test_iterator_previous;
+
+ struct CappedDistanceTest : TestCase
+ {
+ CappedDistanceTest() : TestCase("capped distance") { }
+
+ void run()
+ {
+ std::list<int> v;
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 0), static_cast<std::size_t>(0));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 1), static_cast<std::size_t>(0));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 3), static_cast<std::size_t>(0));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 10), static_cast<std::size_t>(0));
+
+ v.push_back(1);
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 0), static_cast<std::size_t>(0));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 1), static_cast<std::size_t>(1));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 3), static_cast<std::size_t>(1));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 10), static_cast<std::size_t>(1));
+
+ v.push_back(2);
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 0), static_cast<std::size_t>(0));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 1), static_cast<std::size_t>(1));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 3), static_cast<std::size_t>(2));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 10), static_cast<std::size_t>(2));
+
+ v.push_back(3);
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 0), static_cast<std::size_t>(0));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 1), static_cast<std::size_t>(1));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 3), static_cast<std::size_t>(3));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 10), static_cast<std::size_t>(3));
+
+ v.push_back(4);
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 0), static_cast<std::size_t>(0));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 1), static_cast<std::size_t>(1));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 3), static_cast<std::size_t>(3));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 10), static_cast<std::size_t>(4));
+
+ v.push_back(5);
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 0), static_cast<std::size_t>(0));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 1), static_cast<std::size_t>(1));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 3), static_cast<std::size_t>(3));
+ TEST_CHECK_EQUAL(capped_distance(v.begin(), v.end(), 10), static_cast<std::size_t>(5));
+ }
+ } test_capped_distance;
}
diff --git a/src/clients/contrarius/install.cc b/src/clients/contrarius/install.cc
index 7a8de65..d734135 100644
--- a/src/clients/contrarius/install.cc
+++ b/src/clients/contrarius/install.cc
@@ -2,7 +2,7 @@
/*
* Copyright (c) 2006 Danny van Dyk
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 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
@@ -106,7 +106,7 @@ namespace
return false;
}
- virtual std::string make_resume_command(const PackageIDSequence &) const
+ virtual std::string make_resume_command(const bool) const
{
return "";
}
@@ -151,7 +151,9 @@ do_install(tr1::shared_ptr<Environment> env, std::string spec_str)
throw DoHelp("bad value for --debug-build");
}
- if (! task.try_to_add_target(spec_str))
+ tr1::shared_ptr<Sequence<std::string> > specs(new Sequence<std::string>);
+ specs->push_back(spec_str);
+ if (! task.try_to_set_targets_from_user_specs(specs))
return task.exit_status();
task.execute();
diff --git a/src/clients/importare/install.cc b/src/clients/importare/install.cc
index 19e2205..a7c3975 100644
--- a/src/clients/importare/install.cc
+++ b/src/clients/importare/install.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2007 Ciaran McCreesh
+ * Copyright (c) 2007, 2008 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
@@ -118,7 +118,7 @@ namespace
return CommandLine::get_instance()->install_args.want_existing_descriptions();
}
- virtual std::string make_resume_command(const PackageIDSequence &) const
+ virtual std::string make_resume_command(const bool) const
{
return "";
}
@@ -142,7 +142,9 @@ do_install(const tr1::shared_ptr<Environment> & env, const tr1::shared_ptr<const
CommandLine::get_instance()->install_args.populate_install_task(env.get(), task);
CommandLine::get_instance()->dl_args.populate_install_task(env.get(), task);
- task.add_exact_package(target);
+ tr1::shared_ptr<PackageIDSequence> targets(new PackageIDSequence);
+ targets->push_back(target);
+ task.set_targets_from_exact_packages(targets);
task.execute();
cout << endl;
diff --git a/src/clients/paludis/command_line.cc b/src/clients/paludis/command_line.cc
index fbfb9dd..56ef014 100644
--- a/src/clients/paludis/command_line.cc
+++ b/src/clients/paludis/command_line.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2006, 2007, 2008 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
@@ -91,6 +91,11 @@ CommandLine::CommandLine() :
install_args(this, "Install, Uninstall options",
"Options which are relevant for --install, --uninstall or --uninstall-unused."),
+ a_serialised(&install_args, "serialised", '\0',
+ "Rather than being a collection of atoms, treat the positional parameters as a serialised dependency "
+ "list. The parameter to this option specifies the format version. Used by resume commands and Paludis "
+ "exec()ing itself upon an upgrade; not to be used manually"),
+
uninstall_args(this, "Uninstall options",
"Options which are relevant for --uninstall."),
a_with_unused_dependencies(&uninstall_args, "with-unused-dependencies", '\0',
diff --git a/src/clients/paludis/command_line.hh b/src/clients/paludis/command_line.hh
index 2c482be..0a28672 100644
--- a/src/clients/paludis/command_line.hh
+++ b/src/clients/paludis/command_line.hh
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2006, 2007, 2008 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
@@ -197,6 +197,8 @@ class CommandLine :
/// \name (Un)Install arguments
paludis::args::InstallArgsGroup install_args;
+ paludis::args::StringArg a_serialised;
+
/// \name Uninstall arguments
///\{
diff --git a/src/clients/paludis/install.cc b/src/clients/paludis/install.cc
index cba8adc..749a71d 100644
--- a/src/clients/paludis/install.cc
+++ b/src/clients/paludis/install.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2005, 2006, 2007, 2008 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
@@ -32,6 +32,7 @@
#include <paludis/util/tokeniser.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/set.hh>
+#include <paludis/util/wrapped_output_iterator.hh>
#include <paludis/hook.hh>
#include <paludis/query.hh>
@@ -121,17 +122,16 @@ namespace
return CommandLine::get_instance()->install_args.want_existing_descriptions();
}
- virtual std::string make_resume_command(const PackageIDSequence & s) const
+ virtual std::string make_resume_command(const bool undo_failures) const
{
std::string resume_command = environment()->paludis_command()
+ " --" + CommandLine::get_instance()->a_install.long_name();
- resume_command = resume_command + CommandLine::get_instance()->install_args.resume_command_fragment(*this);
- resume_command = resume_command + CommandLine::get_instance()->dl_args.resume_command_fragment(*this);
-
- for (PackageIDSequence::ConstIterator i(s.begin()), i_end(s.end()) ;
- i != i_end ; ++i)
- resume_command = resume_command + " '=" + stringify(**i) + "'";
+ resume_command.append(CommandLine::get_instance()->install_args.resume_command_fragment(*this));
+ resume_command.append(CommandLine::get_instance()->dl_args.resume_command_fragment(*this));
+ resume_command.append(" --" + CommandLine::get_instance()->a_serialised.long_name() + " " + serialised_format());
+ resume_command.append(" ");
+ resume_command.append(serialise(undo_failures));
return resume_command;
}
@@ -161,10 +161,16 @@ do_install(tr1::shared_ptr<Environment> env)
CommandLine::get_instance()->dl_args.populate_install_task(env.get(), task);
cout << "Building target list... " << std::flush;
- for (CommandLine::ParametersConstIterator q(CommandLine::get_instance()->begin_parameters()),
- q_end(CommandLine::get_instance()->end_parameters()) ; q != q_end ; ++q)
- if (! task.try_to_add_target(*q))
+ tr1::shared_ptr<Sequence<std::string> > specs(new Sequence<std::string>);
+ std::copy(CommandLine::get_instance()->begin_parameters(), CommandLine::get_instance()->end_parameters(),
+ specs->back_inserter());
+ if (CommandLine::get_instance()->a_serialised.specified())
+ task.set_targets_from_serialisation(CommandLine::get_instance()->a_serialised.argument(), specs);
+ else
+ {
+ if (! task.try_to_set_targets_from_user_specs(specs))
return task.exit_status();
+ }
cout << endl;
diff --git a/src/clients/paludis/install_TEST_setup.sh b/src/clients/paludis/install_TEST_setup.sh
index 057bf2d..697dd8b 100755
--- a/src/clients/paludis/install_TEST_setup.sh
+++ b/src/clients/paludis/install_TEST_setup.sh
@@ -43,7 +43,7 @@ cache = /var/empty
format = ebuild
names_cache = /var/empty
profiles = \${location}/profiles/testprofile \${location}/profiles/anothertestprofile
-buildroot = `pwd`/build
+builddir = `pwd`/build
END
done
@@ -53,13 +53,13 @@ location = `pwd`/root/var/db/pkg
format = vdb
names_cache = /var/empty
provides_cache = /var/empty
-buildroot = `pwd`/build
+builddir = `pwd`/build
END
cat <<END > root/${SYSCONFDIR}/paludisexndbam/repositories/installed.conf
location = `pwd`/root/var/db/exndbam
format = exndbam
-buildroot = `pwd`/build
+builddir = `pwd`/build
END
mkdir -p root/tmp
diff --git a/src/clients/reconcilio/install.cc b/src/clients/reconcilio/install.cc
index 95bbd3c..774bffa 100644
--- a/src/clients/reconcilio/install.cc
+++ b/src/clients/reconcilio/install.cc
@@ -1,7 +1,7 @@
/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
- * Copyright (c) 2005, 2006, 2007 Ciaran McCreesh
+ * Copyright (c) 2005, 2006, 2007, 2008 Ciaran McCreesh
* Copyright (c) 2007 David Leverton
*
* This file is part of the Paludis package manager. Paludis is free software;
@@ -102,16 +102,15 @@ namespace
return CommandLine::get_instance()->install_args.want_existing_descriptions();
}
- virtual std::string make_resume_command(const PackageIDSequence & s) const
+ virtual std::string make_resume_command(const bool undo_failures) const
{
std::string resume_command = environment()->paludis_command() + " --install";
- resume_command = resume_command + CommandLine::get_instance()->install_args.resume_command_fragment(*this);
- resume_command = resume_command + CommandLine::get_instance()->dl_args.resume_command_fragment(*this);
-
- for (PackageIDSequence::ConstIterator i(s.begin()), i_end(s.end()) ;
- i != i_end ; ++i)
- resume_command = resume_command + " '=" + stringify(**i) + "'";
+ resume_command.append(CommandLine::get_instance()->install_args.resume_command_fragment(*this));
+ resume_command.append(CommandLine::get_instance()->dl_args.resume_command_fragment(*this));
+ resume_command.append(" --serialised " + serialised_format());
+ resume_command.append(" ");
+ resume_command.append(serialise(undo_failures));
return resume_command;
}
@@ -140,10 +139,8 @@ do_install(const tr1::shared_ptr<Environment> & env, const tr1::shared_ptr<const
CommandLine::get_instance()->install_args.populate_install_task(env.get(), task);
CommandLine::get_instance()->dl_args.populate_install_task(env.get(), task);
- for (Sequence<std::string>::ConstIterator t(targets->begin()), t_end(targets->end()) ;
- t != t_end ; ++t)
- if (! task.try_to_add_target(*t))
- return task.exit_status();
+ if (! task.try_to_set_targets_from_user_specs(targets))
+ return task.exit_status();
std::cout << std::endl;
task.execute();
diff --git a/src/output/console_install_task.cc b/src/output/console_install_task.cc
index 3acf75c..fd59cdd 100644
--- a/src/output/console_install_task.cc
+++ b/src/output/console_install_task.cc
@@ -173,12 +173,12 @@ ConsoleInstallTask::exit_status() const
}
bool
-ConsoleInstallTask::try_to_add_target(const std::string & s)
+ConsoleInstallTask::try_to_set_targets_from_user_specs(const tr1::shared_ptr<const Sequence<std::string> > & s)
{
bool is_ok(true);
try
{
- InstallTask::add_target(s);
+ InstallTask::set_targets_from_user_specs(s);
}
catch (const NoSuchPackageError & e)
{
@@ -345,6 +345,9 @@ ConsoleInstallTask::on_display_merge_list_entry(const DepListEntry & d)
throw InternalError(PALUDIS_HERE, "Bad d.kind");
} while (false);
+ if (already_done(d))
+ return;
+
tr1::shared_ptr<RepositoryName> repo;
if (d.destination)
repo.reset(new RepositoryName(d.destination->name()));
@@ -469,6 +472,16 @@ ConsoleInstallTask::on_skip_dependent(const DepListEntry & d, const tr1::shared_
}
void
+ConsoleInstallTask::on_skip_already_done(const DepListEntry & d,
+ const int x, const int y, const int s, const int f)
+{
+ std::string m("(" + make_x_of_y(x, y, s, f) + ") Skipping " + stringify(*d.package_id) +
+ " (already done)");
+
+ output_heading(m);
+}
+
+void
ConsoleInstallTask::on_install_post(const DepListEntry &, const int, const int,
const int, const int)
{
@@ -1703,13 +1716,14 @@ ConsoleInstallTask::on_display_failure_summary_skipped_dependent(const DepListEn
void
ConsoleInstallTask::on_display_failure_summary_totals(const int total, const int successes,
- const int skipped, const int failures)
+ const int skipped, const int failures, const int unreached)
{
std::ostringstream s;
s << "Total: " << total << render_plural(total, " package", " packages");
s << ", " << successes << render_plural(successes, " success", " successes");
s << ", " << skipped << render_plural(skipped, " skipped", " skipped");
s << ", " << failures << render_plural(failures, " failure", " failures");
+ s << ", " << unreached << render_plural(failures, " unreached", " unreached");
output_endl();
output_unstarred_item(s.str());
@@ -1721,12 +1735,6 @@ ConsoleInstallTask::on_display_failure_summary_post()
show_resume_command();
}
-void
-ConsoleInstallTask::on_display_failure_no_summary()
-{
- show_resume_command();
-}
-
std::string
ConsoleInstallTask::make_x_of_y(const int x, const int y, const int s, const int f)
{
@@ -1747,10 +1755,9 @@ ConsoleInstallTask::show_resume_command() const
void
ConsoleInstallTask::show_resume_command(const std::string & resume_command_template) const
{
- const tr1::shared_ptr<const PackageIDSequence> p(packages_not_yet_installed_successfully());
- if (! p->empty())
+ if (had_action_failures())
{
- std::string resume_command(make_resume_command(*p));
+ std::string resume_command(make_resume_command(true));
if (resume_command.empty())
return;
@@ -1816,7 +1823,7 @@ ConsoleInstallTask::on_installed_paludis()
return;
}
- std::string resume_command(make_resume_command(*packages_not_yet_installed_successfully()));
+ std::string resume_command(make_resume_command(false));
if (resume_command.empty())
return;
@@ -1830,7 +1837,7 @@ ConsoleInstallTask::on_installed_paludis()
HookResult
ConsoleInstallTask::perform_hook(const Hook & hook) const
{
- std::string resume_command(make_resume_command(*packages_not_yet_installed_successfully()));
+ std::string resume_command(make_resume_command(true));
if (resume_command.empty())
return InstallTask::perform_hook(hook);
return InstallTask::perform_hook(hook("RESUME_COMMAND", resume_command));
diff --git a/src/output/console_install_task.hh b/src/output/console_install_task.hh
index 46a24f1..5a45085 100644
--- a/src/output/console_install_task.hh
+++ b/src/output/console_install_task.hh
@@ -129,7 +129,8 @@ namespace paludis
virtual void execute();
int exit_status() const;
- bool try_to_add_target(const std::string &) PALUDIS_ATTRIBUTE((warn_unused_result));
+ bool try_to_set_targets_from_user_specs(const tr1::shared_ptr<const Sequence<std::string> > &)
+ PALUDIS_ATTRIBUTE((warn_unused_result));
virtual std::string make_x_of_y(const int x, const int y, const int s, const int f);
@@ -164,6 +165,7 @@ namespace paludis
const int x, const int y, const int s, const int f);
virtual void on_skip_dependent(const DepListEntry &, const tr1::shared_ptr<const PackageID> &,
const int x, const int y, const int s, const int f);
+ virtual void on_skip_already_done(const DepListEntry &, const int, const int, const int, const int);
virtual void on_no_clean_needed(const DepListEntry &);
virtual void on_clean_all_pre(const DepListEntry &,
@@ -201,9 +203,8 @@ namespace paludis
virtual void on_display_failure_summary_failure(const DepListEntry &);
virtual void on_display_failure_summary_skipped_unsatisfied(const DepListEntry &, const PackageDepSpec &);
virtual void on_display_failure_summary_skipped_dependent(const DepListEntry &, const tr1::shared_ptr<const PackageID> &);
- virtual void on_display_failure_summary_totals(const int, const int, const int, const int);
+ virtual void on_display_failure_summary_totals(const int, const int, const int, const int, const int);
virtual void on_display_failure_summary_post();
- virtual void on_display_failure_no_summary();
///\name More granular display routines
///\{
@@ -255,7 +256,7 @@ namespace paludis
virtual void show_resume_command() const;
void show_resume_command(const std::string &) const;
- virtual std::string make_resume_command(const PackageIDSequence &) const = 0;
+ virtual std::string make_resume_command(const bool undo_failures) const = 0;
virtual void on_installed_paludis();
virtual HookResult perform_hook(const Hook &) const;